Skip to content

Commit 9787860

Browse files
committed
Update documentation snapshot
...from latest manually edited docs in the lint source tree.
1 parent a357168 commit 9787860

12 files changed

+284
-43
lines changed

docs/api-guide/basics.md.html

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -714,10 +714,11 @@
714714
example layouts are processed before value files like translations)
715715
3. Kotlin and Java files
716716
4. Bytecode (local `.class` files and library `.jar` files)
717-
5. Gradle files
718-
6. Other files
719-
7. ProGuard files
720-
8. Property Files
717+
5. TOML files
718+
6. Gradle files
719+
7. Other files
720+
8. ProGuard files
721+
9. Property Files
721722

722723
Similarly, lint will always process libraries before the modules
723724
that depend on them.

docs/api-guide/changes.md.html

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,58 @@
55
information about user visible changes to lint, see the User
66
Guide.
77

8+
**8.2**
9+
10+
* For unit tests, you can now specify the language level to be used
11+
for Kotlin and Java. For example, if your unit test is using Java
12+
records, add `.javaLanguageLevel("17")` to your `lint()` test
13+
configuration.
14+
15+
**8.1**
16+
17+
* The [data flow analyzer](dataflow-analyzer.md.html) has been
18+
improved; in addition to fixing a few bugs, there are a couple of
19+
new convenience sub classes which makes common tasks easier to
20+
accomplish; see the documentation for `TargetMethodDataFlowAnalyzer`
21+
for example.
22+
23+
* The new `mavenLibrary` (and `binaryStub`) test files make it simple
24+
to create binary stub files in your tests, without having to perform
25+
compilation and check in base64 and gzip encoded test files. When
26+
your detector resolves references, the PSI elements you get back
27+
differ whether you're calling into source or into binary (jar/.class
28+
file) elements, so testing both (which the new test files automate
29+
using test modes) is helpful. More information about this is
30+
available in [](unit-testing.md.html).
31+
32+
* Lint now supports analyzing TOML files. There is a new
33+
Scope.TOML_FILE detectors can register an interest in, a new
34+
TomlScanner interface to implement for visitTomlDocument callbacks,
35+
etc. From a GradleScanner, you can directly resolve version catalog
36+
libraries via lookup methods on the GradleContext.
37+
38+
* Lint's “diff” output for unit test verification has been improved;
39+
it's now smarter about combining nearby chunks. (This should not
40+
break existing tests; the test infrastructure will try the older
41+
format as a fallback if the diffs aren't matching for the new
42+
format.)
43+
44+
* Lint contains JVM 17 bytecode. You will now need to use JDK 17+
45+
when compiling custom Lint checks. You should also configure
46+
the Kotlin compiler to target JVM 17, otherwise you may see errors
47+
when calling inline functions declared in Lint, UAST, or PSI.
48+
49+
* Lint's testing infrastructure now looks not just for test/
50+
but also androidTest/ and testFixtures/ to set the corresponding
51+
source set type on each test context.
52+
53+
**8.0**
54+
55+
* A new testmode which makes sure lint checks are all suppressible.
56+
It analyzes the reported error locations from the expected test
57+
output, and inserts suppress annotations in XML, Kotlin and Java
58+
files and makes sure that the corresponding warnings disappear.
59+
860
**7.4**
961

1062
* Annotation detectors can now specify just an annotation name instead

docs/api-guide/dataflow-analyzer.md.html

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@
4444
`DataFlowAnalyzer` class, and override one or more of its callbacks,
4545
and then tell it to analyze a method scope.
4646

47+
!!! Tip
48+
In recent versions of lint, there is a new special subclass of the
49+
`DataFlowAnalyzer`, `TargetMethodDataFlowAnalyzer`, which makes it
50+
easier to write flow analyzers where you are looking for a specific
51+
“cleanup” or close function invoked on an instance. See the separate
52+
section on `TargetMethodDataFlowAnalyzer` below for more information.
53+
4754
For the above transaction scenario, it might look like this:
4855

4956
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
@@ -303,6 +310,12 @@
303310
case you want to perform additional analysis to track field values; see
304311
the next section.
305312

313+
!!! Tip
314+
There is a special subclass of the `DataFlowAnalyzer`, called
315+
`EscapeCheckingDataFlowAnalyzer`, which you can extend instead. This
316+
handles recording all the scenarios where the instance escapes from
317+
the method, and at the end you can just check its `escaped` property.
318+
306319
## Non Local Analysis
307320

308321
In the above examples, if we found that the value escaped via a return
@@ -347,4 +360,40 @@
347360
[Source](https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:lint/libs/lint-checks/src/main/java/com/android/tools/lint/checks/SliceDetector.kt)
348361
[Test](https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:lint/libs/lint-tests/src/test/java/com/android/tools/lint/checks/SliceDetectorTest.kt)
349362

363+
## TargetMethodDataFlowAnalyzer
364+
365+
The `TargetMethodDataFlowAnalyzer` is a special subclass of the
366+
`DataFlowAnalyzer` which makes it simple to see if you eventually wind up
367+
calling a target method on a particular instance. For example, calling
368+
`close` on a file that was opened, or calling `start` on an animation you
369+
created.
370+
371+
In addition, there is an extension function on `UMethod` which visits
372+
this analyzer, and then checks for various conditions, e.g. whether the
373+
instance “escaped” (for example by being stored in a field or passed to
374+
another method), in which case you probably don't want to conclude (and
375+
report) that the close method is never called. It also handles failures
376+
to resolve, where it remembers whether there was a resolve failure, and
377+
if so it looks to see if it finds a likely match (with the same name as
378+
the target function), and if so also makes sure you don't report a false
379+
positive.
380+
381+
A simple way to do this is as follows:
382+
383+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
384+
val targets = mapOf("show" to listOf("android.widget.Toast",
385+
"com.google.android.material.snackbar.Snackbar")
386+
val analyzer = TargetMethodDataFlowAnalyzer.create(node, targets)
387+
if (method.isMissingTarget(analyzer)) {
388+
context.report(...)
389+
}
390+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
391+
392+
You can subclass `TargetMethodDataFlowAnalyzer` directly and override the
393+
`getTargetMethod` methods and any other UAST visitor methods if you want
394+
to customize the behavior further.
395+
396+
One advantage of using the `TargetMethodDataFlowAnalyzer` is that it also
397+
correctly handles method references.
398+
350399
<!-- Markdeep: --><style class="fallback">body{visibility:hidden;white-space:pre;font-family:monospace}</style><script src="markdeep.min.js" charset="utf-8"></script><script src="https://morgan3d.github.io/markdeep/latest/markdeep.min.js" charset="utf-8"></script><script>window.alreadyProcessedMarkdeep||(document.body.style.visibility="visible")</script>

docs/api-guide/messages.md.html

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,18 @@
8989
”Hello.“ to ”Hello, world!“ is compatible.
9090
* Adding a prefix
9191

92+
## Plurals
93+
94+
Avoid trying to make sentences gramatically correct and flexible by
95+
using constructs like ”(s)“ to quantity strings. In other words,
96+
instead of for example saying
97+
98+
*”register your receiver(s) in the manifest“*
99+
100+
just use the plural form,
101+
102+
*”register your receivers in the manifest“*
103+
92104
## Examples
93105

94106
Here are some examples from lint's built-in checks. Note that these are not

docs/api-guide/test-modes.md.html

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,4 +517,18 @@
517517
string resources, and will convert regular text into `CDATA` and makes
518518
sure the results continue to be the same.
519519

520+
### Suppressible Mode
521+
522+
Users should be able to ignore lint warnings by inserting suppress annotations
523+
(in Kotlin and Java), and via `tools:ignore` attributes in XML files.
524+
525+
This normally works for simple checks, but if you are combining results from
526+
different parts of the code, or for example caching locations and reporting
527+
them later, this is sometimes broken.
528+
529+
This test mode looks at the reported warnings from your unit tests, and then
530+
for each one, it looks up the corresponding error location's source file, and
531+
inserts a suppress directive at the nearest applicable location. It then
532+
re-runs the analysis, and makes sure that the warning no longer appears.
533+
520534
<!-- Markdeep: --><style class="fallback">body{visibility:hidden;white-space:pre;font-family:monospace}</style><script src="markdeep.min.js" charset="utf-8"></script><script src="https://morgan3d.github.io/markdeep/latest/markdeep.min.js" charset="utf-8"></script><script>window.alreadyProcessedMarkdeep||(document.body.style.visibility="visible")</script>

docs/api-guide/unit-testing.md.html

Lines changed: 81 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -338,10 +338,65 @@
338338

339339
## Binary and Compiled Source Files
340340

341-
If you need to use binaries in your unit tests, there is
342-
a special test file type for that: base64gzip. Here's an
343-
example from a lint check which tries to recognize usage
344-
of Cordova in the bytecode:
341+
If you need to use binaries in your unit tests, there are two options:
342+
343+
1. base64gzip
344+
2. API stubs
345+
346+
If you want to analyze bytecode of method bodies, you'll need to use
347+
the first option.
348+
349+
The first type requires you to actually compile your test file into a
350+
set of .class files, and check those in as a gzip-compressed, base64
351+
encoded string. Lint has utilities for this; see the next section.
352+
353+
The second option is using API stubs. For simple stub files (where you
354+
only need to provide APIs you'll call as binaries, but not code), lint
355+
can produce the corresponding bytecode on the fly, so you don't need
356+
to pre-create binary contents of the class. This is particularly
357+
helpful when you just want to create stubs for a library your lint
358+
check is targeting and you want to make sure the detector is seeing
359+
the same types of elements as it will when analyzing real code outside
360+
of tests (since there is a difference between resolving into APIs from
361+
source and form binaries; when you're analyzing calls into source, you
362+
can access for example method bodies, and this isn't available via
363+
UAST from byte code.)
364+
365+
These test files also let you specify an artifact name instead of a
366+
jar path, and lint will use this to place the jar in a special place
367+
such that it recognizes it (via `JavaEvaluator.findOwnerLibrary`) as
368+
belonging to this library.
369+
370+
Here's an example of how you can create one of these binary stub
371+
files:
372+
373+
```
374+
fun testIdentityEqualsOkay() {
375+
lint().files(
376+
kotlin(
377+
"/*test contents here *using* some recycler view APIs*/"
378+
).indented(),
379+
mavenLibrary(
380+
"androidx.recyclerview:recyclerview:1.0.0",
381+
java(
382+
"""
383+
package androidx.recyclerview.widget;
384+
public class DiffUtil {
385+
public abstract static class ItemCallback<T> {
386+
public abstract boolean areItemsTheSame(T oldItem, T newItem);
387+
public abstract boolean areContentsTheSame(T oldItem, T newItem);
388+
}
389+
}
390+
"""
391+
).indented()
392+
)
393+
).run().expect(
394+
```
395+
396+
## Base64-encoded gzipped byte code
397+
398+
Here's an example from a lint check which tries to recognize usage of
399+
Cordova in the bytecode:
345400

346401
```
347402
fun testVulnerableCordovaVersionInClasses() {
@@ -411,4 +466,26 @@
411466
Dependencies and Stubs“ section above, as well as the [frequently asked
412467
questions](faq.md.html).
413468

469+
## Language Level
470+
471+
Lint will analyze Java and Kotlin test files using its own default
472+
language levels. If you need a higher (or lower) language level in order
473+
to test a particular scenario, you can use the `kotlinLanguageLevel`
474+
and `javaLanguageLevel` setter methods on the lint test configuration.
475+
Here's an example of a unit test setup for Java records:
476+
477+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
478+
lint()
479+
.files(
480+
java("""
481+
record Person(String name, int age) {
482+
}
483+
""")
484+
.indented()
485+
)
486+
.javaLanguageLevel("17")
487+
.run()
488+
.expect(...)
489+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
490+
414491
<!-- Markdeep: --><style class="fallback">body{visibility:hidden;white-space:pre;font-family:monospace}</style><script src="markdeep.min.js" charset="utf-8"></script><script src="https://morgan3d.github.io/markdeep/latest/markdeep.min.js" charset="utf-8"></script><script>window.alreadyProcessedMarkdeep||(document.body.style.visibility="visible")</script>

docs/internal/document-checks.md.html

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@
2727
--builtins Generate documentation for the built-in
2828
issues. This is implied if --lint-jars is
2929
not specified
30+
--gmaven Generate documentation for the lint checks
31+
found on maven.google.com.
32+
--maven-central Generate documentation for a few well known
33+
lint libraries distributed on Maven Central.
3034
--lint-jars <jar-path> Read the lint issues from the specific path
3135
(separated by : of custom jar files
3236
--issues [issues] Limits the issues documented to the specific
@@ -85,34 +89,6 @@
8589
checks. If your lint check are packaged as an AAR file, you can unzip
8690
this file to find `lint.jar` inside.
8791

88-
## Generating AndroidX documentation
89-
90-
To generate the AndroidX documentation, check out the androidx
91-
repository into `$ANDROIDX_REPO`; then run
92-
93-
```shell
94-
$ cd $ANDROIDX_REPO/frameworks/support
95-
$ ./gradlew createArchive
96-
```
97-
98-
This will build all the lint custom checks in AndroidX. Then invoke the
99-
documentation generation tool like this:
100-
101-
```shell
102-
$ export ANDROID_URI_PREFIX=https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:
103-
104-
$ lint \
105-
--generate-docs \
106-
--output /tmp/lint-docs/ \
107-
--lint-jars $ANDROIDX_REPO/out \
108-
--source-url $ANDROID_URI_PREFIX $ANDROIDX_REPO/frameworks/support \
109-
--test-url $ANDROID_URI_PREFIX $ANDROIDX_REPO/frameworks/support
110-
```
111-
112-
If you want to include all the built-in Studio checks as well into a
113-
documentation set containing both, merge in the `--builtins` and
114-
`--source-url` and `--test-url` flags from above.
115-
11692
## Special Conventions
11793

11894
If you include a test URL search path (and note that the URI prefix is

docs/internal/verify.md.html

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@
4646
```ksh
4747
runGradleForAndroidX() {
4848
CUSTOM_REPO=$ADT_SOURCE_TREE/out/repo \
49-
GRADLE_PLUGIN_VERSION=7.1.0-dev \
49+
GRADLE_PLUGIN_VERSION=8.0.0-dev \
50+
LINT_VERSION=31.0.0-dev \
5051
GRADLE_PLUGIN_REPO=$ADT_SOURCE_TREE/out/repo:$ADT_SOURCE_TREE/prebuilts/tools/common/m2/repository \
5152
$ADT_SOURCE_TREE/tools/gradlew --parallel ${@}
5253
}
@@ -64,6 +65,11 @@
6465
flag with `--no-daemon -Dorg.gradle.debug=true`, run the build, and
6566
create a Remote configuration in IntelliJ and use it to attach.
6667

68+
You can also run `gwx updateLintBaseline` to have lint successfully
69+
run all targets and update the baselines and then inspect the diffs if
70+
you've added/updated lint checks and don't want it to stop after the
71+
first new (and correct) failure.
72+
6773
## Testing against Android Platform
6874

6975
Lint is run as part of the Android platform builds, including a number of custom lint checks specific to the platform.

docs/usage/agp-dsl.md.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,19 +135,19 @@
135135
standard output or standard error streams respectively. In recent
136136
versions of lint, this will also imply `textReport true`.
137137

138-
Example: `textOutput file(“$reportsDir/lint-results.txt”)`
138+
Example: `textOutput file(“$buildDir/reports/lint-results.txt”)`
139139

140140
`xmlReport` *true or false*
141141
: Whether lint should generate an XML report. If you don't specify a
142142
location using `xmlOutput`, lint will default to
143143
`lint-results-`*$variant*`.xml` in $module`/build/reports/, such as
144144
`app/build/reports/lint-results-debug.xml`.
145145

146-
`xmlOutput file("$reportsDir/lint-report.xml")`
146+
`xmlOutput file("$buildDir/reports/lint-report.xml")`
147147
: Where lint should write its XML report. In recent versions of lint,
148148
this will also imply `xmlReport true`.
149149

150-
Example: `xmlOutput file("$reportsDir/lint-results.xml")`
150+
Example: `xmlOutput file("$buildDir/reports/lint-results.xml")`
151151

152152
`htmlReport` *true or false*
153153
: Whether lint should generate an HTML report, with issue explanations,
@@ -162,7 +162,7 @@
162162
chapter](variables.md.html) for some flags to configure the HTML
163163
report.
164164

165-
Example: `htmlOutput file(“$reportsDir/lint-results.html”)`
165+
Example: `htmlOutput file(“$buildDir/reports/lint-results.html”)`
166166

167167
`sarifReport` *true or false*
168168
: Whether lint should generate a
@@ -176,7 +176,7 @@
176176
: Where lint should write its HTML SARIF. In recent versions of lint,
177177
this will also imply `sarifReport true`.
178178

179-
Example: `sarifOutput file("$reportsDir/lint-report.sarif.json")`
179+
Example: `sarifOutput file("$buildDir/reports/lint-report.sarif.json")`
180180

181181
`quiet` *true or false*
182182
: Whether lint should limit its diagnostic output. *False by default.*

0 commit comments

Comments
 (0)