diff --git a/.github/workflows/basic.yml b/.github/workflows/basic.yml
new file mode 100644
index 00000000..f9510301
--- /dev/null
+++ b/.github/workflows/basic.yml
@@ -0,0 +1,24 @@
+name: CI
+
+on: [push]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Validate gradle wrapper
+ uses: gradle/wrapper-validation-action@v1
+ - name: Set up JDK 17
+ uses: actions/setup-java@v1
+ with:
+ java-version: 17
+ # AGP 8.2 requires 34.0.0-rc3 - see https://issuetracker.google.com/issues/236167971#comment36
+ # and https://github.com/actions/runner-images/issues/7506#issuecomment-1533097084
+ # TODO: Remove when AGP updates Build Tools to 34.0.0 and pre-installed in the runner
+ #- name: Install Android Build Tools 34.0.0-rc3
+ # run: yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager "build-tools;34.0.0-rc3"
+ # shell: bash
+ - name: Build with Gradle
+ run: ./gradlew build test
diff --git a/.gitignore b/.gitignore
index 12f7e461..44b42418 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,3 +32,5 @@ Thumbs.db
#.idea/workspace.xml - remove # and delete .idea if it better suit your needs.
.gradle
build/
+
+lint-results.sarif
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 3e0558e0..efa2d160 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,5 +1,13 @@
# How to become a contributor and submit your own code
+## Documentation
+
+Note the all the documentation under docs/ is only a mirror;
+the original documentation is maintained in the Android
+source code repository:
+
+https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:lint/docs/
+
## Contributor License Agreements
We'd love to accept your sample apps and patches! Before we can take them, we
@@ -9,11 +17,11 @@ Please fill out either the individual or corporate Contributor License Agreement
(CLA).
* If you are an individual writing original source code and you're sure you
- own the intellectual property, then you'll need to sign an [individual CLA]
- (https://developers.google.com/open-source/cla/individual).
+ own the intellectual property, then you'll need to sign an
+ [individual CLA](https://developers.google.com/open-source/cla/individual).
* If you work for a company that wants to allow you to contribute your work,
- then you'll need to sign a [corporate CLA]
- (https://developers.google.com/open-source/cla/corporate).
+ then you'll need to sign a
+ [corporate CLA](https://developers.google.com/open-source/cla/corporate).
Follow either of the two links above to access the appropriate CLA and
instructions for how to sign and return it. Once we receive it, we'll be able to
@@ -28,9 +36,8 @@ accept your pull requests.
1. Fork the desired repo, develop and test your code changes.
1. Ensure that your code adheres to the existing style in the sample to which
you are contributing. Refer to the
- [Google Cloud Platform Samples Style Guide]
- (https://github.com/GoogleCloudPlatform/Template/wiki/style.html) for the
- recommended coding standards for this organization.
+ [Google Cloud Platform Samples Style Guide](https://github.com/GoogleCloudPlatform/Template/wiki/style.html)
+ for the recommended coding standards for this organization.
1. Ensure that your code has an appropriate set of unit tests which all pass.
1. Submit a pull request.
diff --git a/LICENSE b/LICENSE
index 4f229463..1af981f5 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,4 @@
-Apache License
---------------
-
+ Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
@@ -180,7 +178,7 @@ Apache License
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "{}"
+ boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
@@ -188,7 +186,7 @@ Apache License
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright {yyyy} {name of copyright owner}
+ Copyright 2014 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -201,447 +199,3 @@ Apache License
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-
-All image and audio files (including *.png, *.jpg, *.svg, *.mp3, *.wav
-and *.ogg) are licensed under the CC-BY-NC license. All other files are
-licensed under the Apache 2 license.
-
-CC-BY-NC License
-----------------
-
-Attribution-NonCommercial-ShareAlike 4.0 International
-
-=======================================================================
-
-Creative Commons Corporation ("Creative Commons") is not a law firm and
-does not provide legal services or legal advice. Distribution of
-Creative Commons public licenses does not create a lawyer-client or
-other relationship. Creative Commons makes its licenses and related
-information available on an "as-is" basis. Creative Commons gives no
-warranties regarding its licenses, any material licensed under their
-terms and conditions, or any related information. Creative Commons
-disclaims all liability for damages resulting from their use to the
-fullest extent possible.
-
-Using Creative Commons Public Licenses
-
-Creative Commons public licenses provide a standard set of terms and
-conditions that creators and other rights holders may use to share
-original works of authorship and other material subject to copyright
-and certain other rights specified in the public license below. The
-following considerations are for informational purposes only, are not
-exhaustive, and do not form part of our licenses.
-
- Considerations for licensors: Our public licenses are
- intended for use by those authorized to give the public
- permission to use material in ways otherwise restricted by
- copyright and certain other rights. Our licenses are
- irrevocable. Licensors should read and understand the terms
- and conditions of the license they choose before applying it.
- Licensors should also secure all rights necessary before
- applying our licenses so that the public can reuse the
- material as expected. Licensors should clearly mark any
- material not subject to the license. This includes other CC-
- licensed material, or material used under an exception or
- limitation to copyright. More considerations for licensors:
- wiki.creativecommons.org/Considerations_for_licensors
-
- Considerations for the public: By using one of our public
- licenses, a licensor grants the public permission to use the
- licensed material under specified terms and conditions. If
- the licensor's permission is not necessary for any reason--for
- example, because of any applicable exception or limitation to
- copyright--then that use is not regulated by the license. Our
- licenses grant only permissions under copyright and certain
- other rights that a licensor has authority to grant. Use of
- the licensed material may still be restricted for other
- reasons, including because others have copyright or other
- rights in the material. A licensor may make special requests,
- such as asking that all changes be marked or described.
- Although not required by our licenses, you are encouraged to
- respect those requests where reasonable. More_considerations
- for the public:
- wiki.creativecommons.org/Considerations_for_licensees
-
-=======================================================================
-
-Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
-Public License
-
-By exercising the Licensed Rights (defined below), You accept and agree
-to be bound by the terms and conditions of this Creative Commons
-Attribution-NonCommercial-ShareAlike 4.0 International Public License
-("Public License"). To the extent this Public License may be
-interpreted as a contract, You are granted the Licensed Rights in
-consideration of Your acceptance of these terms and conditions, and the
-Licensor grants You such rights in consideration of benefits the
-Licensor receives from making the Licensed Material available under
-these terms and conditions.
-
-
-Section 1 -- Definitions.
-
- a. Adapted Material means material subject to Copyright and Similar
- Rights that is derived from or based upon the Licensed Material
- and in which the Licensed Material is translated, altered,
- arranged, transformed, or otherwise modified in a manner requiring
- permission under the Copyright and Similar Rights held by the
- Licensor. For purposes of this Public License, where the Licensed
- Material is a musical work, performance, or sound recording,
- Adapted Material is always produced where the Licensed Material is
- synched in timed relation with a moving image.
-
- b. Adapter's License means the license You apply to Your Copyright
- and Similar Rights in Your contributions to Adapted Material in
- accordance with the terms and conditions of this Public License.
-
- c. BY-NC-SA Compatible License means a license listed at
- creativecommons.org/compatiblelicenses, approved by Creative
- Commons as essentially the equivalent of this Public License.
-
- d. Copyright and Similar Rights means copyright and/or similar rights
- closely related to copyright including, without limitation,
- performance, broadcast, sound recording, and Sui Generis Database
- Rights, without regard to how the rights are labeled or
- categorized. For purposes of this Public License, the rights
- specified in Section 2(b)(1)-(2) are not Copyright and Similar
- Rights.
-
- e. Effective Technological Measures means those measures that, in the
- absence of proper authority, may not be circumvented under laws
- fulfilling obligations under Article 11 of the WIPO Copyright
- Treaty adopted on December 20, 1996, and/or similar international
- agreements.
-
- f. Exceptions and Limitations means fair use, fair dealing, and/or
- any other exception or limitation to Copyright and Similar Rights
- that applies to Your use of the Licensed Material.
-
- g. License Elements means the license attributes listed in the name
- of a Creative Commons Public License. The License Elements of this
- Public License are Attribution, NonCommercial, and ShareAlike.
-
- h. Licensed Material means the artistic or literary work, database,
- or other material to which the Licensor applied this Public
- License.
-
- i. Licensed Rights means the rights granted to You subject to the
- terms and conditions of this Public License, which are limited to
- all Copyright and Similar Rights that apply to Your use of the
- Licensed Material and that the Licensor has authority to license.
-
- j. Licensor means the individual(s) or entity(ies) granting rights
- under this Public License.
-
- k. NonCommercial means not primarily intended for or directed towards
- commercial advantage or monetary compensation. For purposes of
- this Public License, the exchange of the Licensed Material for
- other material subject to Copyright and Similar Rights by digital
- file-sharing or similar means is NonCommercial provided there is
- no payment of monetary compensation in connection with the
- exchange.
-
- l. Share means to provide material to the public by any means or
- process that requires permission under the Licensed Rights, such
- as reproduction, public display, public performance, distribution,
- dissemination, communication, or importation, and to make material
- available to the public including in ways that members of the
- public may access the material from a place and at a time
- individually chosen by them.
-
- m. Sui Generis Database Rights means rights other than copyright
- resulting from Directive 96/9/EC of the European Parliament and of
- the Council of 11 March 1996 on the legal protection of databases,
- as amended and/or succeeded, as well as other essentially
- equivalent rights anywhere in the world.
-
- n. You means the individual or entity exercising the Licensed Rights
- under this Public License. Your has a corresponding meaning.
-
-
-Section 2 -- Scope.
-
- a. License grant.
-
- 1. Subject to the terms and conditions of this Public License,
- the Licensor hereby grants You a worldwide, royalty-free,
- non-sublicensable, non-exclusive, irrevocable license to
- exercise the Licensed Rights in the Licensed Material to:
-
- a. reproduce and Share the Licensed Material, in whole or
- in part, for NonCommercial purposes only; and
-
- b. produce, reproduce, and Share Adapted Material for
- NonCommercial purposes only.
-
- 2. Exceptions and Limitations. For the avoidance of doubt, where
- Exceptions and Limitations apply to Your use, this Public
- License does not apply, and You do not need to comply with
- its terms and conditions.
-
- 3. Term. The term of this Public License is specified in Section
- 6(a).
-
- 4. Media and formats; technical modifications allowed. The
- Licensor authorizes You to exercise the Licensed Rights in
- all media and formats whether now known or hereafter created,
- and to make technical modifications necessary to do so. The
- Licensor waives and/or agrees not to assert any right or
- authority to forbid You from making technical modifications
- necessary to exercise the Licensed Rights, including
- technical modifications necessary to circumvent Effective
- Technological Measures. For purposes of this Public License,
- simply making modifications authorized by this Section 2(a)
- (4) never produces Adapted Material.
-
- 5. Downstream recipients.
-
- a. Offer from the Licensor -- Licensed Material. Every
- recipient of the Licensed Material automatically
- receives an offer from the Licensor to exercise the
- Licensed Rights under the terms and conditions of this
- Public License.
-
- b. Additional offer from the Licensor -- Adapted Material.
- Every recipient of Adapted Material from You
- automatically receives an offer from the Licensor to
- exercise the Licensed Rights in the Adapted Material
- under the conditions of the Adapter's License You apply.
-
- c. No downstream restrictions. You may not offer or impose
- any additional or different terms or conditions on, or
- apply any Effective Technological Measures to, the
- Licensed Material if doing so restricts exercise of the
- Licensed Rights by any recipient of the Licensed
- Material.
-
- 6. No endorsement. Nothing in this Public License constitutes or
- may be construed as permission to assert or imply that You
- are, or that Your use of the Licensed Material is, connected
- with, or sponsored, endorsed, or granted official status by,
- the Licensor or others designated to receive attribution as
- provided in Section 3(a)(1)(A)(i).
-
- b. Other rights.
-
- 1. Moral rights, such as the right of integrity, are not
- licensed under this Public License, nor are publicity,
- privacy, and/or other similar personality rights; however, to
- the extent possible, the Licensor waives and/or agrees not to
- assert any such rights held by the Licensor to the limited
- extent necessary to allow You to exercise the Licensed
- Rights, but not otherwise.
-
- 2. Patent and trademark rights are not licensed under this
- Public License.
-
- 3. To the extent possible, the Licensor waives any right to
- collect royalties from You for the exercise of the Licensed
- Rights, whether directly or through a collecting society
- under any voluntary or waivable statutory or compulsory
- licensing scheme. In all other cases the Licensor expressly
- reserves any right to collect such royalties, including when
- the Licensed Material is used other than for NonCommercial
- purposes.
-
-
-Section 3 -- License Conditions.
-
-Your exercise of the Licensed Rights is expressly made subject to the
-following conditions.
-
- a. Attribution.
-
- 1. If You Share the Licensed Material (including in modified
- form), You must:
-
- a. retain the following if it is supplied by the Licensor
- with the Licensed Material:
-
- i. identification of the creator(s) of the Licensed
- Material and any others designated to receive
- attribution, in any reasonable manner requested by
- the Licensor (including by pseudonym if
- designated);
-
- ii. a copyright notice;
-
- iii. a notice that refers to this Public License;
-
- iv. a notice that refers to the disclaimer of
- warranties;
-
- v. a URI or hyperlink to the Licensed Material to the
- extent reasonably practicable;
-
- b. indicate if You modified the Licensed Material and
- retain an indication of any previous modifications; and
-
- c. indicate the Licensed Material is licensed under this
- Public License, and include the text of, or the URI or
- hyperlink to, this Public License.
-
- 2. You may satisfy the conditions in Section 3(a)(1) in any
- reasonable manner based on the medium, means, and context in
- which You Share the Licensed Material. For example, it may be
- reasonable to satisfy the conditions by providing a URI or
- hyperlink to a resource that includes the required
- information.
- 3. If requested by the Licensor, You must remove any of the
- information required by Section 3(a)(1)(A) to the extent
- reasonably practicable.
-
- b. ShareAlike.
-
- In addition to the conditions in Section 3(a), if You Share
- Adapted Material You produce, the following conditions also apply.
-
- 1. The Adapter's License You apply must be a Creative Commons
- license with the same License Elements, this version or
- later, or a BY-NC-SA Compatible License.
-
- 2. You must include the text of, or the URI or hyperlink to, the
- Adapter's License You apply. You may satisfy this condition
- in any reasonable manner based on the medium, means, and
- context in which You Share Adapted Material.
-
- 3. You may not offer or impose any additional or different terms
- or conditions on, or apply any Effective Technological
- Measures to, Adapted Material that restrict exercise of the
- rights granted under the Adapter's License You apply.
-
-
-Section 4 -- Sui Generis Database Rights.
-
-Where the Licensed Rights include Sui Generis Database Rights that
-apply to Your use of the Licensed Material:
-
- a. for the avoidance of doubt, Section 2(a)(1) grants You the right
- to extract, reuse, reproduce, and Share all or a substantial
- portion of the contents of the database for NonCommercial purposes
- only;
-
- b. if You include all or a substantial portion of the database
- contents in a database in which You have Sui Generis Database
- Rights, then the database in which You have Sui Generis Database
- Rights (but not its individual contents) is Adapted Material,
- including for purposes of Section 3(b); and
-
- c. You must comply with the conditions in Section 3(a) if You Share
- all or a substantial portion of the contents of the database.
-
-For the avoidance of doubt, this Section 4 supplements and does not
-replace Your obligations under this Public License where the Licensed
-Rights include other Copyright and Similar Rights.
-
-
-Section 5 -- Disclaimer of Warranties and Limitation of Liability.
-
- a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
- EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
- AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
- ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
- IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
- WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
- PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
- ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
- KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
- ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
-
- b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
- TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
- NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
- INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
- COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
- USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
- ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
- DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
- IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
-
- c. The disclaimer of warranties and limitation of liability provided
- above shall be interpreted in a manner that, to the extent
- possible, most closely approximates an absolute disclaimer and
- waiver of all liability.
-
-
-Section 6 -- Term and Termination.
-
- a. This Public License applies for the term of the Copyright and
- Similar Rights licensed here. However, if You fail to comply with
- this Public License, then Your rights under this Public License
- terminate automatically.
-
- b. Where Your right to use the Licensed Material has terminated under
- Section 6(a), it reinstates:
-
- 1. automatically as of the date the violation is cured, provided
- it is cured within 30 days of Your discovery of the
- violation; or
-
- 2. upon express reinstatement by the Licensor.
-
- For the avoidance of doubt, this Section 6(b) does not affect any
- right the Licensor may have to seek remedies for Your violations
- of this Public License.
-
- c. For the avoidance of doubt, the Licensor may also offer the
- Licensed Material under separate terms or conditions or stop
- distributing the Licensed Material at any time; however, doing so
- will not terminate this Public License.
-
- d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
- License.
-
-
-Section 7 -- Other Terms and Conditions.
-
- a. The Licensor shall not be bound by any additional or different
- terms or conditions communicated by You unless expressly agreed.
-
- b. Any arrangements, understandings, or agreements regarding the
- Licensed Material not stated herein are separate from and
- independent of the terms and conditions of this Public License.
-
-
-Section 8 -- Interpretation.
-
- a. For the avoidance of doubt, this Public License does not, and
- shall not be interpreted to, reduce, limit, restrict, or impose
- conditions on any use of the Licensed Material that could lawfully
- be made without permission under this Public License.
-
- b. To the extent possible, if any provision of this Public License is
- deemed unenforceable, it shall be automatically reformed to the
- minimum extent necessary to make it enforceable. If the provision
- cannot be reformed, it shall be severed from this Public License
- without affecting the enforceability of the remaining terms and
- conditions.
-
- c. No term or condition of this Public License will be waived and no
- failure to comply consented to unless expressly agreed to by the
- Licensor.
-
- d. Nothing in this Public License constitutes or may be interpreted
- as a limitation upon, or waiver of, any privileges and immunities
- that apply to the Licensor or You, including from the legal
- processes of any jurisdiction or authority.
-
-=======================================================================
-
-Creative Commons is not a party to its public licenses.
-Notwithstanding, Creative Commons may elect to apply one of its public
-licenses to material it publishes and in those instances will be
-considered the "Licensor." Except for the limited purpose of indicating
-that material is shared under a Creative Commons public license or as
-otherwise permitted by the Creative Commons policies published at
-creativecommons.org/policies, Creative Commons does not authorize the
-use of the trademark "Creative Commons" or any other trademark or logo
-of Creative Commons without its prior written consent including,
-without limitation, in connection with any unauthorized modifications
-to any of its public licenses or any other arrangements,
-understandings, or agreements concerning use of licensed material. For
-the avoidance of doubt, this paragraph does not form part of the public
-licenses.
-
-Creative Commons may be contacted at creativecommons.org.
-
diff --git a/README.md b/README.md
index 389cbe7f..8348f256 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,26 @@
Custom Lint Rules
-============
+=================
+
+The lint source code contains a lot of documentation on how to write
+custom checks; this git repository contains a snapshot of this
+documentation which you can read here:
+
+* [Full API Guide](https://googlesamples.github.io/android-custom-lint-rules/api-guide.html)
+* [Other docs](https://googlesamples.github.io/android-custom-lint-rules/index.html)
+
+Lint
+----
The [Android `lint` tool](http://developer.android.com/tools/help/lint.html) is a static code
- analysis tool that checks your Android project source files for potential bugs and optimization
- improvements for correctness, security, performance, usability, accessibility, and
- internationalization. Lint comes with over 200 checks, however it can be extended with additional
- custom rules.
+analysis tool that checks your project source files for potential bugs and optimization
+improvements for correctness, security, performance, usability, accessibility, and
+internationalization. Lint comes with around 400 built-in checks, but it can be extended with
+additional custom checks. This sample project shows how those sample checks can be built
+and packaged.
+
+Note that while Android Lint has the name "Android" in it, it is no longer an Android-specific
+static analysis tool; it's a general static analysis tool, and inside Google for example it is
+run to analyze server-side Java and Kotlin code.
**NOTE: The lint API is not a final API; if you rely on this be prepared
to adjust your code for the next tools release.**
@@ -13,14 +28,66 @@ The [Android `lint` tool](http://developer.android.com/tools/help/lint.html) is
Introduction
------------
-The Android Lint API allows users to create custom lint rules. For example, if you are the author of
- a library project, and your library project has certain usage requirements, you can write
- additional lint rules to check that your library is used correctly, and then you can distribute
- those extra lint rules for users of the library. Similarly, you may have company-local rules you'd
- like to enforce.
+The Android Lint API allows users to create custom lint checks. For example, if you are the author of
+an Android library project, and your library project has certain usage requirements, you can write
+additional lint rules to check that your library is used correctly, and then you can distribute
+those extra lint rules for users of the library. Similarly, you may have company-local rules you'd
+like to enforce.
This sample demonstrates how to create a custom lint checks and corresponding tests for those rules.
+
+# Sample Lint Checks
+
+This project shows how Android Studio as well as the Android Gradle plugin handles packaging of lint
+rules.
+
+## Lint Check Jar Library
+
+First, there's the lint check implementation itself. That's done in the
+"checks" project, which just applies the Gradle "java" or "kotlin" plugins, and
+that project produces a jar. Note that the dependencies for the lint
+check project (other than its testing dependencies) must all be "compileOnly":
+
+ dependencies {
+ compileOnly "com.android.tools.lint:lint-api:$lintVersion"
+ compileOnly "com.android.tools.lint:lint-checks:$lintVersion"
+ ...
+
+## Lint Check AAR Library
+
+Next, there's a separate Android library project, called "library". This
+library doesn't have any code on its own (though it could). However,
+in its build.gradle, it specifies this:
+
+ dependencies {
+ lintPublish project(':checks')
+ }
+
+This tells the Gradle plugin to take the output from the "checks" project
+and package that as a "lint.jar" payload inside this library's AAR file.
+When that's done, any other projects that depends on this library will
+automatically be using the lint checks.
+
+## App Modules
+
+Note that you don't have to go through the extra "library indirection"
+if you have a lint check that you only want to apply to one or more
+app modules. You can simply include the `lintChecks` dependency as shown
+above there as well, and then lint will include these rules when analyzing
+the project.
+
+## Lint Version
+
+The lint version of the libraries (specified in this project as the
+`lintVersion` variable in build.gradle) should be the same version
+that is used by the Gradle plugin.
+
+If the Gradle plugin version is *X*.*Y*.*Z*, then the Lint library
+version is *X+23*.*Y*.*Z*.
+
+For example, for AGP 7.0.0-alpha08, the lint API versions are 30.0.0-alpha08.
+
Getting Started
---------------
@@ -31,32 +98,73 @@ git clone https://github.com/googlesamples/android-custom-lint-rules.git
cd android-custom-lint-rules
```
-##### Build the validator
+##### Run The Sample
+
+Run the :app:lint target to have first the custom lint checks in checks/
+compiled, then wrapped into the library, and finally run lint on a
+sample app module which has violations of the check enforced by sample
+check in this project:
+```
+$ ./gradlew :app:lint
+
+> Task :app:lintDebug
-`./gradlew build`
+Scanning app: ...
+Wrote HTML report to file:///demo/android-custom-lint-rules/app/build/reports/lint-results-debug.html
+Wrote SARIF report to file:///demo/android-custom-lint-rules/app/build/reports/lint-results-debug.sarif
+
+/demo/android-custom-lint-rules/app/src/main/java/com/android/example/Test.kt:8: Warning: This code mentions lint: Congratulations [SampleId]
+ val s = "lint"
+ ~~~~
+
+ Explanation for issues of type "SampleId":
+ This check highlights string literals in code which mentions the word lint.
+ Blah blah blah.
+
+ Another paragraph here.
+
+ Vendor: Android Open Source Project
+ Contact: https://github.com/googlesamples/android-custom-lint-rules
+ Feedback: https://github.com/googlesamples/android-custom-lint-rules/issues
+
+0 errors, 1 warnings
+
+BUILD SUCCESSFUL in 1s
+```
-##### Copy to the lint directory
+##### Lint Dependencies
-`cp ./build/libs/android-custom-lint-rules.jar ~/.android/lint/`
+When building your own rules, you will likely want to know which dependencies you should
+bring into your own project. The below descriptions of the dependencies included within
+this project serve to help you make that decision:
-##### Verify whether the issues are registered with lint
+Source Dependencies
-`lint --show MainActivityDetector`
+- **com.android.tools.lint:lint-api**: The most important one; it contains things
+ like `LintClient`, the `Detector` base class, the `Issue` class, and everything else
+ that Lint checks rely on in the Lint framework.
+- **com.android.tools.lint:lint-checks**: Contains the built-in checks that are developed
+ internally. Also contains utilities that are sometimes useful for other lint checks,
+ such as the `VersionChecks` class (which figures out whether a given UAST element is
+ known to only be called at a given API level, either by surrounding `if >= SDK-version`
+ checks or `if < SDK-version` early returns in the method).
-##### Run lint
+Test Dependencies
-`./gradlew lint`
+- **com.android.tools.lint:lint-tests**: Contains useful utilities for writing unit tests
+ for Lint checks, including the `LintDetectorTest` base class.
+- **com.android.tools.lint:lint**: Lint checks don't need to depend on this. It's a
+ separate artifact used by tools that want to integrate lint with the command line,
+ such as the Gradle integration of lint. This is where things like terminal output, HTML
+ reporting, command line parsing etc is handled.
-> Note: If you can't run `lint` directly, you may want to include android tools `PATH` in your
- `~/.bash_profile`.
-> (i.e. `PATH=$PATH:~/Library/Android/sdk/tools`)
->
-> Then run `source ~/.bash_profile`.
+The APIs in all but the lint-api artifact are more likely to change incompatibly than
+the lint-api artifact.
Support
-------
-- Google+ Community: https://plus.google.com/communities/android
+- The "lint-dev" Google group: https://groups.google.com/forum/#!forum/lint-dev
- Stack Overflow: http://stackoverflow.com/questions/tagged/android
If you've found an error in this sample, please file an issue:
@@ -67,8 +175,9 @@ submitting a pull request through GitHub.
License
-------
-Licensed under the Apache 2.0 license. See the LICENSE file for details.
+Licensed under the Apache 2.0 license. See the [LICENSE](LICENSE) file for
+details.
How to make contributions?
--------------------------
-Please read and follow the steps in the CONTRIBUTING.md
+Please read and follow the steps in the [CONTRIBUTING](CONTRIBUTING.md)
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
new file mode 100644
index 00000000..b397c317
--- /dev/null
+++ b/app/build.gradle.kts
@@ -0,0 +1,33 @@
+plugins {
+ alias(libs.plugins.android.application)
+ alias(libs.plugins.kotlin.android)
+}
+
+android {
+ namespace = "com.android.example"
+ compileSdk = 34
+
+ defaultConfig {
+ applicationId = "com.android.example.lint_usage"
+ minSdk = 21
+ targetSdk = 34
+ versionCode = 1
+ versionName = "1.0"
+ }
+
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_17
+ targetCompatibility = JavaVersion.VERSION_17
+ }
+ lint {
+ checkDependencies = true
+ // Produce report for CI:
+ // https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/sarif-support-for-code-scanning
+ sarifOutput = file("../lint-results.sarif")
+ textReport = true
+ }
+}
+
+dependencies {
+ implementation(project(":library"))
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..3afd080a
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
diff --git a/app/src/main/java/com/android/example/Test.kt b/app/src/main/java/com/android/example/Test.kt
new file mode 100644
index 00000000..4983aebe
--- /dev/null
+++ b/app/src/main/java/com/android/example/Test.kt
@@ -0,0 +1,10 @@
+package com.android.example
+
+class Test {
+ // We have a custom lint check bundled with :library
+ // that this module depends on. The lint check looks
+ // for mentions of "lint", which should trigger an
+ // error
+ val s = "lint"
+ fun lint() { }
+}
diff --git a/build.gradle b/build.gradle
deleted file mode 100644
index 511e8e16..00000000
--- a/build.gradle
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-apply plugin: 'java'
-
-repositories {
- jcenter()
-}
-
-// JDK 1.6 is required to support all versions of Android Studio.
-// See http://tools.android.com/build/studio.
-sourceCompatibility = 1.6
-dependencies {
- compile 'com.android.tools.lint:lint-api:24.3.1'
- compile 'com.android.tools.lint:lint-checks:24.3.1'
- testCompile 'junit:junit:4.11'
- testCompile 'com.android.tools.lint:lint:24.3.1'
- testCompile 'com.android.tools.lint:lint-tests:24.3.1'
- testCompile 'com.android.tools:testutils:24.3.1'
-}
-
-jar {
- manifest {
- attributes("Lint-Registry": "com.example.google.lint.MyIssueRegistry")
- }
-}
-
-defaultTasks 'assemble'
diff --git a/build.gradle.kts b/build.gradle.kts
new file mode 100644
index 00000000..7511b799
--- /dev/null
+++ b/build.gradle.kts
@@ -0,0 +1,8 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+plugins {
+ alias(libs.plugins.kotlin.jvm) apply false
+ alias(libs.plugins.kotlin.android) apply false
+ alias(libs.plugins.android.application) apply false
+ alias(libs.plugins.android.library) apply false
+ alias(libs.plugins.android.lint) apply false
+}
diff --git a/checks/.gitignore b/checks/.gitignore
new file mode 100644
index 00000000..6ccc6caa
--- /dev/null
+++ b/checks/.gitignore
@@ -0,0 +1,3 @@
+/build
+lint-report.html
+lint-results.txt
diff --git a/checks/app b/checks/app
new file mode 100644
index 00000000..123a6651
--- /dev/null
+++ b/checks/app
@@ -0,0 +1,51 @@
+plugins {
+ alias(libs.plugins.androidApplication)
+ alias(libs.plugins.kotlinAndroid)
+}
+
+android {
+ namespace = "com.android.example.lint_usage"
+ compileSdk = 34
+
+ defaultConfig {
+ applicationId = "com.android.example.lint_usage"
+ minSdk = 21
+ targetSdk = 34
+ versionCode = 1
+ versionName = "1.0"
+ }
+
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_1_8
+ targetCompatibility = JavaVersion.VERSION_1_8
+ }
+ kotlinOptions {
+ jvmTarget = "1.8"
+ }
+ buildFeatures {
+ compose = true
+ }
+ composeOptions {
+ kotlinCompilerExtensionVersion = "1.5.1"
+ }
+}
+
+dependencies {
+
+ implementation(libs.core.ktx)
+ implementation(libs.lifecycle.runtime.ktx)
+ implementation(libs.activity.compose)
+ implementation(platform(libs.compose.bom))
+ implementation(libs.ui)
+ implementation(libs.ui.graphics)
+ implementation(libs.ui.tooling.preview)
+ implementation(libs.material3)
+ implementation(project(":library"))
+ testImplementation(libs.junit)
+ androidTestImplementation(libs.androidx.test.ext.junit)
+ androidTestImplementation(libs.espresso.core)
+ androidTestImplementation(platform(libs.compose.bom))
+ androidTestImplementation(libs.ui.test.junit4)
+ debugImplementation(libs.ui.tooling)
+ debugImplementation(libs.ui.test.manifest)
+}
\ No newline at end of file
diff --git a/checks/build.gradle.kts b/checks/build.gradle.kts
new file mode 100644
index 00000000..2f515374
--- /dev/null
+++ b/checks/build.gradle.kts
@@ -0,0 +1,24 @@
+plugins {
+ id("java-library")
+ alias(libs.plugins.kotlin.jvm)
+ alias(libs.plugins.android.lint)
+}
+
+java {
+ sourceCompatibility = JavaVersion.VERSION_17
+ targetCompatibility = JavaVersion.VERSION_17
+}
+
+lint {
+ htmlReport = true
+ htmlOutput = file("lint-report.html")
+ textReport = true
+ absolutePaths = false
+ ignoreTestSources = true
+}
+
+dependencies {
+ // For a description of the below dependencies, see the main project README
+ compileOnly(libs.bundles.lint.api)
+ testImplementation(libs.bundles.lint.tests)
+}
diff --git a/checks/src/main/java/com/example/lint/checks/AvoidDateDetector.kt b/checks/src/main/java/com/example/lint/checks/AvoidDateDetector.kt
new file mode 100644
index 00000000..cdda8bd4
--- /dev/null
+++ b/checks/src/main/java/com/example/lint/checks/AvoidDateDetector.kt
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.lint.checks
+
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import com.android.tools.lint.detector.api.SourceCodeScanner
+import com.intellij.psi.PsiMethod
+import org.jetbrains.uast.UCallExpression
+
+class AvoidDateDetector : Detector(), SourceCodeScanner {
+ companion object Issues {
+ private val IMPLEMENTATION =
+ Implementation(AvoidDateDetector::class.java, Scope.JAVA_FILE_SCOPE)
+
+ @JvmField
+ val ISSUE =
+ Issue.create(
+ id = "OldDate",
+ briefDescription = "Avoid Date and Calendar",
+ explanation =
+ """
+ The `java.util.Date` and `java.util.Calendar` classes should not be used; instead \
+ use the `java.time` package, such as `LocalDate` and `LocalTime`.
+ """,
+ category = Category.CORRECTNESS,
+ priority = 6,
+ severity = Severity.ERROR,
+ androidSpecific = true,
+ implementation = IMPLEMENTATION,
+ )
+ }
+
+ // java.util.Date()
+ override fun getApplicableConstructorTypes(): List = listOf("java.util.Date")
+
+ override fun visitConstructor(
+ context: JavaContext,
+ node: UCallExpression,
+ constructor: PsiMethod,
+ ) {
+ context.report(
+ ISSUE,
+ node,
+ context.getLocation(node),
+ "Don't use `Date`; use `java.time.*` instead",
+ fix()
+ .alternatives(
+ fix().replace().all().with("java.time.LocalTime.now()").shortenNames().build(),
+ fix().replace().all().with("java.time.LocalDate.now()").shortenNames().build(),
+ fix().replace().all().with("java.time.LocalDateTime.now()").shortenNames().build(),
+ ),
+ )
+ }
+
+ // java.util.Calendar.getInstance()
+ override fun getApplicableMethodNames(): List = listOf("getInstance")
+
+ override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) {
+ val evaluator = context.evaluator
+ if (!evaluator.isMemberInClass(method, "java.util.Calendar")) {
+ return
+ }
+ context.report(
+ ISSUE,
+ node,
+ context.getLocation(node),
+ "Don't use `Calendar.getInstance`; use `java.time.*` instead",
+ )
+ }
+}
diff --git a/checks/src/main/java/com/example/lint/checks/NotNullAssertionDetector.kt b/checks/src/main/java/com/example/lint/checks/NotNullAssertionDetector.kt
new file mode 100644
index 00000000..8d0fe2de
--- /dev/null
+++ b/checks/src/main/java/com/example/lint/checks/NotNullAssertionDetector.kt
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.lint.checks
+
+import com.android.tools.lint.client.api.UElementHandler
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Incident
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import com.android.tools.lint.detector.api.SourceCodeScanner
+import org.jetbrains.kotlin.analysis.api.analyze
+import org.jetbrains.kotlin.codegen.optimization.common.analyze
+import org.jetbrains.kotlin.psi.KtExpression
+import org.jetbrains.uast.UElement
+import org.jetbrains.uast.UPostfixExpression
+
+class NotNullAssertionDetector : Detector(), SourceCodeScanner {
+ companion object Issues {
+ private val IMPLEMENTATION =
+ Implementation(NotNullAssertionDetector::class.java, Scope.JAVA_FILE_SCOPE)
+
+ @JvmField
+ val ISSUE =
+ Issue.create(
+ id = "NotNullAssertion",
+ briefDescription = "Avoid `!!`",
+ explanation =
+ """
+ Do not use the `!!` operator. It can lead to null pointer exceptions. \
+ Please use the `?` operator instead, or assign to a local variable with \
+ `?:` initialization if necessary.
+ """,
+ category = Category.CORRECTNESS,
+ priority = 6,
+ severity = Severity.WARNING,
+ implementation = IMPLEMENTATION,
+ )
+ }
+
+ override fun getApplicableUastTypes(): List>? {
+ return listOf(UPostfixExpression::class.java)
+ }
+
+ override fun createUastHandler(context: JavaContext): UElementHandler {
+ return object : UElementHandler() {
+ override fun visitPostfixExpression(node: UPostfixExpression) {
+ if (node.operator.text == "!!") {
+ var message = "Do not use `!!`"
+
+ // Kotlin Analysis API example
+ val sourcePsi = node.operand.sourcePsi
+ if (sourcePsi is KtExpression) {
+ analyze(sourcePsi) {
+ val type = sourcePsi.getKtType()
+ if (type != null && !type.canBeNull) {
+ message += " -- it's not even needed here"
+ }
+ }
+ }
+
+ val incident = Incident(ISSUE, node, context.getLocation(node), message)
+ context.report(incident)
+ }
+ }
+ }
+ }
+}
diff --git a/checks/src/main/java/com/example/lint/checks/SampleCodeDetector.kt b/checks/src/main/java/com/example/lint/checks/SampleCodeDetector.kt
new file mode 100644
index 00000000..1f1efdca
--- /dev/null
+++ b/checks/src/main/java/com/example/lint/checks/SampleCodeDetector.kt
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.lint.checks
+
+import com.android.tools.lint.client.api.UElementHandler
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Detector.UastScanner
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import org.jetbrains.uast.UElement
+import org.jetbrains.uast.ULiteralExpression
+import org.jetbrains.uast.evaluateString
+
+/**
+ * Sample detector showing how to analyze Kotlin/Java code. This example flags all string literals
+ * in the code that contain the word "lint".
+ */
+class SampleCodeDetector : Detector(), UastScanner {
+ override fun getApplicableUastTypes(): List> {
+ return listOf(ULiteralExpression::class.java)
+ }
+
+ override fun createUastHandler(context: JavaContext): UElementHandler {
+ // Note: Visiting UAST nodes is a pretty general purpose mechanism;
+ // Lint has specialized support to do common things like "visit every class
+ // that extends a given super class or implements a given interface", and
+ // "visit every call site that calls a method by a given name" etc.
+ // Take a careful look at UastScanner and the various existing lint check
+ // implementations before doing things the "hard way".
+ // Also be aware of context.getJavaEvaluator() which provides a lot of
+ // utility functionality.
+ return object : UElementHandler() {
+ override fun visitLiteralExpression(node: ULiteralExpression) {
+ val string = node.evaluateString() ?: return
+ if (string.contains("lint") && string.matches(Regex(".*\\blint\\b.*"))) {
+ context.report(
+ ISSUE,
+ node,
+ context.getLocation(node),
+ "This code mentions `lint`: **Congratulations**",
+ )
+ }
+ }
+ }
+ }
+
+ companion object {
+ /** Issue describing the problem and pointing to the detector implementation. */
+ @JvmField
+ val ISSUE: Issue =
+ Issue.create(
+ // ID: used in @SuppressLint warnings etc
+ id = "SampleId",
+ // Title -- shown in the IDE's preference dialog, as category headers in the
+ // Analysis results window, etc
+ briefDescription = "Lint Mentions",
+ // Full explanation of the issue; you can use some markdown markup such as
+ // `monospace`, *italic*, and **bold**.
+ explanation =
+ """
+ This check highlights string literals in code which mentions the word `lint`. \
+ Blah blah blah.
+
+ Another paragraph here.
+ """, // no need to .trimIndent(), lint does that automatically
+ category = Category.CORRECTNESS,
+ priority = 6,
+ severity = Severity.WARNING,
+ implementation = Implementation(SampleCodeDetector::class.java, Scope.JAVA_FILE_SCOPE),
+ )
+ }
+}
diff --git a/checks/src/main/java/com/example/lint/checks/SampleIssueRegistry.kt b/checks/src/main/java/com/example/lint/checks/SampleIssueRegistry.kt
new file mode 100644
index 00000000..042eac3c
--- /dev/null
+++ b/checks/src/main/java/com/example/lint/checks/SampleIssueRegistry.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.lint.checks
+
+import com.android.tools.lint.client.api.IssueRegistry
+import com.android.tools.lint.client.api.Vendor
+import com.android.tools.lint.detector.api.CURRENT_API
+
+/*
+ * The list of issues that will be checked when running lint
.
+ */
+class SampleIssueRegistry : IssueRegistry() {
+ override val issues =
+ listOf(SampleCodeDetector.ISSUE, AvoidDateDetector.ISSUE, NotNullAssertionDetector.ISSUE)
+
+ override val api: Int
+ get() = CURRENT_API
+
+ override val minApi: Int
+ get() = 8 // works with Studio 4.1 or later; see com.android.tools.lint.detector.api.Api / ApiKt
+
+ // Requires lint API 30.0+; if you're still building for something
+ // older, just remove this property.
+ override val vendor: Vendor =
+ Vendor(
+ vendorName = "Android Open Source Project",
+ feedbackUrl = "https://github.com/googlesamples/android-custom-lint-rules/issues",
+ contact = "https://github.com/googlesamples/android-custom-lint-rules",
+ )
+}
diff --git a/checks/src/main/resources/META-INF/services/com.android.tools.lint.client.api.IssueRegistry b/checks/src/main/resources/META-INF/services/com.android.tools.lint.client.api.IssueRegistry
new file mode 100644
index 00000000..fa8542a3
--- /dev/null
+++ b/checks/src/main/resources/META-INF/services/com.android.tools.lint.client.api.IssueRegistry
@@ -0,0 +1 @@
+com.example.lint.checks.SampleIssueRegistry
diff --git a/checks/src/test/java/com/example/lint/checks/AvoidDateDetectorTest.kt b/checks/src/test/java/com/example/lint/checks/AvoidDateDetectorTest.kt
new file mode 100644
index 00000000..8f8fe5fb
--- /dev/null
+++ b/checks/src/test/java/com/example/lint/checks/AvoidDateDetectorTest.kt
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.lint.checks
+
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Issue
+
+class AvoidDateDetectorTest : LintDetectorTest() {
+ override fun getDetector(): Detector = AvoidDateDetector()
+
+ override fun getIssues(): List = listOf(AvoidDateDetector.ISSUE)
+
+ fun testDocumentationExample() {
+ lint()
+ .files(
+ kotlin(
+ """
+ package test.pkg
+ import java.util.Date
+ fun test() {
+ val date = Date()
+ }
+ """
+ )
+ .indented(),
+ kotlin(
+ """
+ package test.pkg
+ import java.util.Calendar
+
+ fun test2() {
+ val calendar = Calendar.getInstance()
+ }
+ """
+ )
+ .indented(),
+ )
+ .allowMissingSdk()
+ .run()
+ .expect(
+ """
+ src/test/pkg/test.kt:4: Error: Don't use Date; use java.time.* instead [OldDate]
+ val date = Date()
+ ~~~~~~
+ src/test/pkg/test2.kt:5: Error: Don't use Calendar.getInstance; use java.time.* instead [OldDate]
+ val calendar = Calendar.getInstance()
+ ~~~~~~~~~~~~~~~~~~~~~~
+ 2 errors, 0 warnings
+ """
+ )
+ .expectFixDiffs(
+ """
+ Fix for src/test/pkg/test.kt line 4: Replace with java.time.LocalTime.now():
+ @@ -2 +2
+ + import java.time.LocalTime
+ @@ -4 +5
+ - val date = Date()
+ + val date = LocalTime.now()
+ Fix for src/test/pkg/test.kt line 4: Replace with java.time.LocalDate.now():
+ @@ -2 +2
+ + import java.time.LocalDate
+ @@ -4 +5
+ - val date = Date()
+ + val date = LocalDate.now()
+ Fix for src/test/pkg/test.kt line 4: Replace with java.time.LocalDateTime.now():
+ @@ -2 +2
+ + import java.time.LocalDateTime
+ @@ -4 +5
+ - val date = Date()
+ + val date = LocalDateTime.now()
+ """
+ )
+ }
+}
diff --git a/checks/src/test/java/com/example/lint/checks/NotNullAssertionDetectorTest.kt b/checks/src/test/java/com/example/lint/checks/NotNullAssertionDetectorTest.kt
new file mode 100644
index 00000000..3b951866
--- /dev/null
+++ b/checks/src/test/java/com/example/lint/checks/NotNullAssertionDetectorTest.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.lint.checks
+
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Issue
+
+class NotNullAssertionDetectorTest : LintDetectorTest() {
+ override fun getDetector(): Detector {
+ return NotNullAssertionDetector()
+ }
+
+ override fun getIssues(): List {
+ return listOf(NotNullAssertionDetector.ISSUE)
+ }
+
+ fun testDocumentationExample() {
+ lint()
+ .files(
+ kotlin(
+ """
+ package test.pkg
+
+ fun test(s: String?, t: String) {
+ s?.plus(s)
+ s!!.plus(s)
+ t!!.plus(t)
+ }
+ """
+ )
+ .indented()
+ )
+ .run()
+ .expect(
+ """
+ src/test/pkg/test.kt:5: Warning: Do not use !! [NotNullAssertion]
+ s!!.plus(s)
+ ~~~
+ src/test/pkg/test.kt:6: Warning: Do not use !! -- it's not even needed here [NotNullAssertion]
+ t!!.plus(t)
+ ~~~
+ 0 errors, 2 warnings
+ """
+ )
+ }
+}
diff --git a/checks/src/test/java/com/example/lint/checks/SampleCodeDetectorTest.kt b/checks/src/test/java/com/example/lint/checks/SampleCodeDetectorTest.kt
new file mode 100644
index 00000000..3f9afa37
--- /dev/null
+++ b/checks/src/test/java/com/example/lint/checks/SampleCodeDetectorTest.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.lint.checks
+
+import com.android.tools.lint.checks.infrastructure.TestFiles.java
+import com.android.tools.lint.checks.infrastructure.TestLintTask.lint
+import org.junit.Test
+
+class SampleCodeDetectorTest {
+ @Test
+ fun testBasic() {
+ lint()
+ .files(
+ java(
+ """
+ package test.pkg;
+ public class TestClass1 {
+ // In a comment, mentioning "lint" has no effect
+ private static String s1 = "Ignore non-word usages: linting";
+ private static String s2 = "Let's say it: lint";
+ }
+ """
+ )
+ .indented()
+ )
+ .issues(SampleCodeDetector.ISSUE)
+ .run()
+ .expect(
+ """
+ src/test/pkg/TestClass1.java:5: Warning: This code mentions lint: Congratulations [SampleId]
+ private static String s2 = "Let's say it: lint";
+ ~~~~~~~~~~~~~~~~~~~~
+ 0 errors, 1 warnings
+ """
+ )
+ }
+}
diff --git a/docs/.gitignore b/docs/.gitignore
new file mode 100644
index 00000000..92ba6dce
--- /dev/null
+++ b/docs/.gitignore
@@ -0,0 +1,5 @@
+markdeep.min.js
+todo.md
+blank.md.html
+spell-check.sh
+spelling-ok.txt
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 00000000..e386b599
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,12 @@
+Android Lint
+============
+
+(Note that many files in this docs folder has the extension `.md.html`
+instead of just `.md`. That means that they can be opened in a
+browser for better visualization (such as syntax highlighting of code
+snippets) but are readable and editable as markdown.)
+
+Let's go there right now: [Link](README.md.html)
+
+A (usually recent) snapshot of these docs are hosted
+[here](https://googlesamples.github.io/android-custom-lint-rules/).
diff --git a/docs/README.md.html b/docs/README.md.html
new file mode 100644
index 00000000..4fa4bb40
--- /dev/null
+++ b/docs/README.md.html
@@ -0,0 +1,78 @@
+Android Lint
+============
+
+Android Lint is a static analysis tool (which despite the name is not
+limited to Android, and within Google for example is used to analyze
+Java and Kotlin server side code as well as Android and even desktop
+software like IDEs.)
+
+Lint's focus is on finding bugs (whether they are related to
+correctness, performance, security, internationalization, usability and
+so on); it's not a source code style checker.
+
+Available documentation:
+
+* [Lint Features](features.md.html)
+* [Recent Changes](changes.md.html)
+* Documents for users of lint, in the `usage` folder:
+ - [Complete Book](user-guide.md.html), containing all of the below
+ documents as chapters, suitable for offline reading
+ - [Issue documentation](https://googlesamples.github.io/android-custom-lint-rules/checks/index.md.html)
+ which lists all the available checks and provides documentation
+ for each one.
+ - [Performance Tuning Tips](usage/performance-tuning.md.html)
+ - [How to suppress incidents](usage/suppressing.md.html)
+ - [How to use baselines](usage/baselines.md.html)
+ - [How to use `lint.xml` files](usage/lintxml.md.html)
+ - [Gradle plugin DSL](usage/agp-dsl.md.html)
+ - [Using a newer version of lint than the Gradle bundled one](usage/newer-lint.md.html)
+ - [Lint command line](usage/flags.md.html)
+ - [Environment variables and properties](usage/variables.md.html)
+* Documents for authors of additional lint checks, in the
+ `api-guide` folder:
+ - [Complete Book](api-guide.md.html), containing all of the below
+ documents as chapters, suitable for offline reading
+ - [Basics](api-guide/basics.md.html)
+ - [A Sample Lint Check](api-guide/example.md.html)
+ - [Analyzing data flow](api-guide/dataflow-analyzer.md.html)
+ - [Publishing a Lint check](api-guide/publishing.md.html)
+ - [AST Analysis](api-guide/ast-analysis.md.html)
+ - [Unit Testing](api-guide/unit-testing.md.html)
+ - [Test Modes](api-guide/test-modes.md.html)
+ - [Annotations](api-guide/annotations.md.html)
+ - [Adding Quick Fixes](api-guide/quickfixes.md.html)
+ - [Terminology](api-guide/terminology.md.html)
+ - [Partial analysis](api-guide/partial-analysis.md.html)
+ - [Crafting error messages](api-guide/messages.md.html)
+ - [Configuring detectors with options](api-guide/options.md.html)
+ - [Frequently Asked Questions](api-guide/faq.md.html)
+* Documents for lint internals, intended for developers of lint
+ itself, in the `internal` folder:
+ - [Guidelines](internal/guidelines.md.html)
+ - [Generating Issue Documentation](internal/document-checks.md.html)
+ - [Testing dev builds](internal/verify.md.html)
+
+---------------------------------------------------------------------
+
+Documentation History:
+* June 2022: Added documentation for [crafting error
+ messages](messages.md.html)
+* May 2022: Noticed that the document rendering
+ was broken, such that many chapters were missing from
+ the api-guide: “Adding Quickfixes”, “Partial Analysis”,
+ “Data Flow Analyzer”, “Annotations”, and “Options”.
+ These are now included.
+* November 2021: Added documentation for [option
+ handling](api-guide/options.md.html)
+* September 2021: Added documentation for [annotation
+ handling](api-guide/annotations.md.html)
+* July 2021: Added documentation for
+ [test modes](api-guide/test-modes.md.html)
+* June 2021: Added documentation for the
+ [dataflow analyzer](api-guide/dataflow-analyzer.md.html),
+ [Lint Gradle DSL](usage/agp-dsl.md.html) and
+ [command line flags](usage/flags.md.html).
+* May 2021: Added documentation for individual lint issues
+* March 2021: Initial version
+
+
diff --git a/docs/api-guide.html b/docs/api-guide.html
new file mode 100644
index 00000000..56a7eb25
--- /dev/null
+++ b/docs/api-guide.html
@@ -0,0 +1,8468 @@
+
+
+
+
+$$\newcommand{\n}{\hat{n}}\newcommand{\thetai}{\theta_\mathrm{i}}\newcommand{\thetao}{\theta_\mathrm{o}}\newcommand{\d}[1]{\mathrm{d}#1}\newcommand{\w}{\hat{\omega}}\newcommand{\wi}{\w_\mathrm{i}}\newcommand{\wo}{\w_\mathrm{o}}\newcommand{\wh}{\w_\mathrm{h}}\newcommand{\Li}{L_\mathrm{i}}\newcommand{\Lo}{L_\mathrm{o}}\newcommand{\Le}{L_\mathrm{e}}\newcommand{\Lr}{L_\mathrm{r}}\newcommand{\Lt}{L_\mathrm{t}}\newcommand{\O}{\mathrm{O}}\newcommand{\degrees}{{^{\large\circ}}}\newcommand{\T}{\mathsf{T}}\newcommand{\mathset}[1]{\mathbb{#1}}\newcommand{\Real}{\mathset{R}}\newcommand{\Integer}{\mathset{Z}}\newcommand{\Boolean}{\mathset{B}}\newcommand{\Complex}{\mathset{C}}\newcommand{\un}[1]{\,\mathrm{#1}}$$
+
+
Android Lint API Guide
Android Lint API Guide
+
+
+
+
+
+This chapter inlines all the API documentation into a single
+long book, suitable for printing or reading on a tablet.
+
+
+ Terminology
+
+
+
+You don't need to read this up front and understand everything, but
+this is hopefully a handy reference to return to.
+
+
+
+In alphabetical order:
+
+
+
+
Configuration A configuration provides extra information or parameters to lint on a
+ per-project, or even per-directory, basis. For example, the lint.xml
+ files can change the severity for issues, or list incidents to ignore
+ (matched for example by a regular expression), or even provide values
+ for options read by a specific detector.
+
+
Context An object passed into detectors in many APIs, providing data about
+ (for example) which file is being analyzed (and in which project),
+ and (for specific types of analysis) additional information; for
+ example, an XmlContext points to the DOM document, a JavaContext
+ includes the AST, and so on.
+
+
Detector The implementation of the lint check which registers Issues, analyzes
+ the code, and reports Incidents.
+
+
Implementation An Implementation
tells lint how a given issue is actually
+ analyzed, such as which detector class to instantiate, as well as
+ which scopes the detector applies to.
+
+
Incident A specific occurrence of the issue at a specific location.
+ An example of an incident is:
+
Warning: In file IoUtils.kt, line 140, the field download folder
+ is "/sdcard/downloads"; do not hardcode the path to `/sdcard`.
Issue A type or class of problem that your lint check identifies. An issue
+ has an associated severity (error, warning or info), a priority, a
+ category, an explanation, and so on.
+
+
+
+ An example of an issue is “Don't hardcode paths to /sdcard”.
+
+
IssueRegistry An IssueRegistry
provides a list of issues to lint. When you write
+ one or more lint checks, you'll register these in an IssueRegistry
+ and point to it using the META-INF
service loader mechanism.
+
+
LintClient The LintClient
represents the specific tool the detector is running
+ in. For example, when running in the IDE there is a LintClient which
+ (when incidents are reported) will show highlights in the editor,
+ whereas when lint is running as part of the Gradle plugin, incidents
+ are instead accumulated into HTML (and XML and text) reports, and
+ the build interrupted on error.
+
+
Location A “location” refers to a place where an incident is reported.
+ Typically this refers to a text range within a source file, but a
+ location can also point to a binary file such as a png
file.
+ Locations can also be linked together, along with descriptions.
+ Therefore, if you for example are reporting a duplicate declaration,
+ you can include both Locations, and in the IDE, both locations
+ (if they're in the same file) will be highlighted. A location linked
+ from another is called a “secondary” location, but the chaining can
+ be as long as you want (and lint's unit testing infrastructure will
+ make sure there are no cycles.)
+
+
Partial Analysis A “map reduce” architecture in lint which makes it possible to
+ analyze individual modules in isolation and then later filter and
+ customize the partial results based on conditions outside of these
+ modules. This is explained in greater detail in the
+ partial analysis chapter.
+
+
Platform The Platform
abstraction allows lint issues to indicate where they
+ apply (such as “Android”, or “Server”, and so on). This means that an
+ Android-specific check won't trigger warnings on non-Android code.
+
+
Scanner A Scanner
is a particular interface a detector can implement to
+ indicate that it supports a specific set of callbacks. For example,
+ the XmlScanner
interface is where the methods for visiting XML
+ elements and attributes are defined, and the ClassScanner
is where
+ the ASM bytecode handling methods are defined, and so on.
+
+
Scope Scope
is an enum which lists various types of files that a detector
+ may want to analyze.
+
+
+
+ For example, there is a scope for XML files, there is a scope for
+ Java and Kotlin files, there is a scope for .class files, and so on.
+
+
+
+ Typically lint cares about which set of scopes apply,
+ so most of the APIs take an EnumSet<Scope>
, but we'll often
+ refer to this as just “the scope” instead of the “scope set”.
+
+
Severity For an issue, whether the incident should be an error, or just a
+ warning, or neither (just an FYI highlight). There is also a special
+ type of error severity, “fatal”, discussed later.
+
+
TextFormat An enum describing various text formats lint understands. Lint checks
+ will typically only operate with the “raw” format, which is
+ markdown-like (e.g. you can surround words with an asterisk to make
+ it italics or two to make it bold, and so on).
+
+
Vendor A Vendor
is a simple data class which provides information about
+ the provenance of a lint check: who wrote it, where to file issues,
+ and so on.
+
+
+ Writing a Lint Check: Basics
+
+ Preliminaries
+
+
+
+(If you already know a lot of the basics but you're here because you've
+run into a problem and you're consulting the docs, take a look at the
+frequently asked questions chapter.)
+
+
+ “Lint?”
+
+
+
+The lint
tool shipped with the C compiler and provided additional
+static analysis of C code beyond what the compiler checked.
+
+
+
+Android Lint was named in honor of this tool, and with the Android
+prefix to make it really clear that this is a static analysis tool
+intended for analysis of Android code, provided by the Android Open
+Source Project — and to disambiguate it from the many other tools with
+“lint” in their names.
+
+
+
+However, since then, Android Lint has broadened its support and is no
+longer intended only for Android code. In fact, within Google, it is
+used to analyze all Java and Kotlin code. One of the reasons for this
+is that it can easily analyze both Java and Kotlin code without having
+to implement the checks twice. Additional features are described in the
+features chapter.
+
+
+
+We're planning to rename lint to reflect this new role, so we are
+looking for good name suggestions.
+
+
+ API Stability
+
+
+
+Lint's APIs are not stable, and a large part of Lint's API surface is
+not under our control (such as UAST and PSI). Therefore, custom lint
+checks may need to be updated periodically to keep working.
+
+
+
+However, “some APIs are more stable than others”. In particular, the
+detector API (described below) is much less likely to change than the
+client API (which is not intended for lint check authors but for tools
+integrating lint to run within, such as IDEs and build systems).
+
+
+
+However, this doesn't mean the detector API won't change. A large part
+of the API surface is external to lint; it's the AST libraries (PSI and
+UAST) for Java and Kotlin from JetBrains; it's the bytecode library
+(asm.ow2.io), it's the XML DOM library (org.w3c.dom), and so on. Lint
+intentionally stays up to date with these, so any API or behavior
+changes in these can affect your lint checks.
+
+
+
+Lint's own APIs may also change. The current API has grown organically
+over the last 10 years (the first version of lint was released in 2011)
+and there are a number of things we'd clean up and do differently if
+starting over. Not to mention rename and clean up inconsistencies.
+
+
+
+However, lint has been pretty widely adopted, so at this point creating
+a nicer API would probably cause more harm than good, so we're limiting
+recent changes to just the necessary ones. An example of this is the
+new partial analysis architecture in 7.0
+which is there to allow much better CI and incremental analysis
+performance.
+
+
+ Kotlin
+
+
+
+We recommend that you implement your checks in Kotlin. Part of
+the reason for that is that the lint API uses a number of Kotlin
+features:
+
+
+
+
+Named and default parameters : Rather than using builders, some
+ construction methods, like Issue.create()
have a lot of parameters
+ with default parameters. The API is cleaner to use if you just
+ specify what you need and rely on defaults for everything else.
+
+
+
+
+Compatibility : We may add additional parameters over time. It
+ isn't practical to add @JvmOverloads on everything.
+
+
+
+
+Package-level functions : Lint's API includes a number of package
+ level utility functions (in previous versions of the API these are all
+ thrown together in a LintUtils
class).
+
+
+
+
+Deprecations : Kotlin has support for simple API migrations. For
+ example, in the below example, the new @Deprecated
annotation on
+ lines 1 through 7 will be added in an upcoming release, to ease
+ migration to a new API. IntelliJ can automatically quickfix these
+ deprecation replacements.
+
+
@Deprecated(
+ "Use the new report(Incident) method instead, which is more future proof" ,
+ ReplaceWith(
+ "report(Incident(issue, message, location, null, quickfixData))" ,
+ "com.android.tools.lint.detector.api.Incident"
+ )
+ )
+@JvmOverloads
+open fun report (
+ issue: Issue ,
+ location: Location ,
+ message: String ,
+ quickfixData: LintFix ? = null
+ ) {
+
+ }
+
+As of 7.0, there is more Kotlin code in lint than remaining Java
+code:
+
+
Language files blank comment code
+ Kotlin 420 14243 23239 130250
+ Java 289 8683 15205 101549
+
$ cloc lint/
+
+
+
+And that's for all of lint, including many old lint detectors which
+haven't been touched in years. In the Lint API library,
+lint/libs/lint-api
, the code is 78% Kotlin and 22% Java.
+
+
+ Concepts
+
+
+
+Lint will search your source code for problems. There are many types of
+problems, and each one is called an Issue
, which has associated
+metadata like a unique id, a category, an explanation, and so on.
+
+
+
+Each instance that it finds is called an “incident”.
+
+
+
+The actual responsibility of searching for and reporting incidents is
+handled by detectors — subclasses of Detector
. Your lint check will
+extend Detector
, and when it has found a problem, it will “report”
+the incident to lint.
+
+
+
+A Detector
can analyze more than one Issue
. For example, the
+built-in StringFormatDetector
analyzes formatting strings passed to
+String.format()
calls, and in the process of doing that discovers
+multiple unrelated issues — invalid formatting strings, formatting
+strings which should probably use the plurals API instead, mismatched
+types, and so on. The detector could simply have a single issue called
+“StringFormatProblems” and report everything as a StringFormatProblem,
+but that's not a good idea. Each of these individual types of String
+format problems should have their own explanation, their own category,
+their own severity, and most importantly should be individually
+configurable by the user such that they can disable or promote one of
+these issues separately from the others.
+
+
+
+A Detector
can indicate which sets of files it cares about. These are
+called “scopes”, and the way this works is that when you register your
+Issue
, you tell that issue which Detector
class is responsible for
+analyzing it, as well as which scopes the detector cares about.
+
+
+
+If for example a lint check wants to analyze Kotlin files, it can
+include the Scope.JAVA_FILE
scope, and now that detector will be
+included when lint processes Java or Kotin files.
+
+
+
+
The name Scope.JAVA_FILE
may make it sound like there should also
+ be a Scope.KOTLIN_FILE
. However, JAVA_FILE
here really refers to
+ both Java and Kotlin files since the analysis and APIs are identical
+ for both (using “UAST”, a unified abstract syntax tree). However,
+ at this point we don't want to rename it since it would break a lot
+ of existing checks. We might introduce an alias and deprecate this
+ one in the future.
+
+
+
+When detectors implement various callbacks, they can analyze the
+code, and if they find a problematic pattern, they can “report”
+the incident. This means computing an error message, as well as
+a “location”. A “location” for an incident is really an error
+range — a file, and a starting offset and an ending offset. Locations
+can also be linked together, so for example for a “duplicate
+declaration” error, you can and should include both locations.
+
+
+
+Many detector methods will pass in a Context
, or a more specific
+subclass of Context
such as JavaContext
or XmlContext
. This
+allows lint to give the detectors information they may need, without
+passing in a lot of parameters. It also allows lint to add additional data
+over time without breaking signatures.
+
+
+
+The Context
classes also provide many convenience APIs. For example,
+for XmlContext
there are methods for creating locations for XML tags,
+XML attributes, just the name part of an XML attribute, and just the
+value part of an XML attribute. For a JavaContext
there are also
+methods for creating locations, such as for a method call, including
+whether to include the receiver and/or the argument list.
+
+
+
+When you report an Incident
you can also provide a LintFix
; this is
+a quickfix which the IDE can use to offer actions to take on the
+warning. In some cases, you can offer a complete and correct fix (such
+as removing an unused element). In other cases the fix may be less
+clear; for example, the AccessibilityDetector
asks you to set a
+description for images; the quickfix will set the content attribute,
+but will leave the text value as TODO and will select the string such
+that the user can just type to replace it.
+
+
+
+
When reporting incidents, make sure that the error messages are not
+ generic; try to be explicit and include specifics for the current
+ scenario. For example, instead of just “Duplicate declaration”, use
+ “
$name
has already been declared”. This isn't just for cosmetics;
+ it also makes lint's
baseline
+ mechanism work better since it
+ currently matches by id + file + message, not by line numbers which
+ typically drift over time.
+
+
+ Client API versus Detector API
+
+
+
+Lint's API has two halves:
+
+
+
+
+The Client API : “Integrate (and run) lint from within a tool”.
+ For example, both the IDE and the build system use this API to embed
+ and invoke lint to analyze the code in the project or editor.
+
+
+
+
+The Detector API : “Implement a new lint check”. This is the API
+ which lets checkers analyze code and report problems that they find.
+
+
+
+The class in the Client API which represents lint running in a tool is
+called LintClient
. This class is responsible for, among other things:
+
+
+
+
+Reporting incidents found by detectors . For example, in the IDE, it
+ will place error markers into the source editor, and in a build
+ system, it may write warnings to the console or generate a report or
+ even fail the build.
+
+
+
+
+Handling I/O . Detectors should never read files from disk directly.
+ This allows lint checks to work smoothly in for example the IDE. When
+ lint runs on the fly, and a lint check asks for the source file
+ contents (or other supporting files), the LintClient
in the IDE
+ will implement the readFile
method to first look in the open source
+ editors and if the requested file is being edited, it will return the
+ current (often unsaved!) contents.
+
+
+
+
+Handling network traffic . Lint checks should never open
+ URLConnections themselves. Instead, they should go through the lint API
+ to request data for URLs. Among other things, this allows the
+ LintClient
to use configured IDE proxy settings (as is done in the
+ IntelliJ integration of lint). This is also good for testing, because
+ the special unit test implementation of a LintClient
has a simple way
+ to provide exact responses for specific URLs:
+
+
lint()
+ .files(...)
+ // Set up exactly the expected maven.google.com network output to
+ // ensure stable version suggestions in the tests
+ .networkData("https://maven.google.com/master-index.xml", ""
+ + "\n"
+ + "<metadata > \n"
+ + " <com.android.tools.build > "
+ + "</com.android.tools.build > </metadata > ")
+ .networkData("https://maven.google.com/com/android/tools/build/group-index.xml", ""
+ + "\n"
+ + "<com.android.tools.build > \n"
+ + " <gradle versions ="\" 2.3.3 ,3.0.0-alpha1 \"/"> \n"
+ + "</gradle > </com.android.tools.build > ")
+ .run()
+ .expect(...)
+
+And much, much, more. However, most of the implementation of
+LintClient
is intended for integration of lint itself, and as a check
+author you don't need to worry about it. The detector API will matter
+more, and it's also less likely to change than the client API.
+
+
+
+
The division between the two halves is not perfect; some classes
+ do not fit neatly in between the two or historically were put in
+ the wrong place, so this is a high level design to be aware of but
+ which is not absolute.
+
+
+
+Also,
+
+
+
+
Because of the division between two separate packages, which in
+ retrospect was a mistake, a number of APIs that are only intended
+ for internal lint usage have been made public
such that lint's
+ code in one package can access it from the other. There's normally a
+ comment explaining that this is for internal use only, but be aware
+ that even when something is public
or not final
, it might not be a
+ good idea to call or override it.
+
+
+ Creating an Issue
+
+
+
+For information on how to set up the project and to actually publish
+your lint checks, see the sample and
+publishing chapters.
+
+
+
+Issue
is a final class, so unlike Detector
, you don't subclass
+it; you instantiate it via Issue.create
.
+
+
+
+By convention, issues are registered inside the companion object of the
+corresponding detector, but that is not required.
+
+
+
+Here's an example:
+
+
class SdCardDetector : Detector (), SourceCodeScanner {
+ companion object Issues {
+ @JvmField
+ val ISSUE = Issue.create(
+ id = "SdCardPath" ,
+ briefDescription = "Hardcoded reference to `/sdcard`" ,
+ explanation = """
+ Your code should not reference the `/sdcard` path directly; \
+ instead use `Environment.getExternalStorageDirectory().getPath()`.
+
+ Similarly, do not reference the `/data/data/` path directly; it \
+ can vary in multi-user scenarios. Instead, use \
+ `Context.getFilesDir().getPath()`.
+ """ ,
+ moreInfo = "https://developer.android.com/training/data-storage#filesExternal" ,
+ category = Category.CORRECTNESS,
+ severity = Severity.WARNING,
+ androidSpecific = true ,
+ implementation = Implementation(
+ SdCardDetector::class .java,
+ Scope.JAVA_FILE_SCOPE
+ )
+ )
+ }
+ ...
+
+There are a number of things to note here.
+
+
+
+On line 4, we have the Issue.create()
call. We store the issue into a
+property such that we can reference this issue both from the
+IssueRegistry
, where we provide the Issue
to lint, and also in the
+Detector
code where we report incidents of the issue.
+
+
+
+Note that Issue.create
is a method with a lot of parameters (and we
+will probably add more parameters in the future). Therefore, it's a
+good practice to explicitly include the argument names (and therefore
+to implement your code in Kotlin).
+
+
+
+The Issue
provides metadata about a type of problem.
+
+
+
+The id
is a short, unique identifier for this issue. By
+convention it is a combination of words, capitalized camel case (though
+you can also add your own package prefix as in Java packages). Note
+that the id is “user visible”; it is included in text output when lint
+runs in the build system, such as this:
+
+
src/main/kotlin/test/pkg/MyTest.kt:4: Warning: Do not hardcode "/sdcard/";
+ use Environment.getExternalStorageDirectory().getPath() instead [SdCardPath]
+ val s: String = "/sdcard/mydir"
+ -------------
+ 0 errors, 1 warnings
+
+(Notice the [SdCardPath]
suffix at the end of the error message.)
+
+
+
+The reason the id is made known to the user is that the ID is how
+they'll configure and/or suppress issues. For example, to suppress the
+warning in the current method, use
+
+
@Suppress("SdCardPath" )
+
+(or in Java, @SuppressWarnings). Note that there is an IDE quickfix to
+suppress an incident which will automatically add these annotations, so
+you don't need to know the ID in order to be able to suppress an
+incident, but the ID will be visible in the annotation that it
+generates, so it should be reasonably specific.
+
+
+
+Also, since the namespace is global, try to avoid picking generic names
+that could clash with others, or seem to cover a larger set of issues
+than intended. For example, “InvalidDeclaration” would be a poor id
+since that can cover a lot of potential problems with declarations
+across a number of languages and technologies.
+
+
+
+Next, we have the briefDescription
. You can think of this as a
+“category report header”; this is a static description for all
+incidents of this type, so it cannot include any specifics. This string
+is used for example as a header in HTML reports for all incidents of
+this type, and in the IDE, if you open the Inspections UI, the various
+issues are listed there using the brief descriptions.
+
+
+
+The explanation
is a multi line, ideally multi-paragraph
+explanation of what the problem is. In some cases, the problem is self
+evident, as in the case of “Unused declaration”, but in many cases, the
+issue is more subtle and might require additional explanation,
+particularly for what the developer should do to address the
+problem. The explanation is included both in HTML reports and in the
+IDE inspection results window.
+
+
+
+Note that even though we're using a raw string, and even though the
+string is indented to be flush with the rest of the issue registration
+for better readability, we don't need to call trimIndent()
on
+the raw string. Lint does that automatically.
+
+
+
+However, we do need to add line continuations — those are the trailing
+\'s at the end of the lines.
+
+
+
+Note also that we have a Markdown-like simple syntax, described in the
+“TextFormat” section below. You can use asterisks for italics or double
+asterisks for bold, you can use apostrophes for code font, and so on.
+In terminal output this doesn't make a difference, but the IDE,
+explanations, incident error messages, etc, are all formatted using
+these styles.
+
+
+
+The category
isn't super important; the main use is that category
+names can be treated as id's when it comes to issue configuration; for
+example, a user can turn off all internationalization issues, or run
+lint against only the security related issues. The category is also
+used for locating related issues in HTML reports. If none of the
+built-in categories are appropriate you can also create your own.
+
+
+
+The severity
property is very important. An issue can be either a
+warning or an error. These are treated differently in the IDE (where
+errors are red underlines and warnings are yellow highlights), and in
+the build system (where errors can optionally break the build and
+warnings do not). There are some other severities too; “fatal” is like
+error except these checks are designated important enough (and have
+very few false positives) such that we run them during release builds,
+even if the user hasn't explicitly run a lint target. There's also
+“informational” severity, which is only used in one or two places, and
+finally the “ignore” severity. This is never the severity you register
+for an issue, but it's part of the severities a developer can configure
+for a particular issue, thereby turning off that particular check.
+
+
+
+You can also specify a moreInfo
URL which will be included in the
+issue explanation as a “More Info” link to open to read more details
+about this issue or underlying problem.
+
+
+ TextFormat
+
+
+
+All error messages and issue metadata strings in lint are interpreted
+using simple Markdown-like syntax:
+
+
Raw text format Renders To
+ This is a `code symbol` This is a code symbol
+ This is *italics*
This is italics
+ This is **bold**
This is bold
+ This is ~~strikethrough~~
This is strikethrough
+ http://, https:// http://, https://
+ \*not italics*
\*not italics*
+ ```language\n text\n``` (preformatted text block)
+
Supported markup in lint's markdown-like raw text format
+
+
+
+This is useful when error messages and issue explanations are shown in
+HTML reports generated by Lint, or in the IDE, where for example the
+error message tooltips will use formatting.
+
+
+
+In the API, there is a TextFormat
enum which encapsulates the
+different text formats, and the above syntax is referred to as
+TextFormat.RAW
; it can be converted to .TEXT
or .HTML
for
+example, which lint does when writing text reports to the console or
+HTML reports to files respectively. As a lint check author you don't
+need to know this (though you can for example with the unit testing
+support decide which format you want to compare against in your
+expected output), but the main point here is that your issue's brief
+description, issue explanation, incident report messages etc, should
+use the above “raw” syntax. Especially the first conversion; error
+messages often refer to class names and method names, and these should
+be surrounded by apostrophes.
+
+
+
+See the error message chapter for more information
+on how to craft error messages.
+
+
+ Issue Implementation
+
+
+
+The last issue registration property is the implementation
. This
+is where we glue our metadata to our specific implementation of an
+analyzer which can find instances of this issue.
+
+
+
+Normally, the Implementation
provides two things:
+
+
+
+
+The .class
for our Detector
which should be instantiated. In the
+ code sample above it was SdCardDetector
.
+
+
+
+
+The Scope
that this issue's detector applies to. In the above
+ example it was Scope.JAVA_FILE
, which means it will apply to Java
+ and Kotlin files.
+
+
+ Scopes
+
+
+
+The Implementation
actually takes a set of scopes; we still refer
+to this as a “scope”. Some lint checks want to analyze multiple types
+of files. For example, the StringFormatDetector
will analyze both the
+resource files declaring the formatting strings across various locales,
+as well as the Java and Kotlin files containing String.format
calls
+referencing the formatting strings.
+
+
+
+There are a number of pre-defined sets of scopes in the Scope
+class. Scope.JAVA_FILE_SCOPE
is the most common, which is a
+singleton set containing exactly Scope.JAVA_FILE
, but you
+can always create your own, such as for example
+
EnumSet .of(Scope .CLASS_FILE , Scope .JAVA_LIBRARIES )
+
+When a lint issue requires multiple scopes, that means lint will
+only run this detector if all the scopes are available in the
+running tool. When lint runs a full batch run (such as a Gradle lint
+target or a full “Inspect Code” in the IDE), all scopes are available.
+
+
+
+However, when lint runs on the fly in the editor, it only has access to
+the current file; it won't re-analyze all files in the project for
+every few keystrokes. So in this case, the scope in the lint driver
+only includes the current source file's type, and only lint checks
+which specify a scope that is a subset would run.
+
+
+
+This is a common mistake for new lint check authors: the lint check
+works just fine as a unit test, but they don't see working in the IDE
+because the issue implementation requests multiple scopes, and all
+have to be available.
+
+
+
+Often, a lint check looks at multiple source file types to work
+correctly in all cases, but it can still identify some problems given
+individual source files. In this case, the Implementation
constructor
+(which takes a vararg of scope sets) can be handed additional sets of
+scopes, called “analysis scopes”. If the current lint client's scope
+matches or is a subset of any of the analysis scopes, then the check
+will run after all.
+
+
+ Registering the Issue
+
+
+
+Once you've created your issue, you need to provide it from
+an IssueRegistry
.
+
+
+
+Here's an example IssueRegistry
:
+
+
package com.example.lint.checks
+
+import com.android.tools.lint.client.api.IssueRegistry
+import com.android.tools.lint.client.api.Vendor
+import com.android.tools.lint.detector.api.CURRENT_API
+
+class SampleIssueRegistry : IssueRegistry () {
+ override val issues = listOf(SdCardDetector.ISSUE)
+
+ override val api: Int
+ get () = CURRENT_API
+
+
+
+ override val minApi: Int
+ get () = 8
+
+
+
+ override val vendor: Vendor = Vendor(
+ vendorName = "Android Open Source Project" ,
+ feedbackUrl = "https://com.example.lint.blah.blah/" ,
+ contact = "author@com.example.lint"
+ )
+ }
+
+On line 8, we're returning our issue. It's a list, so an
+IssueRegistry
can provide multiple issues.
+
+
+
+The api
property should be written exactly like the way it
+appears above in your own issue registry as well; this will record
+which version of the lint API this issue registry was compiled against
+(because this references a static final constant which will be copied
+into the jar file instead of looked up dynamically when the jar is
+loaded).
+
+
+
+The minApi
property records the oldest lint API level this check
+has been tested with.
+
+
+
+Both of these are used at issue loading time to make sure lint checks
+are compatible, but in recent versions of lint (7.0) lint will more
+aggressively try to load older detectors even if they have been
+compiled against older APIs since there's a high likelihood that they
+will work (it checks all the lint APIs in the bytecode and uses
+reflection to verify that they're still there).
+
+
+
+The vendor
property is new as of 7.0, and gives lint authors a
+way to indicate where the lint check came from. When users use lint,
+they're running hundreds and hundreds of checks, and sometimes it's not
+clear who to contact with requests or bug reports. When a vendor has
+been specified, lint will include this information in error output and
+reports.
+
+
+
+The last step towards making the lint check available is to make
+the IssueRegistry
known via the service loader mechanism.
+
+
+
+Create a file named exactly
+
src/main/resources/META-INF/services/com.android.tools.lint.client.api.IssueRegistry
+
+with the following contents (but where you substitute in your own
+fully qualified class name for your issue registry):
+
+
com.example.lint.checks.SampleIssueRegistry
+
+If you're not building your lint check using Gradle, you may not want
+the src/main/resources
prefix; the point is that your packaging of
+the jar file should contain META-INF/services/
at the root of the jar
+file.
+
+
+ Implementing a Detector: Scanners
+
+
+
+We've finally come to the main task with writing a lint check:
+implementing the Detector
.
+
+
+
+Here's a trivial one:
+
class MyDetector : Detector () {
+ override fun run (context: Context ) {
+ context.report(ISSUE, Location.create(context.file),
+ "I complain a lot" )
+ }
+ }
+
+This will just complain in every single file. Obviously, no real lint
+detector does this; we want to do some analysis and conditionally report
+incidents. For information about how to phrase error messages, see the error
+message chapter.
+
+
+
+In order to make it simpler to perform analysis, Lint has dedicated
+support for analyzing various file types. The way this works is that
+you register interest, and then various callbacks will be invoked.
+
+
+
+For example:
+
+
+
+
+When implementing XmlScanner
, in an XML element you can be
+ called back
+
+ when any of a set of given tags are declared (visitElement
)
+
+ when any of a set of named attributes are declared
+ (visitAttribute
)
+
+ and you can perform your own document traversal via visitDocument
+
+
+
+
+ When implementing SourceCodeScanner
, in Kotlin and Java files
+ you can be called back
+
+ when a method of a given name is invoked (getApplicableMethodNames
+ and visitMethodCall
)
+
+ when a class of the given type is instantiated
+ (getApplicableConstructorTypes
and visitConstructor
)
+
+ when a new class is declared which extends (possibly indirectly)
+ a given class or interface (applicableSuperClasses
and
+ visitClass
)
+
+ when annotated elements are referenced or combined
+ (applicableAnnotations
and visitAnnotationUsage
)
+
+ when any AST nodes of given types appear (getApplicableUastTypes
+ and createUastHandler
)
+
+
+
+
+ When implementing a ClassScanner
, in .class
and .jar
files
+ you can be called back
+
+ when a method is invoked for a particular owner
+ (getApplicableCallOwners
and checkCall
+
+ when a given bytecode instruction occurs
+ (getApplicableAsmNodeTypes
and checkInstruction
)
+
+ like with XmlScanner's visitDocument
, you can perform your own
+ ASM bytecode iteration via checkClass
+
+
+
+
+ There are various other scanners too, for example GradleScanner
+ which lets you visit build.gradle
and build.gradle.kts
DSL
+ closures, BinaryFileScanner
which visits resource files such as
+ webp and png files, and OtherFileScanner
which lets you visit
+ unknown files.
+
+
+
+
Note that Detector
already implements empty stub methods for all
+ of these interfaces, so if you for example implement
+ SourceFileScanner
in your detector, you don't need to go and add
+ empty implementations for all the methods you aren't using.
+
+
+
+
None of Lint's APIs require you to call super
when you override
+ methods; methods meant to be overridden are always empty so the
+ super-call is superfluous.
+
+
+ Detector Lifecycle
+
+
+
+Detector registration is done by detector class, not by detector
+instance. Lint will instantiate detectors on your behalf. It will
+instantiate the detector once per analysis, so you can stash state on
+the detector in fields and accumulate information for analysis at the
+end.
+
+
+
+There are some callbacks both before and after each individual file is
+analyzed (beforeCheckFile
and afterCheckFile
), as well as before and
+after analysis of all the modules (beforeCheckRootProject
and
+afterCheckRootProject
).
+
+
+
+This is for example how the “unused resources” check works: we store
+all the resource declarations and resource references we find in the
+project as we process each file, and then in the
+afterCheckRootProject
method we analyze the resource graph and
+compute any resource declarations that are not reachable in the
+reference graph, and then we report each of these as unused.
+
+
+ Scanner Order
+
+
+
+Some lint checks involve multiple scanners. This is pretty common in
+Android, where we want to cross check consistency between data in
+resource files with the code usages. For example, the String.format
+check makes sure that the arguments passed to String.format
match the
+formatting strings specified in all the translation XML files.
+
+
+
+Lint defines an exact order in which it processes scanners, and within
+scanners, data. This makes it possible to write some detectors more
+easily because you know that you'll encounter one type of data before
+the other; you don't have to handle the opposite order. For example, in
+our String.format
example, we know that we'll always see the
+formatting strings before we see the code with String.format
calls,
+so we can stash the formatting strings in a map, and when we process
+the formatting calls in code, we can immediately issue reports; we
+don't have to worry about encountering a formatting call for a
+formatting string we haven't processed yet.
+
+
+
+Here's lint's defined order:
+
+
+
+
+Android Manifest
+
+Android resources XML files (alphabetical by folder type, so for
+ example layouts are processed before value files like translations)
+
+Kotlin and Java files
+
+Bytecode (local .class
files and library .jar
files)
+
+TOML files
+
+Gradle files
+
+Other files
+
+ProGuard files
+
+Property Files
+
+
+
+Similarly, lint will always process libraries before the modules
+that depend on them.
+
+
+
+
If you need to access something from later in the iteration order,
+ and it's not practical to store all the current data and instead
+ handle it when the later data is encountered, note that lint has
+ support for “multi-pass analysis”: it can run multiple times over
+ the data. The way you invoke this is via
+ context.driver.requestRepeat(this, …)
. This is actually how the
+ unused resource analysis works. Note however that this repeat is
+ only valid within the current module; you can't re-run the analysis
+ through the whole dependency graph.
+
+
+ Implementing a Detector: Services
+
+
+
+In addition to the scanners, lint provides a number of services
+to make implementation simpler. These include
+
+
+
+
+ConstantEvaluator
: Performs evaluation of AST expressions, so
+ for example if we have the statements x = 5; y = 2 * x
, the
+ constant evaluator can tell you that y is 10. This constant evaluator
+ can also be more permissive than a compiler's strict constant
+ evaluator; e.g. it can return concatenated strings where not all
+ parts are known, or it can use non-final initial values of fields.
+ This can help you find possible bugs instead of certain bugs.
+
+
+
+
+TypeEvaluator
: Attempts to provide the concrete type of an
+ expression. For example, for the Java statements Object s = new
+ StringBuilder(); Object o = s
, the type evaluator can tell you that
+ the type of o
at this point is really StringBuilder
.
+
+
+
+
+JavaEvaluator
: Despite the unfortunate older name, this service
+ applies to both Kotlin and Java, and can for example provide
+ information about inheritance hierarchies, class lookup from fully
+ qualified names, etc.
+
+
+
+
+DataFlowAnalyzer
: Data flow analysis within a method.
+
+
+
+
+For Android analysis, there are several other important services,
+ like the ResourceRepository
and the ResourceEvaluator
.
+
+
+
+
+Finally, there are a number of utility methods; for example there is
+ an editDistance
method used to find likely typos.
+
+
+ Scanner Example
+
+
+
+Let's create a Detector
using one of the above scanners,
+XmlScanner
, which will look at all the XML files in the project and
+if it encounters a <bitmap>
tag it will report that <vector>
should
+be used instead:
+
+
import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Detector.XmlScanner
+import com.android.tools.lint.detector.api.Location
+import com.android.tools.lint.detector.api.XmlContext
+import org.w3c.dom.Element
+
+class MyDetector : Detector (), XmlScanner {
+ override fun getApplicableElements () = listOf("bitmap" )
+
+ override fun visitElement (context: XmlContext , element: Element ) {
+ val incident = Incident(context, ISSUE)
+ .message( "Use `<vector>` instead of `<bitmap>`" )
+ .at(element)
+ context.report(incident)
+ }
+ }
+
+The above is using the new Incident
API from Lint 7.0 and on; in
+older versions you can use the following API, which still works in 7.0:
+
+
class MyDetector : Detector (), XmlScanner {
+ override fun getApplicableElements () = listOf("bitmap" )
+
+ override fun visitElement (context: XmlContext , element: Element ) {
+ context.report(ISSUE, context.getLocation(element),
+ "Use `<vector>` instead of `<bitmap>`" )
+ }
+ }
+
+The second (older) form may seem simpler, but the new API allows a lot
+more metadata to be attached to the report, such as an override
+severity. You don't have to convert to the builder syntax to do this;
+you could also have written the second form as
+
+
context.report(Incident(ISSUE, context.getLocation(element),
+ "Use `<vector>` instead of `<bitmap>`" ))
+ Analyzing Kotlin and Java Code
+
+ UAST
+
+
+
+To analyze Kotlin and Java code, lint offers an abstract syntax tree,
+or “AST”, for the code.
+
+
+
+This AST is called “UAST”, for “Universal Abstract Syntax Tree”, which
+represents multiple languages in the same way, hiding the language
+specific details like whether there is a semicolon at the end of the
+statements or whether the way an annotation class is declared is as
+@interface
or annotation class
, and so on.
+
+
+
+This makes it possible to write a single analyzer which works
+across all languages supported by UAST. And this is
+very useful; most lint checks are doing something API or data-flow
+specific, not something language specific. If however you do need to
+implement something very language specific, see the next section,
+“PSI”.
+
+
+
+In UAST, each element is called a UElement
, and there are a
+number of subclasses — UFile
for the compilation unit, UClass
for
+a class, UMethod
for a method, UExpression
for an expression,
+UIfExpression
for an if
-expression, and so on.
+
+
+
+Here's a visualization of an AST in UAST for two equivalent programs
+written in Kotlin and Java. These programs both result in the same
+AST, shown on the right: a UFile
compilation unit, containing
+a UClass
named MyTest
, containing UField
named s which has
+an initializer setting the initial value to hello
.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+M y T e s t . k t : U A S T : p a c k a g e t e s t . p k g U F i l e c l a s s M y T e s t { p r i v a t e v a l s = “ h e l l o ” } U C l a s s M y T e s t M y T e s t . j a v a : p a c k a g e t e s t . p k g ; U F i e l d s p u b l i c c l a s s M y T e s t { p r i v a t e S t r i n g s = “ h e l l o ” ; } U I d e n t i f i e r s U L i t e r a l E x p r e s s i o n h e l l o
+
+
+
+
The name “UAST” is a bit misleading; it is not some sort of superset
+ of all possible syntax trees; instead, think of this as the “Java
+ view” of all code. So, for example, there isn’t a UProperty
node
+ which represents Kotlin properties. Instead, the AST will look the
+ same as if the property had been implemented in Java: it will
+ contain a private field and a public getter and a public setter
+ (unless of course the Kotlin property specifies a private setter).
+ If you’ve written code in Kotlin and have tried to access that
+ Kotlin code from a Java file you will see the same thing — the
+ “Java view” of Kotlin. The next section, “PSI”, will discuss how to
+ do more language specific analysis.
+
+
+ UAST Example
+
+
+
+Here's an example (from the built-in AlarmDetector
for Android) which
+shows all of the above in practice; this is a lint check which makes
+sure that if anyone calls AlarmManager.setRepeating
, the second
+argument is at least 5,000 and the third argument is at least 60,000.
+
+
+
+Line 1 says we want to have line 3 called whenever lint comes across a
+method to setRepeating
.
+
+
+
+On lines 8-14 we make sure we're talking about the correct method on the
+correct class with the correct signature. This uses the JavaEvaluator
+to check that the called method is a member of the named class. This is
+necessary because the callback would also be invoked if lint came
+across a method call like Unrelated.setRepeating
; the
+visitMethodCall
callback only matches by name, not receiver.
+
+
+
+On line 36 we use the ConstantEvaluator
to compute the value of each
+argument passed in. This will let this lint check not only handle cases
+where you're specifying a specific value directly in the argument list,
+but also for example referencing a constant from elsewhere.
+
+
override fun getApplicableMethodNames () : List<string> = listOf("setRepeating" )
+
+override fun visitMethodCall (
+ context: JavaContext ,
+ node: UCallExpression ,
+ method: PsiMethod
+ ) {
+ val evaluator = context.evaluator
+ if (evaluator.isMemberInClass(method, "android.app.AlarmManager" ) &&
+ evaluator.getParameterCount(method) == 4
+ ) {
+ ensureAtLeast(context, node, 1 , 5000L )
+ ensureAtLeast(context, node, 2 , 60000L )
+ }
+ }
+
+private fun ensureAtLeast (
+ context: JavaContext ,
+ node: UCallExpression ,
+ parameter: Int ,
+ min: Long
+ ) {
+ val argument = node.valueArguments[parameter]
+ val value = getLongValue(context, argument)
+ if (value < min) {
+ val message = "Value will be forced up to $min as of Android 5.1; " +
+ "don't rely on this to be exact"
+ context.report(ISSUE, argument, context.getLocation(argument), message)
+ }
+ }
+
+private fun getLongValue (
+ context: JavaContext ,
+ argument: UExpression
+ ) : Long {
+ val value = ConstantEvaluator.evaluate(context, argument)
+ if (value is Number) {
+ return value.toLong()
+ }
+
+ return java.lang.Long .MAX_VALUE
+ }
+ Looking up UAST
+
+
+
+To write your detector's analysis, you need to know what the AST for
+your code of interest looks like. Instead of trying to figure it out by
+examining the elements under a debugger, a simple way to find out is to
+“pretty print” it, using the UElement
extension method
+asRecursiveLogString
.
+
+
+
+For example, given the following unit test:
+
+
lint().files(
+ kotlin(""
+ + "package test.pkg\n "
+ + "\n "
+ + "class MyTest {\n "
+ + " val s: String = \" hello\" \n "
+ + "}\n " ), ...
+
+If you evaluate context.uastFile?.asRecursiveLogString()
from
+one of the callbacks, it will print this:
+
+
UFile (package = test.pkg)
+ UClass (name = MyTest)
+ UField (name = s)
+ UAnnotation (fqName = org.jetbrains.annotations.NotNull)
+ ULiteralExpression (value = "hello")
+ UAnnotationMethod (name = getS)
+ UAnnotationMethod (name = MyTest)
+
+(This also illustrates the earlier point about UAST representing the
+Java view of the code; here the read-only public Kotlin property “s” is
+represented by both a private field s
and a public getter method,
+getS()
.)
+
+
+ Resolving
+
+
+
+When you have a method call, or a field reference, you may want to take
+a look at the called method or field. This is called “resolving”, and
+UAST supports it directly; on a UCallExpression
for example, call
+.resolve()
, which returns a PsiMethod
, which is like a UMethod
,
+but may not represent a method we have source for (which for example
+would be the case if you resolve a reference to the JDK or to a library
+we do not have sources for). You can call .toUElement()
on the
+PSI element to try to convert it to UAST if source is available.
+
+
+
+
Resolving only works if lint has a correct classpath such that the
+ referenced method, field, or class is actually present. If it is
+ not, resolve will return null, and various lint callbacks will not
+ be invoked. This is a common source of questions for lint checks
+ “not working”; it frequently comes up in lint unit tests where a
+ test file will reference some API that isn't actually included in
+ the class path. The recommended approach for this is to declare
+ local stubs. See the
unit testing chapter
+ for more details about this.
+
+
+ Implicit Calls
+
+
+
+Kotlin supports operator overloading for a number of built-in
+operators. For example, if you have the following code,
+
+
fun test (n1: BigDecimal , n2: BigDecimal ) {
+
+ if (n1 < n2) {
+ ...
+ }
+ }
+
+the <
here is actually a function call (which you can verify by
+invoking Go To Declaration over the symbol in the IDE). This is not
+something that is built specially for the BigDecimal
class; this
+works on any of your Java classes as well, and Kotlin if you put the
+operator
modifier as part of the function declaration.
+
+
+
+However, note that in the abstract syntax tree, this is not
+represented as a UCallExpression
; here we'll have a
+UBinaryExpression
with left operand n1
, right operand n2
and
+operator UastBinaryOperator.LESS
. This means that if your lint check
+is specifically looking at compareTo
calls, you can't just visit
+every UCallExpression
; you also have to visit every
+UBinaryExpression
, and check whether it's invoking a compareTo
+method.
+
+
+
+This is not just specific to binary operators; it also applies to unary
+operators (such as !
, -
, ++
, and so on), as well as even array
+accesses; an array access can map to a get
call or a set
call
+depending on how it's used.
+
+
+
+Lint has some special support to help handle these situations.
+
+
+
+First, the built-in support for call callbacks (where you register an
+interest in call names by returning names from the
+getApplicableMethodNames
and then responding in the visitMethodCall
+callback) already handles this automatically. If you register for
+example an interest in method calls to compareTo
, it will invoke your
+callback for the binary operator scenario shown above as well, passing
+you a call which has the right value arguments, method name, and so on.
+
+
+
+The way this works is that lint can create a “wrapper” class which
+presents the underlying UBinaryExpression
(or
+UArrayAccessExpression
and so on) as a UCallExpression
. In the case
+of a binary operator, the value parameter list will be the left and
+right operands. This means that your code can just process this as if
+the code had written as an explicit call instead of using the operator
+syntax. You can also directly look for this wrapper class,
+UImplicitCallExpression
, which has an accessor method for looking up
+the original or underlying element. And you can construct these
+wrappers yourself, via UBinaryExpression.asCall()
,
+UUnaryExpression.asCall()
, and UArrayAccessExpression.asCall()
.
+
+
+
+There is also a visitor you can use to visit all calls —
+UastCallVisitor
, which will visit all calls, including those from
+array accesses and unary operators and binary operators.
+
+
+
+This support is particularly useful for array accesses, since unlike
+the operator expression, there is no resolveOperator
method on
+UArrayExpression
. There is an open request for that in the UAST issue
+tracker (KTIJ-18765), but for now, lint has a workaround to handle the
+resolve on its own.
+
+
+ PSI
+
+
+
+PSI is short for “Program Structure Interface”, and is IntelliJ's AST
+abstraction used for all language modeling in the IDE.
+
+
+
+Note that there is a different PSI representation for each
+language. Java and Kotlin have completely different PSI classes
+involved. This means that writing a lint check using PSI would involve
+writing a lot of logic twice; once for Java, and once for Kotlin. (And
+the Kotlin PSI is a bit trickier to work with.)
+
+
+
+That's what UAST is for: there's a “bridge” from the Java PSI to UAST
+and there's a bridge from the Kotlin PSI to UAST, and your lint check
+just analyzes UAST.
+
+
+
+However, there are a few scenarios where we have to use PSI.
+
+
+
+The first, and most common one, is listed in the previous section on
+resolving. UAST does not completely replace PSI; in fact, PSI leaks
+through in part of the UAST API surface. For example,
+UMethod.resolve()
returns a PsiMethod
. And more importantly,
+UMethod
extends PsiMethod
.
+
+
+
+
For historical reasons, PsiMethod
and other PSI classes contain
+ some unfortunate APIs that only work for Java, such as asking for
+ the method body. Because UMethod
extends PsiMethod
, you might be
+ tempted to call getBody()
on it, but this will return null from
+ Kotlin. If your unit tests for your lint check only have test cases
+ written in Java, you may not realize that your check is doing the
+ wrong thing and won't work on Kotlin code. It should call uastBody
+ on the UMethod
instead. Lint's special detector for lint detectors
+ looks for this and a few other scenarios (such as calling parent
+ instead of uastParent
), so be sure to configure it for your
+ project.
+
+
+
+When you are dealing with “signatures” — looking at classes and
+class inheritance, methods, parameters and so on — using PSI is
+fine — and unavoidable since UAST does not represent bytecode
+(though in the future it potentially could, via a decompiler)
+or any other JVM languages than Kotlin and Java.
+
+
+
+However, if you are looking at anything inside a method or class
+or field initializer, you must use UAST.
+
+
+
+The second scenario where you may need to use PSI is where you have
+to do something language specific which is not represented in UAST. For
+example, if you are trying to look up the names or default values of a
+parameter, or whether a given class is a companion object, then you'll
+need to dip into Kotlin PSI.
+
+
+
+There is usually no need to look at Java PSI since UAST fully covers
+it, unless you want to look at individual details like specific
+whitespace between AST nodes, which is represented in PSI but not UAST.
+
+
+
+
You can find additional documentation from JetBrains for both
+
PSI and
+
UAST .
+ Just note that their documentation is aimed at IDE plugin developers
+ rather than lint developers.
+
+
+ Testing
+
+
+
+Writing unit tests for the lint check is important, and this is covered
+in detail in the dedicated unit testing
+chapter.
+
+
+
+
+
+
+ Example: Sample Lint Check GitHub Project
+
+
+
+The https://github.com/googlesamples/android-custom-lint-rules
+GitHub project provides a sample lint check which shows a working
+skeleton.
+
+
+
+This chapter walks through that sample project and explains
+what and why.
+
+
+ Project Layout
+
+
+
+Here's the project layout of the sample project:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+i m p l e m e n t a t i o n l i n t P u b l i s h : a p p : l i b r a r y : c h e c k s
+
+
+
+We have an application module, app
, which depends (via an
+implementation
dependency) on a library
, and the library itself has
+a lintPublish
dependency on the checks
project.
+
+
+ :checks
+
+
+
+The checks
project is where the actual lint checks are implemented.
+This project is a plain Kotlin or plain Java Gradle project:
+
+
apply plugin: 'java -library'
+ apply plugin: 'kotlin'
+
+
+
+
If you look at the sample project, you'll see a third plugin
+ applied: apply plugin: 'com.android.lint'
. This pulls in the
+ standalone Lint Gradle plugin, which adds a lint target to this
+ Kotlin project. This means that you can run ./gradlew lint
on the
+ :checks
project too. This is useful because lint ships with a
+ dozen lint checks that look for mistakes in lint detectors! This
+ includes warnings about using the wrong UAST methods, invalid id
+ formats, words in messages which look like code which should
+ probably be surrounded by apostrophes, etc.
+
+
+
+The Gradle file also declares the dependencies on lint APIs
+that our detector needs:
+
+
dependencies {
+ compileOnly "com.android.tools.lint:lint-api:$lintVersion "
+ compileOnly "com.android.tools.lint:lint-checks:$lintVersion "
+ testImplementation "com.android.tools.lint:lint-tests:$lintVersion "
+ }
+
+The second dependency is usually not necessary; you just need to depend
+on the Lint API. However, the built-in checks define a lot of
+additional infrastructure which it's sometimes convenient to depend on,
+such as ApiLookup
which lets you look up the required API level for a
+given method, and so on. Don't add the dependency until you need it.
+
+
+ lintVersion?
+
+
+
+What is the lintVersion
variable defined above?
+
+
+
+Here's the top level build.gradle
+
buildscript {
+ ext {
+ kotlinVersion = '1.4.32'
+
+
+
+
+
+
+ gradlePluginVersion = '7.0.0-alpha10'
+ lintVersion = '30.0.0-alpha10'
+ }
+
+ repositories {
+ google()
+ mavenCentral()
+ }
+ dependencies {
+ classpath "com.android.tools.build:gradle:$gradlePluginVersion "
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion "
+ }
+ }
+
+The $lintVersion
variable is defined on line 11. We don't technically
+need to define the $gradlePluginVersion
here or add it to the classpath on line 19, but that's done so that we can add the lint
+plugin on the checks themselves, as well as for the other modules,
+:app
and :library
, which do need it.
+
+
+
+When you build lint checks, you're compiling against the Lint APIs
+distributed on maven.google.com (which is referenced via google()
in
+Gradle files). These follow the Gradle plugin version numbers.
+
+
+
+Therefore, you first pick which of lint's API you'd like to compile
+against. You should use the latest available if possible.
+
+
+
+Once you know the Gradle plugin version number, say 4.2.0-beta06, you
+can compute the lint version number by simply adding 23 to the
+major version of the gradle plugin, and leave everything the same:
+
+
+
+lintVersion = gradlePluginVersion + 23.0.0
+
+
+
+For example, 7 + 23 = 30, so AGP version 7.something corresponds to
+Lint version 30.something . As another example; as of this writing the
+current stable version of AGP is 4.1.2, so the corresponding version of
+the Lint API is 27.1.2.
+
+
+
+
Why this arbitrary numbering — why can't lint just use the same
+ numbers? This is historical; lint (and various other sibling
+ libraries that lint depends on) was released earlier than the Gradle
+ plugin; it was up to version 22 or so. When we then shipped the
+ initial version of the Gradle plugin with Android Studio 1.0, we
+ wanted to start the numbering over from “1” for this brand new
+ artifact. However, some of the other libraries, like lint, couldn't
+ just start over at 1, so we continued incrementing their versions in
+ lockstep. Most users don't see this, but it's a wrinkle users of the
+ Lint API have to be aware of.
+
+
+ :library and :app
+
+
+
+The library
project depends on the lint check project, and will
+package the lint checks as part of its payload. The app
project
+then depends on the library
, and has some code which triggers
+the lint check. This is there to demonstrate how lint checks can
+be published and consumed, and this is described in detail in the
+Publishing a Lint Check chapter.
+
+
+ Lint Check Project Layout
+
+
+
+The lint checks source project is very simple
+
+
checks/ build.gradle
+ checks/src/ main/resources/ META - INF /services/ com.android.tools.lint.client.api.IssueRegistry
+ checks/src/ main/java/ com/example/ lint/checks/ SampleIssueRegistry .kt
+ checks/src/ main/java/ com/example/ lint/checks/ SampleCodeDetector .kt
+ checks/src/ test/java/ com/example/ lint/checks/ SampleCodeDetectorTest .kt
+
+First is the build file, which we've discussed above.
+
+
+ Service Registration
+
+
+
+Then there's the service registration file. Notice how this file is in
+the source set src/main/resources/
, which means that Gradle will
+treat it as a resource and will package it into the output jar, in the
+META-INF/services
folder. This is using the service-provider loading facility in the JDK to register a service lint can look up. The
+key is the fully qualified name for lint's IssueRegistry
class.
+And the contents of that file is a single line, the fully
+qualified name of the issue registry:
+
+
$ cat checks/src/main/resources/META-INF/services/com.android.tools.lint.client.api.IssueRegistry
+ com.example.lint.checks.SampleIssueRegistry
+
+(The service loader mechanism is understood by IntelliJ, so it will
+correctly update the service file contents if the issue registry is
+renamed etc.)
+
+
+
+The service registration can contain more than one issue registry,
+though there's usually no good reason for that, since a single issue
+registry can provide multiple issues.
+
+
+ IssueRegistry
+
+
+
+Next we have the IssueRegistry
linked from the service registration.
+Lint will instantiate this class and ask it to provide a list of
+issues. These are then merged with lint's other issues when lint
+performs its analysis.
+
+
+
+In its simplest form we'd only need to have the following code
+in that file:
+
+
package com.example.lint.checks
+import com.android.tools.lint.client.api.IssueRegistry
+class SampleIssueRegistry : IssueRegistry () {
+ override val issues = listOf(SampleCodeDetector .ISSUE )
+ }
+
+However, we're also providing some additional metadata about these lint
+checks, such as the Vendor
, which contains information about the
+author and (optionally) contact address or bug tracker information,
+displayed to users when an incident is found.
+
+
+
+We also provide some information about which version of lint's API the
+check was compiled against, and the lowest version of the lint API that
+this lint check has been tested with. (Note that the API versions are
+not identical to the versions of lint itself; the idea and hope is that
+the API may evolve at a slower pace than updates to lint delivering new
+functionality).
+
+
+ Detector
+
+
+
+The IssueRegistry
references the SampleCodeDetector.ISSUE
,
+so let's take a look at SampleCodeDetector
:
+
+
class SampleCodeDetector : Detector (), UastScanner {
+
+
+
+ companion object {
+
+ @JvmField
+ val ISSUE: Issue = Issue.create(
+
+ id = "SampleId" ,
+
+
+ briefDescription = "Lint Mentions" ,
+
+
+ explanation = """
+ This check highlights string literals in code which mentions the word `lint`. \
+ Blah blah blah.
+
+ Another paragraph here.
+ """ ,
+ category = Category.CORRECTNESS,
+ priority = 6 ,
+ severity = Severity.WARNING,
+ implementation = Implementation(
+ SampleCodeDetector::class .java,
+ Scope.JAVA_FILE_SCOPE
+ )
+ )
+ }
+ }
+
+The Issue
registration is pretty self-explanatory, and the details
+about issue registration are covered in the basics
+chapter. The excessive comments here are there to explain the sample,
+and there are usually no comments in issue registration code like this.
+
+
+
+Note how on line 29, the Issue
registration names the Detector
+class responsible for analyzing this issue: SampleCodeDetector
. In
+the above I deleted the body of that class; here it is now without the
+issue registration at the end:
+
+
package com.example.lint.checks
+
+import com.android.tools.lint.client.api.UElementHandler
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Detector.UastScanner
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import org.jetbrains.uast.UElement
+import org.jetbrains.uast.ULiteralExpression
+import org.jetbrains.uast.evaluateString
+
+class SampleCodeDetector : Detector (), UastScanner {
+ override fun getApplicableUastTypes () : List<class <out uelement?="" >> {
+ return listOf(ULiteralExpression::class .java)
+ }
+
+ override fun createUastHandler (context: JavaContext ) : UElementHandler {
+ return object : UElementHandler() {
+ override fun visitLiteralExpression (node: ULiteralExpression ) {
+ val string = node.evaluateString() ?: return
+ if (string.contains("lint" ) && string.matches(Regex(".*\\blint\\b.*" ))) {
+ context.report(
+ ISSUE, node, context.getLocation(node),
+ "This code mentions `lint`: **Congratulations**"
+ )
+ }
+ }
+ }
+ }
+ }
+
+This lint check is very simple; for Kotlin and Java files, it visits
+all the literal strings, and if the string contains the word “lint”,
+then it issues a warning.
+
+
+
+This is using a very general mechanism of AST analysis; specifying the
+relevant node types (literal expressions, on line 18) and visiting them
+on line 23. Lint has a large number of convenience APIs for doing
+higher level things, such as “call this callback when somebody extends
+this class”, or “when somebody calls a method named foo
”, and so on.
+Explore the SourceCodeScanner
and other Detector
interfaces to see
+what's possible. We'll hopefully also add more dedicated documentation
+for this.
+
+
+ Detector Test
+
+
+
+Last but not least, let's not forget the unit test:
+
+
package com.example.lint.checks
+
+import com.android.tools.lint.checks.infrastructure.TestFiles.java
+import com.android.tools.lint.checks.infrastructure.TestLintTask.lint
+import org.junit.Test
+
+class SampleCodeDetectorTest {
+ @Test
+ fun testBasic () {
+ lint().files(
+ java(
+ """
+ package test.pkg;
+ public class TestClass1 {
+ // In a comment, mentioning "lint" has no effect
+ private static String s1 = "Ignore non-word usages: linting";
+ private static String s2 = "Let's say it: lint";
+ }
+ """
+ ).indented()
+ )
+ .issues(SampleCodeDetector.ISSUE)
+ .run()
+ .expect (
+ """
+ src/test/pkg/TestClass1.java:5: Warning: This code mentions lint: Congratulations [SampleId]
+ private static String s2 = "Let's say it: lint";
+ ∼∼∼∼∼∼∼∼∼∼∼∼∼∼∼∼∼∼∼∼
+ 0 errors, 1 warnings
+ """
+ )
+ }
+ }
+
+As you can see, writing a lint unit test is very simple, because
+lint ships with a dedicated testing library; this is what the
+
+
testImplementation "com.android.tools.lint:lint-tests:$lintVersion "
+
+dependency in build.gradle pulled in.
+
+
+
+Unit testing lint checks is covered in depth in the
+unit testing chapter, so we'll cut the
+explanation of the above test short here.
+
+
+
+
+
+
+ AST Analysis
+
+
+
+To analyze Kotlin and Java files, lint offers many convenience callbacks
+to make it simple to accomplish common tasks:
+
+
+
+
+Check calls to a particular method name
+
+Instantiating a particular class
+
+Extending a particular super class or interface
+
+Using a particular annotation, or calling an annotated method
+
+
+
+And more. See the SourceCodeScanner
interface for more information.
+
+
+
+It also has various helpers, such as a ConstantEvaluator
and a
+DataFlowAnalyzer
to help analyze code.
+
+
+
+But in some cases, you'll need to dig in and analyze the “AST” yourself.
+
+
+ AST Analysis
+
+
+
+AST is short for “Abstract Syntax Tree” — a tree representation of the
+source code. Consider the following very simple Java program:
+
+
+package test.pkg;
+
+public class MyTest {
+ String s = "hello" ;
+ }
+
+Here's the AST for the above program, the way it's represented
+internally in IntelliJ.
+
+
+
+
+
+
+
+This is actually a simplified view; in reality, there are also
+whitespace nodes tracking all the spans of whitespace characters between
+these nodes.
+
+
+
+Anyway, you can see there is quite a bit of detail here — tracking
+things like the keywords, the variables, references to for example the
+package — and higher level concepts like a class and a field, which I've
+marked with a thicker border.
+
+
+
+Here's the corresponding Kotlin program:
+
+
+package test.pkg
+
+class MyTest {
+ val s: String = "hello"
+ }
+
+And here's the corresponding AST in IntelliJ:
+
+
+
+
+
+
+
+This program is equivalent to the Java one.
+But notice that it has a completely different shape! They reference
+different element classes, PsiClass
versus KtClass
, and on and on
+all the way down.
+
+
+
+But there's some commonality — they each have a node for the file, for
+the class, for the field, and for the initial value, the string.
+
+
+ UAST
+
+
+
+We can construct a new AST that represents the same concepts:
+
+
+
+
+
+
+
+This is a unified AST, in something called “UAST”, short for Unified
+Abstract Syntax Tree. UAST is the primary AST representation we use for
+code in Lint. All the node classes here are prefixed with a capital U,
+for UAST. And this is the UAST for the first Java file example above.
+
+
+
+Here's the UAST for the corresponding Kotlin example:
+
+
+
+
+
+
+
+As you can see, the ASTs are not always identical. For Strings, in
+Kotlin, we often end up with an extra parent UInjectionHost
. But for
+our purposes, you can see that the ASTs are mostly the same, so if you
+handle the Kotlin scenario, you'll handle the Java ones too.
+
+
+ UAST: The Java View
+
+
+
+Note that “Unified” in the name here is a bit misleading. From the name
+you may assume that this is some sort of superset of the ASTs across
+languages — an AST that can represent everything needed by all
+languages. But that's not the case! Instead, a better way to think of it
+is as the Java view of the AST.
+
+
+
+If you for example have the following Kotlin data class:
+
+
data class Person (
+ var id: String,
+ var name: String
+ )
+
+This is a Kotlin data class with two properties. So you might expect
+that UAST would have a way to represent these concepts. This should
+be a UDataClass
with two UProperty
children, right?
+
+
+
+But Java doesn't support properties. If you try to access a Person
+instance from Java, you'll notice that it exposes a number of public
+methods that you don't see there in the Kotlin code — in addition to
+getId
, setId
, getName
and setName
, there's also component1
and
+component2
(for destructuring), and copy
.
+
+
+
+These methods are directly callable from Java, so they show up in UAST,
+and your analysis can reason about them.
+
+
+
+Consider another complete Kotlin source file, test.kt
:
+
+
var property = 0
+
+Here's the UAST representation:
+
+
+
+
+
+
+
+Here we have a very simple Kotlin file — for a single Kotlin property.
+But notice at the UAST level, there's no such thing as top level methods
+and properties. In Java, everything is a class, so kotlinc
will create
+a “facade class”, using the filename plus “Kt”. So we see our TestKt
+class. And there are three members here. There's the getter and the
+setter for this property, as getProperty
and setProperty
. And then
+there is the private field itself, where the property is stored.
+
+
+
+This all shows up in UAST. It's the Java view of the Kotlin code. This
+may seem limiting, but in practice, for most lint checks, this is
+actually what you want. This makes it easy to reason about calls to APIs
+and so on.
+
+
+ Expressions
+
+
+
+You may be getting the impression that the UAST tree is very shallow and
+only represents high level declarations, like files, classes, methods
+and properties.
+
+
+
+That's not the case. While it does skip low-level, language-specific
+details things like whitespace nodes and individual keyword nodes, all
+the various expression types are represented and can be reasoned about.
+Take the following expression:
+
+
if (s.length > 3 ) 0 else s.count { it.isUpperCase() }
+
+This maps to the following UAST tree:
+
+
+
+
+
+
+
+As you can see it's modeling the if, the comparison, the lambda, and so
+on.
+
+
+ UElement
+
+
+
+Every node in UAST is a subclass of a UElement
. There's a parent
+pointer, which is handy for navigating around in the AST.
+
+
+
+The real skill you need for writing lint checks is understanding the
+AST, and then doing pattern matching on it. And a simple trick for this
+is to create the Kotlin or Java code you want, in a unit test, and then
+in your detector, recursively print out the UAST as a tree.
+
+
+
+Or in the debugger, anytime you have a UElement
, you can call
+UElement.asRecursiveLogString
on it, evaluate and see what you find.
+
+
+
+For example, for the following Kotlin code:
+
+
import java.util.Date
+fun test () {
+ val warn1 = Date()
+ val ok = Date(0L )
+ }
+
+here's the corresponding UAST asRecursiveLogString
output:
+
+
UFile (package = )
+ UImportStatement (isOnDemand = false)
+ UClass (name = JavaTest)
+ UMethod (name = test)
+ UBlockExpression
+ UDeclarationsExpression
+ ULocalVariable (name = warn1)
+ UCallExpression (kind = UastCallKind(name='constructor_call'), …
+ USimpleNameReferenceExpression (identifier = Date)
+ UDeclarationsExpression
+ ULocalVariable (name = ok)
+ UCallExpression (kind = UastCallKind(name='constructor_call'), …
+ USimpleNameReferenceExpression (identifier = Date)
+ ULiteralExpression (value = 0)
+ Visiting
+
+
+
+You generally shouldn't visit a source file on your own. Lint has a
+special UElementHandler
for that, which is used to ensure we don't
+repeat visiting a source file thousands of times, one per detector.
+
+
+
+But when you're doing local analysis, you sometimes need to visit a
+subtree.
+
+
+
+To do that, just extend AbstractUastVisitor
and pass the visitor to
+the accept
method of the corresponding UElement
.
+
+
method.accept(object : AbstractUastVisitor() {
+ override fun visitSimpleNameReferenceExpression (node: USimpleNameReferenceExpression ) : Boolean {
+
+ return super .visitSimpleNameReferenceExpression(node)
+ }
+ })
+
+In a visitor, you generally want to call super
as shown above. You can
+also return true
if you've “seen enough” and can stop visiting the
+remainder of the AST.
+
+
+
+If you're visiting Java PSI elements, you use a
+JavaRecursiveElementVisitor
, and in Kotlin PSI, use a KtTreeVisitor
.
+
+
+ UElement to PSI Mapping
+
+
+
+UAST is built on top of PSI, and each UElement
has a sourcePsi
+property (which may be null). This lets you map from the general UAST
+node, down to the specific PSI elements.
+
+
+
+Here's an illustration of that:
+
+
+
+
+
+
+
+We have our UAST tree in the top right corner. And here's the Java PSI
+AST behind the scenes. We can access the underlying PSI node for a
+UElement
by accessing the sourcePsi
property. So when you do need to dip
+into something language specific, that's trivial to do.
+
+
+
+Note that in some cases, these references are null.
+
+
+
+Most UElement
nodes point back to the PSI AST - whether a Java
+AST or a Kotlin AST. Here's the same AST, but with the type of the
+sourcePsi
property for each node added.
+
+
+
+
+
+
+
+You can see that the facade class generated to contain the top level
+functions has a null sourcePsi
, because in the
+Kotlin PSI, there is no real KtClass
for a facade class. And for the
+three members, the private field and the getter and the setter, they all
+correspond to the exact same, single KtProperty
instance, the single
+node in the Kotlin PSI that these methods were generated from.
+
+
+ PSI to UElement
+
+
+
+In some cases, we can also map back to UAST from PSI elements, using the toUElement
extension function.
+
+
+
+For example, let's say we resolve a method call. This returns a
+PsiMethod
, not a UMethod
. But we can get the corresponding UMethod
+using the following:
+
+
val resolved = call.resolve() ?: return
+val uDeclaration = resolve.toUElement()
+
+Note however that toUElement
may return null. For example, if you've
+resolved to a method call that is compiled (which you can check using
+resolved is PsiCompiledElement
), UAST cannot convert it.
+
+
+ UAST versus PSI
+
+
+
+UAST is the preferred AST to use when you're writing lint checks for
+Kotlin and Java. It lets you reason about things that are the same
+across the languages. Declarations. Function calls. Super classes.
+Assignments. If expressions. Return statements. And on and on.
+
+
+
+There are lint checks that are language specific — for example, if
+you write a lint check that forbids the use of companion objects — in
+that case, there's no big advantage to using UAST over PSI; it's only
+ever going to run on Kotlin code. (Note however that lint's APIs and
+convenience callbacks are all targeting UAST, so it's easier to write
+UAST lint checks even for the language-specific checks.)
+
+
+
+The vast majority of lint checks however aren't language specific,
+they're API or bug pattern specific. And if the API can be called
+from Java, you want your lint check to not only flag problems in Kotlin,
+but in Java code as well. You don't want to have to write the lint check
+twice — so if you use UAST, a single lint check can work for both. But
+while you generally want to use UAST for your analysis (and lint's APIs
+are generally oriented around UAST), there are cases where it's
+appropriate to dip into PSI.
+
+
+
+In particular, you should use PSI when you're doing something highly
+language specific, and where the language details aren't exposed in UAST.
+
+
+
+For example, let's say you need to determine if a UClass
is a Kotlin
+“companion object”. You could cheat and look at the class name to see if
+it's “Companion”. But that's not quite right; in Kotlin you can
+specify a custom companion object name, and of course users are free
+to create classes named “Companion” that aren't companion objects:
+
+
class Test {
+ companion object MyName {
+ }
+
+ object Companion {
+ }
+ }
+
+The right way to do this is using Kotlin PSI, via the
+UElement.sourcePsi
property:
+
+
+val source = node.sourcePsi
+if (source is KtObjectDeclaration && source.isCompanion()) {
+ return
+ }
+
+(To figure out how to write the above code, use a debugger on a test
+case and look at the UClass.sourcePsi
property; you'll discover that
+it's some subclass of KtObjectDeclaration
; look up its most general
+super interface or class, and then use code completion to discover
+available APIs, such as isCompanion()
.)
+
+
+ Kotlin Analysis API
+
+
+
+Using Kotlin PSI was the state of the art for correctly analyzing Kotlin
+code until recently. But when you look at the PSI, you'll discover that
+some things are really hard to accomplish — in particular, resolving
+reference, and dealing with Kotlin types.
+
+
+
+Lint doesn't actually give you access to everything you need if you want
+to try to look up types in Kotlin PSI; you need something called the
+“binding context”, which is not exposed anywhere! And this omission is
+deliberate, because this is an implementation detail of the old
+compiler. The future is K2; a complete rewrite of the compiler front
+end, which is no longer using the old binding context. And as part of
+the tooling support for K2, there's a new API called the “Kotlin
+Analysis API” you can use to dig into details about Kotlin.
+
+
+
+For most lint checks, you should just use UAST if you can. But when you
+need to know really detailed Kotlin information, especially around
+types, and smart casts, and null inference, and so on, the Kotlin
+Analysis API is your best friend (and only option...)
+
+
+
+
The Kotlin Analysis API is not yet final and may continue to change.
+ In fact, most of the symbols have been renamed recently. For example,
+ the KtAnalysisSession
returned by analyze
, has been renamed
+ KaSession
. Most APIs now have the prefix Ka
.
+
+
+ Nothing Type?
+
+
+
+Here's a simple example:
+
+
fun testTodo () {
+ if (SDK_INT < 11 ) {
+ TODO()
+ }
+ val actionBar = getActionBar()
+ }
+
+Here we have a scenario where we know that the TODO call will never
+return, and lint can take advantage of that when analyzing the control
+flow — in particular, it should understand that after the TODO() call
+there's no chance of fallthrough, so it can conclude that SDK_INT must
+be at least 11 after the if block.
+
+
+
+The way the Kotlin compiler can reason about this is that the TODO
+method in the standard library has a return type of Nothing
.
+
+
@kotlin .internal .InlineOnly
+public inline fun TODO () : Nothing = throw NotImplementedError()
+
+The Nothing
return type means it will never return.
+
+
+
+Before the Kotlin lint analysis API, lint didn't have a way to reason
+about the Nothing
type. UAST only returns Java types, which maps to
+void. So instead, lint had an ugly hack that just hardcoded well known
+names of methods that don't return:
+
+
if (nextStatement is UCallExpression) {
+ val methodName = nextStatement.methodName
+ if (methodName == "fail" || methodName == "error" || methodName == "TODO" ) {
+ return true
+ }
+
+However, with the Kotlin analysis API, this is easy:
+
+
fun callNeverReturns (call: UCallExpression ) : Boolean {
+ val sourcePsi = call.sourcePsi as ? KtCallExpression ?: return false
+ analyze(sourcePsi) {
+ val callInfo = sourcePsi.resolveToCall() ?: return false
+ val returnType = callInfo.singleFunctionCallOrNull()?.symbol?.returnType
+ return returnType != null && returnType.isNothingType
+ }
+ }
+
+Older APIs (pre-8.7.0-alpha04):
+
+
+fun callNeverReturns (call: UCallExpression ) : Boolean {
+ val sourcePsi = call.sourcePsi as ? KtCallExpression ?: return false
+ analyze(sourcePsi) {
+ val callInfo = sourcePsi.resolveCall() ?: return false
+ val returnType = callInfo.singleFunctionCallOrNull()?.symbol?.returnType
+ return returnType != null && returnType.isNothing
+ }
+ }
+
+The entry point to all Kotlin Analysis API usages is to call the
+analyze
method (see line 7) and pass in a Kotlin PSI element. This
+creates an “analysis session”. It's very important that you don't leak
+objects from inside the session out of it — to avoid memory leaks and
+other problems. If you do need to hold on to a symbol and compare later,
+you can create a special symbol pointer.
+
+
+
+Anyway, there's a huge number of extension methods that take an analysis
+session as receiver, so inside the lambda on lines 7 to 13, there are
+many new methods available.
+
+
+
+Here, we have a KtCallExpression
, and inside the analyze
block we
+can call resolveCall()
on it to reach the called method's symbol.
+
+
+
+Similarly, on a KtDeclaration
(such as a named function or property) I
+can call .symbol
to get the symbol for that method or property, to
+for example look up parameter information. And on a KtExpression
(such
+as an if statement) I can call .expressionType
to get the Kotlin type.
+
+
+
+KaSymbol
and KaType
are the basic primitives we're working with in
+the Kotlin Analysis API. There are a number of subclasses of symbol,
+such as KaFileSymbol
, KaFunctionSymbol
, KaClassSymbol
, and
+so on.
+
+
+
+In the new implementation of callNeverReturns
, we resolve the call,
+look up the corresponding function, which of course is a KaSymbol
+itself, and from that we get the return type, and then we can just check
+if it's the Nothing
type.
+
+
+
+And this API works both with the old Kotlin compiler, used in lint right
+now, and K2, which can be turned on via a flag and will soon be the
+default (and may well be the default when you read this; we don't always
+remember to update the documentation...)
+
+
+ Compiled Metadata
+
+
+
+Accessing Kotlin-specific knowledge not available via Kotlin PSI is one
+use for the analysis API.
+
+
+
+Another big advantage of the Kotlin analysis API is that it gives you
+access to reason about compiled Kotlin code, in the same way that the
+compiler does.
+
+
+
+Normally, when you resolve with UAST, you just get a plain PsiMethod
+back. For example, if we have a reference to
+kotlin.text.HexFormat.Companion
, and we resolve it in UAST, we get a
+PsiMethod
back. This is not a Kotlin PSI element, so our earlier
+code to check if this is a companion object (source is
+KtObjectDeclaration && source.isCompanion()
) does not work — the first
+instance check fails. These compiled PsiElement
s do not give us access
+to any of the special Kotlin payload we can usually check on
+KtElement
s — modifiers like inline
or infix
, default parameters,
+and so on.
+
+
+
+The analysis API handles this properly, even for compiled code. In fact,
+the earlier implementation of checking for the Nothing
type
+demonstrated this, because the methods it's analyzing from the Kotlin
+standard library (error
, TODO
, and so on), are all compiled classes
+in the Kotlin standard library jar file!
+
+
+
+Therefore, yes, we can use Kotlin PSI to check if a class is a companion
+object if we actually have the source code for the class. But if we're
+resolving a reference to a class, using the Kotlin analysis API is
+better; it will work for both source and compiled:
+
+
symbol is KaClassSymbol && symbol.classKind == KaClassKind.COMPANION_OBJECT
+
+Older APIs (pre-8.7.0-alpha04):
+
+
symbol is KtClassOrObjectSymbol && symbol.classKind == KtClassKind.COMPANION_OBJECT
+ Kotlin Analysis API Howto
+
+
+
+When you're using K2 with lint, a lot of UAST's handling of resolve and
+types in Kotlin is actually using the analysis API behind the scenes.
+
+
+
+If you for example have a Kotlin PSI KtThisExpression
, and you want to
+understand how to resolve the this
reference to another PSI element,
+write the following Kotlin UAST code:
+
+
thisReference.toUElement()?.tryResolve()
+
+You can now use a debugger to step into the tryResolve
call, and
+you'll eventually wind up in code using the Kotlin Analysis API to look
+it up, and as it turns out, here's how:
+
+
analyze(expression) {
+ val reference = expression.getTargetLabel()?.mainReference
+ ?: expression.instanceReference.mainReference
+ val psi = reference.resolveToSymbol()?.psi
+ …
+ }
+ Configuring lint to use K2
+
+
+
+To use K2 from a unit test, you can use the following lint test task override:
+
+
override fun lint () : TestLintTask {
+ return super .lint().configureOptions { flags -> flags.setUseK2Uast(true ) }
+ }
+
+Outside of tests, you can also set the -Dlint.use.fir.uast=true
system property in your run configurations.
+
+
+
+Note that at some point this flag may go away since we'll be switching
+over to K2 completely.
+
+
+ API Compatibility
+
+
+
+Versions of lint before 8.7.0-alpha04 used an older version of the
+analysis API. If your lint check is building against these older
+versions, you need to use the older names and APIs, such as
+KtSymbol
and KtType
instead of KaSymbol
and KaType
.
+
+
+
+The analysis API isn't stable, and changed significantly between
+these versions. The hope/plan is for the API to be stable soon, such
+that you can start using the analysis API in lint checks and have it
+work with future versions of lint.
+
+
+
+For now, lint uses a special bytecode rewriter on the fly to try to
+automatically migrate compiled lint checks using the older API, but
+this doesn't handle all corner cases, so the best path forward is to
+use the new APIs. In the below recipes, we're temporarily showing both
+the new and the old versions.
+
+
+ Recipes
+
+
+
+Here are various other Kotlin Analysis scenarios and potential solutions:
+
+
+ Resolve a function call
+val call: KtCallExpression
+ …
+ analyze(call) {
+ val callInfo = call.resolveToCall() ?: return null
+ val symbol: KaFunctionSymbol? = callInfo.singleFunctionCallOrNull()?.symbol
+ ?: callInfo.singleConstructorCallOrNull()?.symbol
+ ?: callInfo.singleCallOrNull<kaannotationcall>()?.symbol
+ …
+ }
+
+Older APIs (pre-8.7.0-alpha04):
+
+
val call: KtCallExpression
+ …
+ analyze(call) {
+ val callInfo = call.resolveCall()
+ if (callInfo != null ) {
+ val symbol: KtFunctionLikeSymbol = callInfo.singleFunctionCallOrNull()?.symbol
+ ?: callInfo.singleConstructorCallOrNull()?.symbol
+ ?: callInfo.singleCallOrNull<ktannotationcall>()?.symbol
+ …
+ }
+ Resolve a variable reference
+
+
+
+Also use resolveCall
, though it's not really a call:
+
+
val expression: KtNameReferenceExpression
+ …
+ analyze(expression) {
+ val symbol: KaVariableSymbol? = expression.resolveToCall()?.singleVariableAccessCall()?.symbol
+ }
+
+Older APIs (pre-8.7.0-alpha04):
+
+
val expression: KtNameReferenceExpression
+ …
+ analyze(expression) {
+ val symbol: KtVariableLikeSymbol = expression.resolveCall()?.singleVariableAccessCall()?.symbol
+ }
+ Get the containing class of a symbol
+val containingSymbol = symbol.containingSymbol
+if (containingSymbol is KaNamedClassSymbol) {
+ …
+ }
+
+Older APIs (pre-8.7.0-alpha04):
+
+
val containingSymbol = symbol.getContainingSymbol()
+if (containingSymbol is KtNamedClassOrObjectSymbol) {
+ …
+ }
+ Get the fully qualified name of a class
+val containing = declarationSymbol.containingSymbol
+if (containing is KaClassSymbol) {
+ val fqn = containing.classId?.asSingleFqName()
+ …
+ }
+
+Older APIs (pre-8.7.0-alpha04):
+
+
val containing = declarationSymbol.getContainingSymbol()
+if (containing is KtClassOrObjectSymbol) {
+ val fqn = containing.classIdIfNonLocal?.asSingleFqName()
+ …
+ }
+ Look up the deprecation status of a symbol
+if (symbol is KaDeclarationSymbol) {
+ symbol.deprecationStatus?.let { … }
+ }
+
+Older APIs (pre-8.7.0-alpha04):
+
+
if (symbol is KtDeclarationSymbol) {
+ symbol.deprecationStatus?.let { … }
+ }
+ Look up visibility
+if (symbol is KaDeclarationSymbol) {
+ if (!isPublicApi(symbol)) {
+ …
+ }
+ }
+
+Older APIs (pre-8.7.0-alpha04):
+
+
if (symbol is KtSymbolWithVisibility) {
+ val visibility = symbol.visibility
+ if (!visibility.isPublicAPI) {
+ …
+ }
+ }
+ Get the KtType of a class symbol
+if (symbol is KaNamedClassSymbol) {
+ val type = symbol.defaultType
+ }
+
+Older APIs (pre-8.7.0-alpha04):
+
+
containingSymbol.buildSelfClassType()
+ Resolve a KtType into a class
+
+
+
+Example: is this KtParameter
pointing to an interface?
+
+
analyze(ktParameter) {
+ val parameterSymbol = ktParameter.symbol
+ val returnType = parameterSymbol.returnType
+ val typeSymbol = returnType.expandedSymbol
+ if (typeSymbol is KaClassSymbol) {
+ val classKind = typeSymbol.classKind
+ if (classKind == KaClassKind.INTERFACE) {
+ …
+ }
+ }
+ }
+
+Older APIs (pre-8.7.0-alpha04):
+
+
analyze(ktParameter) {
+ val parameterSymbol = ktParameter.getParameterSymbol()
+ val returnType = parameterSymbol.returnType
+ val typeSymbol = returnType.expandedClassSymbol
+ if (typeSymbol is KtClassOrObjectSymbol) {
+ val classKind = typeSymbol.classKind
+ if (classKind == KtClassKind.INTERFACE) {
+ …
+ }
+ }
+ See if two types refer to the same raw class (erasure):
+if (type1 is KaClassType && type2 is KaClassType &&
+ type1.classId == type2.classId
+ ) {
+ …
+ }
+
+Older APIs (pre-8.7.0-alpha04):
+
+
if (type1 is KtNonErrorClassType && type2 is KtNonErrorClassType &&
+ type1.classId == type2.classId) {
+ …
+ }
+ For an extension method, get the receiver type:
+if (declarationSymbol is KaNamedFunctionSymbol) {
+ val declarationReceiverType = declarationSymbol.receiverParameter?.type
+ }
+
+Older APIs (pre-8.7.0-alpha04):
+
+
if (declarationSymbol is KtFunctionSymbol) {
+ val declarationReceiverType = declarationSymbol.receiverParameter?.type
+ Get the PsiFile containing a symbol declaration
+val file = symbol.containingFile
+if (file != null ) {
+ val psi = file.psi
+ if (psi is PsiFile) {
+ …
+ }
+ }
+
+Older APIs (pre-8.7.0-alpha04):
+
+
val file = symbol.getContainingFileSymbol()
+if (file is KtFileSymbol) {
+val psi = file.psi
+if (psi is PsiFile) {
+ …
+ }
+
+
+
+
+ Publishing a Lint Check
+
+
+
+Lint will look for jar files with a service registry key for issue
+registries.
+
+
+
+You can manually point it to your custom lint checks jar files by using
+the environment variable ANDROID_LINT_JARS
:
+
+
$ export ANDROID_LINT_JARS=/path/to/first.jar:/path/to/second.jar
+(On Windows, use ;
instead of :
as the path separator)
+
+
+
+However, that is only intended for development and as a workaround for
+build systems that do not have direct support for lint or embedded lint
+libraries, such as the internal Google build system.
+
+
+ Android
+
+ AAR Support
+
+
+
+Android libraries are shipped as .aar
files instead of .jar
files.
+This means that they can carry more than just the code payload. Under
+the hood, .aar
files are just zip files which contain many other
+nested files, including api and implementation jars, resources,
+proguard/r8 rules, and yes, lint jars.
+
+
+
+For example, if we look at the contents of the timber logging library's
+AAR file, we can see the lint.jar with several lint checks within as
+part of the payload:
+
+
$ jar tvf ~/.gradle/caches/.../jakewharton.timber/timber/4.5.1/?/timber-4.5.1.aar
+ 216 Fri Jan 20 14:45:28 PST 2017 AndroidManifest.xml
+ 8533 Fri Jan 20 14:45:28 PST 2017 classes.jar
+ 10111 Fri Jan 20 14:45:28 PST 2017 lint.jar
+ 39 Fri Jan 20 14:45:28 PST 2017 proguard.txt
+ 0 Fri Jan 20 14:45:24 PST 2017 aidl/
+ 0 Fri Jan 20 14:45:28 PST 2017 assets/
+ 0 Fri Jan 20 14:45:28 PST 2017 jni/
+ 0 Fri Jan 20 14:45:28 PST 2017 res/
+ 0 Fri Jan 20 14:45:28 PST 2017 libs/
+
+The advantage of this approach is that when lint notices that you
+depend on a library, and that library contains custom lint checks, then
+lint will pull in those checks and apply them. This gives library
+authors a way to provide their own additional checks enforcing usage.
+
+
+ lintPublish Configuration
+
+
+
+The Android Gradle library plugin provides some special configurations,
+lintChecks
and lintPublish
.
+
+
+
+The lintPublish
configuration lets you reference another project, and
+it will take that project's output jar and package it as a lint.jar
+inside the AAR file.
+
+
+
+The https://github.com/googlesamples/android-custom-lint-rules
+sample project demonstrates this setup.
+
+
+
+The :checks
project is a pure Kotlin library which depends on the
+Lint APIs, implements a Detector
, and provides an IssueRegistry
+which is linked from META-INF/services
.
+
+
+
+Then in the Android library, the :library
project applies the Android
+Gradle library plugin. It then specifies a lintPublish
configuration
+referencing the checks lint project:
+
+
apply plugin: 'com.android.library'
+ dependencies {
+ lintPublish project (':checks' )
+
+ }
+
+Finally, the sample :app
project is an example of an Android app
+which depends on the library, and the source code in the app contains a
+violation of the lint check defined in the :checks
project. If you
+run ./gradlew :app:lint
to analyze the app, the build will fail
+emitting the custom lint check.
+
+
+ Local Checks
+
+
+
+What if you aren't publishing a library, but you'd like to apply
+some checks locally for your own codebase?
+
+
+
+You can use a similar approach to lintPublish
: In your app
+module, specify
+
+
apply plugin: 'com.android.application'
+ dependencies {
+ lintChecks project (':checks' )
+
+ }
+
+Now, when lint runs on this application, it will apply the checks
+provided from the given project.
+
+
+
+
This mechanism works well on the CI server for enforcing local code
+ conventions, and it also works for developers on your team; the
+ errors should be flagged in the IDE (providing they are analyzing
+ single-file scopes). However, there have been various bugs and
+ difficulties around the lint checks getting rebuilt after changes or
+ clean builds. There are some bugs in the Android Gradle Plugin issue
+ tracker for this.
+
+
+ Unpublishing
+
+
+
+If you end up “deleting” a lint check, perhaps because the original
+conditions for the lint check are not true, don't just stop
+distributing lint checks with your library. Instead, you'll want to
+update your IssueRegistry
to override the deletedIssues
property to
+return your deleted issue id or ids:
+
+
+open val deletedIssues: List <String > = emptyList()
+
+The reason you'll want to do this is listed right there in the doc: If
+you don't do this, and if users have for example listed your issue id
+in their build.gradle
file or in lint.xml
to say change the
+severity, then lint will report an error that it's an unknown id. This
+is done to catch issue id typos. And if the user has a baseline file
+listing incidents from your check, then if your issue id is not
+registered as deleted, lint will think this is an issue that has been
+“fixed” since it's no longer reported, and lint will issue an
+informational message that the baseline contains issues no longer
+reported (which is done such that users can update their baseline
+files, to ensure that the fixed issues aren't reintroduced again.)
+
+
+ Lint Check Unit Testing
+
+
+
+Lint has a dedicated testing library for lint checks. To use it,
+add this dependency to your lint check Gradle project:
+
+
testImplementation "com.android.tools.lint:lint-tests:$lintVersion "
+
+This lends itself nicely to test-driven development. When we get bug
+reports of a false positive, we typically start by adding the text for
+the repro case, ensure that the test is failing, and then work on the
+bug fix (often setting breakpoints and debugging through the unit test)
+until it passes.
+
+
+ Creating a Unit Test
+
+
+
+Here's a sample lint unit test for a simple, sample lint check which
+just issues warnings whenever it sees the word “lint” mentioned
+in a string:
+
+
package com.example.lint.checks
+
+import com.android.tools.lint.checks.infrastructure.TestFiles.java
+import com.android.tools.lint.checks.infrastructure.TestLintTask.lint
+import org.junit.Test
+
+class SampleCodeDetectorTest {
+ @Test
+ fun testBasic () {
+ lint().files(
+ java(
+ """
+ package test.pkg;
+ public class TestClass1 {
+ // In a comment, mentioning "lint" has no effect
+ private static String s1 = "Ignore non-word usages: linting";
+ private static String s2 = "Let's say it: lint";
+ }
+ """
+ ).indented()
+ )
+ .issues(SampleCodeDetector.ISSUE)
+ .run()
+ .expect (
+ """
+ src/test/pkg/TestClass1.java:5: Warning: This code mentions lint: Congratulations [SampleId]
+ private static String s2 = "Let's say it: lint";
+ ∼∼∼∼∼∼∼∼∼∼∼∼∼∼∼∼∼∼∼∼
+ 0 errors, 1 warnings
+ """
+ )
+ }
+ }
+
+Lint's testing API is a “fluent API”; you chain method calls together,
+and the return objects determine what is allowed next.
+
+
+
+Notice how we construct a test object here on line 10 with the lint()
+call. This is a “lint test task”, which has a number of setup methods
+on it (such as the set of source files we want to analyze), the issues
+it should consider, etc.
+
+
+
+Then, on line 23, the run()
method. This runs the lint unit test, and
+then it returns a result object. On the result object we have a number
+of methods to verify that the test succeeded. For a test making sure we
+don't have false positives, you can just call expectClean()
. But the
+most common operation is to call expect(output)
.
+
+
+
+
Notice how we're including the whole text output here; including not
+ just the error message and line number, but lint's output of the
+ relevant line and the error range (using ~~~~ characters).
+
+
+
+ This is the recommended practice for lint checks. It may be tempting
+ to avoid “duplication” of repeating error messages in the tests
+ (“DRY”), so some developers have written tests where they just
+ assert that a given test has say “2 warnings”. But this isn't
+ testing that the error range is exactly what you expect (which
+ matters a lot when users are seeing the lint check from the IDE,
+ since that's the underlined region), and it could also continue to
+ pass even if the errors flagged are no longer what you intended.
+
+
+
+ Finally, even if the location is correct today, it may not be
+ correct tomorrow. Several times in the past, some unit tests in
+ lint's built-in checks have started failing after an update to the
+ Kotlin compiler because of some changes to the AST which required
+ tweaks here and there.
+
+
+ Computing the Expected Output
+
+
+
+You may wonder how we knew what to paste into our expect
call
+to begin with.
+
+
+
+We didn't. When you write a test, simply start with
+expect("")
, and run the test. It will fail. You can now
+copy the actual output into the expect
call as the expected
+output, provided of course that it's correct!
+
+
+ Test Files
+
+
+
+On line 11, we construct a Java test file. We call java(...)
and pass
+in the source file contents. This constructs a TestFile
, and there
+are a number of different types of test source files, such as for
+Kotlin files, manifest files, icons, property files, and so on.
+
+
+
+Using test file descriptors like this to describe an input file has
+a number of advantages over the traditional approach of checking in
+test files as sources:
+
+
+
+
+Everything is kept together, so it's easier to look at a test and see
+ what it analyzes and what the expected results are. This is
+ particularly important for complex lint checks which test a lot of
+ scenarios. As of this writing, ApiDetectorTest
has 157 individual
+ unit tests.
+
+
+
+
Multiple test files shown inline
+
+
+
+
+Lint can provide a DSL to construct test files easily. For example,
+ projectProperties().compileSdk(17)
and
+ manifest().minSdk(5).targetSdk(17)
construct a project.properties
+ and an AndroidManifest.xml
file with the correct contents to
+ specify for example the right element setting up the
+ minSdkVersion
and targetSdkVersion
.
+
+
+
+ For icons, we can construct bitmaps like this:
+
+
image("res/mipmap-hdpi/my_launcher2_round.png" , 50 , 50 )
+ .fillOval(0 , 0 , 50 , 50 , 0xFFFFFFFF )
+ .text (5 , 5 , "x" , 0xFFFFFFFF ))
+
+
+
+Similarly, when we construct java()
or kotlin()
test sources, we
+ don't have to name the files, because lint will analyze the source
+ code and figure out what the class file should be named and where to
+ place it.
+
+
+
+
+We can easily “parameterize” our test files. For example, if you want
+ to run your unit test against a 100K json file, you can construct it
+ programmatically; you don't have to check one in. As another example
+ you can programmatically create a number of repetitive scenarios.
+
+
+
+
+Since test sources often (deliberately!) have errors in them (which
+ is relevant when lint is unning on the fly inside the IDE editor),
+ this sometimes causes problems with the tooling; for example, some
+ code review tools will flag “disallowed” constructs or things like
+ tabs or trailing spaces, which may be deliberate in a lint unit test.
+
+
+
+
+You can test running in single-file mode, which is how lint is run
+ on the fly in the editor.
+
+
+
+
+Lint originally checked in test sources as individual files.
+ Unfortunately over time, source files ended up getting reused by
+ multiple tests. And that made it harder to make changes, or figure
+ out whether test sources are still in use, and so on.
+
+
+
+
+Last but not least, because all the test construction methods
+ specify the correct mime type for their string parameters, IntelliJ
+ will actually syntax highlight the test source declarations! Here's
+ how this looks:
+
+
+
+
Screenshot of nested highlighting
+
+
+
+
+Finally, but most importantly, with the descriptors of your test
+ scenarios, lint can re-run your tests under a number of different
+ scenarios, including modifying your source files and project layout.
+ This concept is documented in more detail in the test
+ modes chapter.
+
+
+ Trimming indents?
+
+
+
+Notice how in the above Kotlin unit tests we used raw strings, and
+we indented the sources to be flush with the opening """
string
+delimiter.
+
+
+
+You might be tempted to call .trimIndent()
on the raw string.
+However, doing that would break the above nested syntax highlighting
+method (or at least it used to). Therefore, instead, call .indented()
+on the test file itself, not the string, as shown on line 20.
+
+
+
+Note that we don't need to do anything with the expect
call; lint
+will automatically call trimIndent()
on the string passed in to it.
+
+
+ Dollars in Raw Strings
+
+
+
+Kotlin requires that raw strings have to escape the dollar ($)
+character. That's normally not a problem, but for some source files, it
+makes the source code look really messy and unreadable.
+
+
+
+For that reason, lint will actually convert $ into $ (a unicode wide
+dollar sign). Lint lets you use this character in test sources, and it
+always converts the test output to use it (though it will convert in
+the opposite direction when creating the test sources on disk).
+
+
+ Quickfixes
+
+
+
+If your lint check registers quickfixes with the reported incidents,
+it's trivial to test these as well.
+
+
+
+For example, for a lint check result which flags two incidents, with a
+single quickfix, the unit test looks like this:
+
+
lint().files(... )
+ .run()
+ .expect(expected)
+ .expectFixDiffs(
+ ""
+ + "Fix for res/layout/textsize.xml line 10: Replace with sp:\n "
+ + "@@ -11 +11\n "
+ + "- android:textSize=\" 14dp\" />\n "
+ + "+ android:textSize=\" 14sp\" />\n "
+ + "Fix for res/layout/textsize.xml line 15: Replace with sp:\n "
+ + "@@ -16 +16\n "
+ + "- android:textSize=\" 14dip\" />\n "
+ + "+ android:textSize=\" 14sp\" />\n " );
+
+The expectFixDiffs
method will iterate over all the incidents it
+found, and in succession, apply the fix, diff the two sources, and
+append this diff along with the fix message into the log.
+
+
+
+When there are multiple fixes offered for a single incident, it will
+iterate through all of these too:
+
+
lint().files(... )
+ .run()
+ .expect(expected)
+ .expectFixDiffs(
+ + "Fix for res/layout/autofill.xml line 7: Set autofillHints:\n "
+ + "@@ -12 +12\n "
+ + " android:layout_width=\" match_parent\" \n "
+ + " android:layout_height=\" wrap_content\" \n "
+ + "+ android:autofillHints=\" |\" \n "
+ + " android:hint=\" hint\" \n "
+ + " android:inputType=\" password\" >\n "
+ + "Fix for res/layout/autofill.xml line 7: Set importantForAutofill=\" no\" :\n "
+ + "@@ -13 +13\n "
+ + " android:layout_height=\" wrap_content\" \n "
+ + " android:hint=\" hint\" \n "
+ + "+ android:importantForAutofill=\" no\" \n "
+ + " android:inputType=\" password\" >\n "
+ + " \n " );
+ Library Dependencies and Stubs
+
+
+
+Let's say you're writing a lint check for something like the Android
+Jetpack library's RecyclerView
widget.
+
+
+
+In this case, it's highly likely that your unit test will reference
+RecyclerView
. But how does lint know what RecyclerView
is? If it
+doesn't, type resolve won't work, and as a result the detector won't.
+
+
+
+You could make your test “depend” on the RecyclerView
. This is
+possible, using the LibraryReferenceTestFile
, but is not recommended.
+
+
+
+Instead, the recommended approach is to just use “stubs”; create
+skeleton classes which represent only the signatures of the
+library, and in particular, only the subset that your lint check cares
+about.
+
+
+
+For example, for lint's own RecyclerView
test, the unit test declares
+a field holding the recycler view stub:
+
+
private val recyclerViewStub = java(
+ """
+ package android.support.v7.widget;
+
+ import android.content.Context;
+ import android.util.AttributeSet;
+ import android.view.View;
+ import java.util.List;
+
+ // Just a stub for lint unit tests
+ public class RecyclerView extends View {
+ public RecyclerView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public abstract static class ViewHolder {
+ public ViewHolder(View itemView) {
+ }
+ }
+
+ public abstract static class Adapter<vh extends="" viewholder=""> {
+ public abstract void onBindViewHolder(VH holder, int position);
+ public void onBindViewHolder(VH holder, int position, List<object> payloads) {
+ }
+ public void notifyDataSetChanged() { }
+ }
+ }
+ """
+ ).indented()
+
+And now, all the other unit tests simply include recyclerViewStub
+as one of the test files. For a larger example, see
+this test .
+
+
+
+
In recent versions of lint, the unit testing library will do some
+ basic checking to make sure that important symbols do resolve
+ correctly. It doesn't check everything (since it's common for unit
+ tests to contain snippets from copy paste that aren't relevant to
+ the test), but it does check all classes and methods referenced via
+ import statements, and any calls or references in the test files
+ that match any of the names returned from
+ getApplicableMethodNames()
or getApplicableReferenceNames()
+ respectively.
+
+
+
+Here's an example of a test failure for an unresolved import:
+
+
java.lang.IllegalStateException:
+ app/src/com/example/MyDiffUtilCallbackJava.java:4: Error:
+ Couldn't resolve this import [LintError]
+ import androidx.recyclerview.widget.DiffUtil;
+ -------------------------------------
+
+ This usually means that the unit test needs to declare a stub file or
+ placeholder with the expected signature such that type resolving works.
+
+ If this import is immaterial to the test, either delete it, or mark
+ this unit test as allowing resolution errors by setting
+ `allowCompilationErrors()`.
+
+ (This check only enforces import references, not all references, so if
+ it doesn't matter to the detector, you can just remove the import but
+ leave references to the class in the code.)
+ Binary and Compiled Source Files
+
+
+
+If you need to use binaries in your unit tests, there are two options:
+
+
+
+
+ base64gzip
+
+ API stubs
+
+
+
+If you want to analyze bytecode of method bodies, you'll need to use
+the first option.
+
+
+
+The first type requires you to actually compile your test file into a
+set of .class files, and check those in as a gzip-compressed, base64
+encoded string. Lint has utilities for this; see the next section.
+
+
+
+The second option is using API stubs. For simple stub files (where you
+only need to provide APIs you'll call as binaries, but not code), lint
+can produce the corresponding bytecode on the fly, so you don't need
+to pre-create binary contents of the class. This is particularly
+helpful when you just want to create stubs for a library your lint
+check is targeting and you want to make sure the detector is seeing
+the same types of elements as it will when analyzing real code outside
+of tests (since there is a difference between resolving into APIs from
+source and form binaries; when you're analyzing calls into source, you
+can access for example method bodies, and this isn't available via
+UAST from byte code.)
+
+
+
+These test files also let you specify an artifact name instead of a
+jar path, and lint will use this to place the jar in a special place
+such that it recognizes it (via JavaEvaluator.findOwnerLibrary
) as
+belonging to this library.
+
+
+
+Here's an example of how you can create one of these binary stub
+files:
+
+
fun testIdentityEqualsOkay() {
+ lint().files(
+ kotlin(
+ "/*test contents here *using* some recycler view APIs*/"
+ ).indented(),
+ mavenLibrary(
+ "androidx.recyclerview:recyclerview:1.0.0" ,
+ java(
+ """
+ package androidx.recyclerview.widget;
+ public class DiffUtil {
+ public abstract static class ItemCallback<t> {
+ public abstract boolean areItemsTheSame(T oldItem, T newItem);
+ public abstract boolean areContentsTheSame(T oldItem, T newItem);
+ }
+ }
+ """
+ ).indented()
+ )
+ ).run().expect(
+ Base64-encoded gzipped byte code
+
+
+
+Here's an example from a lint check which tries to recognize usage of
+Cordova in the bytecode:
+
+
fun testVulnerableCordovaVersionInClasses () {
+ lint().files(
+ base64gzip(
+ "bin/classes/org/apache/cordova/Device.class" ,
+ "" +
+ "yv66vgAAADIAFAoABQAPCAAQCQAEABEHABIHABMBAA5jb3Jkb3ZhVmVyc2lv" +
+ "bgEAEkxqYXZhL2xhbmcvU3RyaW5nOwEABjxpbml0PgEAAygpVgEABENvZGUB" +
+ "AA9MaW5lTnVtYmVyVGFibGUBAAg8Y2xpbml0PgEAClNvdXJjZUZpbGUBAAtE" +
+ "ZXZpY2UuamF2YQwACAAJAQAFMi43LjAMAAYABwEAGW9yZy9hcGFjaGUvY29y" +
+ "ZG92YS9EZXZpY2UBABBqYXZhL2xhbmcvT2JqZWN0ACEABAAFAAAAAQAJAAYA" +
+ "BwAAAAIAAQAIAAkAAQAKAAAAHQABAAEAAAAFKrcAAbEAAAABAAsAAAAGAAEA" +
+ "AAAEAAgADAAJAAEACgAAAB4AAQAAAAAABhICswADsQAAAAEACwAAAAYAAQAA" +
+ "AAUAAQANAAAAAgAO"
+ )
+ ).run().expect (
+
+Here, “base64gzip” means that the file is gzipped and then base64
+encoded.
+
+
+
+If you want to compute the base64gzip string for a given file, a simple
+way to do it is to add this statement at the beginning of your test:
+
+
assertEquals("" , TestFiles.toBase64gzip(File ("/tmp/mybinary.bin" )))
+
+The test will fail, and now you have your output to copy/paste into the
+test.
+
+
+
+However, if you're writing byte-code based tests, don't just hard code
+in the .class file or .jar file contents like this. Lint's own unit
+tests did that, and it's hard to later reconstruct what the byte code
+was later if you need to make changes or extend it to other bytecode
+formats.
+
+
+
+Instead, use the new compiled
or bytecode
test files. The key here
+is that they automate a bit of the above process: the test file
+provides a source test file, as well as a set of corresponding binary
+files (since a single source file can create multiple class files, and
+for Kotlin, some META-INF data).
+
+
+
+Here's an example of a lint test which is using bytecode(...)
to
+describe binary files:
+https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:lint/libs/lint-tests/src/test/java/com/android/tools/lint/client/api/JarFileIssueRegistryTest.kt?q=testNewerLintBroken
+
+
+
+Initially, you just specify the sources, and when no binary data
+has been provided, lint will instead attempt to compile the sources
+and emit the full test file registration.
+
+
+
+This isn't just a convenience; lint's test infrastructure also uses
+this to test some additional scenarios (for example, in a multi-module
+project it will only provide the binaries, not the sources, for
+upstream modules.)
+
+
+ My Detector Isn't Invoked From a Test!
+
+
+
+One common question we hear is
+
+ My Detector works fine when I run it in the IDE or from Gradle, but
+ from my unit test, my detector is never called! Why?
+
+
+
+This is almost always because the test sources are referring to some
+library or dependency which isn't on the class path. See the “Library
+Dependencies and Stubs” section above, as well as the frequently asked
+questions .
+
+
+ Language Level
+
+
+
+Lint will analyze Java and Kotlin test files using its own default
+language levels. If you need a higher (or lower) language level in order
+to test a particular scenario, you can use the kotlinLanguageLevel
+and javaLanguageLevel
setter methods on the lint test configuration.
+Here's an example of a unit test setup for Java records:
+
+
lint()
+ .files(
+ java("""
+ record Person(String name, int age) {
+ }
+ """ )
+ .indented()
+ )
+ .javaLanguageLevel("17" )
+ .run()
+ .expect (...)
+
+
+
+
+ Test Modes
+
+
+
+Lint's unit testing machinery has special support for “test modes”,
+where it repeats a unit test under different conditions and makes sure
+the test continues to pass with the same test results — the same
+warnings in the same test files.
+
+
+
+There are a number of built-in test modes:
+
+
+
+
+Test modes which make small tweaks to the source files which
+ should be compatible, such as
+
+ Inserting unnecessary parentheses
+
+ Replacing imported symbols with fully qualified names
+
+ Replacing imported symbols with Kotlin import aliases
+
+ Replacing types with typealiases
+
+ Reordering Kotlin named arguments
+
+ Replacing simple functions with Kotlin expression bodies
+
+ etc
+
+ A partial analysis test mode which runs the tests in “partial
+ analysis” mode; two phases, analysis and reporting, with
+ minSdkVersion set to 1 during analysis and set to the true test
+ value during reporting etc.
+
+Bytecode Only: Any test files that specify both source and bytecode
+ will only use the bytecode
+
+Source Only: Any test files that specify both source and bytecode
+ will only use the source code
+
+
+
+These are built-in test modes which will be applied to all detector
+tests, but you can opt out of any test modes by invoking the
+skipTestModes
DSL method, as described below.
+
+
+
+You can also add in your own test modes. For example, lint adds its own
+internal test mode for making sure the built-in annotation checks work
+with Android platform annotations in the following test mode:
+
+
+
+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/AndroidPlatformAnnotationsTestMode.kt
+
+
+ How to debug
+
+
+
+Let's say you have a test failure in a particular test mode, such
+as TestMode.PARENTHESIZED
which inserts unnecessary parentheses
+into the source code to make sure detectors are properly skipping
+through UParenthesizedExpression
nodes.
+
+
+
+If you just run this under the debugger, lint will run through
+all the test modes as usual, which means you'll need to skip
+through a lot of intermediate breakpoint hits.
+
+
+
+For these scenarios, it's helpful to limit the test run to only the
+target test mode. To do this, go and specify that specific test mode as
+part of the run setup by adding the following method declaration into
+your detector class:
+
+
override fun lint () : TestLintTask {
+ return super .lint().testModes(TestMode.PARENTHESIZED)
+ }
+
+Now when you run your test, it will run only this test mode, so you
+can set breakpoints and start debugging through the scenario without
+having to figure out which mode you're currently being invoked in.
+
+
+
+
Don't forget to remove that override when you're done!
+
+
+ Handling Intentional Failures
+
+
+
+There are cases where your lint check is doing something very
+particular related to the changes made by the test mode which means
+that the test mode doesn't really apply. For example, there is a test
+mode which adds unnecessary parentheses, to make sure that the detector
+is properly handling the case where there are intermediate parenthesis
+nodes in the AST. Normally, every lint check should behave the same
+whether or not optional parentheses are present. But, if the lint check
+you are writing is actually parenthesis specific, such as suggesting
+removal of optional parentheses, then obviously in that case you don't
+want to apply this test mode.
+
+
+
+To do this, there's a special test DSL method you can add,
+skipTestModes
. Adding a comment for why that particular mode is
+skipped is useful as well.
+
+
lint().files(...)
+ .allowCompilationErrors()
+
+
+ .skipTestModes(TestMode.PARTIAL)
+ .run()
+ .expectClean()
+ Source-Modifying Test Modes
+
+
+
+The most powerful test modes are those that make some deliberate
+transformations to your source code, to test variations of the code
+patterns that may appear in the wild. Examples of this include having
+optional parentheses, or fully qualified names.
+
+
+
+Lint will make these transformations, then run your tests on the
+modified sources, and make sure the results are the same — except for
+the part of the output which shows the relevant source code, since that
+part is expected to differ due to the modifications.
+
+
+
+When lint finds a failure, it will abort with a diff that includes not
+just the different error output between the default mode and the source
+modifying mode, but the source files as well; that makes it easier to
+spot what the difference is.
+
+
+
+In the following screenshot for example we've run a failing test inside
+IntelliJ, and have then clicked on the Show Difference link in the test
+output window (Ctrl+D or Cmd-D) which shows the test failure diff
+nicely:
+
+
+
+
Figure 1: Screenshot of test failure
+
+
+
+This is a test mode which converts all symbols to fully qualified
+names; in addition to the labeled output at the top we can see the
+diffs in the test case files below the error output diff. The test
+files include line numbers to help make it easy to correlate extra or
+missing warnings with their line numbers to the changed source code.
+
+
+ Fully Qualified Names
+
+
+
+The TestMode.FULLY_QUALIFIED
test mode will rewrite the source files
+such that all symbols that it can resolve are replaced with fully
+qualified names.
+
+
+
+For example, this mode will convert the following code:
+
+
import android.widget.RemoteViews
+
+fun test (packageName: String , other: Any ) {
+ val rv = RemoteViews(packageName, R.layout.test)
+ val ov = other as RemoteViews
+ }
+
+to
+
+
import android.widget.RemoteViews
+
+fun test (packageName: String , other: Any ) {
+ val rv = android.widget.RemoteViews(packageName, R.layout.test)
+ val ov = other as android.widget.RemoteViews
+ }
+
+This makes sure that your detector handles not only the case where a
+symbol appears in its normal imported state, but also when it is fully
+qualified in the code, perhaps because there is a different competing
+class of the same name.
+
+
+
+This will typically catch cases where the code is incorrectly just
+comparing the identifier at the call node instead of the fully
+qualified name.
+
+
+
+For example, one detector's tests failed in this mode because
+it was looking to identify references to an EnumSet
,
+and the code looked like this:
+
+
private fun checkEnumSet (node: UCallExpression ) {
+ val receiver = node.receiver
+ if (receiver is USimpleNameReferenceExpression &&
+ receiver.identifier == "EnumSet"
+ ) {
+
+which will work for code such as EnumSet.of()
but not
+java.util.EnumSet.of()
.
+
+
+
+Instead, use something like this:
+
+
private fun checkEnumSet (node: UCallExpression ) {
+ val targetClass = node.resolve()?.containingClass?.qualifiedName
+ ?: return
+ if (targetClass == "java.util.EnumSet" ) {
+
+As with all the source transforming test modes, there are cases where
+it doesn't apply. For example, lint had a built-in check for camera
+EXIF metadata, encouraging you to import the androidx version of the
+library instead of using the built-in version. If it sees you using the
+platform one it will normally encourage you to import the androidx one
+instead:
+
+
src/ test/ pkg/ ExifUsage.java:9 : Warning: Avoid using android.media.ExifInterface; use androidx.exifinterface.media.ExifInterface instead [ExifInterface]
+ android.media.ExifInterface exif = new android.media.ExifInterface(path);
+
+
+However, if you explicitly (via fully qualified imports) reference the
+platform one, in that case the lint check does not issue any warnings
+since it figures you're deliberately trying to use the older version.
+And in this test mode, the results between the two obviously differ,
+and that's fine; as usual we'll deliberately turn off the check in this
+detector:
+
+
@Override protected TestLintTask lint () {
+
+
+
+
+ return super .lint().skipTestModes(TestMode.FULLY_QUALIFIED);
+ }
+
+
+
+
In Kotlin code, you may have code that checks to see if a node is a
+ UCallExpression
. But note that if a call is fully qualified, the
+ node will be a UQualifiedReferenceExpression
instead, and you'll
+ need to look at its selector. So watch out for code which does
+ something like node as? UCallExpression
.
+
+
+ Import Aliasing
+
+
+
+In Kotlin, you can create an import alias, which lets you refer to
+the imported class using an entirely different name.
+
+
+
+This test mode will create import aliases for all the import statements
+in the file and will replace all the references to the import aliases
+instead. This makes sure that the detector handles the equivalent Kotlin
+code.
+
+
+
+For example, this mode will convert the following code:
+
+
import android.widget.RemoteViews
+
+fun test (packageName: String , other: Any ) {
+ val rv = RemoteViews(packageName, R.layout.test)
+ val ov = other as RemoteViews
+ }
+
+to
+
+
import android.widget.RemoteViews as IMPORT_ALIAS_1_REMOTEVIEWS
+
+fun test (packageName: String , other: Any ) {
+ val rv = IMPORT_ALIAS_1_REMOTEVIEWS(packageName, R.layout.test)
+ val ov = other as IMPORT_ALIAS_1_REMOTEVIEWS
+ }
+ Type Aliasing
+
+
+
+Kotlin also lets you alias types using the typealias
keyword.
+This test mode is similar to import aliasing, but applied to all
+types. In addition to the different AST representations of import
+aliases and type aliases, they apply to different things.
+
+
+
+For example, if we import TreeMap, and we have a code reference such as
+TreeMap<string>
, then the import alias will alias the tree map class
+itself, and the reference would look like IMPORT_ALIAS_1<string>
,
+whereas for type aliases, the alias would be for the whole
+TreeMap<string>
, and the code reference would be TYPE_ALIAS_1
.
+
+
+
+Also, import aliases will only apply to the explicitly imported
+classes, whereas type aliases will apply to all types, including Int,
+Boolean, List, etc.
+
+
+
+For example, this mode will convert the following code:
+
+
import android.widget.RemoteViews
+
+fun test (packageName: String , other: Any ) {
+ val rv = RemoteViews(packageName, R.layout.test)
+ val ov = other as RemoteViews
+ }
+
+to
+
+
import android.widget.RemoteViews
+
+fun test (packageName: TYPE_ALIAS_1 , other: TYPE_ALIAS_2 ) {
+ val rv = RemoteViews(packageName, R.layout.test)
+ val ov = other as TYPE_ALIAS_3
+ }
+typealias TYPE_ALIAS_1 = String
+typealias TYPE_ALIAS_2 = Any
+typealias TYPE_ALIAS_3 = RemoteViews
+ Parenthesis Mode
+
+
+
+Kotlin and Java code is allowed to contain extra clarifying
+parentheses. Sometimes these are leftovers from earlier more
+complicated expressions where when the expression was simplified the
+parentheses were left in place.
+
+
+
+In UAST, parentheses are represented in the AST (via a
+UParenthesizedExpression
node). While this is good since it allows
+you to for example write lint checks which identifies unnecessary
+parentheses, it introduces a complication: you can't just look at a
+node's parent to for example see if it's a UQualifiedExpression
; you
+have to be prepared to look “through” it such that if it's a
+UParenthesizedExpression
node, you instead look at its parent in
+turn. (And programmers can of course put as (((many unnecessary)))
+parentheses as they want, so you may have to skip through repeated
+nodes.)
+
+
+
+Note also that this isn't just for looking upwards or outwards at
+parents. Let's say you're looking at a call and you want to see if the
+last argument is a literal expression such as a number or a String. You
+can't just use if (call.valueArguments.lastOrNull() is
+ULiteralExpression)
, because that first argument could be a
+UParenthesizedExpression
, as in call(1, true, ("hello"))
, so you'd
+need to look inside the parentheses.
+
+
+
+UAST comes with two functions to help you handle this correctly:
+
+
+
+
+Whenever you look at the parent, make sure you surround the call with
+ skipParenthesizedExprUp(UExpression)
.
+
+
+
+
+If you are looking at a child node, use the method
+ skipParenthesizedExprDown
, an extension method on UExpression (and
+ from Java import it from UastUtils).
+
+
+
+To help catch these bugs, lint has a special test mode where it inserts
+various redundant parentheses in your test code, and then makes sure
+that the same errors are reported. The error output will of course
+potentially vary slightly (since the source code snippets shown will
+contain extra parentheses), but the test will ignore these differences
+and only fail if it sees new errors reported or expected errors not
+reported.
+
+
+
+In the unlikely event that your lint check is actually doing something
+parenthesis specific, you can turn off this test mode using
+.skipTestModes(TestMode.PARENTHESIZED)
.
+
+
+
+For example, this mode will convert the following code:
+
+
(t as ? String)?.plus("other" )?.get (0 )?.dec()?.inc()
+"foo" .chars().allMatch { it.dec() > 0 }.toString()
+
+to
+
+
(((((t as ? String))?.plus("other" ))?.get (0 ))?.dec())?.inc()
+ (("foo" .chars()).allMatch { (it.dec() > 0 ) }).toString()
+
+By default the parenthesis mode limits itself to “likely” unnecessary
+parentheses; in particular, it won't put extra parenthesis around
+simple literals, like (1) or (false). You can explicitly construct
+ParenthesizedTestMode(includeUnlikely=true)
if you want additional
+parentheses.
+
+
+ Argument Reordering
+
+
+
+In Kotlin, with named parameters you're allowed to pass in the
+arguments in any order. To handle this correctly, detectors should
+never just line up parameters and arguments and match them by index;
+instead, there's a computeArgumentMapping
method on JavaEvaluator
+which returns a map from argument to parameter.
+
+
+
+The argument-reordering test mode will locate all calls to Kotlin
+methods, and it will then first add argument names to any parameter not
+already specifying a name, and then it will shift all the arguments
+around, then repeat the test. This will catch any detectors which were
+incorrectly making assumptions about argument order.
+
+
+
+(Note that the test mode will not touch methods that have vararg
+parameters for now.)
+
+
+
+For example, this mode will convert the following code:
+
+
test("test" , 5 , true )
+
+to
+
+
test(n = 5 , z = true , s = "test" )
+ Body Removal
+
+
+
+In Kotlin, you can replace
+
+
fun test () : List<string> {
+ return if (true ) listOf("hello" ) else emptyList()
+ }
+
+with
+
+
fun test () : List<string> = if (true ) listOf("hello" ) else emptyList()
+
+Note that these two ASTs do not look the same; we'll only have an
+UReturnExpression
node in the first case. Therefore, you have to be
+careful if your detector is just visiting UReturnExpression
s in order
+to find exit points.
+
+
+
+The body removal test mode will identify all scenarios where it can
+replace a simple function declaration with an expression body, and
+will make sure that the test results are the same, to make sure detectors are handling both AST variations.
+
+
+
+It also does one more thing: it toggled optional braces from if
+expressions — converting
+
+
if (x < y) { test(x+1 ) } else test(x+2 )
+
+to
+
+
if (x < y) test(x+1 ) else { test(x+2 ) }
+
+(Here it has removed the braces around the if-then body since they are
+optional, and it has added braces around the if-else body since it did
+not have optional braces.)
+
+
+
+The purpose of these tweaks are similar to the expression body change:
+making sure that detectors are properly handling the presence of
+absence of UBlockExpression
around the child nodes.
+
+
+ If to When Replacement
+
+
+
+In Kotlin, you can replace a series of if
/else
statements with a
+single when
block. These two alternative do not look the same in the
+AST; if
expressions show up as UIfExpression
, and when
+expressions show up as USwitchExpression
.
+
+
+
+The if-to-when test mode will change all the if
statements in Kotlin
+lint tests with the corresponding when statement, and makes sure that
+the test results remain the same. This ensures that detectors are
+properly looking for both UIfExpression
and USwitchExpression
and
+handling each. When this test mode was introduced, around 12 unit tests
+in lint's built-in checks (spread across 5 detectors) needed some
+tweaks.
+
+
+ Whitespace Mode
+
+
+
+This test mode inserts a number of “unnecessary” whitespace characters
+in valid places in the source code.
+
+
+
+This helps catch bugs where lint checks are improperly making
+assumptions about whitespace in the source file, particularly in
+quickfix implementations, or when for example looking up a qualified
+expression and just taking the asSourceString()
or text
property of
+a PSI element or PSI type and checking it for equality with something
+like java.util.List<string>
.
+
+
+
+For example, some of the built-in checks which performed quickfix
+string replacements based on regular expression matching had to be
+updated to be prepared for whitespace characters:
+
+
+++ b/lint/libs/lint-checks/src/main/java/com/android/tools/lint/checks/WakelockDetector.java
+ @@ -454,7 +454,7 @@ public class WakelockDetector extends Detector implements ClassScanner, SourceCo
+ LintFix fix =
+ fix().name("Set timeout to 10 minutes")
+ .replace()
+ - .pattern("acquire\\(()\\)")
+ + .pattern("acquire\\s*\\(()\\s*\\)")
+ .with("10*60*1000L /*10 minutes*/")
+ .build();
+ CDATA Mode
+
+
+
+When declaring string resources, you may want to use XML CDATA sections
+instead of plain text. For example, instead of
+
+
<?xml version="1.0" encoding="UTF-8" ?>
+<resources >
+ <string name ="app_name" > Application Name</string >
+</resources >
+
+you can equivalently use
+
+
<?xml version="1.0" encoding="UTF-8" ?>
+<resources >
+ <string name ="app_name" > <![CDATA[Application Name]]></string >
+</resources >
+
+(where you can place newlines and other unescaped text inside the bracketed span.)
+
+
+
+This alternative form shows up differently in the XML DOM that is
+provided to lint detectors; in particular, if you are iterating through
+the Node
children of an Element
, you should not just look at nodes
+with nodeType == Node.TEXT_NODE
; you need to also handle noteType ==
+Node.CDATA_SECTION_NODE
.
+
+
+
+This test mode will automatically retry all your tests that define
+string resources, and will convert regular text into CDATA
and makes
+sure the results continue to be the same.
+
+
+ Suppressible Mode
+
+
+
+Users should be able to ignore lint warnings by inserting suppress annotations
+(in Kotlin and Java), and via tools:ignore
attributes in XML files.
+
+
+
+This normally works for simple checks, but if you are combining results from
+different parts of the code, or for example caching locations and reporting
+them later, this is sometimes broken.
+
+
+
+This test mode looks at the reported warnings from your unit tests, and then
+for each one, it looks up the corresponding error location's source file, and
+inserts a suppress directive at the nearest applicable location. It then
+re-runs the analysis, and makes sure that the warning no longer appears.
+
+
+ @JvmOverloads Test Mode
+
+
+
+When UAST comes across a method like this:
+
+
@JvmOverloads
+fun test (parameter: Int = 0 ) {
+ implementation()
+ }
+
+it will “inline” these two methods in the AST, such that we see the whole
+method body twice:
+
+
fun test () {
+ implementation()
+ }
+
+fun test (parameter: Int ) {
+ implementation()
+ }
+
+If there were additional default parameters, there would be additional
+repetitions.
+
+
+
+This is similar to what the compiler does, since Java doesn't have
+default arguments, but the compiler will actually just generate some
+trampoline code to jump to the implementation with all the parameters;
+it will NOT repeat the method implementation:
+
+
fun test (parameter: Int ) {
+ implementation()
+ }
+
+
+fun `test$default`(var0: Int , var1: Int , var2: Any ?) {
+ var var0 = var0
+ if ((var1 and 1 ) != 0 ) {
+ var0 = 0
+ }
+
+ test(var0)
+ }
+
+Again, UAST will instead just repeat the method body. And this means
+lint detectors may trigger repeatedly on the same code. In most cases
+this will result in duplicated warnings. But it can also lead to other
+problems; for example, a lint check which makes sure you don't have any
+code duplication would incorrectly believe code fragments are repeated.
+
+
+
+Lint already looks for this situation and avoids visiting duplicated
+methods in its shared implementations (which is dispatching to most
+Detector
callbacks). However, if you manually visit a class yourself,
+you can run into this problem.
+
+
+
+This test mode simulates this situation by finding all methods where
+it can safely add at least one default parameter, and marks it
+@JvmOverloaded. It then makes sure the results are the same as before.
+
+
+
+
+
+
+ Adding Quick Fixes
+
+ Introduction
+
+
+
+When your detector reports an incident, it can also provide one or more
+“quick fixes”, which are actions the users can invoke in the IDE (or,
+for safe fixes, in batch mode) to address the reported incident.
+
+
+
+For example, if the lint check reports an unused resource, a quick fix
+could offer to remove the unused resource.
+
+
+
+In some cases, quick fixes can take partial steps towards fixing the
+problem, but not fully. For example, the accessibility lint check which
+makes sure that for images you set a content description, the quickfix
+can offer to add it — but obviously it doesn't know what description
+to put. In that case, the lint fix will go ahead and add the attribute
+declaration with the correct namespace and attribute name, but will
+leave the value up to the user (so it uses a special quick fix provided
+by lint to place a TODO marker as the value, along with selecting just
+that TODO string such that the user can type to replace without having
+to manually delete the TODO string first.)
+
+
+ The LintFix builder class
+
+
+
+The class in lint which represents a quick fix is LintFix
.
+
+
+
+Note that LintFix
is not a class you can subclass and then for
+example implement your own arbitrary code in something like a
+perform()
method.
+
+
+
+Instead, LintFix
has a number of builders where you describe the
+action that you would like the quickfix to take. Then, lint will offer
+that quickfix in the IDE, and when the user invokes it, lint runs its
+own implementation of the various descriptors.
+
+
+
+The historical reason for this is that many of the quickfixes in lint
+depended on machinery in the IDE (such as code and import cleanup after
+an edit operation) that isn't available in lint itself, along with
+other concepts that only make sense in the IDE, such as moving the
+caret, opening files, selecting text, and so on.
+
+
+
+More recently, this is also used to persist quickfixes properly for
+later reuse; this is required for partial
+analysis .
+
+
+ Creating a LintFix
+
+
+
+Lint fixes use a “fluent API”; you first construct a LintFix
, and on
+that method you call various available type methods, which will then
+further direct you to the allowed options.
+
+
+
+For example, to create a lint fix to set an XML attribute of a given
+name to “true”, use something like this:
+
+
LintFix fix = fix().set (null , "singleLine" , "true" ).build()
+
+Here the fix()
method is provided by the Detector
super class, but
+that's just a utility method for LintFix.fix()
(or in older versions,
+LintFix.create()
).
+
+
+
+There are a number of additional, common methods you can set on
+the fix()
object:
+
+
+
+
+name
: Sets the description of the lint fix. This should be brief;
+ it's in the quickfix popup shown to the user.
+
+
+
+
+sharedName
: This sets the “shared” or “family” name: all fixes in
+ the file will with the same name can be applied in a single
+ invocation by the user. For example, if you register 500 “Remove
+ unused import” quickfixes in a file, you don't want to force the user
+ to have to invoke each and every one. By setting the shared name, the
+ user will be offered to Fix All $family name problems in the
+ current file , which they can then perform to have all 500
+ individual fixes applied in one go.
+
+
+
+
+autoFix
: If you get a lint report and you notice there are a lot of
+ incidents that lint can fix automatically, you don't want to have to
+ go and open each and every file and all the fixes in the file.
+ Therefore, lint can apply the fixes in batch mode; the Gradle
+ integration has a lintFix
target to perform this, and the lint
+ command has an --apply-suggestions
option.
+
+
+
+ However, many quick fixes require user intervention. Not just the
+ ones where the user has to choose among alternatives, and not just
+ the ones where the quick fix inserts a placeholder value like TODO.
+ Take for example lint's built-in check which requires overrides of a
+ method annotated with @CallSuper
to invoke super.
on the
+ overridden method. Where should we insert the call — at the
+ beginning? At the end?
+
+
+
+ Therefore, lint has the autoFix
property you can set on a quickfix.
+ This indicates that this fix is “safe” and can be performed in batch
+ mode. When the lintFix
target runs, it will only apply fixes marked
+ safe in this way.
+
+
+ Available Fixes
+
+
+
+The current set of available quick fix types are:
+
+
+
+
+fix().replace
: String replacements. This is the most general
+ mechanism, and allows you to perform arbitrary edits to the source
+ code. In addition to the obvious “replace old string with new”, the
+ old string can use a different location range than the incident
+ range, you can match with regular expressions (and perform
+ replacements on a specific group within the regular expression), and
+ so on.
+
+
+
+ This fix is also the most straightforward way to delete text.
+
+
+
+ It offers some useful cleanup operations:
+
+
+
+
+ Source code cleanup, which will run the IDE's code formatter on the
+ modified source code range. This will apply the user's code
+ preferences, such as whether there should be a space between a cast
+ and the expression, and so on.
+
+
+
+
+ Import cleanup. That means that if you are referencing a new type,
+ you don't have to worry about checking whether it is imported and
+ if not adding an import statement; you can simply write your string
+ replacements using the fully qualified names, and then tag the
+ quickfix with the import cleanup option, and when the quickfix is
+ performed the import will be added if necessary and all the fully
+ qualified references replaced with simple names. And this will also
+ correctly handle the scenario where the symbols cannot be replaced
+ with simple names because there is a conflicting import of the same
+ name from a different package.
+
+
+
+ Normally, you should write your replacement source code using fully
+ qualified names, and then apply shortenNames
to the quickfix to
+ tell lint to replace fully qualified names with imports; don't try
+ to write your quickfix to also add the import statements on its
+ own. There's a possibility that a given name cannot be imported
+ because it's already importing the same name for a different
+ namespace. When using fully qualified names, lint will specifically
+ handle this.
+
+
+
+ In some cases you cannot use fully qualified names in the code
+ snippet; this is the case with Kotlin extension functions for
+ example. For that scenario, the replacement quickfix has an
+ imports
property you can use to specify methods (and classes and
+ fields) to import at the same time.
+
+
+
+
+fix().annotate
: Annotating an element. This will add (or optionally
+ replace) an annotation on a source element such as a method. It will
+ also handle import management.
+
+
+
+
+fix().set
: Add XML attributes. This will insert an attribute into
+ the given element, applying the user's code style preferences for
+ where to insert the attribute. (In Android XML for example there's a
+ specific sorting convention which is generally alphabetical, except
+ layout params go before other attributes, and width goes before
+ height.)
+
+
+
+ You can either set the value to something specific, or place the
+ caret inside the newly created empty attribute value, or set it
+ to TODO and select that text for easy type-to-replace.
+
+
+
+
If you use the todo()
quickfix, it's a good idea to special case
+ your lint check to deliberately not accept “TODO” as a valid value.
+ For example, for lint's accessibility check which makes sure you set
+ a content description, it will complain both when you haven't set
+ the content description attribute, and if the text is set to
+ “TODO”. That way, if the user applies the quickfix, which creates
+ the attribute in the right place and moves the focus to the right
+ place, the editor is still showing a warning that the content
+ description should be set.
+
+
+
+
+fix().unset
: Remove XML attribute. This is a special case of add
+ attribute.
+
+
+
+
+fix().url
: Show URL. In some cases, you can't “fix” or do anything
+ local to address the problem, but you really want to direct the
+ user's attention to additional documentation. In that case, you can
+ attach a “show this URL” quick fix to the incident which will open
+ the browser with the given URL when invoked. For example, in a
+ complicated deprecation where you want users to migrate from one
+ approach to a completely different one that you cannot automate, you
+ could use something like this:
+
+
val message = "Job scheduling with `GcmNetworkManager` is deprecated: Use AndroidX `WorkManager` instead"
+val fix = fix()
+ .url(http://github.com/%3Cspan%20class=%22hljs-string%22%3E%22https://developer.android.com/topic/libraries/architecture/workmanager/migrating-gcm%22%3C/span%3E)
+ .build()
+ Combining Fixes
+
+
+
+You might notice that lint's APIs to report incidents only takes a
+single quick fix instead of a list of fixes.
+
+
+
+But let's say that it did take a list of quick fixes.
+
+
+
+
+Should they all be performed as a single unit? That makes sense if
+ you're trying to write a quickfix which performs multiple string
+ replacements.
+
+
+
+
+Or should they be offered as separate alternatives for the user to
+ choose between? That makes sense if the incident says for example
+ that you must set at least one attribute among three possibilities;
+ in this case we may want to add quickfixes for setting each attribute.
+
+
+
+Both scenarios have their uses, so lint makes this explicit:
+
+
+
+
+fix().composite
: create a “composite” fix, which composes the fix
+ out of multiple individual fixes, or
+
+
+
+
+fix().alternatives
: create an “alternatives” fix, which holds a
+ number of individual fixes, which lint will present as separate
+ options to the user.
+
+
+
+Here's an example of how to create a composite fix, which will be
+performed as a unit; here we're both setting a new attribute and
+deleting a previous attribute:
+
+
val fix = fix().name("Replace with singleLine=\"true\"" )
+ .composite(
+ fix().set (ANDROID_URI, "singleLine" , "true" ).build(),
+ fix().unset(namespace, oldAttributeName).build()
+ )
+
+And here's an example of how to create an alternatives fix, which are
+offered to the user as separate options; this is from our earlier
+example of the accessibility check which requires you to set a content
+description, which can be set either on the “text” attribute or the
+“contentDescription” attribute:
+
+
val fix = fix().alternatives(
+ fix().set ().todo(ANDROID_URI, "text" ).build(),
+ fix().set ().todo(ANDROID_URI, "contentDescription" )
+ .build())
+ Refactoring Java and Kotlin code
+
+
+
+It would be nice if there was an AST manipulation API, similar to UAST
+for visiting ASTs, that quickfixes could use to implement refactorings,
+but we don't have a library like that. And it's unlikely it would work
+well; when you rewrite the user's code you typically have to take
+language specific conventions into account.
+
+
+
+Therefore, today, when you create quickfixes for Kotlin and Java code,
+if the quickfix isn't something simple which would work for both
+languages, then you need to conditionally create either the Kotlin
+version or the Java version of the quickfix based on whether the source
+file it applies to is in Kotlin or Java. (For an easy way to check you
+can use the isKotlin
or isJava
package level methods in
+com.android.tools.lint.detector.api
.)
+
+
+
+However, it's often the case that the quickfix is something simple
+which would work for both; that's true for most of the built-in lint
+checks with quickfixes for Kotlin and Java.
+
+
+ Regular Expressions and Back References
+
+
+
+The replace
string quick fix allows you to match the text to
+with regular expressions.
+
+
+
+You can also use back references in the regular expression such
+that the quick fix replacement text includes portions from the
+original string.
+
+
+
+Here's an example from lint's AssertDetector
:
+
+
val fix = fix().name("Surround with desiredAssertionStatus() check" )
+ .replace()
+ .range(context.getLocation(assertCall))
+ .pattern("(.*)" )
+ .with("if (javaClass.desiredAssertionStatus()) { \\k<1> }" )
+ .reformat(true )
+ .build()
+
+The replacement string's back reference above, on line 5, is \k<1>. If
+there were multiple regular expression groups in the replacement
+string, this could have been \k<2>, \k<3>, and so on.
+
+
+
+Here's how this looks when applied, from its unit test:
+
+
lint().files().run().expectFixDiffs(
+ """
+ Fix for src/test/pkg/AssertTest.kt line 18: Surround with desiredAssertionStatus() check:
+ @@ -18 +18
+ - assert(expensive()) // WARN
+ + if (javaClass.desiredAssertionStatus()) { assert(expensive()) } // WARN
+ """
+ )
+ Emitting quick fix XML to apply on CI
+
+
+
+Note that the lint
has an option (--describe-suggestions
) to emit
+an XML file which describes all the edits to perform on documents to
+apply a fix. This maps all quick fixes into chapter edits (including
+XML logic operations). This can be (and is, within Google) used to
+integrate with code review tools such that the user can choose whether
+to auto-fix a suggestion right from within the code review tool.
+
+
+ Partial Analysis
+
+ About
+
+
+
+This chapter describes Lint's “partial analysis”; its architecture and
+APIs for allowing lint results to be cached.
+
+
+
+This focuses on how to write or update existing lint checks such that
+they work correctly under partial analysis. For other details about
+partial analysis, such as the client side implemented by the build
+system, see the lint internal docs folder.
+
+
+
+
Note that while lint has this architecture, and all lint detectors
+ must support it, the checks may not run in partial analysis mode;
+ they may instead run in “global analysis mode”, which is how lint
+ has worked up until this point.
+
+
+
+ This is because coordinating partial results and merging is
+ performed by the LintClient
; e.g. in the IDE, there's no good
+ reason to do all this extra work (because all sources are generally
+ available, including “downstream” module info like the
+ minSdkVersion
).
+
+
+
+ Right now, only the Android Gradle Plugin turns on partial analysis
+ mode. But that's a very important client, since it's usually how
+ lint checks are performed on continuous integration servers to
+ validate code reviews.
+
+
+ The Problem
+
+
+
+Many lint checks require “global” analysis. For example you can't
+determine whether a particular string defined in a library module is
+unused unless you look at all modules transitively consuming this
+library as well.
+
+
+
+However, many developers run lint as part of their continuous
+integration. Particularly in large projects, analyzing all modules for
+every check-in is too costly.
+
+
+
+This chapter describes lint's architecture for handling this, such
+that module results can be cached.
+
+
+ Overview
+
+
+
+Briefly stated, lint's architecture for this is “map reduce”: lint now
+has two separate phases, analyze and report (map and reduce
+respectively):
+
+
+
+
+analyze - where lint analyzes source code of a single module in
+ isolation, and stores some intermediate partial results (map)
+
+
+
+
+report - where lint reads in the previously stored module results,
+ and performs some post-processing on this data to generate an actual
+ lint report.
+
+
+
+Crucially, the individual module results can be cached, such that if
+nothing has changed in a module, the module results continue to be
+valid (unless signatures have changed in libraries it depends on.)
+
+
+
+Making this work requires some modifications to any Detector
which
+considers data from outside the current module. However, there are some
+very common scenarios that lint has special support for to make this
+easier.
+
+
+
+Detectors fit into one of the following categories (and these
+categories will be explained in subsequent sessions) :
+
+
+
+
+Local analysis which doesn't depend on anything else. For example,
+ a lint check which flags typos can report incidents immediately.
+ Lint calls these “definite incidents”.
+
+
+
+
+Local analysis which depends on a few, common conditions. For
+ example, in Android, a check may only apply if the minSdkVersion <
+ 21
. Lint has special support for this; you basically report an
+ incident and attach a “constraint” to it. Lint calls these, and
+ incidents reported as part of #3 below, as “provisional incidents”.
+
+
+
+
+Analysis which depends on some conditions of downstream modules that
+ are not part of the built-in constraints. For example, a lint check
+ may only apply if the consuming module depends on a certain version
+ of a networking library. In this case, the detector will report the
+ incident and attach a map to it, with whatever data it needs to
+ consult later to decide if the incident actually should be reported.
+ When the detector reports incidents this way, it has to also
+ override a callback method. Lint will record these incidents, and
+ during reporting, call the detector and pass it back its data map
+ and provisional incidents such that it can decide whether the
+ incidents should indeed be reported.
+
+
+
+
+Last, and least, there are some scenarios where you cannot compute
+ provisional incidents up front and filter them later (or doing so
+ would be very costly). For example, unused resources fit into this
+ category. We don't want to report every single resource declaration
+ as unused and then filter later. Instead, we compute the resource
+ usage graph within the module analysis. And in the reporting task,
+ we then load all the partial usage graphs, and merge them together
+ and walk the graph to report all the unused resources. To support
+ this, lint provides a map per module for detectors to put their data
+ into, and you can put maps into the map to model structured data.
+ Lint will persist these, and in the reporting task the lint
+ detectors will be passed their data to do their post-processing and
+ reporting based on their data.
+
+
+
+These are listed in increasing order of effort, and thankfully, they're
+also listed in order of frequency. For lint's built-in checks (~385),
+
+
+
+
+89% needed no work at all.
+
+6% were updated to report incidents with constraints
+
+4% were updated to report incidents with data for later filtering
+
+1% were updated to perform map recording and later reduce filtering
+
+
+ Does My Detector Need Work?
+
+
+
+At this point you're probably wondering whether your checks are in the
+89% category where you don't need to do anything, or in the remaining
+11%. How do you know?
+
+
+
+Lint has several built-in mechanisms to try to catch problems. There
+are a few scenarios it cannot detect, and these are described below,
+but for the vast majority, simply running your unit tests (which are
+comprehensive, right?) should create unit test failures if your
+detector is doing something it shouldn't.
+
+
+ Catching Mistakes: Blocking Access to Main Project
+
+
+
+In Android checks, it's very common to try to access the main (“app”)
+project, to see what the real minSdkVersion
is, since the app
+minSdkVersion
can be higher than the one in the library. For the
+targetSdkVersion
it's even more important, since the library
+targetSdkVersion
has no meaningful relationship to the app one.
+
+
+
+When you run lint unit tests, as of 7.0, it will now run your tests
+twice — once with global analysis (the previous behavior), and once
+with partial analysis. When lint is running in partial analysis, a
+number of calls, such as looking up the main project, or consulting the
+merged manifest, is not allowed during the analysis phase. Attempting
+to do so will generate an error:
+
+
SdCardTest.java: Error: The lint detector
+ com.android.tools.lint.checks.SdCardDetector
+ called context.getMainProject() during module analysis.
+
+ This does not work correctly when running in Lint Unit Tests.
+
+ In particular, there may be false positives or false negatives because
+ the lint check may be using the minSdkVersion or manifest information
+ from the library instead of any consuming app module.
+
+ Contact the vendor of the lint issue to get it fixed/updated (if
+ known, listed below), and in the meantime you can try to work around
+ this by disabling the following issues:
+
+ "SdCardPath"
+
+ Issue Vendor:
+ Vendor: Android Open Source Project
+ Contact: https://groups.google.com/g/lint-dev
+ Feedback: https://issuetracker.google.com/issues/new?component=192708
+
+ Call stack: Context.getMainProject(Context.kt:117)←SdCardDetector$createUastHandler$1.visitLiteralExpression(SdCardDetector.kt:66)
+ ←UElementVisitor$DispatchPsiVisitor.visitLiteralExpression(UElementVisitor.kt:791)
+ ←ULiteralExpression$DefaultImpls.accept(ULiteralExpression.kt:38)
+ ←JavaULiteralExpression.accept(JavaULiteralExpression.kt:24)←UVariableKt.visitContents(UVariable.kt:64)
+ ←UVariableKt.access$visitContents(UVariable.kt:1)←UField$DefaultImpls.accept(UVariable.kt:92)
+ ...
+
+Specific examples of information many lint checks look at in this
+category:
+
+
+
+
+minSdkVersion
and targetSdkVersion
+
+The merged manifest
+
+The resource repository
+
+Whether the main module is an Android project
+
+
+ Catching Mistakes: Simulated App Module
+
+
+
+Lint will also modify the unit test when running the test in partial
+analysis mode. In particular, let's say your test has a manifest which
+sets minSdkVersion
to 21.
+
+
+
+Lint will instead run the analysis task on a modified test project
+where the minSdkVersion
is set to 1, and then run the reporting task
+where minSdkVersion
is set back to 21. This ensures that lint checks
+will correctly use the minSdkVersion
from the main project, not the
+library.
+
+
+ Catching Mistakes: Diffing Results
+
+
+
+Lint will also diff the report output from running the same unit tests
+both in global analysis mode and in partial analysis mode. We expect
+the results to always be identical, and in some cases if the module
+analysis is not written correctly, they're not.
+
+
+ Catching Mistakes: Remaining Issues
+
+
+
+The above three mechanisms will catch most problems related to partial
+analysis. However, there are a few remaining scenarios to be aware of:
+
+
+
+
+Resolving into library source code. If you have a Kotlin or Java
+ function call AST node (UCallExpression
) you can call resolve()
+ on it to find the called PsiMethod
, and from there you can look at
+ its source code, to make some decisions.
+
+
+
+ For example, lint's API Check uses this to see if a given method is a
+ version-check utility (“SDK_INT > 21
?”); it resolves the method
+ call in if (isOnLollipop()) { ... }
and looks at its method body to
+ see if the return value corresponds to a proper SDK_INT
check.
+
+
+
+ In partial analysis mode, you cannot look at source files from
+ libraries you depend on; they will only be provided in binary
+ (bytecode inside a jar file) form.
+
+
+
+ This means that instead, you need to aggregate data along the way.
+ For example, the way lint handles the version check method lookup is
+ to look for SDK_INT comparisons, and if found, stores a reference to
+ the method in the partial results map which it can later consult
+ from downstream modules.
+
+
+
+
+Multiple passes across the modules (lint has a way to request
+ multiple passes; this was used by a few lint checks like the unused
+ resource detector; the multiple passes now only apply to the local
+ module)
+
+
+
+In order to test for correct operation of your check, you should add
+your own individual unit test for a multi-module project.
+
+
+
+Lint's unit test infrastructure makes this easy; just use relative
+paths in the test file descriptions.
+
+
+
+For example, if you have the following unit test declaration:
+
+
lint().files(
+ manifest().minSdk(15 ),
+ manifest().to("../app/AndroidManifest.xml" ).minSdk(21 ),
+ xml(
+ "res/layout/linear.xml" ,
+ "<linearlayout ...=" ">" + ...
+
+The second manifest()
call here on line 3 does all the heavy lifting:
+the fact that you're referencing ../app
means it will create another
+module named “app”, and it will add a dependency from that module on
+this one. It will also mark the current module as a library. This is
+based on the name patterns; if you for example reference say ../lib1
,
+it will assume the current module is an app module and the dependency
+will go from here to the library.
+
+
+
+Finally, to test a multi-module setup where the code in the other
+module is only available as binary, lint has a new special test file
+type. The CompiledSourceFile
can be constructed via either
+compiled()
, if you want to make both the source code and the class
+file available in the project, or bytecode()
if you want to only
+provide the bytecode. In both cases you include the source code in the
+test file declaration, and the first time you run your test it will try
+to run compilation and emit the extra base64 string to include the test
+file. By having the sources included for the binary it's easy to
+regenerate bytecode tests later (this was an issue with some of lint's
+older unit tests; we recently decompiled them and created new test
+files using this mechanism to make the code more maintainable.
+
+
+
+Lint's partial analysis testing support will automatically only use
+binaries for the dependencies (even if using CompiledSourceFile
with
+sources).
+
+
+
+
Lint's testing infrastructure may try to automate this testing at
+ some point; e.g. by looking at the error locations from a global
+ analysis, it can then create a new project where only the source
+ file with the warnings is provided as source, and all the other test
+ files are placed in a separate module, and then represented only as
+ binaries (through a lint AST to PsiCompiled pretty printer.)
+
+
+ Incidents
+
+
+
+In the past, you would typically report problems like this:
+
context.report(
+ ISSUE,
+ element,
+ context.getNameLocation(element),
+ "Missing `contentDescription` attribute on image"
+ )
+
+At some point, we added support for quickfixes, so the
+report method took an additional parameter, line 6:
+
+
context.report(
+ ISSUE,
+ element,
+ context.getNameLocation(element),
+ "Missing `contentDescription` attribute on image" ,
+ fix().set ().todo(ANDROID_URI, ATTR_CONTENT_DESCRIPTION).build()
+ )
+
+Now that we need to attach various additional data (like constraints
+and maps), we don't really want to just add more parameters.
+
+
+
+Instead, this tuple of data about a particular occurrence of a problem
+is called an “incident”, and there is a new Incident
class which
+represents it. To report an incident you simply call
+context.report(incident)
. There are several ways to create these
+incidents. The easiest is to simply edit your existing call above by
+putting it inside Incident(...)
(in Java, new Incident(...)
) inside
+the context.report
block like this:
+
+
context.report(Incident(
+ ISSUE,
+ element,
+ context.getNameLocation(element),
+ "Missing `contentDescription` attribute on image"
+ ))
+
+and then reformatting the source code:
+
+
context.report(
+ Incident(
+ ISSUE,
+ element,
+ context.getNameLocation(element),
+ "Missing `contentDescription` attribute on image"
+ )
+ )
+
+Incident
has a number of overloaded constructors to make it easy to
+construct it from existing report calls.
+
+
+
+There are other ways to construct it too, for example like the
+following:
+
+
Incident(context)
+ .issue(ISSUE)
+ .scope(node)
+ .location(context.getLocation(node))
+ .message("Do not hardcode \"/sdcard/\"" ).report()
+
+That are additional methods you can fall too, like fix()
, and
+conveniently, at()
which specifies not only the scope node but
+automatically computes and records the location of that scope node too,
+such that the following is equivalent:
+
+
Incident(context)
+ .issue(ISSUE)
+ .at(node)
+ .message("Do not hardcode \"/sdcard/\"" ).report()
+
+So step one to partial analysis is to convert your code to report
+incidents instead of the passing in all the individual properties of an
+incident. Note that for backwards compatibility, if your check doesn't
+need any work for partial analysis, you can keep calling the older
+report methods; they will be redirected to an Incident
call
+internally, but since you don't need to attach data you don't have to
+make any changes
+
+
+ Constraints
+
+
+
+If your check needs to be conditional, perhaps on the minSdkVersion
,
+you need to attach a “constraint” to your report call.
+
+
+
+All the constraints are built in; there isn't a way to implement your
+own. For custom logic, see the next section: LintMaps.
+
+
+
+Here are the current constraints, though this list may grow over time:
+
+
+
+
+minSdkAtLeast(Int)
+
+minSdkLessThan(Int)
+
+targetSdkAtLeast(Int)
+
+targetSdkLessThan(Int)
+
+isLibraryProject()
+
+isAndroidProject()
+
+notLibraryProject()
+
+notAndroidProject()
+
+
+
+These are package-level functions, though from Java you can access them
+from the Constraints
class.
+
+
+
+Recording an incident with a constraint is easy; first construct the
+Incident
as before, and then report it via
+context.report(incident, constraint)
:
+
+
String message =
+ "One or more images in this project can be converted to "
+ + "the WebP format which typically results in smaller file sizes, "
+ + "even for lossless conversion" ;
+ Incident incident = new Incident (WEBP_ELIGIBLE, location, message);
+ context.report(incident, minSdkAtLeast(18 ));
+
+Finally, note that you can combine constraints; there are both “and”
+and “or” operators defined for the Constraint
class, so the following
+is valid:
+
+
val constraint = targetSdkAtLeast(23 ) and notLibraryProject()
+ context.report(incident, constraint)
+
+That's all you have to do. Lint will record this provisional incident,
+and when it is performing reporting, it will evaluate these constraints
+on its own and only report incidents that meet the constraint.
+
+
+ Incident LintMaps
+
+
+
+In some cases, you cannot use one of the built-in constraints; you have
+to do your own “filtering” from the reporting task, where you have
+access to the main module.
+
+
+
+In that case, you call context.report(incident, map)
instead.
+
+
+
+Like Incident
, LintMap
is a new data holder class in lint which
+makes it convenient to pass around (and more importantly, persist)
+data. All the set methods return the map itself, so you can easily
+chain property calls.
+
+
+
+Here's an example:
+
+
context.report(
+ incident,
+ map()
+ .put(KEY_OVERRIDES, overrides)
+ .put(KEY_IMPLICIT, implicitlyExportedPreS)
+ )
+
+Here, map()
is a method defined by Detector
to create a new
+LintMap
, similar to how fix()
constructs a new LintFix
.
+
+
+
+Note however that when reporting data, you need to do the post
+processing yourself. To do this, you need to override this method:
+
+
+ open fun filterIncident (context: Context , incident: Incident , map: LintMap ) : Boolean { }
+
+For example, for the above report call, the corresponding
+implementation of filterIncident
looks like this:
+
+
override fun filterIncident (context: Context , incident: Incident , map: LintMap ) : Boolean {
+ if (context.mainProject.targetSdk < 19 ) return true
+ if (map.getBoolean(KEY_IMPLICIT, false ) == true && context.mainProject.targetSdk >= 31 ) return true
+ return map.getBoolean(KEY_OVERRIDES, false ) == false
+ }
+
+Note also that you are allowed to modify incidents here before
+reporting them. The most common reason scenario for this is changing
+the incident message, perhaps to reflect data not known at module
+analysis time. For example, lint's API check creates messages like this:
+
+
+
+Error: Cast from AudioFormat to Parcelable requires API level 24 (current min is 21)
+
+
+
+At module analysis time when the incident was created, the minSdk being
+21 was not known (and in fact can vary if this library is consumed by
+many different app modules!)
+
+
+
+
You must store state in the lint map; don't try to store it in the
+ detector itself as instance state. That won't work because the
+ detector instance that filterInstance
is called on is not the same
+ instance as the one which originally reported it. If you think about
+ it, that makes sense; when module results are cached, the same
+ reported data can be used over and over again for repeated builds,
+ each time for new detector instances in the reporting task.
+
+
+ Module LintMaps
+
+
+
+The last (and most involved) scenario for partial analysis is one where
+you cannot just create incidents and filter or customize them later.
+
+
+
+The most complicated example of this is lint's built-in
+UnusedResourceDetector , which locates unused resources. This “requires”
+global analysis, since we want to include all resources in the entire
+project. We also cannot just store lists of “resources declared” and
+“resources referenced” since we really want to treat this as a graph.
+For example if @layout/main
is including @drawable/icon
, then a
+naive approach would see the icon as referenced (by main) and therefore
+mark it as not unused. But what we want is that if the icon is only
+referenced from main, and if main is unused, then so is the icon.
+
+
+
+To handle this, we model the resources as a graph, with edges
+representing references.
+
+
+
+When analyzing individual modules, we create the resource graph for
+just that model, and we store that in the results. That means we store
+it in the module's LintMap
. This is a map for the whole module
+maintained by lint, so you can access it repeatedly and add to it.
+(This is also where lint's API check stores the SDK_INT
comparison
+functions as described earlier in this chapter).
+
+
+
+The unused resource detector creates a persistence string for the
+graph, and records that in the map.
+
+
+
+Then, during reporting, it is given access to all the lint maps for
+all the modules that the reporting module depends on, including itself.
+It then merges all the graphs into a single reference graph.
+
+
+
+For example, let's say in module 1 we have layout A which includes
+drawables B and D, and B in turn depends on color C. We get a resource
+graph like the following:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+A B C D
+
+
+
+Then in another module, we have the following resource reference graph:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+E B D
+
+
+
+In the reporting task, we merge the two graphs like the following:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+E A B C D
+
+
+
+Once that's done, it can proceed precisely as before: analyze the graph
+and report all the resources that are not reachable from the reference
+roots (e.g. manifest and used code).
+
+
+
+The way this works in code is that you report data into the module by
+first looking up the module data map, by calling this method on the
+Context
:
+
+
+ fun getPartialResults (issue: Issue ) : PartialResult { ... }
+
+Then you put whatever data you want, such as the resource usage model
+encoded as a string.
+
+
+
+
Note that you don't have to worry about clashes in key names; each
+ issue (and therefore detector) is given its own map.
+
+
+
+And then your detector should also override the following method, where
+you can walk through the map contents, compute incidents and report
+them:
+
+
+ open fun checkPartialResults (context: Context , partialResults: PartialResult ) { ... }
+ Optimizations
+
+
+
+Most lint checks run on the fly in the IDE editor as well. In some
+cases, if all the map computations are expensive, you can check whether
+partial analysis is in effect, and if not, just directly access (for
+example) the main project.
+
+
+
+Do this by calling isGlobalAnalysis()
:
+
+
if (context.isGlobalAnalysis()) {
+
+ } else {
+
+ }
+
+
+
+
+ Data Flow Analyzer
+
+
+
+The dataflow analyzer is a helper in lint which makes writing certain
+kinds of lint checks a lot easier.
+
+
+
+Let's say you have an API which creates an object, and then you want to
+make sure that at some point a particular method is called on the same
+instance.
+
+
+
+There are a lot of scenarios like this;
+
+
+
+
+Calling show
on a message in a Toast or Snackbar
+
+Calling commit
or apply
on a transaction
+
+Calling recycle
on a TypedArray
+
+Calling enqueue
on a newly created work request
+
+
+
+and so on. I didn't include calling close on a file object since you
+typically use try-with-resources for those.
+
+
+
+Here are some examples:
+
+
getFragmentManager().beginTransaction().commit()
+val t1 = getFragmentManager().beginTransaction()
+val t2 = getFragmentManager().beginTransaction()
+ t2.commit()
+
+Here we are creating 3 transactions. The first one is committed
+immediately. The second one is never committed. And the third one
+is.
+
+
+
+This example shows us creating multiple transactions, and that
+demonstrates that solving this problem isn't as simple as just visiting
+the method and seeing if the code invokes Transaction#commit
+anywhere; we have to make sure that it's invoked on all the instances
+we care about.
+
+
+ Usage
+
+
+
+To use the dataflow analyzer, you basically extend the
+DataFlowAnalyzer
class, and override one or more of its callbacks,
+and then tell it to analyze a method scope.
+
+
+
+
In recent versions of lint, there is a new special subclass of the
+ DataFlowAnalyzer
, TargetMethodDataFlowAnalyzer
, which makes it
+ easier to write flow analyzers where you are looking for a specific
+ “cleanup” or close function invoked on an instance. See the separate
+ section on TargetMethodDataFlowAnalyzer
below for more information.
+
+
+
+For the above transaction scenario, it might look like this:
+
+
override fun getApplicableMethodNames () : List<string> =
+ listOf("beginTransaction" )
+
+override fun visitMethodCall (context: JavaContext , node: UCallExpression , method: PsiMethod ) {
+ val containingClass = method.containingClass
+ val evaluator = context.evaluator
+
+ if (evaluator.extendsClass(containingClass, "android.app.FragmentManager" , false )) {
+
+
+
+
+ var foundCommit = false
+ val visitor = object : DataFlowAnalyzer(setOf(node)) {
+ override fun receiver (call: UCallExpression ) {
+ if (call.methodName == "commit" ) {
+ foundCommit = true
+ }
+ }
+ }
+ val method = node.getParentOfType(UMethod::class .java)
+ method?.accept(visitor)
+ if (!foundCommit) {
+ context.report(Incident(...))
+ }
+ }
+ }
+
+As you can see, the DataFlowAnalyzer
is a visitor, so when we find a
+call we're interested in, we construct a DataFlowAnalyzer
and
+initialize it with the instance we want to track, and then we visit the
+surrounding method with this visitor.
+
+
+
+The visitor will invoke the receiver
method whenever the instance is
+invoked as the receiver of a method call; this is the case with
+t2.commit()
in the above example; here “t2” is the receiver, and
+commit
is the method call name.
+
+
+
+With the above setup, basic value tracking is working; e.g. it will
+correctly handle the following case:
+
+
val t = getFragmentManager().beginTransaction().commit()
+val t2 = t
+val t3 = t2
+ t3.commit()
+
+However, there's a lot that can go wrong, which we'll need to deal with. This is explained in the following sections
+
+
+ Self-referencing Calls
+
+
+
+The Transaction API has a number of utility methods; here's a partial
+list:
+
+
public abstract class FragmentTransaction {
+ public abstract int commit () ;
+ public abstract int commitAllowingStateLoss () ;
+ public abstract FragmentTransaction show (Fragment fragment) ;
+ public abstract FragmentTransaction hide (Fragment fragment) ;
+ public abstract FragmentTransaction attach (Fragment fragment) ;
+ public abstract FragmentTransaction detach (Fragment fragment) ;
+ public abstract FragmentTransaction add (int containerViewId, Fragment fragment) ;
+ public abstract FragmentTransaction add (Fragment fragment, String tag) ;
+ public abstract FragmentTransaction addToBackStack (String name) ;
+ ...
+ }
+
+The reason all these methods return a FragmentTransaction
is to make it easy to chain calls; e.g.
+
+
final int id = getFragmentManager().beginTransaction()
+ .add(new Fragment (), null )
+ .addToBackStack(null )
+ .commit();
+
+In order to correctly analyze this, we'd need to know what the implementation of add
and addToBackStack
return. If we know that they simply return “this”, then it's easy; we can transfer the instance through the call.
+
+
+
+And this is what the DataFlowAnalyzer
will try to do by default. When
+it encounters a call on our tracked receivers, it will try to guess
+whether that method is returning itself. It has several heuristics for
+this:
+
+
+
+
+The return type is the same as its surrounding class, or a subtype of
+ it
+
+It's an extension method returning the same type
+
+It's not named something which indicates a new instance (such as
+ clone, copy, or to*X*), unless ignoreCopies()
is overridden to
+ return false
+
+
+
+In our example, the above heuristics work, so out of the box, the lint check would correctly handle this scenario.
+
+
+
+But there may be cases where you either don't want these heuristics, or you want to add your own. In these cases, you would override the returnsSelf
method on the flow analyzer and apply your own logic:
+
+
val visitor = object : DataFlowAnalyzer(setOf(node)) {
+ override fun returnsSelf (call: UCallExpression ) : Boolean {
+ return super .returnsSelf(call) || call.methodName == "copy"
+ }
+ }
+ Kotlin Scoping Functions
+
+
+
+With this in place, lint will track the flow through the method.
+This includes handling Kotlin's scoping functions as well. For
+example, it will automatically handle scenarios like the
+following:
+
+
transaction1.let { it.commit() }
+ transaction2.apply { commit() }
+ with (transaction3) { commit() }
+ transaction4.also { it.commit() }
+
+ getFragmentManager.let {
+ it.beginTransaction()
+ }.commit()
+
+
+ transaction5.let {
+ it.also {
+ it.apply {
+ with(this ) {
+ commit()
+ }
+ }
+ }
+ }
+ Limitations
+
+
+
+It doesn't try to “execute”, constant evaluation (maybe)
+if/else
+
+
+ Escaping Values
+
+
+
+What if your check gets invoked on a code snippet like this:
+
+
fun createTransaction () : FragmentTransaction =
+ getFragmentManager().beginTransaction().add(new Fragment(), null )
+
+Here, we're not calling commit
, so our lint check would issue a
+warning. However, it's quite possible and likely that elsewhere,
+there's code using it, like this:
+
+
val transaction = createTransaction()
+ ...
+ transaction.commit()
+
+Ideally, we'd perform global analysis to handle this, but that's not
+currently possible. However, we can analyze some additional non-local
+scenarios, and more importantly, we need to ensure that we don't offer false positive warnings in the above scenario.
+
+
+ Returns
+
+
+
+In the above case, our tracked transaction “escapes” the method that
+we're analyzing through either an implicit return as in the above
+Kotlin code or via an explicit return.
+
+
+
+The analyzer has a callback method to let us know when this is happening. We can override that callback to remember that the value escapes, and if so, ignore the missing commit:
+
+
var foundCommit = false
+var escapes = false
+val visitor = object : DataFlowAnalyzer(setOf(node)) {
+ override fun returns (expression: UReturnExpression ) {
+ escapes = true
+ }
+
+ override fun argument (call: UCallExpression , reference: UElement ) {
+ super .argument(call, reference)
+ }
+
+ override fun field (field: UElement ) {
+ super .field(field)
+ }
+ }
+ node.getParentOfType(UMethod::class .java)?.accept(visitor)
+if (!escapes && !foundCommit) {
+ context.report(Incident(...))
+ }
+ Parameters
+
+
+
+Another way our transaction can “escape” out of the method such that we
+no longer know for certain whether it gets committed is via a method
+call.
+
+
fun test () {
+ val transaction = getFragmentManager().beginTransaction()
+ process(transaction)
+ }
+
+Here, it's possible that the process
method will proceed to actually
+commit the transaction.
+
+
+
+If we have source, we could resolve the call and take a look at the
+method implementation (see the “Non Local Analysis” section below), but
+in the general case, if a value escapes, we'll want to do something similar to a returned value. The analyzer has a callback for this, argument
, which is invoked whenever our tracked value is passed into a method as an argument. The callback gives us both the argument and the call in case we want to handle conditional logic based on the specific method call.
+
+
var escapes = false
+val visitor = object : DataFlowAnalyzer(setOf(node)) {
+ ...
+ override fun argument (call: UCallExpression , reference: UElement ) {
+ escapes = true
+ }
+ ...
+ }
+
+(By default, the analyzer will ignore calls that look like logging calls since those are probably safe and not true escapes; you can
+customize this by overriding ignoreArgument()
.)
+
+
+ Fields
+
+
+
+Finally, a value may escape a local method context if it gets stored
+into a field:
+
+
fun initialize () {
+ this .transaction = createTransaction()
+ }
+
+As with returns and method calls, the analyzer has a callback to make
+it easy to handle when this is the case:
+
+
var escapes = false
+val visitor = object : DataFlowAnalyzer(setOf(node)) {
+ ...
+ override fun field (field: UElement ) {
+ escapes = true
+ }
+ ...
+ }
+
+As you can see, it's passing in the field that is being stored to, in
+case you want to perform additional analysis to track field values; see
+the next section.
+
+
+
+
There is a special subclass of the DataFlowAnalyzer
, called
+ EscapeCheckingDataFlowAnalyzer
, which you can extend instead. This
+ handles recording all the scenarios where the instance escapes from
+ the method, and at the end you can just check its escaped
property.
+
+
+ Non Local Analysis
+
+
+
+In the above examples, if we found that the value escaped via a return
+or method call or storage in a field, we simply gave up. In some cases
+we can do better than that.
+
+
+
+
+If the field we stored it into is a private field, we can visit
+ the surrounding class, and check each reference to the field. If we
+ can see that the field never escapes the class, we can perform the
+ same analysis (using the data flow analyzer!) on each method where
+ it's referenced.
+
+
+
+
+Similarly, if the method which returns the value is private, we can
+ visit the surrounding class and see how the method is invoked, and
+ track the value returned from it in each usage.
+
+
+
+
+Finally, if the value escapes as an argument to a call, we can
+ resolve that call, and if it's to a method we have source for (which
+ doesn't have to be in the same class, as long as it's in the same
+ module), we can perform the analysis in that method as well, even
+ reusing the same flow analyzer!
+
+
+
+Complications: - storing in a field, returning, intermediate variables, self-referencing methods, scoping functions,
+
+
+ Examples
+
+
+
+Here are some existing usages of the data flow analyzer in lint's
+built-in rules.
+
+
+ Simple Example
+
+
+
+For WorkManager, ensure that newly created work tasks eventually
+get enqueued:
+
+
+
+Source
+Test
+
+
+ Complex Example
+
+
+
+For the Slices API, apply a number of checks on chained calls constructing slices, checking that you only specify a single timestamp, that you don't mix icons and actions, etc etc.
+
+
+
+Source
+Test
+
+
+ TargetMethodDataFlowAnalyzer
+
+
+
+The TargetMethodDataFlowAnalyzer
is a special subclass of the
+DataFlowAnalyzer
which makes it simple to see if you eventually wind up
+calling a target method on a particular instance. For example, calling
+close
on a file that was opened, or calling start
on an animation you
+created.
+
+
+
+In addition, there is an extension function on UMethod
which visits
+this analyzer, and then checks for various conditions, e.g. whether the
+instance “escaped” (for example by being stored in a field or passed to
+another method), in which case you probably don't want to conclude (and
+report) that the close method is never called. It also handles failures
+to resolve, where it remembers whether there was a resolve failure, and
+if so it looks to see if it finds a likely match (with the same name as
+the target function), and if so also makes sure you don't report a false
+positive.
+
+
+
+A simple way to do this is as follows:
+
+
val targets = mapOf("show" to listOf("android.widget.Toast" ,
+ "com.google.android.material.snackbar.Snackbar" )
+val analyzer = TargetMethodDataFlowAnalyzer.create(node, targets)
+if (method.isMissingTarget(analyzer)) {
+ context.report(...)
+ }
+
+You can subclass TargetMethodDataFlowAnalyzer
directly and override the
+getTargetMethod
methods and any other UAST visitor methods if you want
+to customize the behavior further.
+
+
+
+One advantage of using the TargetMethodDataFlowAnalyzer
is that it also
+correctly handles method references.
+
+
+
+
+
+
+ Annotations
+
+
+
+Annotations allow API authors to express constraints that tools can
+enforce. There are many examples of these, along with existing lint
+checks:
+
+
+
+
+@VisibleForTesting
: this API is considered private, and has been
+ exposed only for unit testing purposes
+
+@CheckResult
: anyone calling this method is expected to do
+ something with the return value
+
+@CallSuper
: anyone overriding this method must also invoke super
+
+@UiThread
: anyone calling this method must be calling from the UI thread
+
+@Size
: the size of the annotated array or collection must be
+ of a particular size
+
+@IntRange
: the annotated integer must have a value in the given range
+
+
+
+...and so on. Lint has built-in checks to enforce these, along with
+infrastructure to make them easy to write, and to share analysis such
+that improvements to one helps them all. This means that you can easily
+write your own annotations-based checks as well.
+
+
+
+
Note that the annotation support helps you write checks where you
+ check usages of annotated elements, not usages of the annotations
+ themselves. If you simply want to look at actual annotations,
+ override getApplicableUastTypes
to return
+ listOf(UAnnotation::class.java)
, and override createUastHandler
+ to return an object : UElementHandler
which simply overrides
+ visitAnnotation
.
+
+
+ Basics
+
+
+
+To create a basic annotation checker, there are two required steps:
+
+
+
+
+Register the fully qualified name (or names) of the annotation
+ classes you want to analyze, and
+
+Implement the visitAnnotationUsage
callback for handling each
+ occurrence.
+
+
+
+Here's a basic example:
+
+
override fun applicableAnnotations () : List<string> {
+ return listOf("my.pkg.MyAnnotation" )
+ }
+
+override fun visitAnnotationUsage (
+ context: JavaContext ,
+ element: UElement ,
+ annotationInfo: AnnotationInfo ,
+ usageInfo: AnnotationUsageInfo
+ ) {
+ val name = annotationInfo.qualifiedName.substringAfterLast('.' )
+ val message = "`${usageInfo.type.name} ` usage associated with " +
+ "`@$name ` on ${annotationInfo.origin} "
+ val location = context.getLocation(element)
+ context.report(TEST_ISSUE, element, location, message)
+ }
+
+All this simple detector does is flag any usage associated with the
+given annotation, including some information about the usage.
+
+
+
+If we for example have the following annotated API:
+
+
annotation class MyAnnotation
+abstract class Book {
+ operator fun contains (@MyAnnotation word: String ) : Boolean = TODO()
+ fun length () : Int = TODO()
+ @MyAnnotation fun close () = TODO()
+ }
+operator fun Book.get (@MyAnnotation index: Int ) : Int = TODO()
+
+...and we then run the above detector on the following test case:
+
+
fun test (book: Book ) {
+ val found = "lint" in book
+ val firstWord = book[0 ]
+ book.close()
+ }
+
+we get the following output:
+
+
src/book.kt:14: Error: METHOD_CALL_PARAMETER usage associated with @MyAnnotation on PARAMETER
+ val found = "lint" in book
+ ----
+ src/book.kt:15: Error: METHOD_CALL_PARAMETER usage associated with @MyAnnotation on PARAMETER
+ val firstWord = book[0]
+ -
+ src/book.kt:16: Error: METHOD_CALL usage associated with @MyAnnotation on METHOD
+ book.close()
+ -------
+
+In the first case, the infix operator “in” will call contains
under
+the hood, and here we've annotated the parameter, so lint visits the
+argument corresponding to that parameter (the literal string “lint”).
+
+
+
+The second case shows a similar situation where the array syntax will
+end up calling our extension method, get()
.
+
+
+
+And the third case shows the most common scenario: a straightforward
+method call to an annotated method.
+
+
+
+In many cases, the above detector implementation is nearly all you have
+to do to enforce an annotation constraint. For example, in the
+@CheckResult
detector, we want to make sure that anyone calling a
+method annotated with @CheckResult
will not ignore the method return
+value. All the lint check has to do is register an interest in
+androidx.annotation.CheckResult
, and lint will invoke
+visitAnnotationUsage
for each method call to the annotated method.
+Then we just check the method call to make sure that its return value
+isn't ignored, e.g. that it's stored into a variable or passed into
+another method call.
+
+
+
+
In applicableAnnotations
, you typically return the fully
+ qualified names of the annotation classes your detector is
+ targeting. However, in some cases, it's useful to match all
+ annotations of a given name; for example, there are many, many
+ variations of the @Nullable
annotations, and you don't really
+ want to be in the business of keeping track of and listing all of
+ them here. Lint will also let you specify just the basename of an
+ annotation here, such as "Nullable"
, and if so, annotations like
+ androidx.annotation.Nullable
and
+ org.jetbrains.annotations.Nullable
will both match.
+
+
+ Annotation Usage Types and isApplicableAnnotationUsage
+
+ Method Override
+
+
+
+In the detector above, we're including the “usage type” in the error
+message. The usage type tells you something about how the annotation is
+associated with the usage element — and in the above, the first two
+cases have a usage type of “parameter” because the visited element
+corresponds to a parameter annotation, and the third one a method
+annotation.
+
+
+
+There are many other usage types. For example, if we add the following
+to the API:
+
+
open class Paperback : Book () {
+ override fun close () { }
+ }
+
+then the detector will emit the following incident since the new method
+overrides another method that was annotated:
+
+
src/book.kt:14: Error: METHOD_OVERRIDE usage associated with @MyAnnotation on METHOD
+ override fun close() { }
+ -----
+ 1 errors, 0 warnings
+
+Overriding an annotated element is how the @CallSuper
detector is
+implemented, which makes sure that any method which overrides a method
+annotated with @CallSuper
is invoking super
on the overridden
+method somewhere in the method body.
+
+
+ Method Return
+
+
+
+Here's another example, where we have annotated the return value
+with @MyAnnotation:
+
+
open class Paperback : Book () {
+ fun getDefaultCaption () : String = TODO()
+ @MyAnnotation
+ fun getCaption (imageId: Int ) : String {
+ if (imageId == 5 ) {
+ return "Blah blah blah"
+ } else {
+ return getDefaultCaption()
+ }
+ }
+ }
+
+Here, lint will flag the various exit points from the method
+associated with the annotation:
+
+
src/book.kt:18: Error: METHOD_RETURN usage associated with @MyAnnotation on METHOD
+ return "Blah blah blah"
+ --------------
+ src/book.kt:20: Error: METHOD_RETURN usage associated with @MyAnnotation on METHOD
+ return getDefaultCaption()
+ -------------------
+ 2 errors, 0 warnings
+
+Note also that this would have worked if the annotation had been
+inherited from a super method instead of being explicitly set here.
+
+
+
+One usage of this mechanism in Lint is the enforcement of return values
+in methods. For example, if a method has been marked with
+@DrawableRes
, Lint will make sure that the returned value of that
+method will not be of an incompatible resource type (such as
+@StringRes
).
+
+
+ Handling Usage Types
+
+
+
+As you can see, your callback will be invoked for a wide variety of
+usage types, and sometimes, they don't apply to the scenario that your
+detector is interested in. Consider the @CheckResult
detector again,
+which makes sure that any calls to a given method will look at the
+return value. From the “method override” section above, you can see
+that lint would also notify your detector for any method that is
+overriding (rather than calling) a method annotated with
+@CheckResult
. We don't want to report those.
+
+
+
+There are two ways to handle this. The first one is to check whether
+the usage element is a UMethod
, which it will be in the overriding
+case, and return early in that case.
+
+
+
+The recommended approach, which CheckResultDetector
uses, is to
+override the isApplicableAnnotationUsage
method:
+
+
override fun isApplicableAnnotationUsage (type: AnnotationUsageType ) : Boolean {
+ return type != AnnotationUsageType.METHOD_OVERRIDE &&
+ super .isApplicableAnnotationUsage(type)
+ }
+
+
+
+
Notice how we are also calling super
here and combining the result
+ instead of just using a hardcoded list of expected usage types. This
+ is because, as discussed below, lint already filters out some usage
+ types by default in the super implementation.
+
+
+ Usage Types Filtered By Default
+
+
+
+The default implementation of Detector.isApplicableAnnotationUsage
+looks like this:
+
+
open fun isApplicableAnnotationUsage (type: AnnotationUsageType ) : Boolean {
+ return type != AnnotationUsageType.BINARY &&
+ type != AnnotationUsageType.EQUALITY
+ }
+
+These usage types apply to cases where annotated elements are
+compared for equality or using other binary operators. Initially
+introducing this support led to a lot of noise and false positives;
+most of the existing lint checks do not want this, so they're opt-in.
+
+
+
+An example of a lint check which does enforce this is the
+@HalfFloat
lint check. In Android, a
+HalfFloat is a representation of a floating point value (with less
+precision than a float
) which is stored in a short
, normally an
+integer primitive value. If you annotate a short
with @HalfFloat
,
+including in APIs, lint can help catch cases where you are making
+mistakes — such as accidentally widening the value to an int, and so
+on. Here are some example error messages from lint's unit tests for the
+half float check:
+
+
src/test/pkg/HalfFloatTest.java:23: Error: Expected a half float here, not a resource id [HalfFloat]
+ method1(getDimension1()); // ERROR
+ ---------------
+ src/test/pkg/HalfFloatTest.java:43: Error: Half-float type in expression widened to int [HalfFloat]
+ int result3 = float1 + 1; // error: widening
+ ------
+ src/test/pkg/HalfFloatTest.java:50: Error: Half-float type in expression widened to int [HalfFloat]
+ Math.round(float1); // Error: should use Half.round
+ ------
+ Scopes
+
+
+
+Many annotations apply not just to methods or fields but to classes and
+even packages, with the idea that the annotation applies to everything
+within the package.
+
+
+
+For example, if we have this annotated API:
+
+
annotation class ThreadSafe
+annotation class NotThreadSafe
+
+@ThreadSafe
+abstract class Stack <t > {
+ abstract fun size () : Int
+ abstract fun push (item: T )
+ abstract fun pop () : String
+ @NotThreadSafe fun save () { }
+
+ @NotThreadSafe
+ abstract class FileStack <t > : Stack <t >() {
+ abstract override fun pop () : String
+ }
+ }
+
+And the following test case:
+
+
fun test (stack: Stack <string >, fileStack: Stack <string >) {
+ stack.push("Hello" )
+ stack.pop()
+ fileStack.push("Hello" )
+ fileStack.pop()
+ }
+
+Here, stack.push
call on line 2 resolves to the API method on line 7.
+That method is not annotated, but it's inside a class that is annotated
+with @ThreadSafe
. Similarly for the pop()
call on line 3.
+
+
+
+The fileStack.push
call on line 4 also resolves to the same method
+as the call on line 2 (even though the concrete type is a FileStack
+instead of a Stack
), so like on line 2, this call is taken to be
+thread safe.
+
+
+
+However, the fileStack.pop
call on line 6 resolves to the API method
+on line 14. That method is not annotated, but it's inside a class
+annotated with @NotThreadSafe
, which in turn is inside an outer class
+annotated with @ThreadSafe
. The intent here is clearly that that
+method should be considered not thread safe.
+
+
+
+To help with scenarios like this, lint will provide all the
+annotations (well, all annotations that any lint checks have registered
+interest in via getApplicableAnnotations
; it will not include
+annotations like java.lang.SuppressWarnings
and so on unless a lint
+check asks for it).
+
+
+
+This is provided in the AnnotationUsageInfo
passed to the
+visitAnnotationUsage
parameters. The annotations
list will include
+all relevant annotations, in scope order . That means that for the
+above pop
call on line 5, it will point to first the annotations on
+the pop
method (and here there are none), then the @NotThreadSafe
+annotation on the surrounding class, and then the @ThreadSafe
+annotation on the outer class, and then annotations on the file itself
+and the package.
+
+
+
+The index
points to the annotation we're analyzing. If for example
+our detector had registered an interest in @ThreadSafe
, it would be
+called for the second pop
call as well, since it calls a method
+inside a @ThreadSafe
annotation (on the outer class), but the index
+would be 1. The lint check can check all the annotations earlier than
+the one at the index to see if they “counteract” the annotation, which
+of course the @NotThreadSafe
annotation does.
+
+
+
+Lint uses this mechanism for example for the @CheckResult
annotation,
+since some APIs are annotated with @CheckResult
for whole packages
+(as an API convention), and then there are explicit exceptions carved
+out using @CanIgnoreReturnValue
. There is a method on the
+AnnotationUsageInfo
, anyCloser
, which makes this check easy:
+
+
if (usageInfo.anyCloser { it.qualifiedName ==
+ "com.google.errorprone.annotations.CanIgnoreReturnValue" }) {
+
+
+ return
+ }
+
+
+
+
You only have to worry about this when there are different
+ annotations that interact with each other. If the same annotation is
+ found in multiple nested contexts, lint will include all the
+ annotations in the AnnotationUsageInfo
, but it will not invoke
+ your callback for any outer occurrences; only the closest one. This
+ is usually what detectors expect: the innermost one “overrides” the
+ outer ones, so lint omits these to help avoid false positives where
+ a lint check author forgot to handle and test this scenario. A good
+ example of this situation is with the @RequiresApi
annotation; a
+ class may be annotated as requiring a particular API level, but a
+ specific inner class or method within the class can have a more
+ specific @RequiresApi
annotation, and we only want the detector to
+ be invoked for the innermost one. If for some reason your detector
+ does need to handle all of the repeated outer occurrences, note
+ that they're all there in the annotations
list for the
+ AnnotationUsageInfo
so you can look for them and handle them when
+ you are invoked for the innermost one.
+
+
+ Inherited Annotations
+
+
+
+As we saw in the method overrides section, lint will include
+annotations in the hierarchy: annotations specified not just on a
+specific method but super implementations and so on.
+
+
+
+This is normally what you want — for example, if a method is annotated
+with @CheckResult
(such as String.trim()
, where it's important to
+understand that you're not changing the string in place, there's a new
+string returned so it's probably a mistake to not use it), you probably
+want any overriding implementations to have the same semantics.
+
+
+
+However, there are exceptions to this. For example,
+@VisibleForTesting
. Perhaps a super class made a method public only
+for testing purposes, but you have a concrete subclass where you are
+deliberately supporting the operation, not just from tests. If
+annotations were always inherited, you would have to create some sort
+of annotation to “revert” the semantics, e.g.
+@VisibleNotJustForTesting
, which would require a lot of noisy
+annotations.
+
+
+
+Lint lets you specify the inheritance behavior of individual
+annotations. For example, the lint check which enforces the
+@VisibleForTesting
and @RestrictTo
annotations handles it like this:
+
+
override fun inheritAnnotation (annotation : String ) : Boolean {
+
+ return false
+ }
+
+(Note that the API passes in the fully qualified name of the annotation
+in question so you can control this behavior individually for each
+annotation when your detector applies to multiple annotations.)
+
+
+
+
+
+
+ Options
+
+ Usage
+
+
+
+Users can configure lint using lint.xml
files, turning on and off
+checks, changing the default severity, ignoring violations based on
+paths or regular expressions matching paths or messages, and so on.
+
+
+
+They can also configure “options” on a per issue type basis. Options
+are simply strings, booleans, integers or paths that configure how a
+detector works.
+
+
+
+For example, in the following lint.xml
file, we're configuring the
+UnknownNullness
detector to turn on its ignoreDeprecated
option,
+and we're telling the TooManyViews
detector that the maximum number
+of views in a layout it should allow before generating a warning should
+be set to 20:
+
+
<?xml version="1.0" encoding="UTF-8" ?>
+<lint >
+ <issue id ="UnknownNullness" >
+ <option name ="ignoreDeprecated" value ="true" />
+ </issue >
+ <issue id ="TooManyViews" >
+ <option name ="maxCount" value ="20" />
+ </issue >
+</lint >
+
+Note that lint.xml
files can be located not just in the project
+directory but nested as well, for example for a particular source
+folder.
+
+
+
+(See the lint.xml documentation for more.)
+
+
+ Creating Options
+
+
+
+First, create an Option
and register it with the corresponding
+Issue
.
+
+
val MAX_COUNT = IntOption("maxCount" , "Max number of views allowed" , 80 )
+val MY_ISSUE = Issue.create("MyId" , ...)
+ .setOptions(listOf(MAX_COUNT))
+
+An option has a few pieces of metadata:
+
+
+
+
+The name, which is a short identifier. Users will configure the
+ option by listing this key along with the configured value in their
+ lint.xml
files. By convention this should be using camel case and
+ only valid Java identifier characters.
+
+
+
+
+A description. This should be a short sentence which lists the
+ purpose of the option (and should be capitalized, and not end with
+ punctuation).
+
+
+
+
+A default value. This is the value that will be returned from
+ Option.getValue()
if the user has not configured the setting.
+
+
+
+
+For integer and float options, minimum and maximum allowed values.
+
+
+
+
+An optional explanation. This is a longer explanation of the option,
+ if necessary.
+
+
+
+The name and default value are used by lint when options are looked up
+by detectors; the description, explanation and allowed ranges are used
+to include information about available options when lint generates for
+example HTML reports, or text reports including explanations, or
+displaying lint checks in the IDE settings panel, and so on.
+
+
+
+There are currently 5 types of options: Strings, booleans, ints, floats
+and paths. There's a separate option class for each one, which makes it
+easier to look up these options since for example for a StringOption
,
+getValue
returns a String
, for an IntOption
it returns an Int
,
+and so on.
+
Option Type Option Class
+ String
StringOption
+ Boolean
BooleanOption
+ Int
IntOption
+ Float
FloatOption
+ File
FileOption
+
+
+
+ Reading Options
+
+
+
+To look up the configured value for an option, just call getValue
+and pass in the context
:
+
+
val maxCount = MAX_COUNT.getValue(context)
+
+This will return the Int
value configured for this option by the
+user, or if not set, our original default value, in this case 80.
+
+
+ Specific Configurations
+
+
+
+The above call will look up the option configured for the specific
+source file in the current context
, which might be an individual
+Kotlin source file. That's generally what you want; users can configure
+lint.xml
files not just at the root of the project; they can be
+placed throughout the source folders and are interpreted by lint to
+apply to the folders below. Therefore, if we're analyzing a particular
+Kotlin file and we want to check an option, you generally want to check
+what's configured locally for this file.
+
+
+
+However, there are cases where you want to look up options up front,
+for example at the project level.
+
+
+
+In that case, first look up the particular configuration you want, and
+then pass in that configuration instead of the context to the
+Option.getValue
call.
+
+
+
+For example, the context for the current module is already available in
+the context
, so you might for example look up the option value like
+this:
+
+
val maxCount = MAX_COUNT.getValue(context.configuration)
+
+If you want to find the most applicable configuration for a given
+source file, use
+
+
val configuration = context.findConfiguration(context.file)
+val maxCount = MAX_COUNT.getValue(configuration)
+ Files
+
+
+
+Note that there is a special Option
type for files and paths:
+FileOption
. Make sure that you use this instead of just a
+StringOption
if you are planning on configuring files, because in the
+case of paths, users will want to specify paths relative to the
+location of the lint.xml
file where the path is defined. For
+FileOption
lint is aware of this and will convert the relative path
+string as necessary.
+
+
+ Constraints
+
+
+
+Note that the integer and float options allow you to specify a valid
+range for the configured value — a minimum (inclusive) and a maximum
+(exclusive):
+
+
+
+This range will be included with the option documentation, such as in
+“duration (default is 1.5): Expected duration in seconds. Must be
+at least 0.0 and less than 15.0.”
+
+
private val DURATION_OPTION = FloatOption(
+ name = "duration" ,
+ description = "Expected duration" ,
+ defaultValue = 1.5f ,
+ min = 0f ,
+ max = 15f
+ )
+
+It will also be checked at runtime, and if the configured value is
+outside of the range, lint will report an error and pinpoint the
+location in the invalid lint.xml
file:
+
+
lint.xml:4: Error: duration: Must be less than 15.0 [LintError]
+ <option name="duration" value="100.0">
+ ----------------------------------------
+ 1 errors, 0 warnings
+ Testing Options
+
+
+
+When writing a lint unit test, you can easily configure specific values
+for your detector options. On the lint()
test task, you can call
+configureOption(option, value)
. There are a number of overloads for
+this method, so you can reference the option by its string name, or
+passing in the option instance, and if you do, you can pass in strings,
+integers, booleans, floats and files as values. Here's an example:
+
+
lint().files(
+ kotlin("fun test() { println(" Hello World.") }" )
+ )
+ .configureOption(MAX_COUNT, 150 )
+ .run()
+ .expectClean()
+ Supporting Lint 4.2, 7.0 and 7.1
+
+
+
+The Option
support is new in 7.2. If your lint check still needs to
+work with older versions of lint, you can bypass the option
+registration, and just read option values directly from the
+configuration.
+
+
+
+First, find the configuration as shown above, and then instead of
+calling Option.getValue
, call getOption
on the configuration:
+
+
val option: String? = configuration.getOption(ISSUE, "maxCount" )
+
+The getOption
method returns a String
. For numbers and booleans,
+the coniguration also provides lookups which will convert the value to
+a number or boolean respectively: getOptionAsInt
,
+getOptionAsBoolean
, and most importantly, getOptionAsFile
. If you
+are looking up paths, be sure to use getOptionAsFile
since it has the
+important attribute that it allows paths to be relative to the
+configuration file where the (possibly inherited) value was defined,
+which is what users expect when editing lint.xml
files.
+
+
val option = configuration.getOptionAsInt(ISSUE, "maxCount" , 100 )
+
+
+
+
+ Error Message Conventions
+
+ Length
+
+
+
+The error message reported by a detector should typically be short; think of
+typical compiler error messages you see from kotlinc
or javac
.
+
+
+
+This is particularly important when your lint check is running inside the IDE,
+because the error message will typically be shown as a tooltip as the user
+hovers over the underlined symbol.
+
+
+
+It's tempting to try to fully explain what's going on, but lint has separate
+facilities for that — the issue explanation metadata. When lint generates text
+and html reports, it will include the explanation metadata. Similarly, in the
+IDE, users can pull up the full explanation with a tooltip.
+
+
+
+This is not a hard rule; there are cases where lint uses multiple sentences to
+explain an issue, but strive to make the error message as short as possible
+while still legible.
+
+
+ Formatting
+
+
+
+Use the available formatting support for text in lint:
+
+
Raw text format Renders To
+ This is a `code symbol` This is a code symbol
+ This is *italics*
This is italics
+ This is **bold**
This is bold
+ This is ~~strikethrough~~
This is strikethrough
+ http://, https:// http://, https://
+ \*not italics*
\*not italics*
+ ```language\n text\n``` (preformatted text block)
+
Supported markup in lint's markdown-like raw text format
+
+
+
+In particular, when referencing code elements such as variable names, APIs, and
+so on, use the code symbol formatting (`like this`), not simple or double
+quotes.
+
+
+ Punctuation
+
+
+
+One line error messages should not be punctuated — e.g. the error message
+should be “Unused import foo”, not “Unused import foo.”
+
+
+
+However, if there are multiple sentences in the error message, all sentences
+should be punctuated.
+
+
+
+Note that there should be no space before an exclamation (!) or question mark
+(?) sign.
+
+
+ Include Details
+
+
+
+Avoid generic error messages such as “Unused import”; try to incorporate
+specific details from the current error. In the unused import example, instead
+of just saying “Unused import”, say “Unused import java.io.List”.
+
+
+
+In addition to being clearer (you can see from the error message what the
+problem is without having to look up the corresponding source code), this is
+important to support lint's baseline feature.
+Lint matches known errors not by matching on specific line numbers (which would
+cause problems as soon as the line numbers drift after edits to the file), lint
+matches by error message in the file, so the more unique error messages are,
+the better. If all unused import warnings were just “Unused import”, lint would
+match them in order, which often would match the wrong import.
+
+
+ Reference Android By Number
+
+
+
+When referring to Android behaviors introduced in new API levels, use the
+phrase “In Android 12 and higher”, instead of variations like “Android S” or
+“API 31”.
+
+
+ Keep Messages Stable
+
+
+
+Once you have written an error message, think twice before changing it. This is
+again because of the baseline mechanism mentioned above. If users have already
+run lint with your previous error message, and that message has been written
+into baselines, changing the error message will cause the baseline to no longer
+match, which means this will show up as a new error for users.
+
+
+
+If you have to change an error message because it's misleading, then of
+course, do that — but avoid it if there isn't a strong reason to do so.
+
+
+
+There are some edits you can make to the error message which the baseline
+matcher will handle:
+
+
+
+
+Adding a suffix
+
+Adding a suffix which also changes the final punctuation; e.g. changing
+ “Hello.” to “Hello, world!” is compatible.
+
+Adding a prefix
+
+
+ Plurals
+
+
+
+Avoid trying to make sentences gramatically correct and flexible by
+using constructs like “(s)” to quantity strings. In other words,
+instead of for example saying
+
+
+
+ “register your receiver(s) in the manifest”
+
+
+
+just use the plural form,
+
+
+
+ “register your receivers in the manifest”
+
+
+ Examples
+
+
+
+Here are some examples from lint's built-in checks. Note that these are not
+chosen as great examples of clear error messages; most of these were written
+by engineers without review from a tech writer. But for better or worse they
+reflect the “tone” of the built-in lint checks today. (These were derived from
+lint's unit test suite, which explains silly symbols like test.pkg
in the
+error messages.)
+
+
+
+Note that the [Id] block is not part of the error message; it's included here
+to help cross reference the messages with the corresponding lint check.
+
+
+
+
+[AccidentalOctal] The leading 0 turns this number into octal which is probably not what was intended (interpreted as 8)
+
+[AdapterViewChildren] A list/grid should have no children declared in XML
+
+[AllCaps] Using `textAllCaps` with a string (`has_markup`) that contains markup; the markup will be dropped by the caps conversion
+
+[AllowAllHostnameVerifier] Using the `AllowAllHostnameVerifier` HostnameVerifier is unsafe because it always returns true, which could cause insecure network traffic due to trusting TLS/SSL server certificates for wrong hostnames
+
+[AlwaysShowAction] Prefer `ifRoom` instead of `always`
+
+[AndroidGradlePluginVersion] A newer version of com.android.tools.build:gradle than 3.3.0-alpha04 is available: 3.3.2
+
+[AnimatorKeep] This method is accessed from an ObjectAnimator so it should be annotated with `@Keep` to ensure that it is not discarded or renamed in release builds
+
+[AnnotateVersionCheck] This field should be annotated with `ChecksSdkIntAtLeast(api=Build.VERSION_CODES.LOLLIPOP)`
+
+[AnnotationProcessorOnCompilePath] Add annotation processor to processor path using `annotationProcessor` instead of `api`
+
+[AppBundleLocaleChanges] Found dynamic locale changes, but did not find corresponding Play Core library calls for downloading languages and splitting by language is not disabled in the `bundle` configuration
+
+[AppCompatCustomView] This custom view should extend `android.support.v7.widget.AppCompatButton` instead
+
+[AppCompatMethod] Should use `getSupportActionBar` instead of `getActionBar` name
+
+[AppCompatResource] Should use `android:showAsAction` when not using the appcompat library
+
+[AppIndexingService] `UPDATE_INDEX` is configured as a service in your app, which is no longer supported for the API level you're targeting. Use a `BroadcastReceiver` instead.
+
+[AppLinkUrlError] Missing URL for the intent filter
+
+[AppLinksAutoVerify] This host does not support app links to your app. Checks the Digital Asset Links JSON file: http://example.com/.well-known/assetlinks.json
+
+[ApplySharedPref] Consider using `apply()` instead; `commit` writes its data to persistent storage immediately, whereas `apply` will handle it in the background
+
+[AssertionSideEffect] Assertion condition has a side effect: i++
+
+[Autofill] Missing `autofillHints` attribute
+
+[BackButton] Back buttons are not standard on Android; see design guide's navigation section
+
+[BadHostnameVerifier] `verify` always returns `true`, which could cause insecure network traffic due to trusting TLS/SSL server certificates for wrong hostnames
+
+[BatteryLife] Use of `com.android.camera.NEW_PICTURE` is deprecated for all apps starting with the N release independent of the target SDK. Apps should not rely on these broadcasts and instead use `WorkManager`
+
+[BidiSpoofing] Comment contains misleading Unicode bidirectional text
+
+[BlockedPrivateApi] Reflective access to NETWORK_TYPES is forbidden when targeting API 28 and above
+
+[BottomAppBar] This `BottomAppBar` must be wrapped in a `CoordinatorLayout` (`android.support.design.widget.CoordinatorLayout`)
+
+[BrokenIterator] `Vector#listIterator` was broken in API 24 and 25; it can return `hasNext()=false` before the last element. Consider switching to `ArrayList` with synchronization if you need it.
+
+[ButtonCase] @android:string/yes actually returns “OK”, not “Yes”; use @android:string/ok instead or create a local string resource for Yes
+
+[ButtonOrder] OK button should be on the right (was “OK | Cancel”, should be “Cancel | OK”)
+
+[ButtonStyle] Buttons in button bars should be borderless; use `style=”?android:attr/buttonBarButtonStyle”` (and `?android:attr/buttonBarStyle` on the parent)
+
+[ByteOrderMark] Found byte-order-mark in the middle of a file
+
+[CanvasSize] Calling `Canvas.getWidth()` is usually wrong; you should be calling `getWidth()` instead
+
+[CheckResult] The result of `double` is not used
+
+[ClickableViewAccessibility] Custom view ``NoPerformClick`` has `setOnTouchListener` called on it but does not override `performClick`
+
+[CoarseFineLocation] If you need access to FINE location, you must request both `ACCESS_FINE_LOCATION` and `ACCESS_COARSE_LOCATION`
+
+[CommitPrefEdits] `SharedPreferences.edit()` without a corresponding `commit()` or `apply()` call
+
+[CommitTransaction] This transaction should be completed with a `commit()` call
+
+[ConstantLocale] Assigning `Locale.getDefault()` to a final static field is suspicious; this code will not work correctly if the user changes locale while the app is running
+
+[ContentDescription] Missing `contentDescription` attribute on image
+
+[ConvertToWebp] One or more images in this project can be converted to the WebP format which typically results in smaller file sizes, even for lossless conversion
+
+[CustomPermissionTypo] Did you mean `my.custom.permission.FOOBAR`?
+
+[CustomSplashScreen] The application should not provide its own launch screen
+
+[CustomViewStyleable] By convention, the custom view (`CustomView1`) and the declare-styleable (`MyDeclareStyleable`) should have the same name (various editor features rely on this convention)
+
+[CustomX509TrustManager] Implementing a custom `X509TrustManager` is error-prone and likely to be insecure. It is likely to disable certificate validation altogether, and is non-trivial to implement correctly without calling Android's default implementation.
+
+[CutPasteId] The id `R.id.duplicated` has already been looked up in this method; possible cut & paste error?
+
+[DalvikOverride] This package private method may be unintentionally overriding `method` in `pkg1.Class1`
+
+[DataBindingWithoutKapt] If you plan to use data binding in a Kotlin project, you should apply the kotlin-kapt plugin.
+
+[DataExtractionRules] The attribute `android:allowBackup` is deprecated from Android 12 and the default allows backup
+
+[DefaultEncoding] This `Scanner` will use the default system encoding instead of a specific charset which is usually a mistake; add charset argument, `Scanner(..., UTF_8)`?
+
+[DefaultLocale] Implicitly using the default locale is a common source of bugs: Use `toUpperCase(Locale)` instead. For strings meant to be internal use `Locale.ROOT`, otherwise `Locale.getDefault()`.
+
+[DeletedProvider] The Crypto provider has been deleted in Android P (and was deprecated in Android N), so the code will crash
+
+[DeprecatedProvider] The `BC` provider is deprecated and when `targetSdkVersion` is moved to `P` this method will throw a `NoSuchAlgorithmException`. To fix this you should stop specifying a provider and use the default implementation
+
+[DeprecatedSinceApi] This method is deprecated as of API level 25
+
+[Deprecated] `AbsoluteLayout` is deprecated
+
+[DevModeObsolete] You no longer need a `dev` mode to enable multi-dexing during development, and this can break API version checks
+
+[DeviceAdmin] You must have an intent filter for action `android.app.action.DEVICE_ADMIN_ENABLED`
+
+[DiffUtilEquals] Suspicious equality check: Did you mean `.equals()` instead of `==` ?
+
+[DisableBaselineAlignment] Set `android:baselineAligned=“false”` on this element for better performance
+
+[DiscouragedPrivateApi] Reflective access to addAssetPath, which is not part of the public SDK and therefore likely to change in future Android releases
+
+[DrawAllocation] Avoid object allocations during draw/layout operations (preallocate and reuse instead)
+
+[DuplicateActivity] Duplicate registration for activity `com.example.helloworld.HelloWorld`
+
+[DuplicateDefinition] `app_name` has already been defined in this folder
+
+[DuplicateDivider] Replace with `android.support.v7.widget.DividerItemDecoration`?
+
+[DuplicateIds] Duplicate id `@+id/android_logo`, already defined earlier in this layout
+
+[DuplicateIncludedIds] Duplicate id @+id/button1, defined or included multiple times in layout/layout2.xml: * [layout/layout2.xml => layout/layout3.xml defines @+id/button1, layout/layout2.xml => layout/layout4.xml defines @+id/button1]
+
+[DuplicatePlatformClasses] `xpp3` defines classes that conflict with classes now provided by Android. Solutions include finding newer versions or alternative libraries that don't have the same problem (for example, for `httpclient` use `HttpUrlConnection` or `okhttp` instead), or repackaging the library using something like `jarjar`.
+
+[DuplicateStrings] Duplicate string value `HELLO`, used in `hello_caps` and `hello`. Use `android:inputType` or `android:capitalize` to treat these as the same and avoid string duplication.
+
+[DuplicateUsesFeature] Duplicate declaration of uses-feature `android.hardware.camera`
+
+[EllipsizeMaxLines] Combining `ellipsize=start` and `lines=1` can lead to crashes. Use `singleLine=true` instead.
+
+[EmptySuperCall] No need to call `super.someOtherMethod`; the super method is defined to be empty
+
+[EnforceUTF8] iso-latin-1: Not using UTF-8 as the file encoding. This can lead to subtle bugs with non-ascii characters
+
+[EnqueueWork] WorkContinuation `cont` not enqueued: did you forget to call `enqueue()`?
+
+
+ Frequently Asked Questions
+
+
+
+This chapter contains a random collection of questions people
+have asked in the past.
+
+
+ My detector callbacks aren't invoked
+
+
+
+If you've for example implemented the Detector callback for visiting
+method calls, visitMethodCall
, notice how the third parameter is a
+PsiMethod
, and that it is not nullable:
+
+
open fun visitMethodCall (
+ context: JavaContext ,
+ node: UCallExpression ,
+ method: PsiMethod
+ ) {
+
+This passes in the method that has been called. When lint is visiting
+the AST, it will resolve calls, and if the called method cannot be
+resolved, the callback won't be called.
+
+
+
+This happens when the classpath that lint has been configured with does
+not contain everything needed. When lint is running from Gradle, this
+shouldn't happen; the build system should have a complete classpath and
+pass it to Lint (or the build wouldn't have succeeded in the first
+place).
+
+
+
+This usually comes up in unit tests for lint, where you've added a test
+case which is referencing some API for some library, but the library
+itself isn't part of the test. The solution for this is to create stubs
+for the part of the API you care about. This is discussed in more
+detail in the unit testing chapter.
+
+
+ My lint check works from the unit test but not in the IDE
+
+
+
+There are several things to check if you have a lint check which
+works correctly from your unit test but not in the IDE.
+
+
+
+
+First check that the lint jar is packaged correctly; use jar tvf
+ lint.jar
to look at the jar file to make sure it contains the
+ service loader registration of your issue registry, and javap
+ -classpath lint.jar com.example.YourIssueRegistry
to inspect your
+ issue registry.
+
+
+
+
+If that's correct, the next thing to check is that lint is actually
+ loading your issue registry. First look in the IDE log (from the
+ Help menu) to make sure there aren't log messages from lint
+ explaining why it can't load the registry, for example because it
+ does not specify a valid applicable API range.
+
+
+
+
+If there's no relevant warning in the log, try setting the
+ $ANDROID_LINT_JARS
environment variable to point directly to your
+ lint jar file and restart Studio to make sure that that works.
+
+
+
+
+Next, try running Analyze | Inspect Code... . This runs lint on
+ the whole project. If that works, then the issue is that your lint
+ check isn't eligible to run “on the fly”; the reason for this is
+ that your implementation scope registers more than one scope, which
+ says that your lint check can only run if lint gets to look at both
+ types of files, and in the editor, only the current file is analyzed
+ by lint. However, you can still make the check work on the fly by
+ specifying additional analysis scopes; see the API guide for more
+ information about this.
+
+
+ visitAnnotationUsage
isn't called for annotations
+
+
+
+If you want to just visit any annotation declarations (e.g. @Foo
on
+method foo
), don't use the applicableAnnotations
and
+visitAnnotationUsage
machinery. The purpose of that facility is to
+look at elements that are being combined with annotated elements,
+such as a method call to a method whose return value has been
+annotated, or an argument to a method a method parameter that has been
+annotated, or assigning an assigned value to an annotated variable, etc.
+
+
+
+If you just want to look at annotations, use getApplicableUastTypes
+with UAnnotation::class.java
, and a UElementHandler
which overrides
+visitAnnotation
.
+
+
+ How do I check if a UAST or PSI element is for Java or Kotlin?
+
+
+
+To check whether an element is in Java or Kotlin, call one
+of the package level methods in the detector API (and from
+Java, you can access them as utility methods on the “Lint”
+class) :
+
+
package com.android.tools.lint.detector.api
+
+
+fun isJava (element: PsiElement ?) : Boolean { }
+
+
+fun isKotlin (language: Language ?) : Boolean { }
+
+
+fun isJava (language: Language ?) : Boolean { }
+
+If you have a UElement
and need a PsiElement
for the above method,
+see the next question.
+
+
+ What if I need a PsiElement
and I have a UElement
?
+
+
+
+If you have a UElement
, you can get the underlying source PSI element
+by calling element.sourcePsi
.
+
+
+ How do I get the UMethod
for a PsiMethod
?
+
+
+
+Call psiMethod.toUElementOfType<UMethod>()
. Note that this may return
+null if UAST cannot find valid Java or Kotlin source code for the
+method.
+
+
+
+For PsiField
and PsiClass
instances use the equivalent
+toUElementOfType
type arguments.
+
+
+ How do get a JavaEvaluator
?
+
+
+
+The Context
passed into most of the Detector
callback methods
+relevant to Kotlin and Java analysis is of type JavaContext
, and it
+has a public evaluator
property which provides a JavaEvaluator
you
+can use in your analysis.
+
+
+
+If you need one outside of that scenario (this is not common) you can
+construct one directly by instantiating a DefaultJavaEvaluator
; the
+constructor parameters are nullable, and are only needed for a couple
+of operations on the evaluator.
+
+
+ How do I check whether an element is internal?
+
+
+
+First get a JavaEvaluator
as explained above, then call
+this evaluator method:
+
+
open fun isInternal (owner: PsiModifierListOwner ?) : Boolean {
+
+(Note that a PsiModifierListOwner
is an interface which includes
+PsiMethod
, PsiClass
, PsiField
, PsiMember
, PsiVariable
, etc.)
+
+
+ Is element inline, sealed, operator, infix, suspend, data?
+
+
+
+Get the JavaEvaluator
as explained above, and then call one of these
+evaluator method:
+
+
open fun isData (owner: PsiModifierListOwner ?) : Boolean {
+open fun isInline (owner: PsiModifierListOwner ?) : Boolean {
+open fun isLateInit (owner: PsiModifierListOwner ?) : Boolean {
+open fun isSealed (owner: PsiModifierListOwner ?) : Boolean {
+open fun isOperator (owner: PsiModifierListOwner ?) : Boolean {
+open fun isInfix (owner: PsiModifierListOwner ?) : Boolean {
+open fun isSuspend (owner: PsiModifierListOwner ?) : Boolean {
+ How do I look up a class if I have its fully qualified name?
+
+
+
+Get the JavaEvaluator
as explained above, then call
+evaluator.findClass(qualifiedName: String)
. Note that the result is
+nullable.
+
+
+ How do I look up a class if I have a PsiType?
+
+
+
+Get the JavaEvaluator
as explained above, then call
+evaluator.getTypeClass
. To go from a class to its type,
+use getClassType
.
+
+
abstract fun getClassType (psiClass: PsiClass ?) : PsiClassType?
+ abstract fun getTypeClass (psiType: PsiType ?) : PsiClass?
+ How do I look up hierarchy annotations for an element?
+
+
+
+You can directly look up annotations via the modified list
+of PsiElement or the annotations for a UAnnotated
element,
+but if you want to search the inheritance hierarchy for
+annotations (e.g. if a method is overriding another, get
+any annotations specified on super implementations), use
+one of these two evaluator methods:
+
+
abstract fun getAllAnnotations (
+ owner: UAnnotated ,
+ inHierarchy: Boolean
+ ) : List<uannotation>
+
+ abstract fun getAllAnnotations (
+ owner: PsiModifierListOwner ,
+ inHierarchy: Boolean
+ ) : Array<psiannotation>
+ How do I look up if a class is a subclass of another?
+
+
+
+To see if a method is a direct member of a particular
+named class, use the following method in JavaEvaluator
:
+
+
fun isMemberInClass (member: PsiMember ?, className: String ) : Boolean { }
+
+To see if a method is a member in any subclass of a named class, use
+
+
open fun isMemberInSubClassOf (
+ member: PsiMember ,
+ className: String ,
+ strict: Boolean = false
+ ) : Boolean { }
+
+
+Here, use strict = true
if you don't want to include members in the
+named class itself as a match.
+
+
+
+To see if a class extends another or implements an interface, use one
+of these methods. Again, strict
controls whether we include the super
+class or super interface itself as a match.
+
+
abstract fun extendsClass (
+ cls: PsiClass ?,
+ className: String ,
+ strict: Boolean = false
+ ) : Boolean
+
+ abstract fun implementsInterface (
+ cls: PsiClass ,
+ interfaceName: String ,
+ strict: Boolean = false
+ ) : Boolean
+ How do I know which parameter a call argument corresponds to?
+
+
+
+In Java, matching up the arguments in a call with the parameters in the
+called method is easy: the first argument corresponds to the first
+parameter, the second argument corresponds to the second parameter and
+so on. If there are more arguments than parameters, the last arguments
+are all vararg arguments to the last parameter.
+
+
+
+In Kotlin, it's much more complicated. With named parameters, but
+arguments can appear in any order, and with default parameters, only
+some of them may be specified. And if it's an extension method, the
+first argument passed to a PsiMethod
is actually the instance itself.
+
+
+
+Lint has a utility method to help with this on the JavaEvaluator
:
+
+
open fun computeArgumentMapping (
+ call: UCallExpression ,
+ method: PsiMethod
+ ) : Map<UExpression, PsiParameter> {
+
+This returns a map from UAST expressions (each argument to a UAST call
+is a UExpression
, and these are the valueArguments
property on the
+UCallExpression
) to each corresponding PsiParameter
on the
+PsiMethod
that the method calls.
+
+
+ How can my lint checks target two different versions of lint?
+
+
+
+If you need to ship different versions of your lint checks to target
+different versions of lint (because perhaps you need to work both with
+an older version of lint, and a newer version that has a different
+API), the way to do this (as of Lint 7.0) is to use the maxApi
+property on the IssueRegistry
. In the service loader registration
+(META-INF/services
), register two issue registries; one for each
+implementation, and mark the older one with the right minApi
to
+maxApi
range, and the newer one with minApi
following the previous
+registry's maxApi
. (Both minApi
and maxApi
are inclusive). When
+lint loads the issue registries it will ignore registries with a range
+outside of the current API level.
+
+
+ Can I make my lint check “not suppressible?”
+
+
+
+In some (hopefully rare) cases, you may want your lint checks to not be
+suppressible using the normal mechanisms — suppress annotations,
+comments, lint.xml files, baselines, and so on. The usecase for this is
+typically strict company guidelines around compliance or security and
+you want to remove the easy possibility of just silencing the check.
+
+
+
+This is possible as part of the issue registration. After creating your
+Issue
, set the suppressNames
property to an empty collection.
+
+
+ Why are overloaded operators not handled?
+
+
+
+Kotlin supports overloaded operators, but these are not handled as
+calls in the AST — instead, an implicit get
or set
method from an
+array access will show up as a UArrayAccessExpression
. Lint has
+specific support to help handling these scenarios; see the “Implicit
+Calls” section in the basics chapter.
+
+
+ How do I check out the current lint source code?
+$ git clone --branch=mirror-goog-studio-main --single-branch \
+ https://android.googlesource.com/platform/tools/base
+ Cloning into 'base'...
+ remote: Total 648820 (delta 325442), reused 635137 (delta 325442)
+ Receiving objects: 100% (648820/648820), 1.26 GiB | 15.52 MiB/s, done.
+ Resolving deltas: 100% (325442/325442), done.
+ Updating files: 100% (14416/14416), done.
+
+ $ du -sh base
+ 1.8G base
+$ cd base/lint
+$ ls
+ .editorconfig BUILD build.gradle libs/
+ .gitignore MODULE_LICENSE_APACHE2 cli/
+$ ls libs/
+ intellij-core/ kotlin-compiler/ lint-api/ lint-checks/ lint-gradle/ lint-model/ lint-tests/ uast/
+ Where do I find examples of lint checks?
+
+
+
+The built-in lint checks are a good source. Check out the source code
+as shown above and look in
+lint/libs/lint-checks/src/main/java/com/android/tools/lint/checks/
or
+browse sources online:
+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/
+
+
+ How do I analyze details about Kotlin?
+
+
+
+The new Kotlin Analysis API offers access to detailed information about
+Kotlin (types, resolution, as well as information the compiler has
+figured out such as smart casts, nullability, deprecation info, and so
+on). There are more details about this, as well as a number of recipes,
+in the AST Analysis chapter.
+
+
+
+
+
+
+ Appendix: Recent Changes
+
+
+
+Recent Changes
+
+
+
+This chapter lists recent changes to lint that affect lint check
+authors: new features, API and behavior changes, and so on. For
+information about user visible changes to lint, see the User
+Guide.
+
+
+
+8.8
+
+
+
+
+For the string-replacement quickfix, you can now specify
+ regex flags (such as Pattern.DOT_ALL) to change the pattern
+ matching behavior.
+
+
+
+8.7
+
+
+
+
+The unit testing support now checks to make sure that you
+ don't have duplicate class names across Java and Kotlin
+ (which can lead to subtle and confusing errors.)
+
+The build.gradle.kts
unit testing support (TestFiles.kts()
)
+ now performs the same mocking of the builder model that the
+ corresponding Groovy Gradle support (Testfiles.gradle()
)
+ performs. Among other things, this means that the other
+ source files (java()
, kotlin()
, etc) must be located in
+ source sets, e.g. src/main/res/
and /src/main/java/
+ rather than just res/
and src/
. This happens automatically
+ if you don't manually specify a target path in the test file
+ declaration.
+
+
+
+8.6
+
+
+
+
+UAST repeats @JvmOverloaded methods in the AST. Lint now looks for
+ and skips these duplications, and a new test mode also looks for
+ potential problems in third party checks.
+
+Added a new chapter to the api-guide on AST analysis, and in
+ particular, using the Kotlin Analysis API.
+
+The UElementHandler
now supports recently added UAST element
+ types: UPatternExpression
and UBinaryExpressionWithPattern
.
+
+There's a new test mode checking for issues related to
+ @JvmOverloads
. See the test modes chapter
+ for more.
+
+
+
+8.4
+
+
+
+
+You can now use ~~
in text messages (error messages, issue
+ explanations, etc) to create strikethrough text. For example, “Don't
+ do this: ~~super.onCreate()~~
” will render as “Don't do this:
+ super.onCreate()”.
+
+
+
+8.3
+
+
+
+
+If you'd like to change your error message reported by your
+ detector, you can now override your Detector
's sameMessage
+ method: match the details in the previous error message with the
+ new format. This is used by the baseline mechanism such that your
+ message change doesn't suddenly invalidate all existing baseline
+ files for your issue.
+
+
+
+
+The replace-string quickfix descriptor now lets you replace a string
+ repeatedly. Example:
+
fix().replace ().text("Foo" ).with ("Bar" ).repeatedly().build()
+
+ You can also match an element optionally. Example:
+
fix().composite(
+ fix().replace ().text("<tag>" ).with ("<tag>" ).build(),
+ fix().replace ().text("</tag>" ).with ("</tag>" ).optional().build()
+ )
+
+
+The quickfix machinery was improved significantly. It now does a
+ better job inserting imports (in alphabetical order instead of always
+ prepending to the import list), inserting new XML attributes in the
+ right canonical Android order, cleaning up whitespace after edits,
+ etc. This may result in some diffs in any quickfix-related unit tests
+ (e.g. lint().run().expectFixDiffs(...)
)
+
+
+
+
+The getFileNameWithParent
utility method now always uses / as
+ a file separator instead of the platform-specific one (e.g. \ on
+ Windows). This ensures that baselines don't vary their error
+ messages (where this utility method is typically used) based on
+ which OS they were generated on.
+
+
+
+8.2
+
+
+
+
+For unit tests, you can now specify the language level to be used
+ for Kotlin and Java. For example, if your unit test is using Java
+ records, add .javaLanguageLevel("17")
to your lint()
test
+ configuration.
+
+
+
+8.1
+
+
+
+
+The data flow analyzer has been
+ improved; in addition to fixing a few bugs, there are a couple of
+ new convenience sub classes which makes common tasks easier to
+ accomplish; see the documentation for TargetMethodDataFlowAnalyzer
+ for example.
+
+
+
+
+The new mavenLibrary
(and binaryStub
) test files make it simple
+ to create binary stub files in your tests, without having to perform
+ compilation and check in base64 and gzip encoded test files. When
+ your detector resolves references, the PSI elements you get back
+ differ whether you're calling into source or into binary (jar/.class
+ file) elements, so testing both (which the new test files automate
+ using test modes) is helpful. More information about this is
+ available in api-guide/unit-testing.md.html .
+
+
+
+
+Lint now supports analyzing TOML files. There is a new
+ Scope.TOML_FILE detectors can register an interest in, a new
+ TomlScanner interface to implement for visitTomlDocument callbacks,
+ etc. From a GradleScanner, you can directly resolve version catalog
+ libraries via lookup methods on the GradleContext.
+
+
+
+
+Lint's “diff” output for unit test verification has been improved;
+ it's now smarter about combining nearby chunks. (This should not
+ break existing tests; the test infrastructure will try the older
+ format as a fallback if the diffs aren't matching for the new
+ format.)
+
+
+
+
+Lint contains JVM 17 bytecode. You will now need to use JDK 17+
+ when compiling custom Lint checks. You should also configure
+ the Kotlin compiler to target JVM 17, otherwise you may see errors
+ when calling inline functions declared in Lint, UAST, or PSI.
+
+
+
+
+Lint's testing infrastructure now looks not just for test/
+ but also androidTest/ and testFixtures/ to set the corresponding
+ source set type on each test context.
+
+
+
+8.0
+
+
+
+
+A new testmode which makes sure lint checks are all suppressible.
+ It analyzes the reported error locations from the expected test
+ output, and inserts suppress annotations in XML, Kotlin and Java
+ files and makes sure that the corresponding warnings disappear.
+
+
+
+7.4
+
+
+
+
+Annotation detectors can now specify just an annotation name instead
+ of its fully qualified name in order to match all annotations of
+ that name. For example,
+ override fun applicableAnnotations() = listOf("Nullable")
+ will match both androidx.annotation.Nullable
and
+ org.jetbrains.annotations.Nullable
. This is used by for example
+ the built-in CheckResultDetector to match many new variants of the
+ CheckReturnValue
annotations, such as the ones in mockito and in
+ protobuf.
+
+
+
+
+The new AnnotationUsageTypes IMPLICIT_CONSTRUCTOR and
+ IMPLICIT_CONSTRUCTOR_CALL let detectors analyzing annotations get callbacks
+ when an annotated no-args constructor is invoked explicitly from a subclass
+ which has an implicit constructor, or from an implicit super call in an
+ explicit sub constructor. These are not included by default, so override
+ isApplicableAnnotationUsage to opt in.
+
+
+
+7.3
+
+
+
+
+The new AnnotationUsageType.DEFINTION now lets detectors easily check
+ occurrences of an annotation in the source code. Previously,
+ visitAnnotationUsage
would only check annotated elements, not the
+ annotations themselves, and to check an annotation you'd need to
+ create an UElementHandler
. See the docs for the new enum constant
+ for more details, and for an example of a detector that was converted
+ from a handler to using this, see IgnoreWithoutReasonDetector
.
+
+
+
+
+Lint unit tests can now include package-info.java
files with
+ annotations in source form (until now, this only worked if the files
+ were provided as binary class files)
+
+
+
+
+String replacement quickfixes can now be configured with a list of
+ imports to be performed when the fix is applied. This can be used to
+ for example import Kotlin extension functions needed by the
+ replacement string. (You should not use this for normal imports;
+ instead, the replacement string should use fully qualified names
+ everywhere along with the shortenNames
property on the fix, and
+ then lint will rewrite and import all symbols that can be done
+ without conflicts.)
+
+
+
+7.2
+
+
+
+
+
+
+
+7.1
+
+
+
+
+Lint now bundles IntelliJ version 2021.1 and Kotlin compiler version 1.5.30.
+ You may see minor API changes in these dependencies. For example,
+ the Kotlin UAST class KotlinUMethod
changed packages from
+ org.jetbrains.uast.kotlin.declarations
to org.jetbrains.uast.kotlin
.
+
+
+
+
+The default behaviour of ResourceXmlDetector will change.
+ It will skip res/raw folder and you have to override appliesTo method
+ if you want your Lint checks to run there.
+
+
+
+
+The computation of checksums for binary test files (e.g. compiled
+ and bytecode
) unfortunately had to change; the old mechamism was
+ not stable. This means that after updating some of the test files
+ will show as having wrong checksums (e.g. “The checksum does not
+ match for test.kt; expected 0×26e3997d but was 0xb76b5946”). In these
+ cases, just drop in the new checksum.
+
+
+
+
+Source-modifying test modes. Lint's testing library now runs your
+ unit tests through a number of additional paces: it will try
+ inserting unnecessary parentheses, it will try replacing all
+ imported symbols with fully qualified names, it will try adding
+ argument names and reordering arguments to Kotlin calls, etc, and
+ making sure the same results are reported. More information about
+ this is available in api-guide/test-modes.md.html .
+
+
+
+
+The support for Kotlin's overloaded operators is significantly
+ improved. While these are method calls, in the AST they do not show
+ up as UCallExpressions
(instead, you'll find them as
+ UBinaryExpression
, UPrefixExpression
, UArrayAccessExpression
+ and so on), which meant various call-specific checks ignored them.
+
+
+
+ Now, in addition to the built-in checks all applying to these
+ implicit calls as well, lint can present these expressions as call
+ expressions. This means that the getApplicableMethodNames
machinery
+ for call callbacks will now also work for overloaded functions, and
+ code which is iterating through calls can use the new
+ UastCallVisitor
(or directly construct UImplicitCallExpression
+ wrappers) to simplify processing of all these types of calls.
+
+
+
+ Finally, lint now provides a way to resolve operators for array
+ access expressions (which is missing in UAST) via the
+ UArrayAccessExpression.resolveOperator extension method, which is
+ also used by the above machinery.
+
+
+
+
+The annotation support (where a detector callback is invoked when
+ elements are combined with annotated elements) has been significantly
+ reworked (and the detector API changed). It now supports visiting
+ the following additional scenarios:
+
+
+
+
+ Fields in annotated classes and packages
+
+ Fields and methods in annotated outerclasses
+
+ Class and object literals
+
+ Overridden methods
+
+ File level annotations (from Kotlin)
+
+
+
+
+ It also offers better control for handling scopes — providing all
+ relevant annotations in the hierarchy at the same time such that a
+ lint check for example can easily determine whether an outer
+ annotation like @Immutable
is canceled by a closer @Mutable
+ annotation.
+
+
+
+ There are some new annotation usage type enum constants which let
+ your lint checks treat these differently. For example, the lint check
+ which makes sure that calls to methods annotated with @CheckResult
+ started flagging overrides of these methods. The fix was to add the
+ following override to the CheckResultDetector
:
+
+
override fun isApplicableAnnotationUsage (type: AnnotationUsageType ) : Boolean {
+ return type != AnnotationUsageType.METHOD_OVERRIDE &&
+ super .isApplicableAnnotationUsage(type)
+ }
+
+ (Using this new API constant will make your lint check only work with
+ the new version of lint. An alternative fix is to check that the
+ usage
parameter is not a UMethod
.)
+
+
+
+ For more, see the new documentation for
+ how to handle annotations from detectors.
+
+
+
+
+The lint testing library now contains a new test file type, rClass
,
+ which lets you easily construct Android R
classes with resource
+ declarations (which are needed in tests that reference the R fields
+ to ensure that symbol resolution works.)
+
+
+
+
+When you call context.getLocation(UMethod)
, lint will now default
+ this method to be equivalent to context.getNameLocation(UMethod)
+ instead, which will highlight the method name. This might surface
+ itself as unit test failures where the location range moves from a
+ single ^
into a ~~~~~
range. This is because the location printer
+ uses ^
to just indicate the start offset when a range is multi-line.
+
+
+
+7.0
+
+
+
+
+The API level has bumped to 10.
+
+
+
+
+Partial analysis. Lint's architecture has changed to support better
+ scalability across large projects, where module results can be
+ cached, etc. See the api-guide's dedicated chapter for more details.
+ It is enabled by default starting in AGP 7.0.0-alpha13.
+
+
+
+
+Issue registration now takes an optional Vendor
property, where you
+ can specify information about which company or team provided this
+ lint check, which library it's associated with, contact information,
+ and so on. This will make it easier for users to figure out where to
+ send feedback or requests for 3rd party lint checks.
+
+
+
+
+Bytecode verification: Instead of warning about 3rd party lint checks
+ being obsolete because they were not compiled against the latest Lint
+ API, lint now run its own bytecode verification against the lint jar
+ and will silently accept older (and newer!) lint checks if they do
+ not reference APIs that are not available.
+
+
+
+
+Android Lint checks can now always access the resource repository for
+ random access to resources, instead of having to gather them in batch
+ mode. (Previously this was only available when lint checks were
+ running in the IDE.)
+
+
+
+
+The lint unit testing library now provides a TestMode
concept. You
+ can define setup and teardown methods, and lint will run unit tests
+ repeatedly for each test mode. There are a number of built-in test
+ modes already enabled; for example, all lint tests will run both in
+ global analysis mode and in partial analysis mode, and the results
+ compared to ensure they are the same.
+
+
+
+
+Lint unit tests now include source contents for secondary locations
+ too. If the test fails, lint will retry without secondary source
+ locations and not report an error; this preserves backwards
+ compatibility.
+
+
+
+
+There's a new Incident
class which is used to hold information to
+ be reported to the user. Previously, there were a number of
+ overloaded methods to report issues, taking locations, error
+ messages, quick fixes, and so on. Each time we added another one we'd
+ have to add another overload. Now, you instead just report incidents.
+ This is critical to the new partial analysis architecture but is also
+ required if you for example want to override severities per incident
+ as described above.
+
+
+
+
+Lint checks can now vary the severity on a per incident basis by
+ calling overrideSeverity on the incidents. This means that there is
+ no longer a need to create separate issues for flavors of the same
+ underlying problem with slightly different expectations around
+ warnings or errors.
+
+
+
+
+There are additional modifier lookup methods for Kotlin modifiers
+ on JavaEvaluator
, like isReified()
, isCompanion()
,
+ isTailRec()
, and so on.
+
+
+
+
+API documentation is now available.
+
+
+
+
+UAST for Kotlin is now based on Kotlin 1.5.
+
+
+
+
+Certain Kotlin PSI elements have new implementations known as ultra
+ light classes . Ultra light classes improve performance by answering
+ PSI queries “directly from source” rather than delegating to the
+ Kotlin compiler backend. You may see ultra light classes when
+ accessing the UElement.javaPsi
property of a Kotlin UAST element.
+ They can also appear when resolving references. For example,
+ resolving a Kotlin field reference to its declaration may result in
+ an instance of KtUltraLightFieldForSourceDeclaration
. As a
+ reminder, Kotlin light classes represent the “Java view” of an
+ underlying Kotlin PSI element. To access the underlying Kotlin PSI
+ element you should use UElement.sourcePsi
(preferred) or otherwise
+ the extension property PsiElement.unwrapped
(declared in
+ org.jetbrains.kotlin.asJava
).
+
+
+
+
+There is a new bug where calling getNameIdentifier()
on Kotlin
+ fields may return null
+ (KT-45629 ).
+ As a workaround you can use JavaContext.findNameElement()
instead.
+
+
+
+
+Kotlin references to Java methods now trigger both the
+ visitMethodCall()
callback and the visitReference()
callback.
+ Previously only visitMethodCall()
was triggered.
+
+
+
+
+Quickfixes can now create and delete new files; see
+ LintFix#newFile
and LintFix#deleteFile
..
+
+
+
+
+For quickfixes, the independent
property had inverted logic;
+ this has now been reversed to follow the meaning of the name.
+
+
+
+
+The location range returned when looking up the location for a call
+ will now include arguments outside of the call range itself. This is
+ important when the code is using Kotlin's assignment syntax for
+ calling methods as if they are properties.
+
+
+
+
+Lint's unit testing framework now checks all import
statements in
+ test files to make sure that they resolve. This will help catch
+ common bugs and misunderstandings where tests reference frameworks
+ that aren't available to lint in the unit test, and where you need to
+ either add the library or more commonly just add some simple stubs.
+ If the import statements do not matter to the test, you can just mark
+ the test as allowing compilation errors, using
+ .allowCompilationErrors()
on the lint()
task.
+
+
+
+
+The data flow analyzer has been
+ significantly improved, particularly around Kotlin scoping functions.
+
+
+
+
+
+
+ Appendix: Environment Variables and System Properties
+
+
+
+This chapter lists the various environment variables and system
+properties that Lint will look at. None of these are really intended to
+be used or guaranteed to be supported in the future, but documenting
+what they are seems useful.
+
+
+ Environment Variables
+
+ Detector Configuration Variables
+
+
+
+
ANDROID_LINT_INCLUDE_LDPI
Lint's icon checks normally ignore the ldpi
density since it's not
+ commonly used any more, but you can turn this back on with this
+ environment variable set to true
.
+
+
ANDROID_LINT_MAX_VIEW_COUNT
Lint's TooManyViews
check makes sure that a single layout does not
+ have more than 80 views. You can set this environment variable to a
+ different number to change the limit.
+
+
ANDROID_LINT_MAX_DEPTH
Lint's TooManyViews
check makes sure that a single layout does not
+ have a deeper layout hierarchy than 10 levels.You can set this
+ environment variable to a different number to change the limit.
+
+
ANDROID_LINT_NULLNESS_IGNORE_DEPRECATED
Lint's UnknownNullness
which flags any API element which is not
+ explicitly annotated with nullness annotations, normally skips
+ deprecated elements. Set this environment variable to true to include
+ these as well.
+
+
+
+ Corresponding system property: lint.nullness.ignore-deprecated
.
+
+
+
+ Note that this setting can also be configured using a proper
+ lint.xml
setting instead; this is now listed in the documentation
+ for that check.
+
+
+ Lint Configuration Variables
+
+
+
+
ANDROID_SDK_ROOT
Locates the Android SDK root
+
+
ANDROID_HOME
Locates the Android SDK root, if $ANDROID_SDK_ROOT
has not been set
+
+
JAVA_HOME
Locates the JDK when lint is analyzing JDK (not Android) projects
+
+
LINT_XML_ROOT
Normally the search for lint.xml
files proceeds upwards in the
+ directory hierarchy. In the Gradle integration, the search will stop
+ at the root Gradle project, but in other build systems, it can
+ continue up to the root directory. This environment variable sets a
+ path where the search should stop.
+
+
ANDROID_LINT_JARS
A path of jar files (using the path separator — semicolon on
+ Windows, colon elsewhere) for lint to load extra lint checks from
+
+
ANDROID_SDK_CACHE_DIR
Sets the directory where lint should read and write its cache files.
+ Lint has a number of databases that it caches between invocations,
+ such as its binary representation of the SDK API database, used to
+ look up API levels quickly. In the Gradle integration of lint, this
+ cache directory is set to the root build/
directory, but elsewhere
+ the cache directory is located in a lint
subfolder of the normal
+ Android tooling cache directory, such as ~/.android
.
+
+
LINT_OVERRIDE_CONFIGURATION
Path to a lint XML file which should override any local lint.xml
+ files closer to reported issues. This provides a way to globally
+ change configuration.
+
+
+
+ Corresponding system property: lint.configuration.override
+
+
LINT_DO_NOT_REUSE_UAST_ENV
Set to true
to enable a workaround (if affected) for
+ bug 159733104
+ until 7.0 is released.
+
+
+
+ Corresponding system property: lint.do.not.reuse.uast.env
+
+
LINT_API_DATABASE
Point lint to an alternative API database XML file instead of the
+ normally used $SDK/platforms/android-?/data/api-versions.xml
file.
+
+
ANDROID_LINT_SKIP_BYTECODE_VERIFIER
If set to true
, lint will not perform bytecode verification of custom
+ lint check jars from libraries or passed in via command line flags.
+
+
+
+ Corresponding system property: android.lint.skip.bytecode.verifier
+
+
+ Lint Development Variables
+
+
+
+
LINT_PRINT_STACKTRACE
If set to true, lint will print the full stack traces of any internal
+ exceptions encountered during analysis. This is useful for authors of
+ lint checks, or for power users who can reproduce a bug and want to
+ report it with more details.
+
+
+
+ Corresponding system property: lint.print-stacktrace
+
+
LINT_TEST_KOTLINC
When writing a lint check unit test, when creating a compiled
or
+ bytecode
test file, lint can generate the .class file binary
+ content automatically if it is pointed to the kotlinc
compiler.
+
+
LINT_TEST_JAVAC
When writing a lint check unit test, when creating a compiled
or
+ bytecode
test file, lint can generate the .class file binary
+ content automatically if it is pointed to the javac
compiler.
+
+
LINT_TEST_KOTLINC_NATIVE
When writing a lint check unit test, when creating a klib
file,
+ lint can generate the .klib
file binary content automatically
+ if it is pointed to kotlinc-native
.
+
+
LINT_TEST_INTEROP
When writing a lint check unit test, when creating a c
or def
+ test file, lint can generate the .klib
file binary content
+ automatically if it is pointed to cinterop
.
+
+
INCLUDE_EXPENSIVE_LINT_TESTS
When working on lint itself, set this environment variable to true
+ some really, really expensive tests that we don't want run on the CI
+ server or by the rest of the development team.
+
+
+ System Properties
+
+
+
+
+
+
To set system properties when running lint via Gradle, try for
+ example ./gradlew lintDebug -Dlint.baselines.continue=true
+
+
+
+
lint.baselines.continue
When you configure a new baseline, lint normally fails the build
+ after creating the baseline. You can set this system property to true
+ to force lint to continue.
+
+
lint.autofix
Turns on auto-fixing (applying safe quickfixes) by default. This is a
+ shortcut for invoking the lintFix
targets or running the lint
+ command with --apply-suggestions
.
+
+
lint.autofix.imports
If lint.autofix
is on, setting this flag will also include updating
+ imports and applying reference shortening for updated code. This
+ is normally only done in the IDE, relying on the safe refactoring
+ machinery there. Lint's implementation isn't accurate in all cases
+ (for example, it may apply reference shortening in comments), but
+ can be enabled when useful (such as large bulk operations along with
+ manual verification.)
+
+
+
+ Turns on auto-fixing (applying safe quickfixes) by default. This is a
+ shortcut for invoking the lintFix
targets or running the lint
+ command with --apply-suggestions
.
+
+
lint.html.prefs
This property allows you to customize lint's HTML reports. It
+ consists of a comma separated list of property assignments, e.g.
+ ./gradlew :app:lintDebug -Dlint.html.prefs=theme=darcula,window=5
+
+
Property Explanation and Values Default
+ theme
light
, darcula
, solarized
light
+ window
Number of lines around problem 3
+ maxIncidents
Maximum incidents shown per issue type 50
+ splitLimit
Issue count before “More...” button 8
+ maxPerIssue
Name of split limit prior to 7.0 8
+ underlineErrors
If true, wavy underlines, else highlight true
+
+
+
+
+
lint.unused-resources.exclude-tests
Whether the unused resource check should exclude test sources as
+ referenced resources.
+
+
lint.configuration.override
Alias for $LINT_OVERRIDE_CONFIGURATION
+
+
lint.print-stacktrace
Alias for $LINT_PRINT_STACKTRACE
+
+
lint.do.not.reuse.uast.env
Alias for $LINT_DO_NOT_REUSE_UAST_ENV
+
+
android.lint.log-jar-problems
Controls whether lint will complain about custom check lint jar
+ loading problems. By default, true.
+
+
android.lint.api-database-binary-path
Point lint to a precomputed per-SDK platform, per-lint binary API
+ database to read from. If the file is not found or uses the wrong format
+ version, lint will fail.
+
+
android.lint.skip.bytecode.verifier
Alias for $ANDROID_LINT_SKIP_BYTECODE_VERIFIER
+
+
+
+ Corresponding system property: android.lint.skip.bytecode.verifier
+
+
+
\ No newline at end of file
diff --git a/docs/api-guide.md.html b/docs/api-guide.md.html
new file mode 100644
index 00000000..d95f9729
--- /dev/null
+++ b/docs/api-guide.md.html
@@ -0,0 +1,27 @@
+
+
+**Android Lint API Guide**
+
+This chapter inlines all the API documentation into a single
+long book, suitable for printing or reading on a tablet.
+
+ (insert api-guide/terminology.md.html here)
+ (insert api-guide/basics.md.html here)
+ (insert api-guide/example.md.html here)
+ (insert api-guide/ast-analysis.md.html here)
+ (insert api-guide/publishing.md.html here)
+ (insert api-guide/unit-testing.md.html here)
+ (insert api-guide/test-modes.md.html here)
+ (insert api-guide/quickfixes.md.html here)
+ (insert api-guide/partial-analysis.md.html here)
+ (insert api-guide/dataflow-analyzer.md.html here)
+ (insert api-guide/annotations.md.html here)
+ (insert api-guide/options.md.html here)
+ (insert api-guide/messages.md.html here)
+ (insert api-guide/faq.md.html here)
+
+ # Appendix: Recent Changes
+ (insert api-guide/changes.md.html here)
+ (insert usage/variables.md.html here)
+
+
diff --git a/docs/api-guide/annotations.md.html b/docs/api-guide/annotations.md.html
new file mode 100644
index 00000000..6422dfe2
--- /dev/null
+++ b/docs/api-guide/annotations.md.html
@@ -0,0 +1,427 @@
+
+
+# Annotations
+
+Annotations allow API authors to express constraints that tools can
+enforce. There are many examples of these, along with existing lint
+checks:
+
+* `@VisibleForTesting`: this API is considered private, and has been
+ exposed only for unit testing purposes
+* `@CheckResult`: anyone calling this method is expected to do
+ something with the return value
+* `@CallSuper`: anyone overriding this method must also invoke `super`
+* `@UiThread`: anyone calling this method must be calling from the UI thread
+* `@Size`: the size of the annotated array or collection must be
+ of a particular size
+* `@IntRange`: the annotated integer must have a value in the given range
+
+...and so on. Lint has built-in checks to enforce these, along with
+infrastructure to make them easy to write, and to share analysis such
+that improvements to one helps them all. This means that you can easily
+write your own annotations-based checks as well.
+
+!!! Tip
+ Note that the annotation support helps you write checks where you
+ check *usages* of annotated elements, not usages of the annotations
+ themselves. If you simply want to look at actual annotations,
+ override `getApplicableUastTypes` to return
+ `listOf(UAnnotation::class.java)`, and override `createUastHandler`
+ to return an `object : UElementHandler` which simply overrides
+ `visitAnnotation`.
+
+## Basics
+
+To create a basic annotation checker, there are two required steps:
+
+1. Register the fully qualified name (or names) of the annotation
+ classes you want to analyze, and
+2. Implement the `visitAnnotationUsage` callback for handling each
+ occurrence.
+
+Here's a basic example:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+override fun applicableAnnotations(): List {
+ return listOf("my.pkg.MyAnnotation")
+}
+
+override fun visitAnnotationUsage(
+ context: JavaContext,
+ element: UElement,
+ annotationInfo: AnnotationInfo,
+ usageInfo: AnnotationUsageInfo
+) {
+ val name = annotationInfo.qualifiedName.substringAfterLast('.')
+ val message = "`${usageInfo.type.name}` usage associated with " +
+ "`@$name` on ${annotationInfo.origin}"
+ val location = context.getLocation(element)
+ context.report(TEST_ISSUE, element, location, message)
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+All this simple detector does is flag any usage associated with the
+given annotation, including some information about the usage.
+
+If we for example have the following annotated API:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+annotation class MyAnnotation
+abstract class Book {
+ operator fun contains(@MyAnnotation word: String): Boolean = TODO()
+ fun length(): Int = TODO()
+ @MyAnnotation fun close() = TODO()
+}
+operator fun Book.get(@MyAnnotation index: Int): Int = TODO()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+...and we then run the above detector on the following test case:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+fun test(book: Book) {
+ val found = "lint" in book
+ val firstWord = book[0]
+ book.close()
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+we get the following output:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/book.kt:14: Error: METHOD_CALL_PARAMETER usage associated with @MyAnnotation on PARAMETER
+ val found = "lint" in book
+ ----
+src/book.kt:15: Error: METHOD_CALL_PARAMETER usage associated with @MyAnnotation on PARAMETER
+ val firstWord = book[0]
+ -
+src/book.kt:16: Error: METHOD_CALL usage associated with @MyAnnotation on METHOD
+ book.close()
+ -------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In the first case, the infix operator “in” will call `contains` under
+the hood, and here we've annotated the parameter, so lint visits the
+argument corresponding to that parameter (the literal string “lint”).
+
+The second case shows a similar situation where the array syntax will
+end up calling our extension method, `get()`.
+
+And the third case shows the most common scenario: a straightforward
+method call to an annotated method.
+
+In many cases, the above detector implementation is nearly all you have
+to do to enforce an annotation constraint. For example, in the
+`@CheckResult` detector, we want to make sure that anyone calling a
+method annotated with `@CheckResult` will not ignore the method return
+value. All the lint check has to do is register an interest in
+*`androidx.annotation.CheckResult`*, and lint will invoke
+`visitAnnotationUsage` for each method call to the annotated method.
+Then we just check the method call to make sure that its return value
+isn't ignored, e.g. that it's stored into a variable or passed into
+another method call.
+
+!!! Tip
+ In `applicableAnnotations`, you typically return the fully
+ qualified names of the annotation classes your detector is
+ targeting. However, in some cases, it's useful to match all
+ annotations of a given name; for example, there are many, many
+ variations of the `@Nullable` annotations, and you don't really
+ want to be in the business of keeping track of and listing all of
+ them here. Lint will also let you specify just the basename of an
+ annotation here, such as `"Nullable"`, and if so, annotations like
+ `androidx.annotation.Nullable` and
+ `org.jetbrains.annotations.Nullable` will both match.
+
+## Annotation Usage Types and isApplicableAnnotationUsage
+
+### Method Override
+
+In the detector above, we're including the “usage type” in the error
+message. The usage type tells you something about how the annotation is
+associated with the usage element -- and in the above, the first two
+cases have a usage type of “parameter” because the visited element
+corresponds to a parameter annotation, and the third one a method
+annotation.
+
+There are many other usage types. For example, if we add the following
+to the API:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+open class Paperback : Book() {
+ override fun close() { }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+then the detector will emit the following incident since the new method
+overrides another method that was annotated:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/book.kt:14: Error: METHOD_OVERRIDE usage associated with @MyAnnotation on METHOD
+ override fun close() { }
+ -----
+1 errors, 0 warnings
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Overriding an annotated element is how the `@CallSuper` detector is
+implemented, which makes sure that any method which overrides a method
+annotated with `@CallSuper` is invoking `super` on the overridden
+method somewhere in the method body.
+
+### Method Return
+
+Here's another example, where we have annotated the return value
+with @MyAnnotation:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+open class Paperback : Book() {
+ fun getDefaultCaption(): String = TODO()
+ @MyAnnotation
+ fun getCaption(imageId: Int): String {
+ if (imageId == 5) {
+ return "Blah blah blah"
+ } else {
+ return getDefaultCaption()
+ }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here, lint will flag the various exit points from the method
+associated with the annotation:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/book.kt:18: Error: METHOD_RETURN usage associated with @MyAnnotation on METHOD
+ return "Blah blah blah"
+ --------------
+src/book.kt:20: Error: METHOD_RETURN usage associated with @MyAnnotation on METHOD
+ return getDefaultCaption()
+ -------------------
+2 errors, 0 warnings
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Note also that this would have worked if the annotation had been
+inherited from a super method instead of being explicitly set here.
+
+One usage of this mechanism in Lint is the enforcement of return values
+in methods. For example, if a method has been marked with
+`@DrawableRes`, Lint will make sure that the returned value of that
+method will not be of an incompatible resource type (such as
+`@StringRes`).
+
+### Handling Usage Types
+
+As you can see, your callback will be invoked for a wide variety of
+usage types, and sometimes, they don't apply to the scenario that your
+detector is interested in. Consider the `@CheckResult` detector again,
+which makes sure that any calls to a given method will look at the
+return value. From the “method override” section above, you can see
+that lint would *also* notify your detector for any method that is
+*overriding* (rather than calling) a method annotated with
+`@CheckResult`. We don't want to report those.
+
+There are two ways to handle this. The first one is to check whether
+the usage element is a `UMethod`, which it will be in the overriding
+case, and return early in that case.
+
+The recommended approach, which `CheckResultDetector` uses, is to
+override the `isApplicableAnnotationUsage` method:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+override fun isApplicableAnnotationUsage(type: AnnotationUsageType): Boolean {
+ return type != AnnotationUsageType.METHOD_OVERRIDE &&
+ super.isApplicableAnnotationUsage(type)
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+!!! Tip
+ Notice how we are also calling `super` here and combining the result
+ instead of just using a hardcoded list of expected usage types. This
+ is because, as discussed below, lint already filters out some usage
+ types by default in the super implementation.
+
+### Usage Types Filtered By Default
+
+The default implementation of `Detector.isApplicableAnnotationUsage`
+looks like this:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+open fun isApplicableAnnotationUsage(type: AnnotationUsageType): Boolean {
+ return type != AnnotationUsageType.BINARY &&
+ type != AnnotationUsageType.EQUALITY
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+These usage types apply to cases where annotated elements are
+compared for equality or using other binary operators. Initially
+introducing this support led to a lot of noise and false positives;
+most of the existing lint checks do not want this, so they're opt-in.
+
+An example of a lint check which *does* enforce this is the
+`@HalfFloat` lint check. In Android, a
+[HalfFloat](https://developer.android.com/reference/androidx/annotation/
+ HalfFloat) is a representation of a floating point value (with less
+precision than a `float`) which is stored in a `short`, normally an
+integer primitive value. If you annotate a `short` with `@HalfFloat`,
+including in APIs, lint can help catch cases where you are making
+mistakes -- such as accidentally widening the value to an int, and so
+on. Here are some example error messages from lint's unit tests for the
+half float check:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/HalfFloatTest.java:23: Error: Expected a half float here, not a resource id [HalfFloat]
+ method1(getDimension1()); // ERROR
+ ---------------
+src/test/pkg/HalfFloatTest.java:43: Error: Half-float type in expression widened to int [HalfFloat]
+ int result3 = float1 + 1; // error: widening
+ ------
+src/test/pkg/HalfFloatTest.java:50: Error: Half-float type in expression widened to int [HalfFloat]
+ Math.round(float1); // Error: should use Half.round
+ ------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+### Scopes
+
+Many annotations apply not just to methods or fields but to classes and
+even packages, with the idea that the annotation applies to everything
+within the package.
+
+For example, if we have this annotated API:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+annotation class ThreadSafe
+annotation class NotThreadSafe
+
+@ThreadSafe
+abstract class Stack {
+ abstract fun size(): Int
+ abstract fun push(item: T)
+ abstract fun pop(): String
+ @NotThreadSafe fun save() { }
+
+ @NotThreadSafe
+ abstract class FileStack : Stack() {
+ abstract override fun pop(): String
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+And the following test case:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+fun test(stack: Stack, fileStack: Stack) {
+ stack.push("Hello")
+ stack.pop()
+ fileStack.push("Hello")
+ fileStack.pop()
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here, `stack.push` call on line 2 resolves to the API method on line 7.
+That method is not annotated, but it's inside a class that is annotated
+with `@ThreadSafe`. Similarly for the `pop()` call on line 3.
+
+The `fileStack.push` call on line 4 also resolves to the same method
+as the call on line 2 (even though the concrete type is a `FileStack`
+instead of a `Stack`), so like on line 2, this call is taken to be
+thread safe.
+
+However, the `fileStack.pop` call on line 6 resolves to the API method
+on line 14. That method is not annotated, but it's inside a class
+annotated with `@NotThreadSafe`, which in turn is inside an outer class
+annotated with `@ThreadSafe`. The intent here is clearly that that
+method should be considered not thread safe.
+
+To help with scenarios like this, lint will provide *all* the
+annotations (well, all annotations that any lint checks have registered
+interest in via `getApplicableAnnotations`; it will not include
+annotations like `java.lang.SuppressWarnings` and so on unless a lint
+check asks for it).
+
+This is provided in the `AnnotationUsageInfo` passed to the
+`visitAnnotationUsage` parameters. The `annotations` list will include
+all relevant annotations, **in scope order**. That means that for the
+above `pop` call on line 5, it will point to first the annotations on
+the `pop` method (and here there are none), then the `@NotThreadSafe`
+annotation on the surrounding class, and then the `@ThreadSafe`
+annotation on the outer class, and then annotations on the file itself
+and the package.
+
+The `index` points to the annotation we're analyzing. If for example
+our detector had registered an interest in `@ThreadSafe`, it would be
+called for the second `pop` call as well, since it calls a method
+inside a `@ThreadSafe` annotation (on the outer class), but the `index`
+would be 1. The lint check can check all the annotations earlier than
+the one at the index to see if they “counteract” the annotation, which
+of course the `@NotThreadSafe` annotation does.
+
+Lint uses this mechanism for example for the `@CheckResult` annotation,
+since some APIs are annotated with `@CheckResult` for whole packages
+(as an API convention), and then there are explicit exceptions carved
+out using `@CanIgnoreReturnValue`. There is a method on the
+`AnnotationUsageInfo`, `anyCloser`, which makes this check easy:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+if (usageInfo.anyCloser { it.qualifiedName ==
+ "com.google.errorprone.annotations.CanIgnoreReturnValue" }) {
+ // There's a closer @CanIgnoreReturnValue which cancels the
+ // outer @CheckReturnValue annotation we're analyzing here
+ return
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+!!! Tip
+ You only have to worry about this when there are different
+ annotations that interact with each other. If the same annotation is
+ found in multiple nested contexts, lint *will* include all the
+ annotations in the `AnnotationUsageInfo`, but it will not invoke
+ your callback for any outer occurrences; only the closest one. This
+ is usually what detectors expect: the innermost one “overrides” the
+ outer ones, so lint omits these to help avoid false positives where
+ a lint check author forgot to handle and test this scenario. A good
+ example of this situation is with the `@RequiresApi` annotation; a
+ class may be annotated as requiring a particular API level, but a
+ specific inner class or method within the class can have a more
+ specific `@RequiresApi` annotation, and we only want the detector to
+ be invoked for the innermost one. If for some reason your detector
+ *does need* to handle all of the repeated outer occurrences, note
+ that they're all there in the `annotations` list for the
+ `AnnotationUsageInfo` so you can look for them and handle them when
+ you are invoked for the innermost one.
+
+### Inherited Annotations
+
+As we saw in the method overrides section, lint will include
+annotations in the hierarchy: annotations specified not just on a
+specific method but super implementations and so on.
+
+This is normally what you want -- for example, if a method is annotated
+with `@CheckResult` (such as `String.trim()`, where it's important to
+understand that you're not changing the string in place, there's a new
+string returned so it's probably a mistake to not use it), you probably
+want any overriding implementations to have the same semantics.
+
+However, there are exceptions to this. For example,
+`@VisibleForTesting`. Perhaps a super class made a method public only
+for testing purposes, but you have a concrete subclass where you are
+deliberately supporting the operation, not just from tests. If
+annotations were always inherited, you would have to create some sort
+of annotation to “revert” the semantics, e.g.
+`@VisibleNotJustForTesting`, which would require a lot of noisy
+annotations.
+
+Lint lets you specify the inheritance behavior of individual
+annotations. For example, the lint check which enforces the
+`@VisibleForTesting` and `@RestrictTo` annotations handles it like this:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+override fun inheritAnnotation(annotation: String): Boolean {
+ // Require restriction annotations to be annotated everywhere
+ return false
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(Note that the API passes in the fully qualified name of the annotation
+in question so you can control this behavior individually for each
+annotation when your detector applies to multiple annotations.)
+
+
diff --git a/docs/api-guide/ast-analysis.md.html b/docs/api-guide/ast-analysis.md.html
new file mode 100644
index 00000000..d2e27c6b
--- /dev/null
+++ b/docs/api-guide/ast-analysis.md.html
@@ -0,0 +1,809 @@
+
+
+# AST Analysis
+
+To analyze Kotlin and Java files, lint offers many convenience callbacks
+to make it simple to accomplish common tasks:
+
+* Check calls to a particular method name
+* Instantiating a particular class
+* Extending a particular super class or interface
+* Using a particular annotation, or calling an annotated method
+
+And more. See the `SourceCodeScanner` interface for more information.
+
+It also has various helpers, such as a `ConstantEvaluator` and a
+`DataFlowAnalyzer` to help analyze code.
+
+But in some cases, you'll need to dig in and analyze the “AST” yourself.
+
+## AST Analysis
+
+AST is short for “Abstract Syntax Tree” -- a tree representation of the
+source code. Consider the following very simple Java program:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java
+// MyTest.java
+package test.pkg;
+
+public class MyTest {
+ String s = "hello";
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here's the AST for the above program, the way it's represented
+internally in IntelliJ.
+
+
+
+This is actually a simplified view; in reality, there are also
+whitespace nodes tracking all the spans of whitespace characters between
+these nodes.
+
+Anyway, you can see there is quite a bit of detail here -- tracking
+things like the keywords, the variables, references to for example the
+package -- and higher level concepts like a class and a field, which I've
+marked with a thicker border.
+
+Here's the corresponding Kotlin program:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+// MyTest.kt
+package test.pkg
+
+class MyTest {
+ val s: String = "hello"
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+And here's the corresponding AST in IntelliJ:
+
+
+
+This program is equivalent to the Java one.
+But notice that it has a completely different shape! They reference
+different element classes, `PsiClass` versus `KtClass`, and on and on
+all the way down.
+
+But there's some commonality -- they each have a node for the file, for
+the class, for the field, and for the initial value, the string.
+
+## UAST
+
+We can construct a new AST that represents the same concepts:
+
+
+
+This is a unified AST, in something called “UAST”, short for Unified
+Abstract Syntax Tree. UAST is the primary AST representation we use for
+code in Lint. All the node classes here are prefixed with a capital U,
+for UAST. And this is the UAST for the first Java file example above.
+
+Here's the UAST for the corresponding Kotlin example:
+
+
+
+As you can see, the ASTs are not always identical. For Strings, in
+Kotlin, we often end up with an extra parent `UInjectionHost`. But for
+our purposes, you can see that the ASTs are mostly the same, so if you
+handle the Kotlin scenario, you'll handle the Java ones too.
+
+## UAST: The Java View
+
+Note that “Unified” in the name here is a bit misleading. From the name
+you may assume that this is some sort of superset of the ASTs across
+languages -- an AST that can represent everything needed by all
+languages. But that's not the case! Instead, a better way to think of it
+is as the **Java view** of the AST.
+
+If you for example have the following Kotlin data class:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+data class Person(
+ var id: String,
+ var name: String
+)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This is a Kotlin data class with two properties. So you might expect
+that UAST would have a way to represent these concepts. This should
+be a `UDataClass` with two `UProperty` children, right?
+
+But Java doesn't support properties. If you try to access a `Person`
+instance from Java, you'll notice that it exposes a number of public
+methods that you don't see there in the Kotlin code -- in addition to
+`getId`, `setId`, `getName` and `setName`, there's also `component1` and
+`component2` (for destructuring), and `copy`.
+
+These methods are directly callable from Java, so they show up in UAST,
+and your analysis can reason about them.
+
+Consider another complete Kotlin source file, `test.kt`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+var property = 0
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here's the UAST representation:
+
+
+
+Here we have a very simple Kotlin file -- for a single Kotlin property.
+But notice at the UAST level, there's no such thing as top level methods
+and properties. In Java, everything is a class, so `kotlinc` will create
+a “facade class”, using the filename plus “Kt”. So we see our `TestKt`
+class. And there are three members here. There's the getter and the
+setter for this property, as `getProperty` and `setProperty`. And then
+there is the private field itself, where the property is stored.
+
+This all shows up in UAST. It's the Java view of the Kotlin code. This
+may seem limiting, but in practice, for most lint checks, this is
+actually what you want. This makes it easy to reason about calls to APIs
+and so on.
+
+## Expressions
+
+You may be getting the impression that the UAST tree is very shallow and
+only represents high level declarations, like files, classes, methods
+and properties.
+
+That's not the case. While it **does** skip low-level, language-specific
+details things like whitespace nodes and individual keyword nodes, all
+the various expression types are represented and can be reasoned about.
+Take the following expression:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+if (s.length > 3) 0 else s.count { it.isUpperCase() }
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This maps to the following UAST tree:
+
+
+
+As you can see it's modeling the if, the comparison, the lambda, and so
+on.
+
+## UElement
+
+Every node in UAST is a subclass of a `UElement`. There's a parent
+pointer, which is handy for navigating around in the AST.
+
+The real skill you need for writing lint checks is understanding the
+AST, and then doing pattern matching on it. And a simple trick for this
+is to create the Kotlin or Java code you want, in a unit test, and then
+in your detector, recursively print out the UAST as a tree.
+
+Or in the debugger, anytime you have a `UElement`, you can call
+`UElement.asRecursiveLogString` on it, evaluate and see what you find.
+
+For example, for the following Kotlin code:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+import java.util.Date
+fun test() {
+ val warn1 = Date()
+ val ok = Date(0L)
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+here's the corresponding UAST `asRecursiveLogString` output:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+UFile (package = )
+ UImportStatement (isOnDemand = false)
+ UClass (name = JavaTest)
+ UMethod (name = test)
+ UBlockExpression
+ UDeclarationsExpression
+ ULocalVariable (name = warn1)
+ UCallExpression (kind = UastCallKind(name='constructor_call'), …
+ USimpleNameReferenceExpression (identifier = Date)
+ UDeclarationsExpression
+ ULocalVariable (name = ok)
+ UCallExpression (kind = UastCallKind(name='constructor_call'), …
+ USimpleNameReferenceExpression (identifier = Date)
+ ULiteralExpression (value = 0)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+## Visiting
+
+You generally shouldn't visit a source file on your own. Lint has a
+special `UElementHandler` for that, which is used to ensure we don't
+repeat visiting a source file thousands of times, one per detector.
+
+But when you're doing local analysis, you sometimes need to visit a
+subtree.
+
+To do that, just extend `AbstractUastVisitor` and pass the visitor to
+the `accept` method of the corresponding `UElement`.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+method.accept(object : AbstractUastVisitor() {
+ override fun visitSimpleNameReferenceExpression(node: USimpleNameReferenceExpression): Boolean {
+ // your code here
+ return super.visitSimpleNameReferenceExpression(node)
+ }
+})
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In a visitor, you generally want to call `super` as shown above. You can
+also `return true` if you've “seen enough” and can stop visiting the
+remainder of the AST.
+
+If you're visiting Java PSI elements, you use a
+`JavaRecursiveElementVisitor`, and in Kotlin PSI, use a `KtTreeVisitor`.
+
+## UElement to PSI Mapping
+
+UAST is built on top of PSI, and each `UElement` has a `sourcePsi`
+property (which may be null). This lets you map from the general UAST
+node, down to the specific PSI elements.
+
+Here's an illustration of that:
+
+
+
+We have our UAST tree in the top right corner. And here's the Java PSI
+AST behind the scenes. We can access the underlying PSI node for a
+`UElement` by accessing the `sourcePsi` property. So when you do need to dip
+into something language specific, that's trivial to do.
+
+Note that in some cases, these references are null.
+
+Most `UElement` nodes point back to the PSI AST - whether a Java
+AST or a Kotlin AST. Here's the same AST, but with the **type** of the
+`sourcePsi` property for each node added.
+
+
+
+You can see that the facade class generated to contain the top level
+functions has a null `sourcePsi`, because in the
+Kotlin PSI, there is no real `KtClass` for a facade class. And for the
+three members, the private field and the getter and the setter, they all
+correspond to the exact same, single `KtProperty` instance, the single
+node in the Kotlin PSI that these methods were generated from.
+
+## PSI to UElement
+
+In some cases, we can also map back to UAST from PSI elements, using the `toUElement` extension function.
+
+For example, let's say we resolve a method call. This returns a
+`PsiMethod`, not a `UMethod`. But we can get the corresponding `UMethod`
+using the following:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+val resolved = call.resolve() ?: return
+val uDeclaration = resolve.toUElement()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Note however that `toUElement` may return null. For example, if you've
+resolved to a method call that is compiled (which you can check using
+`resolved is PsiCompiledElement`), UAST cannot convert it.
+
+## UAST versus PSI
+
+UAST is the preferred AST to use when you're writing lint checks for
+Kotlin and Java. It lets you reason about things that are the same
+across the languages. Declarations. Function calls. Super classes.
+Assignments. If expressions. Return statements. And on and on.
+
+There *are* lint checks that are language specific -- for example, if
+you write a lint check that forbids the use of companion objects -- in
+that case, there's no big advantage to using UAST over PSI; it's only
+ever going to run on Kotlin code. (Note however that lint's APIs and
+convenience callbacks are all targeting UAST, so it's easier to write
+UAST lint checks even for the language-specific checks.)
+
+The vast majority of lint checks however aren't language specific,
+they're **API** or bug pattern specific. And if the API can be called
+from Java, you want your lint check to not only flag problems in Kotlin,
+but in Java code as well. You don't want to have to write the lint check
+twice -- so if you use UAST, a single lint check can work for both. But
+while you generally want to use UAST for your analysis (and lint's APIs
+are generally oriented around UAST), there **are** cases where it's
+appropriate to dip into PSI.
+
+In particular, you should use PSI when you're doing something highly
+language specific, and where the language details aren't exposed in UAST.
+
+For example, let's say you need to determine if a `UClass` is a Kotlin
+“companion object”. You could cheat and look at the class name to see if
+it's “Companion”. But that's not quite right; in Kotlin you can
+specify a custom companion object name, and of course users are free
+to create classes named “Companion” that aren't companion objects:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+class Test {
+ companion object MyName { // Companion object not named "Companion"!
+ }
+
+ object Companion { // Named "Companion" but not a companion object!
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The right way to do this is using Kotlin PSI, via the
+`UElement.sourcePsi` property:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+// Skip companion objects
+val source = node.sourcePsi
+if (source is KtObjectDeclaration && source.isCompanion()) {
+ return
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(To figure out how to write the above code, use a debugger on a test
+case and look at the `UClass.sourcePsi` property; you'll discover that
+it's some subclass of `KtObjectDeclaration`; look up its most general
+super interface or class, and then use code completion to discover
+available APIs, such as `isCompanion()`.)
+
+## Kotlin Analysis API
+
+Using Kotlin PSI was the state of the art for correctly analyzing Kotlin
+code until recently. But when you look at the PSI, you'll discover that
+some things are really hard to accomplish -- in particular, resolving
+reference, and dealing with Kotlin types.
+
+Lint doesn't actually give you access to everything you need if you want
+to try to look up types in Kotlin PSI; you need something called the
+“binding context”, which is not exposed anywhere! And this omission is
+deliberate, because this is an implementation detail of the old
+compiler. The future is K2; a complete rewrite of the compiler front
+end, which is no longer using the old binding context. And as part of
+the tooling support for K2, there's a new API called the “Kotlin
+Analysis API” you can use to dig into details about Kotlin.
+
+For most lint checks, you should just use UAST if you can. But when you
+need to know really **detailed** Kotlin information, especially around
+types, and smart casts, and null inference, and so on, the Kotlin
+Analysis API is your best friend (and only option...)
+
+!!! WARNING
+ The Kotlin Analysis API is not yet final and may continue to change.
+ In fact, most of the symbols have been renamed recently. For example,
+ the `KtAnalysisSession` returned by `analyze`, has been renamed
+ `KaSession`. Most APIs now have the prefix `Ka`.
+
+### Nothing Type?
+
+Here's a simple example:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+fun testTodo() {
+ if (SDK_INT < 11) {
+ TODO() // never returns
+ }
+ val actionBar = getActionBar() // OK - SDK_INT must be >= 11 !
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here we have a scenario where we know that the TODO call will never
+return, and lint can take advantage of that when analyzing the control
+flow -- in particular, it should understand that after the TODO() call
+there's no chance of fallthrough, so it can conclude that SDK_INT must
+be at least 11 after the if block.
+
+The way the Kotlin compiler can reason about this is that the `TODO`
+method in the standard library has a return type of `Nothing`.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+@kotlin.internal.InlineOnly
+public inline fun TODO(): Nothing = throw NotImplementedError()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The `Nothing` return type means it will never return.
+
+Before the Kotlin lint analysis API, lint didn't have a way to reason
+about the `Nothing` type. UAST only returns Java types, which maps to
+void. So instead, lint had an ugly hack that just hardcoded well known
+names of methods that don't return:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+if (nextStatement is UCallExpression) {
+ val methodName = nextStatement.methodName
+ if (methodName == "fail" || methodName == "error" || methodName == "TODO") {
+ return true
+ }
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+However, with the Kotlin analysis API, this is easy:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+fun callNeverReturns(call: UCallExpression): Boolean {
+ val sourcePsi = call.sourcePsi as? KtCallExpression ?: return false
+ analyze(sourcePsi) {
+ val callInfo = sourcePsi.resolveToCall() ?: return false
+ val returnType = callInfo.singleFunctionCallOrNull()?.symbol?.returnType
+ return returnType != null && returnType.isNothingType
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Older APIs (pre-8.7.0-alpha04):
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+/**
+ * Returns true if this [call] node calls a method known to never
+ * return, such as Kotlin's standard library method "error".
+ */
+fun callNeverReturns(call: UCallExpression): Boolean {
+ val sourcePsi = call.sourcePsi as? KtCallExpression ?: return false
+ analyze(sourcePsi) {
+ val callInfo = sourcePsi.resolveCall() ?: return false
+ val returnType = callInfo.singleFunctionCallOrNull()?.symbol?.returnType
+ return returnType != null && returnType.isNothing
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The entry point to all Kotlin Analysis API usages is to call the
+`analyze` method (see line 7) and pass in a Kotlin PSI element. This
+creates an “analysis session”. **It's very important that you don't leak
+objects from inside the session out of it** -- to avoid memory leaks and
+other problems. If you do need to hold on to a symbol and compare later,
+you can create a special symbol pointer.
+
+Anyway, there's a huge number of extension methods that take an analysis
+session as receiver, so inside the lambda on lines 7 to 13, there are
+many new methods available.
+
+Here, we have a `KtCallExpression`, and inside the `analyze` block we
+can call `resolveCall()` on it to reach the called method's symbol.
+
+Similarly, on a `KtDeclaration` (such as a named function or property) I
+can call `.symbol` to get the symbol for that method or property, to
+for example look up parameter information. And on a `KtExpression` (such
+as an if statement) I can call `.expressionType` to get the Kotlin type.
+
+`KaSymbol` and `KaType` are the basic primitives we're working with in
+the Kotlin Analysis API. There are a number of subclasses of symbol,
+such as `KaFileSymbol`, `KaFunctionSymbol`, `KaClassSymbol`, and
+so on.
+
+In the new implementation of `callNeverReturns`, we resolve the call,
+look up the corresponding function, which of course is a `KaSymbol`
+itself, and from that we get the return type, and then we can just check
+if it's the `Nothing` type.
+
+And this API works both with the old Kotlin compiler, used in lint right
+now, and K2, which can be turned on via a flag and will soon be the
+default (and may well be the default when you read this; we don't always
+remember to update the documentation...)
+
+### Compiled Metadata
+
+Accessing Kotlin-specific knowledge not available via Kotlin PSI is one
+use for the analysis API.
+
+Another big advantage of the Kotlin analysis API is that it gives you
+access to reason about compiled Kotlin code, in the same way that the
+compiler does.
+
+Normally, when you resolve with UAST, you just get a plain `PsiMethod`
+back. For example, if we have a reference to
+`kotlin.text.HexFormat.Companion`, and we resolve it in UAST, we get a
+`PsiMethod` back. This is **not** a Kotlin PSI element, so our earlier
+code to check if this is a companion object (`source is
+KtObjectDeclaration && source.isCompanion()`) does not work -- the first
+instance check fails. These compiled `PsiElement`s do not give us access
+to any of the special Kotlin payload we can usually check on
+`KtElement`s -- modifiers like `inline` or `infix`, default parameters,
+and so on.
+
+The analysis API handles this properly, even for compiled code. In fact,
+the earlier implementation of checking for the `Nothing` type
+demonstrated this, because the methods it's analyzing from the Kotlin
+standard library (`error`, `TODO`, and so on), are all compiled classes
+in the Kotlin standard library jar file!
+
+Therefore, yes, we can use Kotlin PSI to check if a class is a companion
+object if we actually have the source code for the class. But if we're
+resolving a *reference* to a class, using the Kotlin analysis API is
+better; it will work for both source and compiled:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+symbol is KaClassSymbol && symbol.classKind == KaClassKind.COMPANION_OBJECT
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Older APIs (pre-8.7.0-alpha04):
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+symbol is KtClassOrObjectSymbol && symbol.classKind == KtClassKind.COMPANION_OBJECT
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+#### Kotlin Analysis API Howto
+
+When you're using K2 with lint, a lot of UAST's handling of resolve and
+types in Kotlin is actually using the analysis API behind the scenes.
+
+If you for example have a Kotlin PSI `KtThisExpression`, and you want to
+understand how to resolve the `this` reference to another PSI element,
+write the following Kotlin UAST code:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+thisReference.toUElement()?.tryResolve()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can now use a debugger to step into the `tryResolve` call, and
+you'll eventually wind up in code using the Kotlin Analysis API to look
+it up, and as it turns out, here's how:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+analyze(expression) {
+ val reference = expression.getTargetLabel()?.mainReference
+ ?: expression.instanceReference.mainReference
+ val psi = reference.resolveToSymbol()?.psi
+ …
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+### Configuring lint to use K2
+
+To use K2 from a unit test, you can use the following lint test task override:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+override fun lint(): TestLintTask {
+ return super.lint().configureOptions { flags -> flags.setUseK2Uast(true) }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Outside of tests, you can also set the `-Dlint.use.fir.uast=true` system property in your run configurations.
+
+Note that at some point this flag may go away since we'll be switching
+over to K2 completely.
+
+## API Compatibility
+
+Versions of lint before 8.7.0-alpha04 used an older version of the
+analysis API. If your lint check is building against these older
+versions, you need to use the older names and APIs, such as
+`KtSymbol` and `KtType` instead of `KaSymbol` and `KaType`.
+
+The analysis API isn't stable, and changed significantly between
+these versions. The hope/plan is for the API to be stable soon, such
+that you can start using the analysis API in lint checks and have it
+work with future versions of lint.
+
+For now, lint uses a special bytecode rewriter on the fly to try to
+automatically migrate compiled lint checks using the older API, but
+this doesn't handle all corner cases, so the best path forward is to
+use the new APIs. In the below recipes, we're temporarily showing both
+the new and the old versions.
+
+## Recipes
+
+Here are various other Kotlin Analysis scenarios and potential solutions:
+
+### Resolve a function call
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+val call: KtCallExpression
+…
+analyze(call) {
+ val callInfo = call.resolveToCall() ?: return null
+ val symbol: KaFunctionSymbol? = callInfo.singleFunctionCallOrNull()?.symbol
+ ?: callInfo.singleConstructorCallOrNull()?.symbol
+ ?: callInfo.singleCallOrNull()?.symbol
+ …
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Older APIs (pre-8.7.0-alpha04):
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+val call: KtCallExpression
+…
+analyze(call) {
+ val callInfo = call.resolveCall()
+ if (callInfo != null) {
+ val symbol: KtFunctionLikeSymbol = callInfo.singleFunctionCallOrNull()?.symbol
+ ?: callInfo.singleConstructorCallOrNull()?.symbol
+ ?: callInfo.singleCallOrNull()?.symbol
+ …
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+### Resolve a variable reference
+
+Also use `resolveCall`, though it's not really a call:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+val expression: KtNameReferenceExpression
+…
+analyze(expression) {
+ val symbol: KaVariableSymbol? = expression.resolveToCall()?.singleVariableAccessCall()?.symbol
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Older APIs (pre-8.7.0-alpha04):
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+val expression: KtNameReferenceExpression
+…
+analyze(expression) {
+ val symbol: KtVariableLikeSymbol = expression.resolveCall()?.singleVariableAccessCall()?.symbol
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+### Get the containing class of a symbol
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+val containingSymbol = symbol.containingSymbol
+if (containingSymbol is KaNamedClassSymbol) {
+ …
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Older APIs (pre-8.7.0-alpha04):
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+val containingSymbol = symbol.getContainingSymbol()
+if (containingSymbol is KtNamedClassOrObjectSymbol) {
+ …
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+### Get the fully qualified name of a class
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+val containing = declarationSymbol.containingSymbol
+if (containing is KaClassSymbol) {
+ val fqn = containing.classId?.asSingleFqName()
+ …
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Older APIs (pre-8.7.0-alpha04):
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+val containing = declarationSymbol.getContainingSymbol()
+if (containing is KtClassOrObjectSymbol) {
+ val fqn = containing.classIdIfNonLocal?.asSingleFqName()
+ …
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+### Look up the deprecation status of a symbol
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+if (symbol is KaDeclarationSymbol) {
+ symbol.deprecationStatus?.let { … }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Older APIs (pre-8.7.0-alpha04):
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+if (symbol is KtDeclarationSymbol) {
+ symbol.deprecationStatus?.let { … }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+### Look up visibility
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+if (symbol is KaDeclarationSymbol) {
+ if (!isPublicApi(symbol)) {
+ …
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Older APIs (pre-8.7.0-alpha04):
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+if (symbol is KtSymbolWithVisibility) {
+ val visibility = symbol.visibility
+ if (!visibility.isPublicAPI) {
+ …
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+### Get the KtType of a class symbol
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+if (symbol is KaNamedClassSymbol) {
+ val type = symbol.defaultType
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Older APIs (pre-8.7.0-alpha04):
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+containingSymbol.buildSelfClassType()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+### Resolve a KtType into a class
+
+Example: is this `KtParameter` pointing to an interface?
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+analyze(ktParameter) {
+ val parameterSymbol = ktParameter.symbol
+ val returnType = parameterSymbol.returnType
+ val typeSymbol = returnType.expandedSymbol
+ if (typeSymbol is KaClassSymbol) {
+ val classKind = typeSymbol.classKind
+ if (classKind == KaClassKind.INTERFACE) {
+ …
+ }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Older APIs (pre-8.7.0-alpha04):
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+analyze(ktParameter) {
+ val parameterSymbol = ktParameter.getParameterSymbol()
+ val returnType = parameterSymbol.returnType
+ val typeSymbol = returnType.expandedClassSymbol
+ if (typeSymbol is KtClassOrObjectSymbol) {
+ val classKind = typeSymbol.classKind
+ if (classKind == KtClassKind.INTERFACE) {
+ …
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+### See if two types refer to the same raw class (erasure):
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+if (type1 is KaClassType && type2 is KaClassType &&
+ type1.classId == type2.classId
+) {
+ …
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Older APIs (pre-8.7.0-alpha04):
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+if (type1 is KtNonErrorClassType && type2 is KtNonErrorClassType &&
+ type1.classId == type2.classId) {
+ …
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+### For an extension method, get the receiver type:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+if (declarationSymbol is KaNamedFunctionSymbol) {
+ val declarationReceiverType = declarationSymbol.receiverParameter?.type
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Older APIs (pre-8.7.0-alpha04):
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+if (declarationSymbol is KtFunctionSymbol) {
+ val declarationReceiverType = declarationSymbol.receiverParameter?.type
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+### Get the PsiFile containing a symbol declaration
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+val file = symbol.containingFile
+if (file != null) {
+ val psi = file.psi
+ if (psi is PsiFile) {
+ …
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Older APIs (pre-8.7.0-alpha04):
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+val file = symbol.getContainingFileSymbol()
+if (file is KtFileSymbol) {
+val psi = file.psi
+if (psi is PsiFile) {
+ …
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
diff --git a/docs/api-guide/basics.md.html b/docs/api-guide/basics.md.html
new file mode 100644
index 00000000..e61e03c4
--- /dev/null
+++ b/docs/api-guide/basics.md.html
@@ -0,0 +1,1147 @@
+
+
+# Writing a Lint Check: Basics
+
+## Preliminaries
+
+(If you already know a lot of the basics but you're here because you've
+run into a problem and you're consulting the docs, take a look at the
+frequently asked questions chapter.)
+
+### “Lint?”
+
+The `lint` tool shipped with the C compiler and provided additional
+static analysis of C code beyond what the compiler checked.
+
+Android Lint was named in honor of this tool, and with the Android
+prefix to make it really clear that this is a static analysis tool
+intended for analysis of Android code, provided by the Android Open
+Source Project -- and to disambiguate it from the many other tools with
+“lint” in their names.
+
+However, since then, Android Lint has broadened its support and is no
+longer intended only for Android code. In fact, within Google, it is
+used to analyze all Java and Kotlin code. One of the reasons for this
+is that it can easily analyze both Java and Kotlin code without having
+to implement the checks twice. Additional features are described in the
+[features](../features.html.md) chapter.
+
+We're planning to rename lint to reflect this new role, so we are
+looking for good name suggestions.
+
+### API Stability
+
+Lint's APIs are not stable, and a large part of Lint's API surface is
+not under our control (such as UAST and PSI). Therefore, custom lint
+checks may need to be updated periodically to keep working.
+
+However, “some APIs are more stable than others”. In particular, the
+detector API (described below) is much less likely to change than the
+client API (which is not intended for lint check authors but for tools
+integrating lint to run within, such as IDEs and build systems).
+
+However, this doesn't mean the detector API won't change. A large part
+of the API surface is external to lint; it's the AST libraries (PSI and
+UAST) for Java and Kotlin from JetBrains; it's the bytecode library
+(asm.ow2.io), it's the XML DOM library (org.w3c.dom), and so on. Lint
+intentionally stays up to date with these, so any API or behavior
+changes in these can affect your lint checks.
+
+Lint's own APIs may also change. The current API has grown organically
+over the last 10 years (the first version of lint was released in 2011)
+and there are a number of things we'd clean up and do differently if
+starting over. Not to mention rename and clean up inconsistencies.
+
+However, lint has been pretty widely adopted, so at this point creating
+a nicer API would probably cause more harm than good, so we're limiting
+recent changes to just the necessary ones. An example of this is the
+new [partial analysis](partial-analysis.md.html) architecture in 7.0
+which is there to allow much better CI and incremental analysis
+performance.
+
+### Kotlin
+
+We recommend that you implement your checks in Kotlin. Part of
+the reason for that is that the lint API uses a number of Kotlin
+features:
+
+* **Named and default parameters**: Rather than using builders, some
+ construction methods, like `Issue.create()` have a lot of parameters
+ with default parameters. The API is cleaner to use if you just
+ specify what you need and rely on defaults for everything else.
+
+* **Compatibility**: We may add additional parameters over time. It
+ isn't practical to add @JvmOverloads on everything.
+
+* **Package-level functions**: Lint's API includes a number of package
+ level utility functions (in previous versions of the API these are all
+ thrown together in a `LintUtils` class).
+
+* **Deprecations**: Kotlin has support for simple API migrations. For
+ example, in the below example, the new `@Deprecated` annotation on
+ lines 1 through 7 will be added in an upcoming release, to ease
+ migration to a new API. IntelliJ can automatically quickfix these
+ deprecation replacements.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+@Deprecated(
+ "Use the new report(Incident) method instead, which is more future proof",
+ ReplaceWith(
+ "report(Incident(issue, message, location, null, quickfixData))",
+ "com.android.tools.lint.detector.api.Incident"
+ )
+)
+@JvmOverloads
+open fun report(
+ issue: Issue,
+ location: Location,
+ message: String,
+ quickfixData: LintFix? = null
+) {
+ // ...
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+As of 7.0, there is more Kotlin code in lint than remaining Java
+code:
+
+Language | files | blank | comment | code
+-------------|------:|--------:|--------:|------:
+Kotlin | 420 | 14243 | 23239 | 130250
+Java | 289 | 8683 | 15205 | 101549
+ [`$ cloc lint/`]
+
+And that's for all of lint, including many old lint detectors which
+haven't been touched in years. In the Lint API library,
+`lint/libs/lint-api`, the code is 78% Kotlin and 22% Java.
+
+## Concepts
+
+Lint will search your source code for problems. There are many types of
+problems, and each one is called an `Issue`, which has associated
+metadata like a unique id, a category, an explanation, and so on.
+
+Each instance that it finds is called an “incident”.
+
+The actual responsibility of searching for and reporting incidents is
+handled by detectors -- subclasses of `Detector`. Your lint check will
+extend `Detector`, and when it has found a problem, it will “report”
+the incident to lint.
+
+A `Detector` can analyze more than one `Issue`. For example, the
+built-in `StringFormatDetector` analyzes formatting strings passed to
+`String.format()` calls, and in the process of doing that discovers
+multiple unrelated issues -- invalid formatting strings, formatting
+strings which should probably use the plurals API instead, mismatched
+types, and so on. The detector could simply have a single issue called
+“StringFormatProblems” and report everything as a StringFormatProblem,
+but that's not a good idea. Each of these individual types of String
+format problems should have their own explanation, their own category,
+their own severity, and most importantly should be individually
+configurable by the user such that they can disable or promote one of
+these issues separately from the others.
+
+A `Detector` can indicate which sets of files it cares about. These are
+called “scopes”, and the way this works is that when you register your
+`Issue`, you tell that issue which `Detector` class is responsible for
+analyzing it, as well as which scopes the detector cares about.
+
+If for example a lint check wants to analyze Kotlin files, it can
+include the `Scope.JAVA_FILE` scope, and now that detector will be
+included when lint processes Java or Kotin files.
+
+!!! Tip
+ The name `Scope.JAVA_FILE` may make it sound like there should also
+ be a `Scope.KOTLIN_FILE`. However, `JAVA_FILE` here really refers to
+ both Java and Kotlin files since the analysis and APIs are identical
+ for both (using “UAST”, a unified abstract syntax tree). However,
+ at this point we don't want to rename it since it would break a lot
+ of existing checks. We might introduce an alias and deprecate this
+ one in the future.
+
+When detectors implement various callbacks, they can analyze the
+code, and if they find a problematic pattern, they can “report”
+the incident. This means computing an error message, as well as
+a “location”. A “location” for an incident is really an error
+range -- a file, and a starting offset and an ending offset. Locations
+can also be linked together, so for example for a “duplicate
+declaration” error, you can and should include both locations.
+
+Many detector methods will pass in a `Context`, or a more specific
+subclass of `Context` such as `JavaContext` or `XmlContext`. This
+allows lint to give the detectors information they may need, without
+passing in a lot of parameters. It also allows lint to add additional data
+over time without breaking signatures.
+
+The `Context` classes also provide many convenience APIs. For example,
+for `XmlContext` there are methods for creating locations for XML tags,
+XML attributes, just the name part of an XML attribute, and just the
+value part of an XML attribute. For a `JavaContext` there are also
+methods for creating locations, such as for a method call, including
+whether to include the receiver and/or the argument list.
+
+When you report an `Incident` you can also provide a `LintFix`; this is
+a quickfix which the IDE can use to offer actions to take on the
+warning. In some cases, you can offer a complete and correct fix (such
+as removing an unused element). In other cases the fix may be less
+clear; for example, the `AccessibilityDetector` asks you to set a
+description for images; the quickfix will set the content attribute,
+but will leave the text value as TODO and will select the string such
+that the user can just type to replace it.
+
+!!! Tip
+ When reporting incidents, make sure that the error messages are not
+ generic; try to be explicit and include specifics for the current
+ scenario. For example, instead of just “Duplicate declaration”, use
+ “`$name` has already been declared”. This isn't just for cosmetics;
+ it also makes lint's [baseline
+ mechanism](../usage/baselines.md.html) work better since it
+ currently matches by id + file + message, not by line numbers which
+ typically drift over time.
+
+## Client API versus Detector API
+
+Lint's API has two halves:
+
+- The **Client API**: “Integrate (and run) lint from within a tool”.
+ For example, both the IDE and the build system use this API to embed
+ and invoke lint to analyze the code in the project or editor.
+
+- The **Detector API**: “Implement a new lint check”. This is the API
+ which lets checkers analyze code and report problems that they find.
+
+The class in the Client API which represents lint running in a tool is
+called `LintClient`. This class is responsible for, among other things:
+
+* **Reporting incidents found by detectors**. For example, in the IDE, it
+ will place error markers into the source editor, and in a build
+ system, it may write warnings to the console or generate a report or
+ even fail the build.
+
+* **Handling I/O**. Detectors should never read files from disk directly.
+ This allows lint checks to work smoothly in for example the IDE. When
+ lint runs on the fly, and a lint check asks for the source file
+ contents (or other supporting files), the `LintClient` in the IDE
+ will implement the `readFile` method to first look in the open source
+ editors and if the requested file is being edited, it will return the
+ current (often unsaved!) contents.
+
+* **Handling network traffic**. Lint checks should never open
+ URLConnections themselves. Instead, they should go through the lint API
+ to request data for URLs. Among other things, this allows the
+ `LintClient` to use configured IDE proxy settings (as is done in the
+ IntelliJ integration of lint). This is also good for testing, because
+ the special unit test implementation of a `LintClient` has a simple way
+ to provide exact responses for specific URLs:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+lint()
+ .files(...)
+ // Set up exactly the expected maven.google.com network output to
+ // ensure stable version suggestions in the tests
+ .networkData("https://maven.google.com/master-index.xml", ""
+ + "\n"
+ + "\n"
+ + " "
+ + " ")
+ .networkData("https://maven.google.com/com/android/tools/build/group-index.xml", ""
+ + "\n"
+ + "\n"
+ + " \n"
+ + " ")
+.run()
+.expect(...)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+And much, much, more. **However, most of the implementation of
+`LintClient` is intended for integration of lint itself, and as a check
+author you don't need to worry about it.** The detector API will matter
+more, and it's also less likely to change than the client API.
+
+!!! Tip
+ The division between the two halves is not perfect; some classes
+ do not fit neatly in between the two or historically were put in
+ the wrong place, so this is a high level design to be aware of but
+ which is not absolute.
+
+Also,
+
+!!! Warning
+ Because of the division between two separate packages, which in
+ retrospect was a mistake, a number of APIs that are only intended
+ for internal lint usage have been made `public` such that lint's
+ code in one package can access it from the other. There's normally a
+ comment explaining that this is for internal use only, but be aware
+ that even when something is `public` or not `final`, it might not be a
+ good idea to call or override it.
+
+## Creating an Issue
+
+For information on how to set up the project and to actually publish
+your lint checks, see the [sample](example.md.html) and
+[publishing](publishing.md.html) chapters.
+
+`Issue` is a final class, so unlike `Detector`, you don't subclass
+it; you instantiate it via `Issue.create`.
+
+By convention, issues are registered inside the companion object of the
+corresponding detector, but that is not required.
+
+Here's an example:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+class SdCardDetector : Detector(), SourceCodeScanner {
+ companion object Issues {
+ @JvmField
+ val ISSUE = Issue.create(
+ id = "SdCardPath",
+ briefDescription = "Hardcoded reference to `/sdcard`",
+ explanation = """
+ Your code should not reference the `/sdcard` path directly; \
+ instead use `Environment.getExternalStorageDirectory().getPath()`.
+
+ Similarly, do not reference the `/data/data/` path directly; it \
+ can vary in multi-user scenarios. Instead, use \
+ `Context.getFilesDir().getPath()`.
+ """,
+ moreInfo = "https://developer.android.com/training/data-storage#filesExternal",
+ category = Category.CORRECTNESS,
+ severity = Severity.WARNING,
+ androidSpecific = true,
+ implementation = Implementation(
+ SdCardDetector::class.java,
+ Scope.JAVA_FILE_SCOPE
+ )
+ )
+ }
+ ...
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+There are a number of things to note here.
+
+On line 4, we have the `Issue.create()` call. We store the issue into a
+property such that we can reference this issue both from the
+`IssueRegistry`, where we provide the `Issue` to lint, and also in the
+`Detector` code where we report incidents of the issue.
+
+Note that `Issue.create` is a method with a lot of parameters (and we
+will probably add more parameters in the future). Therefore, it's a
+good practice to explicitly include the argument names (and therefore
+to implement your code in Kotlin).
+
+The `Issue` provides metadata about a type of problem.
+
+The **`id`** is a short, unique identifier for this issue. By
+convention it is a combination of words, capitalized camel case (though
+you can also add your own package prefix as in Java packages). Note
+that the id is “user visible”; it is included in text output when lint
+runs in the build system, such as this:
+
+```shell
+src/main/kotlin/test/pkg/MyTest.kt:4: Warning: Do not hardcode "/sdcard/";
+ use Environment.getExternalStorageDirectory().getPath() instead [SdCardPath]
+ val s: String = "/sdcard/mydir"
+ -------------
+0 errors, 1 warnings
+```
+
+(Notice the `[SdCardPath]` suffix at the end of the error message.)
+
+The reason the id is made known to the user is that the ID is how
+they'll configure and/or suppress issues. For example, to suppress the
+warning in the current method, use
+
+```
+@Suppress("SdCardPath")
+```
+
+(or in Java, @SuppressWarnings). Note that there is an IDE quickfix to
+suppress an incident which will automatically add these annotations, so
+you don't need to know the ID in order to be able to suppress an
+incident, but the ID will be visible in the annotation that it
+generates, so it should be reasonably specific.
+
+Also, since the namespace is global, try to avoid picking generic names
+that could clash with others, or seem to cover a larger set of issues
+than intended. For example, “InvalidDeclaration” would be a poor id
+since that can cover a lot of potential problems with declarations
+across a number of languages and technologies.
+
+Next, we have the **`briefDescription`**. You can think of this as a
+“category report header”; this is a static description for all
+incidents of this type, so it cannot include any specifics. This string
+is used for example as a header in HTML reports for all incidents of
+this type, and in the IDE, if you open the Inspections UI, the various
+issues are listed there using the brief descriptions.
+
+The **`explanation`** is a multi line, ideally multi-paragraph
+explanation of what the problem is. In some cases, the problem is self
+evident, as in the case of “Unused declaration”, but in many cases, the
+issue is more subtle and might require additional explanation,
+particularly for what the developer should **do** to address the
+problem. The explanation is included both in HTML reports and in the
+IDE inspection results window.
+
+Note that even though we're using a raw string, and even though the
+string is indented to be flush with the rest of the issue registration
+for better readability, we don't need to call `trimIndent()` on
+the raw string. Lint does that automatically.
+
+However, we do need to add line continuations -- those are the trailing
+\'s at the end of the lines.
+
+Note also that we have a Markdown-like simple syntax, described in the
+“TextFormat” section below. You can use asterisks for italics or double
+asterisks for bold, you can use apostrophes for code font, and so on.
+In terminal output this doesn't make a difference, but the IDE,
+explanations, incident error messages, etc, are all formatted using
+these styles.
+
+The **`category`** isn't super important; the main use is that category
+names can be treated as id's when it comes to issue configuration; for
+example, a user can turn off all internationalization issues, or run
+lint against only the security related issues. The category is also
+used for locating related issues in HTML reports. If none of the
+built-in categories are appropriate you can also create your own.
+
+The **`severity`** property is very important. An issue can be either a
+warning or an error. These are treated differently in the IDE (where
+errors are red underlines and warnings are yellow highlights), and in
+the build system (where errors can optionally break the build and
+warnings do not). There are some other severities too; “fatal” is like
+error except these checks are designated important enough (and have
+very few false positives) such that we run them during release builds,
+even if the user hasn't explicitly run a lint target. There's also
+“informational” severity, which is only used in one or two places, and
+finally the “ignore” severity. This is never the severity you register
+for an issue, but it's part of the severities a developer can configure
+for a particular issue, thereby turning off that particular check.
+
+You can also specify a **`moreInfo`** URL which will be included in the
+issue explanation as a “More Info” link to open to read more details
+about this issue or underlying problem.
+
+## TextFormat
+
+All error messages and issue metadata strings in lint are interpreted
+using simple Markdown-like syntax:
+
+Raw text format | Renders To
+-----------------------------|--------------------------
+This is a \`code symbol\` | This is a `code symbol`
+This is `*italics*` | This is *italics*
+This is `**bold**` | This is **bold**
+This is `~~strikethrough~~` | This is ~~strikethrough~~
+http://, https:// | [](http://), [](https://)
+`\*not italics*` | `\*not italics*`
+\`\`\`language\n text\n\`\`\`| (preformatted text block)
+ [Supported markup in lint's markdown-like raw text format]
+
+This is useful when error messages and issue explanations are shown in
+HTML reports generated by Lint, or in the IDE, where for example the
+error message tooltips will use formatting.
+
+In the API, there is a `TextFormat` enum which encapsulates the
+different text formats, and the above syntax is referred to as
+`TextFormat.RAW`; it can be converted to `.TEXT` or `.HTML` for
+example, which lint does when writing text reports to the console or
+HTML reports to files respectively. As a lint check author you don't
+need to know this (though you can for example with the unit testing
+support decide which format you want to compare against in your
+expected output), but the main point here is that your issue's brief
+description, issue explanation, incident report messages etc, should
+use the above “raw” syntax. Especially the first conversion; error
+messages often refer to class names and method names, and these should
+be surrounded by apostrophes.
+
+See the [error message](messages.md.html) chapter for more information
+on how to craft error messages.
+
+## Issue Implementation
+
+The last issue registration property is the **`implementation`**. This
+is where we glue our metadata to our specific implementation of an
+analyzer which can find instances of this issue.
+
+Normally, the `Implementation` provides two things:
+
+* The `.class` for our `Detector` which should be instantiated. In the
+ code sample above it was `SdCardDetector`.
+
+* The `Scope` that this issue's detector applies to. In the above
+ example it was `Scope.JAVA_FILE`, which means it will apply to Java
+ and Kotlin files.
+
+## Scopes
+
+The `Implementation` actually takes a **set** of scopes; we still refer
+to this as a “scope”. Some lint checks want to analyze multiple types
+of files. For example, the `StringFormatDetector` will analyze both the
+resource files declaring the formatting strings across various locales,
+as well as the Java and Kotlin files containing `String.format` calls
+referencing the formatting strings.
+
+There are a number of pre-defined sets of scopes in the `Scope`
+class. `Scope.JAVA_FILE_SCOPE` is the most common, which is a
+singleton set containing exactly `Scope.JAVA_FILE`, but you
+can always create your own, such as for example
+```
+ EnumSet.of(Scope.CLASS_FILE, Scope.JAVA_LIBRARIES)
+```
+
+When a lint issue requires multiple scopes, that means lint will
+**only** run this detector if **all** the scopes are available in the
+running tool. When lint runs a full batch run (such as a Gradle lint
+target or a full “Inspect Code” in the IDE), all scopes are available.
+
+However, when lint runs on the fly in the editor, it only has access to
+the current file; it won't re-analyze *all* files in the project for
+every few keystrokes. So in this case, the scope in the lint driver
+only includes the current source file's type, and only lint checks
+which specify a scope that is a subset would run.
+
+This is a common mistake for new lint check authors: the lint check
+works just fine as a unit test, but they don't see working in the IDE
+because the issue implementation requests multiple scopes, and **all**
+have to be available.
+
+Often, a lint check looks at multiple source file types to work
+correctly in all cases, but it can still identify *some* problems given
+individual source files. In this case, the `Implementation` constructor
+(which takes a vararg of scope sets) can be handed additional sets of
+scopes, called “analysis scopes”. If the current lint client's scope
+matches or is a subset of any of the analysis scopes, then the check
+will run after all.
+
+## Registering the Issue
+
+Once you've created your issue, you need to provide it from
+an `IssueRegistry`.
+
+Here's an example `IssueRegistry`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package com.example.lint.checks
+
+import com.android.tools.lint.client.api.IssueRegistry
+import com.android.tools.lint.client.api.Vendor
+import com.android.tools.lint.detector.api.CURRENT_API
+
+class SampleIssueRegistry : IssueRegistry() {
+ override val issues = listOf(SdCardDetector.ISSUE)
+
+ override val api: Int
+ get() = CURRENT_API
+
+ // works with Studio 4.1 or later; see
+ // com.android.tools.lint.detector.api.Api / ApiKt
+ override val minApi: Int
+ get() = 8
+
+ // Requires lint API 30.0+; if you're still building for something
+ // older, just remove this property.
+ override val vendor: Vendor = Vendor(
+ vendorName = "Android Open Source Project",
+ feedbackUrl = "https://com.example.lint.blah.blah/",
+ contact = "author@com.example.lint"
+ )
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+On line 8, we're returning our issue. It's a list, so an
+`IssueRegistry` can provide multiple issues.
+
+The **`api`** property should be written exactly like the way it
+appears above in your own issue registry as well; this will record
+which version of the lint API this issue registry was compiled against
+(because this references a static final constant which will be copied
+into the jar file instead of looked up dynamically when the jar is
+loaded).
+
+The **`minApi`** property records the oldest lint API level this check
+has been tested with.
+
+Both of these are used at issue loading time to make sure lint checks
+are compatible, but in recent versions of lint (7.0) lint will more
+aggressively try to load older detectors even if they have been
+compiled against older APIs since there's a high likelihood that they
+will work (it checks all the lint APIs in the bytecode and uses
+reflection to verify that they're still there).
+
+The **`vendor`** property is new as of 7.0, and gives lint authors a
+way to indicate where the lint check came from. When users use lint,
+they're running hundreds and hundreds of checks, and sometimes it's not
+clear who to contact with requests or bug reports. When a vendor has
+been specified, lint will include this information in error output and
+reports.
+
+The last step towards making the lint check available is to make
+the `IssueRegistry` known via the service loader mechanism.
+
+Create a file named exactly
+```
+src/main/resources/META-INF/services/com.android.tools.lint.client.api.IssueRegistry
+```
+
+with the following contents (but where you substitute in your own
+fully qualified class name for your issue registry):
+
+```
+com.example.lint.checks.SampleIssueRegistry
+```
+
+If you're not building your lint check using Gradle, you may not want
+the `src/main/resources` prefix; the point is that your packaging of
+the jar file should contain `META-INF/services/` at the root of the jar
+file.
+
+## Implementing a Detector: Scanners
+
+We've finally come to the main task with writing a lint check:
+implementing the **`Detector`**.
+
+Here's a trivial one:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+class MyDetector : Detector() {
+ override fun run(context: Context) {
+ context.report(ISSUE, Location.create(context.file),
+ "I complain a lot")
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This will just complain in every single file. Obviously, no real lint
+detector does this; we want to do some analysis and **conditionally** report
+incidents. For information about how to phrase error messages, see the [error
+message](messages.md.html) chapter.
+
+In order to make it simpler to perform analysis, Lint has dedicated
+support for analyzing various file types. The way this works is that
+you register interest, and then various callbacks will be invoked.
+
+For example:
+
+* When implementing **`XmlScanner`**, in an XML element you can be
+ called back
+ - when any of a set of given tags are declared (`visitElement`)
+ - when any of a set of named attributes are declared
+ (`visitAttribute`)
+ - and you can perform your own document traversal via `visitDocument`
+
+* When implementing **`SourceCodeScanner`**, in Kotlin and Java files
+ you can be called back
+ - when a method of a given name is invoked (`getApplicableMethodNames`
+ and `visitMethodCall`)
+ - when a class of the given type is instantiated
+ (`getApplicableConstructorTypes` and `visitConstructor`)
+ - when a new class is declared which extends (possibly indirectly)
+ a given class or interface (`applicableSuperClasses` and
+ `visitClass`)
+ - when annotated elements are referenced or combined
+ (`applicableAnnotations` and `visitAnnotationUsage`)
+ - when any AST nodes of given types appear (`getApplicableUastTypes`
+ and `createUastHandler`)
+
+* When implementing a **`ClassScanner`**, in `.class` and `.jar` files
+ you can be called back
+ - when a method is invoked for a particular owner
+ (`getApplicableCallOwners` and `checkCall`
+ - when a given bytecode instruction occurs
+ (`getApplicableAsmNodeTypes` and `checkInstruction`)
+ - like with XmlScanner's `visitDocument`, you can perform your own
+ ASM bytecode iteration via `checkClass`
+
+* There are various other scanners too, for example `GradleScanner`
+ which lets you visit `build.gradle` and `build.gradle.kts` DSL
+ closures, `BinaryFileScanner` which visits resource files such as
+ webp and png files, and `OtherFileScanner` which lets you visit
+ unknown files.
+
+!!! Note
+ Note that `Detector` already implements empty stub methods for all
+ of these interfaces, so if you for example implement
+ `SourceFileScanner` in your detector, you don't need to go and add
+ empty implementations for all the methods you aren't using.
+
+!!! Tip
+ None of Lint's APIs require you to call `super` when you override
+ methods; methods meant to be overridden are always empty so the
+ super-call is superfluous.
+
+## Detector Lifecycle
+
+Detector registration is done by detector class, not by detector
+instance. Lint will instantiate detectors on your behalf. It will
+instantiate the detector once per analysis, so you can stash state on
+the detector in fields and accumulate information for analysis at the
+end.
+
+There are some callbacks both before and after each individual file is
+analyzed (`beforeCheckFile` and `afterCheckFile`), as well as before and
+after analysis of all the modules (`beforeCheckRootProject` and
+`afterCheckRootProject`).
+
+This is for example how the “unused resources” check works: we store
+all the resource declarations and resource references we find in the
+project as we process each file, and then in the
+`afterCheckRootProject` method we analyze the resource graph and
+compute any resource declarations that are not reachable in the
+reference graph, and then we report each of these as unused.
+
+## Scanner Order
+
+Some lint checks involve multiple scanners. This is pretty common in
+Android, where we want to cross check consistency between data in
+resource files with the code usages. For example, the `String.format`
+check makes sure that the arguments passed to `String.format` match the
+formatting strings specified in all the translation XML files.
+
+Lint defines an exact order in which it processes scanners, and within
+scanners, data. This makes it possible to write some detectors more
+easily because you know that you'll encounter one type of data before
+the other; you don't have to handle the opposite order. For example, in
+our `String.format` example, we know that we'll always see the
+formatting strings before we see the code with `String.format` calls,
+so we can stash the formatting strings in a map, and when we process
+the formatting calls in code, we can immediately issue reports; we
+don't have to worry about encountering a formatting call for a
+formatting string we haven't processed yet.
+
+Here's lint's defined order:
+
+1. Android Manifest
+2. Android resources XML files (alphabetical by folder type, so for
+ example layouts are processed before value files like translations)
+3. Kotlin and Java files
+4. Bytecode (local `.class` files and library `.jar` files)
+5. TOML files
+6. Gradle files
+7. Other files
+8. ProGuard files
+9. Property Files
+
+Similarly, lint will always process libraries before the modules
+that depend on them.
+
+!!! Tip
+ If you need to access something from later in the iteration order,
+ and it's not practical to store all the current data and instead
+ handle it when the later data is encountered, note that lint has
+ support for “multi-pass analysis”: it can run multiple times over
+ the data. The way you invoke this is via
+ `context.driver.requestRepeat(this, …)`. This is actually how the
+ unused resource analysis works. Note however that this repeat is
+ only valid within the current module; you can't re-run the analysis
+ through the whole dependency graph.
+
+## Implementing a Detector: Services
+
+In addition to the scanners, lint provides a number of services
+to make implementation simpler. These include
+
+* **`ConstantEvaluator`**: Performs evaluation of AST expressions, so
+ for example if we have the statements `x = 5; y = 2 * x`, the
+ constant evaluator can tell you that y is 10. This constant evaluator
+ can also be more permissive than a compiler's strict constant
+ evaluator; e.g. it can return concatenated strings where not all
+ parts are known, or it can use non-final initial values of fields.
+ This can help you find *possible* bugs instead of *certain* bugs.
+
+* **`TypeEvaluator`**: Attempts to provide the concrete type of an
+ expression. For example, for the Java statements `Object s = new
+ StringBuilder(); Object o = s`, the type evaluator can tell you that
+ the type of `o` at this point is really `StringBuilder`.
+
+* **`JavaEvaluator`**: Despite the unfortunate older name, this service
+ applies to both Kotlin and Java, and can for example provide
+ information about inheritance hierarchies, class lookup from fully
+ qualified names, etc.
+
+* **`DataFlowAnalyzer`**: Data flow analysis within a method.
+
+* For Android analysis, there are several other important services,
+ like the `ResourceRepository` and the `ResourceEvaluator`.
+
+* Finally, there are a number of utility methods; for example there is
+ an `editDistance` method used to find likely typos.
+
+## Scanner Example
+
+Let's create a `Detector` using one of the above scanners,
+`XmlScanner`, which will look at all the XML files in the project and
+if it encounters a `` tag it will report that `` should
+be used instead:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Detector.XmlScanner
+import com.android.tools.lint.detector.api.Location
+import com.android.tools.lint.detector.api.XmlContext
+import org.w3c.dom.Element
+
+class MyDetector : Detector(), XmlScanner {
+ override fun getApplicableElements() = listOf("bitmap")
+
+ override fun visitElement(context: XmlContext, element: Element) {
+ val incident = Incident(context, ISSUE)
+ .message( "Use `` instead of ``")
+ .at(element)
+ context.report(incident)
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The above is using the new `Incident` API from Lint 7.0 and on; in
+older versions you can use the following API, which still works in 7.0:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+class MyDetector : Detector(), XmlScanner {
+ override fun getApplicableElements() = listOf("bitmap")
+
+ override fun visitElement(context: XmlContext, element: Element) {
+ context.report(ISSUE, context.getLocation(element),
+ "Use `` instead of ``")
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The second (older) form may seem simpler, but the new API allows a lot
+more metadata to be attached to the report, such as an override
+severity. You don't have to convert to the builder syntax to do this;
+you could also have written the second form as
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+context.report(Incident(ISSUE, context.getLocation(element),
+ "Use `` instead of ``"))
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+## Analyzing Kotlin and Java Code
+
+### UAST
+
+To analyze Kotlin and Java code, lint offers an abstract syntax tree,
+or “AST”, for the code.
+
+This AST is called “UAST”, for “Universal Abstract Syntax Tree”, which
+represents multiple languages in the same way, hiding the language
+specific details like whether there is a semicolon at the end of the
+statements or whether the way an annotation class is declared is as
+`@interface` or `annotation class`, and so on.
+
+This makes it possible to write a single analyzer which works
+across all languages supported by UAST. And this is
+very useful; most lint checks are doing something API or data-flow
+specific, not something language specific. If however you do need to
+implement something very language specific, see the next section,
+“PSI”.
+
+In UAST, each element is called a **`UElement`**, and there are a
+number of subclasses -- `UFile` for the compilation unit, `UClass` for
+a class, `UMethod` for a method, `UExpression` for an expression,
+`UIfExpression` for an `if`-expression, and so on.
+
+Here's a visualization of an AST in UAST for two equivalent programs
+written in Kotlin and Java. These programs both result in the same
+AST, shown on the right: a `UFile` compilation unit, containing
+a `UClass` named `MyTest`, containing `UField` named s which has
+an initializer setting the initial value to `hello`.
+
+************************************************************************
+*
+* MyTest.kt: UAST:
+* +---------------------------+ .-------.
+* | package test.pkg | | UFile |
+* | class MyTest { | '---+---'
+* | private val s = “hello” | |
+* | } | .------+------.
+* +---------------------------+ | UClass MyTest |
+* '------+------'
+* MyTest.java: |
+* +------------------------+ .---+----.
+* | package test.pkg; | | UField s |
+* | public class MyTest { | '+------+'
+* | private String s = | / \
+* | “hello”; | / \
+* | } | / \
+* +------------------------+ / \
+* .-----------+. .--------+---------------.
+* |UIdentifier s | | ULiteralExpression hello |
+* '------------' '------------------------'
+*
+************************************************************************
+
+!!! Tip
+ The name “UAST” is a bit misleading; it is not some sort of superset
+ of all possible syntax trees; instead, think of this as the “Java
+ view” of all code. So, for example, there isn’t a `UProperty` node
+ which represents Kotlin properties. Instead, the AST will look the
+ same as if the property had been implemented in Java: it will
+ contain a private field and a public getter and a public setter
+ (unless of course the Kotlin property specifies a private setter).
+ If you’ve written code in Kotlin and have tried to access that
+ Kotlin code from a Java file you will see the same thing -- the
+ “Java view” of Kotlin. The next section, “PSI”, will discuss how to
+ do more language specific analysis.
+
+### UAST Example
+
+Here's an example (from the built-in `AlarmDetector` for Android) which
+shows all of the above in practice; this is a lint check which makes
+sure that if anyone calls `AlarmManager.setRepeating`, the second
+argument is at least 5,000 and the third argument is at least 60,000.
+
+Line 1 says we want to have line 3 called whenever lint comes across a
+method to `setRepeating`.
+
+On lines 8-14 we make sure we're talking about the correct method on the
+correct class with the correct signature. This uses the `JavaEvaluator`
+to check that the called method is a member of the named class. This is
+necessary because the callback would also be invoked if lint came
+across a method call like `Unrelated.setRepeating`; the
+`visitMethodCall` callback only matches by name, not receiver.
+
+On line 36 we use the `ConstantEvaluator` to compute the value of each
+argument passed in. This will let this lint check not only handle cases
+where you're specifying a specific value directly in the argument list,
+but also for example referencing a constant from elsewhere.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+override fun getApplicableMethodNames(): List = listOf("setRepeating")
+
+override fun visitMethodCall(
+ context: JavaContext,
+ node: UCallExpression,
+ method: PsiMethod
+) {
+ val evaluator = context.evaluator
+ if (evaluator.isMemberInClass(method, "android.app.AlarmManager") &&
+ evaluator.getParameterCount(method) == 4
+ ) {
+ ensureAtLeast(context, node, 1, 5000L)
+ ensureAtLeast(context, node, 2, 60000L)
+ }
+}
+
+private fun ensureAtLeast(
+ context: JavaContext,
+ node: UCallExpression,
+ parameter: Int,
+ min: Long
+) {
+ val argument = node.valueArguments[parameter]
+ val value = getLongValue(context, argument)
+ if (value < min) {
+ val message = "Value will be forced up to $min as of Android 5.1; " +
+ "don't rely on this to be exact"
+ context.report(ISSUE, argument, context.getLocation(argument), message)
+ }
+}
+
+private fun getLongValue(
+ context: JavaContext,
+ argument: UExpression
+): Long {
+ val value = ConstantEvaluator.evaluate(context, argument)
+ if (value is Number) {
+ return value.toLong()
+ }
+
+ return java.lang.Long.MAX_VALUE
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+### Looking up UAST
+
+To write your detector's analysis, you need to know what the AST for
+your code of interest looks like. Instead of trying to figure it out by
+examining the elements under a debugger, a simple way to find out is to
+“pretty print” it, using the `UElement` extension method
+**`asRecursiveLogString`**.
+
+For example, given the following unit test:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+lint().files(
+ kotlin(""
+ + "package test.pkg\n"
+ + "\n"
+ + "class MyTest {\n"
+ + " val s: String = \"hello\"\n"
+ + "}\n"), ...
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you evaluate `context.uastFile?.asRecursiveLogString()` from
+one of the callbacks, it will print this:
+
+```text
+UFile (package = test.pkg)
+ UClass (name = MyTest)
+ UField (name = s)
+ UAnnotation (fqName = org.jetbrains.annotations.NotNull)
+ ULiteralExpression (value = "hello")
+ UAnnotationMethod (name = getS)
+ UAnnotationMethod (name = MyTest)
+```
+
+(This also illustrates the earlier point about UAST representing the
+Java view of the code; here the read-only public Kotlin property “s” is
+represented by both a private field `s` and a public getter method,
+`getS()`.)
+
+### Resolving
+
+When you have a method call, or a field reference, you may want to take
+a look at the called method or field. This is called “resolving”, and
+UAST supports it directly; on a `UCallExpression` for example, call
+`.resolve()`, which returns a `PsiMethod`, which is like a `UMethod`,
+but may not represent a method we have source for (which for example
+would be the case if you resolve a reference to the JDK or to a library
+we do not have sources for). You can call `.toUElement()` on the
+PSI element to try to convert it to UAST if source is available.
+
+!!! Warning
+ Resolving only works if lint has a correct classpath such that the
+ referenced method, field, or class is actually present. If it is
+ not, resolve will return null, and various lint callbacks will not
+ be invoked. This is a common source of questions for lint checks
+ “not working”; it frequently comes up in lint unit tests where a
+ test file will reference some API that isn't actually included in
+ the class path. The recommended approach for this is to declare
+ local stubs. See the [unit testing](unit-testing.md.html) chapter
+ for more details about this.
+
+### Implicit Calls
+
+Kotlin supports operator overloading for a number of built-in
+operators. For example, if you have the following code,
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+fun test(n1: BigDecimal, n2: BigDecimal) {
+ // Here, this is really an infix call to BigDecimal#compareTo
+ if (n1 < n2) {
+ ...
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+the `<` here is actually a function call (which you can verify by
+invoking Go To Declaration over the symbol in the IDE). This is not
+something that is built specially for the `BigDecimal` class; this
+works on any of your Java classes as well, and Kotlin if you put the
+`operator` modifier as part of the function declaration.
+
+However, note that in the abstract syntax tree, this is **not**
+represented as a `UCallExpression`; here we'll have a
+`UBinaryExpression` with left operand `n1`, right operand `n2` and
+operator `UastBinaryOperator.LESS`. This means that if your lint check
+is specifically looking at `compareTo` calls, you can't just visit
+every `UCallExpression`; you *also* have to visit every
+`UBinaryExpression`, and check whether it's invoking a `compareTo`
+method.
+
+This is not just specific to binary operators; it also applies to unary
+operators (such as `!`, `-`, `++`, and so on), as well as even array
+accesses; an array access can map to a `get` call or a `set` call
+depending on how it's used.
+
+Lint has some special support to help handle these situations.
+
+First, the built-in support for call callbacks (where you register an
+interest in call names by returning names from the
+`getApplicableMethodNames` and then responding in the `visitMethodCall`
+callback) already handles this automatically. If you register for
+example an interest in method calls to `compareTo`, it will invoke your
+callback for the binary operator scenario shown above as well, passing
+you a call which has the right value arguments, method name, and so on.
+
+The way this works is that lint can create a “wrapper” class which
+presents the underlying `UBinaryExpression` (or
+`UArrayAccessExpression` and so on) as a `UCallExpression`. In the case
+of a binary operator, the value parameter list will be the left and
+right operands. This means that your code can just process this as if
+the code had written as an explicit call instead of using the operator
+syntax. You can also directly look for this wrapper class,
+`UImplicitCallExpression`, which has an accessor method for looking up
+the original or underlying element. And you can construct these
+wrappers yourself, via `UBinaryExpression.asCall()`,
+`UUnaryExpression.asCall()`, and `UArrayAccessExpression.asCall()`.
+
+There is also a visitor you can use to visit all calls --
+`UastCallVisitor`, which will visit all calls, including those from
+array accesses and unary operators and binary operators.
+
+This support is particularly useful for array accesses, since unlike
+the operator expression, there is no `resolveOperator` method on
+`UArrayExpression`. There is an open request for that in the UAST issue
+tracker (KTIJ-18765), but for now, lint has a workaround to handle the
+resolve on its own.
+
+### PSI
+
+PSI is short for “Program Structure Interface”, and is IntelliJ's AST
+abstraction used for all language modeling in the IDE.
+
+Note that there is a **different** PSI representation for each
+language. Java and Kotlin have completely different PSI classes
+involved. This means that writing a lint check using PSI would involve
+writing a lot of logic twice; once for Java, and once for Kotlin. (And
+the Kotlin PSI is a bit trickier to work with.)
+
+That's what UAST is for: there's a “bridge” from the Java PSI to UAST
+and there's a bridge from the Kotlin PSI to UAST, and your lint check
+just analyzes UAST.
+
+However, there are a few scenarios where we have to use PSI.
+
+The first, and most common one, is listed in the previous section on
+resolving. UAST does not completely replace PSI; in fact, PSI leaks
+through in part of the UAST API surface. For example,
+`UMethod.resolve()` returns a `PsiMethod`. And more importantly,
+`UMethod` **extends** `PsiMethod`.
+
+!!! Warning
+ For historical reasons, `PsiMethod` and other PSI classes contain
+ some unfortunate APIs that only work for Java, such as asking for
+ the method body. Because `UMethod` extends `PsiMethod`, you might be
+ tempted to call `getBody()` on it, but this will return null from
+ Kotlin. If your unit tests for your lint check only have test cases
+ written in Java, you may not realize that your check is doing the
+ wrong thing and won't work on Kotlin code. It should call `uastBody`
+ on the `UMethod` instead. Lint's special detector for lint detectors
+ looks for this and a few other scenarios (such as calling `parent`
+ instead of `uastParent`), so be sure to configure it for your
+ project.
+
+When you are dealing with “signatures” -- looking at classes and
+class inheritance, methods, parameters and so on -- using PSI is
+fine -- and unavoidable since UAST does not represent bytecode
+(though in the future it potentially could, via a decompiler)
+or any other JVM languages than Kotlin and Java.
+
+However, if you are looking at anything *inside* a method or class
+or field initializer, you **must** use UAST.
+
+The **second** scenario where you may need to use PSI is where you have
+to do something language specific which is not represented in UAST. For
+example, if you are trying to look up the names or default values of a
+parameter, or whether a given class is a companion object, then you'll
+need to dip into Kotlin PSI.
+
+There is usually no need to look at Java PSI since UAST fully covers
+it, unless you want to look at individual details like specific
+whitespace between AST nodes, which is represented in PSI but not UAST.
+
+!!! Tip
+ You can find additional documentation from JetBrains for both
+ [PSI](https://plugins.jetbrains.com/docs/intellij/psi.html) and
+ [UAST](https://plugins.jetbrains.com/docs/intellij/uast.html).
+ Just note that their documentation is aimed at IDE plugin developers
+ rather than lint developers.
+
+## Testing
+
+Writing unit tests for the lint check is important, and this is covered
+in detail in the dedicated [unit testing](unit-testing.md.html)
+chapter.
+
+
diff --git a/docs/api-guide/changes.md.html b/docs/api-guide/changes.md.html
new file mode 100644
index 00000000..dc87c11e
--- /dev/null
+++ b/docs/api-guide/changes.md.html
@@ -0,0 +1,403 @@
+**Recent Changes**
+
+This chapter lists recent changes to lint that affect lint check
+authors: new features, API and behavior changes, and so on. For
+information about user visible changes to lint, see the User
+Guide.
+
+**8.9**
+
+* Lint's testing infrastructure support for testing quickfixes
+ (`expectFixDiffs()`) now also validates that the modified
+ source file is valid Kotlin, Java or XML. You can control
+ this using the `lint().verifyFixedFileSyntax()` option.
+
+**8.8**
+
+* For the string-replacement quickfix, you can now specify
+ regex flags (such as Pattern.DOT_ALL) to change the pattern
+ matching behavior.
+
+**8.7**
+
+* The unit testing support now checks to make sure that you
+ don't have duplicate class names across Java and Kotlin
+ (which can lead to subtle and confusing errors.)
+* The `build.gradle.kts` unit testing support (`TestFiles.kts()`)
+ now performs the same mocking of the builder model that the
+ corresponding Groovy Gradle support (`Testfiles.gradle()`)
+ performs. Among other things, this means that the other
+ source files (`java()`, `kotlin()`, etc) must be located in
+ source sets, e.g. `src/main/res/` and `/src/main/java/`
+ rather than just `res/` and `src/`. This happens automatically
+ if you don't manually specify a target path in the test file
+ declaration.
+
+**8.6**
+
+* UAST repeats @JvmOverloaded methods in the AST. Lint now looks for
+ and skips these duplications, and a new test mode also looks for
+ potential problems in third party checks.
+* Added a new chapter to the api-guide on AST analysis, and in
+ particular, using the Kotlin Analysis API.
+* The `UElementHandler` now supports recently added UAST element
+ types: `UPatternExpression` and `UBinaryExpressionWithPattern`.
+* There's a new test mode checking for issues related to
+ `@JvmOverloads`. See the [test modes](test-modes.md.html) chapter
+ for more.
+
+**8.4**
+
+* You can now use `~~` in text messages (error messages, issue
+ explanations, etc) to create strikethrough text. For example, “`Don't
+ do this: ~~super.onCreate()~~`” will render as “Don't do this:
+ ~~super.onCreate()~~”.
+
+**8.3**
+
+* If you'd like to change your error message reported by your
+ detector, you can now override your `Detector`'s `sameMessage`
+ method: match the details in the previous error message with the
+ new format. This is used by the baseline mechanism such that your
+ message change doesn't suddenly invalidate all existing baseline
+ files for your issue.
+
+* The replace-string quickfix descriptor now lets you replace a string
+ repeatedly. Example:
+ ```
+ fix().replace().text("Foo").with("Bar").repeatedly().build()
+ ```
+
+ You can also match an element optionally. Example:
+ ```
+ fix().composite(
+ fix().replace().text("").with("").build(),
+ fix().replace().text(" ").with(" ").optional().build()
+ )
+ ```
+
+* The quickfix machinery was improved significantly. It now does a
+ better job inserting imports (in alphabetical order instead of always
+ prepending to the import list), inserting new XML attributes in the
+ right canonical Android order, cleaning up whitespace after edits,
+ etc. This may result in some diffs in any quickfix-related unit tests
+ (e.g. `lint().run().expectFixDiffs(...)`)
+
+* The `getFileNameWithParent` utility method now always uses / as
+ a file separator instead of the platform-specific one (e.g. \ on
+ Windows). This ensures that baselines don't vary their error
+ messages (where this utility method is typically used) based on
+ which OS they were generated on.
+
+**8.2**
+
+* For unit tests, you can now specify the language level to be used
+ for Kotlin and Java. For example, if your unit test is using Java
+ records, add `.javaLanguageLevel("17")` to your `lint()` test
+ configuration.
+
+**8.1**
+
+* The [data flow analyzer](dataflow-analyzer.md.html) has been
+ improved; in addition to fixing a few bugs, there are a couple of
+ new convenience sub classes which makes common tasks easier to
+ accomplish; see the documentation for `TargetMethodDataFlowAnalyzer`
+ for example.
+
+* The new `mavenLibrary` (and `binaryStub`) test files make it simple
+ to create binary stub files in your tests, without having to perform
+ compilation and check in base64 and gzip encoded test files. When
+ your detector resolves references, the PSI elements you get back
+ differ whether you're calling into source or into binary (jar/.class
+ file) elements, so testing both (which the new test files automate
+ using test modes) is helpful. More information about this is
+ available in [](unit-testing.md.html).
+
+* Lint now supports analyzing TOML files. There is a new
+ Scope.TOML_FILE detectors can register an interest in, a new
+ TomlScanner interface to implement for visitTomlDocument callbacks,
+ etc. From a GradleScanner, you can directly resolve version catalog
+ libraries via lookup methods on the GradleContext.
+
+* Lint's “diff” output for unit test verification has been improved;
+ it's now smarter about combining nearby chunks. (This should not
+ break existing tests; the test infrastructure will try the older
+ format as a fallback if the diffs aren't matching for the new
+ format.)
+
+* Lint contains JVM 17 bytecode. You will now need to use JDK 17+
+ when compiling custom Lint checks. You should also configure
+ the Kotlin compiler to target JVM 17, otherwise you may see errors
+ when calling inline functions declared in Lint, UAST, or PSI.
+
+* Lint's testing infrastructure now looks not just for test/
+ but also androidTest/ and testFixtures/ to set the corresponding
+ source set type on each test context.
+
+**8.0**
+
+* A new testmode which makes sure lint checks are all suppressible.
+ It analyzes the reported error locations from the expected test
+ output, and inserts suppress annotations in XML, Kotlin and Java
+ files and makes sure that the corresponding warnings disappear.
+
+**7.4**
+
+* Annotation detectors can now specify just an annotation name instead
+ of its fully qualified name in order to match *all* annotations of
+ that name. For example,
+ `override fun applicableAnnotations() = listOf("Nullable")`
+ will match both `androidx.annotation.Nullable` and
+ `org.jetbrains.annotations.Nullable`. This is used by for example
+ the built-in CheckResultDetector to match many new variants of the
+ `CheckReturnValue` annotations, such as the ones in mockito and in
+ protobuf.
+
+* The new AnnotationUsageTypes IMPLICIT_CONSTRUCTOR and
+ IMPLICIT_CONSTRUCTOR_CALL let detectors analyzing annotations get callbacks
+ when an annotated no-args constructor is invoked explicitly from a subclass
+ which has an implicit constructor, or from an implicit super call in an
+ explicit sub constructor. These are not included by default, so override
+ isApplicableAnnotationUsage to opt in.
+
+**7.3**
+
+* The new AnnotationUsageType.DEFINTION now lets detectors easily check
+ occurrences of an annotation in the source code. Previously,
+ `visitAnnotationUsage` would only check annotated elements, not the
+ annotations themselves, and to check an annotation you'd need to
+ create an `UElementHandler`. See the docs for the new enum constant
+ for more details, and for an example of a detector that was converted
+ from a handler to using this, see `IgnoreWithoutReasonDetector`.
+
+* Lint unit tests can now include `package-info.java` files with
+ annotations in source form (until now, this only worked if the files
+ were provided as binary class files)
+
+* String replacement quickfixes can now be configured with a list of
+ imports to be performed when the fix is applied. This can be used to
+ for example import Kotlin extension functions needed by the
+ replacement string. (You should not use this for normal imports;
+ instead, the replacement string should use fully qualified names
+ everywhere along with the `shortenNames` property on the fix, and
+ then lint will rewrite and import all symbols that can be done
+ without conflicts.)
+
+**7.2**
+
+* There is now a way to register “options” for detectors. These are
+ simple key/value pairs of type string, integer, boolean or file, and
+ users can configure values in `lint.xml` files. This has all been
+ possible since 4.2, but in 7.2 there is now a way to register the
+ names, descriptions and default values of these options, and these
+ will show up in issue explanations, HTML reports, and so on. (In the
+ future we can use this to create an Options UI in the IDE, allow
+ configuration via Gradle DSL, and so on.)
+
+ For more, see the [options chapter](options.md.html).
+
+* A new test mode, `TestMode.CDATA`, checks that tests correctly handle
+ XML CDATA sections in `` declarations.
+
+**7.1**
+
+* Lint now bundles IntelliJ version 2021.1 and Kotlin compiler version 1.5.30.
+ You may see minor API changes in these dependencies. For example,
+ the Kotlin UAST class `KotlinUMethod` changed packages from
+ `org.jetbrains.uast.kotlin.declarations` to `org.jetbrains.uast.kotlin`.
+
+* The default behaviour of ResourceXmlDetector will change.
+ It will skip res/raw folder and you have to override appliesTo method
+ if you want your Lint checks to run there.
+
+* The computation of checksums for binary test files (e.g. `compiled`
+ and `bytecode`) unfortunately had to change; the old mechamism was
+ not stable. This means that after updating some of the test files
+ will show as having wrong checksums (e.g. “The checksum does not
+ match for test.kt; expected 0x26e3997d but was 0xb76b5946”). In these
+ cases, just drop in the new checksum.
+
+* Source-modifying test modes. Lint's testing library now runs your
+ unit tests through a number of additional paces: it will try
+ inserting unnecessary parentheses, it will try replacing all
+ imported symbols with fully qualified names, it will try adding
+ argument names and reordering arguments to Kotlin calls, etc, and
+ making sure the same results are reported. More information about
+ this is available in [](test-modes.md.html).
+
+* The support for Kotlin's overloaded operators is significantly
+ improved. While these are method calls, in the AST they do not show
+ up as `UCallExpressions` (instead, you'll find them as
+ `UBinaryExpression`, `UPrefixExpression`, `UArrayAccessExpression`
+ and so on), which meant various call-specific checks ignored them.
+
+ Now, in addition to the built-in checks all applying to these
+ implicit calls as well, lint can present these expressions as call
+ expressions. This means that the `getApplicableMethodNames` machinery
+ for call callbacks will now also work for overloaded functions, and
+ code which is iterating through calls can use the new
+ `UastCallVisitor` (or directly construct `UImplicitCallExpression`
+ wrappers) to simplify processing of all these types of calls.
+
+ Finally, lint now provides a way to resolve operators for array
+ access expressions (which is missing in UAST) via the
+ UArrayAccessExpression.resolveOperator extension method, which is
+ also used by the above machinery.
+
+* The annotation support (where a detector callback is invoked when
+ elements are combined with annotated elements) has been significantly
+ reworked (and the detector API changed). It now supports visiting
+ the following additional scenarios:
+
+ * Fields in annotated classes and packages
+ * Fields and methods in annotated outerclasses
+ * Class and object literals
+ * Overridden methods
+ * File level annotations (from Kotlin)
+
+ It also offers better control for handling scopes -- providing all
+ relevant annotations in the hierarchy at the same time such that a
+ lint check for example can easily determine whether an outer
+ annotation like `@Immutable` is canceled by a closer `@Mutable`
+ annotation.
+
+ There are some new annotation usage type enum constants which let
+ your lint checks treat these differently. For example, the lint check
+ which makes sure that calls to methods annotated with `@CheckResult`
+ started flagging overrides of these methods. The fix was to add the
+ following override to the `CheckResultDetector`:
+
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+ override fun isApplicableAnnotationUsage(type: AnnotationUsageType): Boolean {
+ return type != AnnotationUsageType.METHOD_OVERRIDE &&
+ super.isApplicableAnnotationUsage(type)
+ }
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ (Using this new API constant will make your lint check only work with
+ the new version of lint. An alternative fix is to check that the
+ `usage` parameter is not a `UMethod`.)
+
+ For more, see the [new documentation](annotations.md.html) for
+ how to handle annotations from detectors.
+
+* The lint testing library now contains a new test file type, `rClass`,
+ which lets you easily construct Android `R` classes with resource
+ declarations (which are needed in tests that reference the R fields
+ to ensure that symbol resolution works.)
+
+* When you call `context.getLocation(UMethod)`, lint will now default
+ this method to be equivalent to `context.getNameLocation(UMethod)`
+ instead, which will highlight the method name. This might surface
+ itself as unit test failures where the location range moves from a
+ single `^` into a `~~~~~` range. This is because the location printer
+ uses `^` to just indicate the start offset when a range is multi-line.
+
+**7.0**
+
+* The API level has bumped to 10.
+
+* Partial analysis. Lint's architecture has changed to support better
+ scalability across large projects, where module results can be
+ cached, etc. See the api-guide's dedicated chapter for more details.
+ It is enabled by default starting in AGP 7.0.0-alpha13.
+
+* Issue registration now takes an optional `Vendor` property, where you
+ can specify information about which company or team provided this
+ lint check, which library it's associated with, contact information,
+ and so on. This will make it easier for users to figure out where to
+ send feedback or requests for 3rd party lint checks.
+
+* Bytecode verification: Instead of warning about 3rd party lint checks
+ being obsolete because they were not compiled against the latest Lint
+ API, lint now run its own bytecode verification against the lint jar
+ and will silently accept older (and newer!) lint checks if they do
+ not reference APIs that are not available.
+
+* Android Lint checks can now always access the resource repository for
+ random access to resources, instead of having to gather them in batch
+ mode. (Previously this was only available when lint checks were
+ running in the IDE.)
+
+* The lint unit testing library now provides a `TestMode` concept. You
+ can define setup and teardown methods, and lint will run unit tests
+ repeatedly for each test mode. There are a number of built-in test
+ modes already enabled; for example, all lint tests will run both in
+ global analysis mode and in partial analysis mode, and the results
+ compared to ensure they are the same.
+
+* Lint unit tests now include source contents for secondary locations
+ too. If the test fails, lint will retry without secondary source
+ locations and not report an error; this preserves backwards
+ compatibility.
+
+* There's a new `Incident` class which is used to hold information to
+ be reported to the user. Previously, there were a number of
+ overloaded methods to report issues, taking locations, error
+ messages, quick fixes, and so on. Each time we added another one we'd
+ have to add another overload. Now, you instead just report incidents.
+ This is critical to the new partial analysis architecture but is also
+ required if you for example want to override severities per incident
+ as described above.
+
+* Lint checks can now vary the severity on a per incident basis by
+ calling overrideSeverity on the incidents. This means that there is
+ no longer a need to create separate issues for flavors of the same
+ underlying problem with slightly different expectations around
+ warnings or errors.
+
+* There are additional modifier lookup methods for Kotlin modifiers
+ on `JavaEvaluator`, like `isReified()`, `isCompanion()`,
+ `isTailRec()`, and so on.
+
+* API documentation is now available.
+
+* UAST for Kotlin is now based on Kotlin 1.5.
+
+* Certain Kotlin PSI elements have new implementations known as _ultra
+ light classes_. Ultra light classes improve performance by answering
+ PSI queries “directly from source” rather than delegating to the
+ Kotlin compiler backend. You may see ultra light classes when
+ accessing the `UElement.javaPsi` property of a Kotlin UAST element.
+ They can also appear when resolving references. For example,
+ resolving a Kotlin field reference to its declaration may result in
+ an instance of `KtUltraLightFieldForSourceDeclaration`. As a
+ reminder, Kotlin light classes represent the “Java view” of an
+ underlying Kotlin PSI element. To access the underlying Kotlin PSI
+ element you should use `UElement.sourcePsi` (preferred) or otherwise
+ the extension property `PsiElement.unwrapped` (declared in
+ `org.jetbrains.kotlin.asJava`).
+
+* There is a new bug where calling `getNameIdentifier()` on Kotlin
+ fields may return `null`
+ ([KT-45629](https://youtrack.jetbrains.com/issue/KT-45629)).
+ As a workaround you can use `JavaContext.findNameElement()` instead.
+
+* Kotlin references to Java methods now trigger both the
+ `visitMethodCall()` callback _and_ the `visitReference()` callback.
+ Previously only `visitMethodCall()` was triggered.
+
+* Quickfixes can now create and delete new files; see
+ `LintFix#newFile` and `LintFix#deleteFile`.
+
+* For quickfixes, the `independent` property had inverted logic;
+ this has now been reversed to follow the meaning of the name.
+
+* The location range returned when looking up the location for a call
+ will now include arguments outside of the call range itself. This is
+ important when the code is using Kotlin's assignment syntax for
+ calling methods as if they are properties.
+
+* Lint's unit testing framework now checks all `import` statements in
+ test files to make sure that they resolve. This will help catch
+ common bugs and misunderstandings where tests reference frameworks
+ that aren't available to lint in the unit test, and where you need to
+ either add the library or more commonly just add some simple stubs.
+ If the import statements do not matter to the test, you can just mark
+ the test as allowing compilation errors, using
+ `.allowCompilationErrors()` on the `lint()` task.
+
+* The [data flow analyzer](dataflow-analyzer.md.html) has been
+ significantly improved, particularly around Kotlin scoping functions.
+
+
diff --git a/docs/api-guide/dataflow-analyzer.md.html b/docs/api-guide/dataflow-analyzer.md.html
new file mode 100644
index 00000000..1af02645
--- /dev/null
+++ b/docs/api-guide/dataflow-analyzer.md.html
@@ -0,0 +1,399 @@
+
+
+# Data Flow Analyzer
+
+The dataflow analyzer is a helper in lint which makes writing certain
+kinds of lint checks a lot easier.
+
+Let's say you have an API which creates an object, and then you want to
+make sure that at some point a particular method is called on the same
+instance.
+
+There are a lot of scenarios like this;
+
+* Calling `show` on a message in a Toast or Snackbar
+* Calling `commit` or `apply` on a transaction
+* Calling `recycle` on a TypedArray
+* Calling `enqueue` on a newly created work request
+
+and so on. I didn't include calling close on a file object since you
+typically use try-with-resources for those.
+
+Here are some examples:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+getFragmentManager().beginTransaction().commit() // OK
+val t1 = getFragmentManager().beginTransaction() // NEVER COMMITTED
+val t2 = getFragmentManager().beginTransaction() // OK
+t2.commit()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here we are creating 3 transactions. The first one is committed
+immediately. The second one is never committed. And the third one
+is.
+
+This example shows us creating multiple transactions, and that
+demonstrates that solving this problem isn't as simple as just visiting
+the method and seeing if the code invokes `Transaction#commit`
+anywhere; we have to make sure that it's invoked on all the instances
+we care about.
+
+## Usage
+
+To use the dataflow analyzer, you basically extend the
+`DataFlowAnalyzer` class, and override one or more of its callbacks,
+and then tell it to analyze a method scope.
+
+!!! Tip
+ In recent versions of lint, there is a new special subclass of the
+ `DataFlowAnalyzer`, `TargetMethodDataFlowAnalyzer`, which makes it
+ easier to write flow analyzers where you are looking for a specific
+ “cleanup” or close function invoked on an instance. See the separate
+ section on `TargetMethodDataFlowAnalyzer` below for more information.
+
+For the above transaction scenario, it might look like this:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+override fun getApplicableMethodNames(): List =
+ listOf("beginTransaction")
+
+override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) {
+ val containingClass = method.containingClass
+ val evaluator = context.evaluator
+
+ if (evaluator.extendsClass(containingClass, "android.app.FragmentManager", false)) {
+ // node is a call to FragmentManager.beginTransaction(),
+ // so this expression will evaluate to an instance of
+ // a Transaction. We want to track this instance to see
+ // if we eventually call commit on it.
+ var foundCommit = false
+ val visitor = object : DataFlowAnalyzer(setOf(node)) {
+ override fun receiver(call: UCallExpression) {
+ if (call.methodName == "commit") {
+ foundCommit = true
+ }
+ }
+ }
+ val method = node.getParentOfType(UMethod::class.java)
+ method?.accept(visitor)
+ if (!foundCommit) {
+ context.report(Incident(...))
+ }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+As you can see, the `DataFlowAnalyzer` is a visitor, so when we find a
+call we're interested in, we construct a `DataFlowAnalyzer` and
+initialize it with the instance we want to track, and then we visit the
+surrounding method with this visitor.
+
+The visitor will invoke the `receiver` method whenever the instance is
+invoked as the receiver of a method call; this is the case with
+`t2.commit()` in the above example; here “t2” is the receiver, and
+`commit` is the method call name.
+
+With the above setup, basic value tracking is working; e.g. it will
+correctly handle the following case:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+val t = getFragmentManager().beginTransaction().commit()
+val t2 = t
+val t3 = t2
+t3.commit()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+However, there's a lot that can go wrong, which we'll need to deal with. This is explained in the following sections
+
+## Self-referencing Calls
+
+The Transaction API has a number of utility methods; here's a partial
+list:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+public abstract class FragmentTransaction {
+ public abstract int commit();
+ public abstract int commitAllowingStateLoss();
+ public abstract FragmentTransaction show(Fragment fragment);
+ public abstract FragmentTransaction hide(Fragment fragment);
+ public abstract FragmentTransaction attach(Fragment fragment);
+ public abstract FragmentTransaction detach(Fragment fragment);
+ public abstract FragmentTransaction add(int containerViewId, Fragment fragment);
+ public abstract FragmentTransaction add(Fragment fragment, String tag);
+ public abstract FragmentTransaction addToBackStack(String name);
+ ...
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The reason all these methods return a `FragmentTransaction` is to make it easy to chain calls; e.g.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+final int id = getFragmentManager().beginTransaction()
+ .add(new Fragment(), null)
+ .addToBackStack(null)
+ .commit();
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In order to correctly analyze this, we'd need to know what the implementation of `add` and `addToBackStack` return. If we know that they simply return “this”, then it's easy; we can transfer the instance through the call.
+
+And this is what the `DataFlowAnalyzer` will try to do by default. When
+it encounters a call on our tracked receivers, it will try to guess
+whether that method is returning itself. It has several heuristics for
+this:
+
+* The return type is the same as its surrounding class, or a subtype of
+ it
+* It's an extension method returning the same type
+* It's not named something which indicates a new instance (such as
+ clone, copy, or to*X*), unless `ignoreCopies()` is overridden to
+ return false
+
+In our example, the above heuristics work, so out of the box, the lint check would correctly handle this scenario.
+
+But there may be cases where you either don't want these heuristics, or you want to add your own. In these cases, you would override the `returnsSelf` method on the flow analyzer and apply your own logic:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+val visitor = object : DataFlowAnalyzer(setOf(node)) {
+ override fun returnsSelf(call: UCallExpression): Boolean {
+ return super.returnsSelf(call) || call.methodName == "copy"
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+## Kotlin Scoping Functions
+
+With this in place, lint will track the flow through the method.
+This includes handling Kotlin's scoping functions as well. For
+example, it will automatically handle scenarios like the
+following:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+transaction1.let { it.commit() }
+transaction2.apply { commit() }
+with (transaction3) { commit() }
+transaction4.also { it.commit() }
+
+getFragmentManager.let {
+ it.beginTransaction()
+}.commit()
+
+// complex (contrived and unrealistic) example:
+transaction5.let {
+ it.also {
+ it.apply {
+ with(this) {
+ commit()
+ }
+ }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+## Limitations
+
+It doesn't try to “execute”, constant evaluation (maybe)
+if/else
+
+## Escaping Values
+
+What if your check gets invoked on a code snippet like this:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+fun createTransaction(): FragmentTransaction =
+ getFragmentManager().beginTransaction().add(new Fragment(), null)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here, we're not calling `commit`, so our lint check would issue a
+warning. However, it's quite possible and likely that elsewhere,
+there's code using it, like this:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+val transaction = createTransaction()
+...
+transaction.commit()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Ideally, we'd perform global analysis to handle this, but that's not
+currently possible. However, we *can* analyze some additional non-local
+scenarios, and more importantly, we need to ensure that we don't offer false positive warnings in the above scenario.
+
+### Returns
+
+In the above case, our tracked transaction “escapes” the method that
+we're analyzing through either an implicit return as in the above
+Kotlin code or via an explicit return.
+
+The analyzer has a callback method to let us know when this is happening. We can override that callback to remember that the value escapes, and if so, ignore the missing commit:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+var foundCommit = false
+var escapes = false
+val visitor = object : DataFlowAnalyzer(setOf(node)) {
+ override fun returns(expression: UReturnExpression) {
+ escapes = true
+ }
+
+ override fun argument(call: UCallExpression, reference: UElement) {
+ super.argument(call, reference)
+ }
+
+ override fun field(field: UElement) {
+ super.field(field)
+ }
+}
+node.getParentOfType(UMethod::class.java)?.accept(visitor)
+if (!escapes && !foundCommit) {
+ context.report(Incident(...))
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+### Parameters
+
+Another way our transaction can “escape” out of the method such that we
+no longer know for certain whether it gets committed is via a method
+call.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+fun test() {
+ val transaction = getFragmentManager().beginTransaction()
+ process(transaction)
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here, it's possible that the `process` method will proceed to actually
+commit the transaction.
+
+If we have source, we could resolve the call and take a look at the
+method implementation (see the “Non Local Analysis” section below), but
+in the general case, if a value escapes, we'll want to do something similar to a returned value. The analyzer has a callback for this, `argument`, which is invoked whenever our tracked value is passed into a method as an argument. The callback gives us both the argument and the call in case we want to handle conditional logic based on the specific method call.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+var escapes = false
+val visitor = object : DataFlowAnalyzer(setOf(node)) {
+ ...
+ override fun argument(call: UCallExpression, reference: UElement) {
+ escapes = true
+ }
+ ...
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(By default, the analyzer will ignore calls that look like logging calls since those are probably safe and not true escapes; you can
+customize this by overriding `ignoreArgument()`.)
+
+### Fields
+
+Finally, a value may escape a local method context if it gets stored
+into a field:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+fun initialize() {
+ this.transaction = createTransaction()
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+As with returns and method calls, the analyzer has a callback to make
+it easy to handle when this is the case:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+var escapes = false
+val visitor = object : DataFlowAnalyzer(setOf(node)) {
+ ...
+ override fun field(field: UElement) {
+ escapes = true
+ }
+ ...
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+As you can see, it's passing in the field that is being stored to, in
+case you want to perform additional analysis to track field values; see
+the next section.
+
+!!! Tip
+ There is a special subclass of the `DataFlowAnalyzer`, called
+ `EscapeCheckingDataFlowAnalyzer`, which you can extend instead. This
+ handles recording all the scenarios where the instance escapes from
+ the method, and at the end you can just check its `escaped` property.
+
+## Non Local Analysis
+
+In the above examples, if we found that the value escaped via a return
+or method call or storage in a field, we simply gave up. In some cases
+we can do better than that.
+
+* If the field we stored it into is a private field, we can visit
+ the surrounding class, and check each reference to the field. If we
+ can see that the field never escapes the class, we can perform the
+ same analysis (using the data flow analyzer!) on each method where
+ it's referenced.
+
+* Similarly, if the method which returns the value is private, we can
+ visit the surrounding class and see how the method is invoked, and
+ track the value returned from it in each usage.
+
+* Finally, if the value escapes as an argument to a call, we can
+ resolve that call, and if it's to a method we have source for (which
+ doesn't have to be in the same class, as long as it's in the same
+ module), we can perform the analysis in that method as well, even
+ reusing the same flow analyzer!
+
+Complications: - storing in a field, returning, intermediate variables, self-referencing methods, scoping functions,
+
+## Examples
+
+Here are some existing usages of the data flow analyzer in lint's
+built-in rules.
+
+### Simple Example
+
+For WorkManager, ensure that newly created work tasks eventually
+get enqueued:
+
+[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/WorkManagerDetector.kt)
+[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/WorkManagerDetectorTest.kt)
+
+### Complex Example
+
+For the Slices API, apply a number of checks on chained calls constructing slices, checking that you only specify a single timestamp, that you don't mix icons and actions, etc etc.
+
+[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)
+[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)
+
+## TargetMethodDataFlowAnalyzer
+
+The `TargetMethodDataFlowAnalyzer` is a special subclass of the
+`DataFlowAnalyzer` which makes it simple to see if you eventually wind up
+calling a target method on a particular instance. For example, calling
+`close` on a file that was opened, or calling `start` on an animation you
+created.
+
+In addition, there is an extension function on `UMethod` which visits
+this analyzer, and then checks for various conditions, e.g. whether the
+instance “escaped” (for example by being stored in a field or passed to
+another method), in which case you probably don't want to conclude (and
+report) that the close method is never called. It also handles failures
+to resolve, where it remembers whether there was a resolve failure, and
+if so it looks to see if it finds a likely match (with the same name as
+the target function), and if so also makes sure you don't report a false
+positive.
+
+A simple way to do this is as follows:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+val targets = mapOf("show" to listOf("android.widget.Toast",
+ "com.google.android.material.snackbar.Snackbar")
+val analyzer = TargetMethodDataFlowAnalyzer.create(node, targets)
+if (method.isMissingTarget(analyzer)) {
+ context.report(...)
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can subclass `TargetMethodDataFlowAnalyzer` directly and override the
+`getTargetMethod` methods and any other UAST visitor methods if you want
+to customize the behavior further.
+
+One advantage of using the `TargetMethodDataFlowAnalyzer` is that it also
+correctly handles method references.
+
+
diff --git a/docs/api-guide/example.md.html b/docs/api-guide/example.md.html
new file mode 100644
index 00000000..51c93d7c
--- /dev/null
+++ b/docs/api-guide/example.md.html
@@ -0,0 +1,362 @@
+
+
+# Example: Sample Lint Check GitHub Project
+
+The [](https://github.com/googlesamples/android-custom-lint-rules)
+GitHub project provides a sample lint check which shows a working
+skeleton.
+
+This chapter walks through that sample project and explains
+what and why.
+
+## Project Layout
+
+Here's the project layout of the sample project:
+
+*******************************************************************
+* *
+* +----+ implementation +--------+ lintPublish +-------+ *
+* |:app+----------------->|:library+-------------->|:checks| *
+* +----+ +--------+ +-------+ *
+* *
+*******************************************************************
+
+We have an application module, `app`, which depends (via an
+`implementation` dependency) on a `library`, and the library itself has
+a `lintPublish` dependency on the `checks` project.
+
+## :checks
+
+The `checks` project is where the actual lint checks are implemented.
+This project is a plain Kotlin or plain Java Gradle project:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+apply plugin: 'java-library'
+apply plugin: 'kotlin'
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+!!! Tip
+ If you look at the sample project, you'll see a third plugin
+ applied: `apply plugin: 'com.android.lint'`. This pulls in the
+ standalone Lint Gradle plugin, which adds a lint target to this
+ Kotlin project. This means that you can run `./gradlew lint` on the
+ `:checks` project too. This is useful because lint ships with a
+ dozen lint checks that look for mistakes in lint detectors! This
+ includes warnings about using the wrong UAST methods, invalid id
+ formats, words in messages which look like code which should
+ probably be surrounded by apostrophes, etc.
+
+The Gradle file also declares the dependencies on lint APIs
+that our detector needs:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+dependencies {
+ compileOnly "com.android.tools.lint:lint-api:$lintVersion"
+ compileOnly "com.android.tools.lint:lint-checks:$lintVersion"
+ testImplementation "com.android.tools.lint:lint-tests:$lintVersion"
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The second dependency is usually not necessary; you just need to depend
+on the Lint API. However, the built-in checks define a lot of
+additional infrastructure which it's sometimes convenient to depend on,
+such as `ApiLookup` which lets you look up the required API level for a
+given method, and so on. Don't add the dependency until you need it.
+
+## lintVersion?
+
+What is the `lintVersion` variable defined above?
+
+Here's the top level build.gradle
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+buildscript {
+ ext {
+ kotlinVersion = '1.4.32'
+
+ // Current lint target: Studio 4.2 / AGP 7
+ //gradlePluginVersion = '4.2.0-beta06'
+ //lintVersion = '27.2.0-beta06'
+
+ // Upcoming lint target: Arctic Fox / AGP 7
+ gradlePluginVersion = '7.0.0-alpha10'
+ lintVersion = '30.0.0-alpha10'
+ }
+
+ repositories {
+ google()
+ mavenCentral()
+ }
+ dependencies {
+ classpath "com.android.tools.build:gradle:$gradlePluginVersion"
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The `$lintVersion` variable is defined on line 11. We don't technically
+need to define the `$gradlePluginVersion` here or add it to the classpath on line 19, but that's done so that we can add the `lint`
+plugin on the checks themselves, as well as for the other modules,
+`:app` and `:library`, which do need it.
+
+When you build lint checks, you're compiling against the Lint APIs
+distributed on maven.google.com (which is referenced via `google()` in
+Gradle files). These follow the Gradle plugin version numbers.
+
+Therefore, you first pick which of lint's API you'd like to compile
+against. You should use the latest available if possible.
+
+Once you know the Gradle plugin version number, say 4.2.0-beta06, you
+can compute the lint version number by simply adding **23** to the
+major version of the gradle plugin, and leave everything the same:
+
+**lintVersion = gradlePluginVersion + 23.0.0**
+
+For example, 7 + 23 = 30, so AGP version *7.something* corresponds to
+Lint version *30.something*. As another example; as of this writing the
+current stable version of AGP is 4.1.2, so the corresponding version of
+the Lint API is 27.1.2.
+
+!!! Tip
+ Why this arbitrary numbering -- why can't lint just use the same
+ numbers? This is historical; lint (and various other sibling
+ libraries that lint depends on) was released earlier than the Gradle
+ plugin; it was up to version 22 or so. When we then shipped the
+ initial version of the Gradle plugin with Android Studio 1.0, we
+ wanted to start the numbering over from “1” for this brand new
+ artifact. However, some of the other libraries, like lint, couldn't
+ just start over at 1, so we continued incrementing their versions in
+ lockstep. Most users don't see this, but it's a wrinkle users of the
+ Lint API have to be aware of.
+
+## :library and :app
+
+The `library` project depends on the lint check project, and will
+package the lint checks as part of its payload. The `app` project
+then depends on the `library`, and has some code which triggers
+the lint check. This is there to demonstrate how lint checks can
+be published and consumed, and this is described in detail in the
+[Publishing a Lint Check](publishing.md.html) chapter.
+
+## Lint Check Project Layout
+
+The lint checks source project is very simple
+
+```
+checks/build.gradle
+checks/src/main/resources/META-INF/services/com.android.tools.lint.client.api.IssueRegistry
+checks/src/main/java/com/example/lint/checks/SampleIssueRegistry.kt
+checks/src/main/java/com/example/lint/checks/SampleCodeDetector.kt
+checks/src/test/java/com/example/lint/checks/SampleCodeDetectorTest.kt
+```
+
+First is the build file, which we've discussed above.
+
+## Service Registration
+
+Then there's the service registration file. Notice how this file is in
+the source set `src/main/resources/`, which means that Gradle will
+treat it as a resource and will package it into the output jar, in the
+`META-INF/services` folder. This is using the service-provider loading facility in the JDK to register a service lint can look up. The
+key is the fully qualified name for lint's `IssueRegistry` class.
+And the **contents** of that file is a single line, the fully
+qualified name of the issue registry:
+
+```
+$ cat checks/src/main/resources/META-INF/services/com.android.tools.lint.client.api.IssueRegistry
+com.example.lint.checks.SampleIssueRegistry
+```
+
+(The service loader mechanism is understood by IntelliJ, so it will
+correctly update the service file contents if the issue registry is
+renamed etc.)
+
+The service registration can contain more than one issue registry,
+though there's usually no good reason for that, since a single issue
+registry can provide multiple issues.
+
+## IssueRegistry
+
+Next we have the `IssueRegistry` linked from the service registration.
+Lint will instantiate this class and ask it to provide a list of
+issues. These are then merged with lint's other issues when lint
+performs its analysis.
+
+In its simplest form we'd only need to have the following code
+in that file:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+package com.example.lint.checks
+import com.android.tools.lint.client.api.IssueRegistry
+class SampleIssueRegistry : IssueRegistry() {
+ override val issues = listOf(SampleCodeDetector.ISSUE)
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+However, we're also providing some additional metadata about these lint
+checks, such as the `Vendor`, which contains information about the
+author and (optionally) contact address or bug tracker information,
+displayed to users when an incident is found.
+
+We also provide some information about which version of lint's API the
+check was compiled against, and the lowest version of the lint API that
+this lint check has been tested with. (Note that the API versions are
+not identical to the versions of lint itself; the idea and hope is that
+the API may evolve at a slower pace than updates to lint delivering new
+functionality).
+
+## Detector
+
+The `IssueRegistry` references the `SampleCodeDetector.ISSUE`,
+so let's take a look at `SampleCodeDetector`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+class SampleCodeDetector : Detector(), UastScanner {
+
+ // ...
+
+ companion object {
+ /**
+ * Issue describing the problem and pointing to the detector
+ * implementation.
+ */
+ @JvmField
+ val ISSUE: Issue = Issue.create(
+ // ID: used in @SuppressLint warnings etc
+ id = "SampleId",
+ // Title -- shown in the IDE's preference dialog, as category headers in the
+ // Analysis results window, etc
+ briefDescription = "Lint Mentions",
+ // Full explanation of the issue; you can use some markdown markup such as
+ // `monospace`, *italic*, and **bold**.
+ explanation = """
+ This check highlights string literals in code which mentions the word `lint`. \
+ Blah blah blah.
+
+ Another paragraph here.
+ """,
+ category = Category.CORRECTNESS,
+ priority = 6,
+ severity = Severity.WARNING,
+ implementation = Implementation(
+ SampleCodeDetector::class.java,
+ Scope.JAVA_FILE_SCOPE
+ )
+ )
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The `Issue` registration is pretty self-explanatory, and the details
+about issue registration are covered in the [basics](basics.md.html)
+chapter. The excessive comments here are there to explain the sample,
+and there are usually no comments in issue registration code like this.
+
+Note how on line 29, the `Issue` registration names the `Detector`
+class responsible for analyzing this issue: `SampleCodeDetector`. In
+the above I deleted the body of that class; here it is now without the
+issue registration at the end:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package com.example.lint.checks
+
+import com.android.tools.lint.client.api.UElementHandler
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Detector.UastScanner
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import org.jetbrains.uast.UElement
+import org.jetbrains.uast.ULiteralExpression
+import org.jetbrains.uast.evaluateString
+
+class SampleCodeDetector : Detector(), UastScanner {
+ override fun getApplicableUastTypes(): List> {
+ return listOf(ULiteralExpression::class.java)
+ }
+
+ override fun createUastHandler(context: JavaContext): UElementHandler {
+ return object : UElementHandler() {
+ override fun visitLiteralExpression(node: ULiteralExpression) {
+ val string = node.evaluateString() ?: return
+ if (string.contains("lint") && string.matches(Regex(".*\\blint\\b.*"))) {
+ context.report(
+ ISSUE, node, context.getLocation(node),
+ "This code mentions `lint`: **Congratulations**"
+ )
+ }
+ }
+ }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This lint check is very simple; for Kotlin and Java files, it visits
+all the literal strings, and if the string contains the word “lint”,
+then it issues a warning.
+
+This is using a very general mechanism of AST analysis; specifying the
+relevant node types (literal expressions, on line 18) and visiting them
+on line 23. Lint has a large number of convenience APIs for doing
+higher level things, such as “call this callback when somebody extends
+this class”, or “when somebody calls a method named `foo`”, and so on.
+Explore the `SourceCodeScanner` and other `Detector` interfaces to see
+what's possible. We'll hopefully also add more dedicated documentation
+for this.
+
+## Detector Test
+
+Last but not least, let's not forget the unit test:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package com.example.lint.checks
+
+import com.android.tools.lint.checks.infrastructure.TestFiles.java
+import com.android.tools.lint.checks.infrastructure.TestLintTask.lint
+import org.junit.Test
+
+class SampleCodeDetectorTest {
+ @Test
+ fun testBasic() {
+ lint().files(
+ java(
+ """
+ package test.pkg;
+ public class TestClass1 {
+ // In a comment, mentioning "lint" has no effect
+ private static String s1 = "Ignore non-word usages: linting";
+ private static String s2 = "Let's say it: lint";
+ }
+ """
+ ).indented()
+ )
+ .issues(SampleCodeDetector.ISSUE)
+ .run()
+ .expect(
+ """
+ src/test/pkg/TestClass1.java:5: Warning: This code mentions lint: Congratulations [SampleId]
+ private static String s2 = "Let's say it: lint";
+ ∼∼∼∼∼∼∼∼∼∼∼∼∼∼∼∼∼∼∼∼
+ 0 errors, 1 warnings
+ """
+ )
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+As you can see, writing a lint unit test is very simple, because
+lint ships with a dedicated testing library; this is what the
+
+```
+ testImplementation "com.android.tools.lint:lint-tests:$lintVersion"
+```
+
+dependency in build.gradle pulled in.
+
+Unit testing lint checks is covered in depth in the
+[unit testing chapter](unit-testing.md.html), so we'll cut the
+explanation of the above test short here.
+
+
diff --git a/docs/api-guide/faq.md.html b/docs/api-guide/faq.md.html
new file mode 100644
index 00000000..d0a9ac87
--- /dev/null
+++ b/docs/api-guide/faq.md.html
@@ -0,0 +1,335 @@
+
+
+# Frequently Asked Questions
+
+This chapter contains a random collection of questions people
+have asked in the past.
+
+### My detector callbacks aren't invoked
+
+If you've for example implemented the Detector callback for visiting
+method calls, `visitMethodCall`, notice how the third parameter is a
+`PsiMethod`, and that it is not nullable:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ open fun visitMethodCall(
+ context: JavaContext,
+ node: UCallExpression,
+ method: PsiMethod
+ ) {
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This passes in the method that has been called. When lint is visiting
+the AST, it will resolve calls, and if the called method cannot be
+resolved, the callback won't be called.
+
+This happens when the classpath that lint has been configured with does
+not contain everything needed. When lint is running from Gradle, this
+shouldn't happen; the build system should have a complete classpath and
+pass it to Lint (or the build wouldn't have succeeded in the first
+place).
+
+This usually comes up in unit tests for lint, where you've added a test
+case which is referencing some API for some library, but the library
+itself isn't part of the test. The solution for this is to create stubs
+for the part of the API you care about. This is discussed in more
+detail in the [unit testing](unit-testing.md.html) chapter.
+
+### My lint check works from the unit test but not in the IDE
+
+There are several things to check if you have a lint check which
+works correctly from your unit test but not in the IDE.
+
+1. First check that the lint jar is packaged correctly; use `jar tvf
+ lint.jar` to look at the jar file to make sure it contains the
+ service loader registration of your issue registry, and `javap
+ -classpath lint.jar com.example.YourIssueRegistry` to inspect your
+ issue registry.
+
+2. If that's correct, the next thing to check is that lint is actually
+ loading your issue registry. First look in the IDE log (from the
+ Help menu) to make sure there aren't log messages from lint
+ explaining why it can't load the registry, for example because it
+ does not specify a valid applicable API range.
+
+3. If there's no relevant warning in the log, try setting the
+ `$ANDROID_LINT_JARS` environment variable to point directly to your
+ lint jar file and restart Studio to make sure that that works.
+
+4. Next, try running **Analyze | Inspect Code...**. This runs lint on
+ the whole project. If that works, then the issue is that your lint
+ check isn't eligible to run “on the fly”; the reason for this is
+ that your implementation scope registers more than one scope, which
+ says that your lint check can only run if lint gets to look at both
+ types of files, and in the editor, only the current file is analyzed
+ by lint. However, you can still make the check work on the fly by
+ specifying additional analysis scopes; see the API guide for more
+ information about this.
+
+### `visitAnnotationUsage` isn't called for annotations
+
+If you want to just visit any annotation declarations (e.g. `@Foo` on
+method `foo`), don't use the `applicableAnnotations` and
+`visitAnnotationUsage` machinery. The purpose of that facility is to
+look at *elements* that are being combined with annotated elements,
+such as a method call to a method whose return value has been
+annotated, or an argument to a method a method parameter that has been
+annotated, or assigning an assigned value to an annotated variable, etc.
+
+If you just want to look at annotations, use `getApplicableUastTypes`
+with `UAnnotation::class.java`, and a `UElementHandler` which overrides
+`visitAnnotation`.
+
+### How do I check if a UAST or PSI element is for Java or Kotlin?
+
+To check whether an element is in Java or Kotlin, call one
+of the package level methods in the detector API (and from
+Java, you can access them as utility methods on the “Lint”
+class) :
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+package com.android.tools.lint.detector.api
+
+/** Returns true if the given element is written in Java. */
+fun isJava(element: PsiElement?): Boolean { /* ... */ }
+
+/** Returns true if the given language is Kotlin. */
+fun isKotlin(language: Language?): Boolean { /* ... */ }
+
+/** Returns true if the given language is Java. */
+fun isJava(language: Language?): Boolean { /* ... */ }
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you have a `UElement` and need a `PsiElement` for the above method,
+see the next question.
+
+### What if I need a `PsiElement` and I have a `UElement` ?
+
+If you have a `UElement`, you can get the underlying source PSI element
+by calling `element.sourcePsi`.
+
+### How do I get the `UMethod` for a `PsiMethod` ?
+
+Call `psiMethod.toUElementOfType<UMethod>()`. Note that this may return
+null if UAST cannot find valid Java or Kotlin source code for the
+method.
+
+For `PsiField` and `PsiClass` instances use the equivalent
+`toUElementOfType` type arguments.
+
+### How do get a `JavaEvaluator`?
+
+The `Context` passed into most of the `Detector` callback methods
+relevant to Kotlin and Java analysis is of type `JavaContext`, and it
+has a public `evaluator` property which provides a `JavaEvaluator` you
+can use in your analysis.
+
+If you need one outside of that scenario (this is not common) you can
+construct one directly by instantiating a `DefaultJavaEvaluator`; the
+constructor parameters are nullable, and are only needed for a couple
+of operations on the evaluator.
+
+### How do I check whether an element is internal?
+
+First get a `JavaEvaluator` as explained above, then call
+this evaluator method:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+open fun isInternal(owner: PsiModifierListOwner?): Boolean { /* ... */
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(Note that a `PsiModifierListOwner` is an interface which includes
+`PsiMethod`, `PsiClass`, `PsiField`, `PsiMember`, `PsiVariable`, etc.)
+
+### Is element inline, sealed, operator, infix, suspend, data?
+
+Get the `JavaEvaluator` as explained above, and then call one of these
+evaluator method:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+open fun isData(owner: PsiModifierListOwner?): Boolean { /* ... */
+open fun isInline(owner: PsiModifierListOwner?): Boolean { /* ... */
+open fun isLateInit(owner: PsiModifierListOwner?): Boolean { /* ... */
+open fun isSealed(owner: PsiModifierListOwner?): Boolean { /* ... */
+open fun isOperator(owner: PsiModifierListOwner?): Boolean { /* ... */
+open fun isInfix(owner: PsiModifierListOwner?): Boolean { /* ... */
+open fun isSuspend(owner: PsiModifierListOwner?): Boolean { /* ... */
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+### How do I look up a class if I have its fully qualified name?
+
+Get the `JavaEvaluator` as explained above, then call
+`evaluator.findClass(qualifiedName: String)`. Note that the result is
+nullable.
+
+### How do I look up a class if I have a PsiType?
+
+Get the `JavaEvaluator` as explained above, then call
+`evaluator.getTypeClass`. To go from a class to its type,
+use `getClassType`.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+ abstract fun getClassType(psiClass: PsiClass?): PsiClassType?
+ abstract fun getTypeClass(psiType: PsiType?): PsiClass?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+### How do I look up hierarchy annotations for an element?
+
+You can directly look up annotations via the modified list
+of PsiElement or the annotations for a `UAnnotated` element,
+but if you want to search the inheritance hierarchy for
+annotations (e.g. if a method is overriding another, get
+any annotations specified on super implementations), use
+one of these two evaluator methods:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+ abstract fun getAllAnnotations(
+ owner: UAnnotated,
+ inHierarchy: Boolean
+ ): List
+
+ abstract fun getAllAnnotations(
+ owner: PsiModifierListOwner,
+ inHierarchy: Boolean
+ ): Array
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+### How do I look up if a class is a subclass of another?
+
+To see if a method is a direct member of a particular
+named class, use the following method in `JavaEvaluator`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+fun isMemberInClass(member: PsiMember?, className: String): Boolean { }
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To see if a method is a member in any *subclass* of a named class, use
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+ open fun isMemberInSubClassOf(
+ member: PsiMember,
+ className: String,
+ strict: Boolean = false
+ ): Boolean { /* ... */ }
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here, use `strict = true` if you don't want to include members in the
+named class itself as a match.
+
+To see if a class extends another or implements an interface, use one
+of these methods. Again, `strict` controls whether we include the super
+class or super interface itself as a match.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ abstract fun extendsClass(
+ cls: PsiClass?,
+ className: String,
+ strict: Boolean = false
+ ): Boolean
+
+ abstract fun implementsInterface(
+ cls: PsiClass,
+ interfaceName: String,
+ strict: Boolean = false
+ ): Boolean
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+### How do I know which parameter a call argument corresponds to?
+
+In Java, matching up the arguments in a call with the parameters in the
+called method is easy: the first argument corresponds to the first
+parameter, the second argument corresponds to the second parameter and
+so on. If there are more arguments than parameters, the last arguments
+are all vararg arguments to the last parameter.
+
+In Kotlin, it's much more complicated. With named parameters, but
+arguments can appear in any order, and with default parameters, only
+some of them may be specified. And if it's an extension method, the
+first argument passed to a `PsiMethod` is actually the instance itself.
+
+Lint has a utility method to help with this on the `JavaEvaluator`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ open fun computeArgumentMapping(
+ call: UCallExpression,
+ method: PsiMethod
+ ): Map<UExpression, PsiParameter> { /* ... */
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This returns a map from UAST expressions (each argument to a UAST call
+is a `UExpression`, and these are the `valueArguments` property on the
+`UCallExpression`) to each corresponding `PsiParameter` on the
+`PsiMethod` that the method calls.
+
+### How can my lint checks target two different versions of lint?
+
+If you need to ship different versions of your lint checks to target
+different versions of lint (because perhaps you need to work both with
+an older version of lint, and a newer version that has a different
+API), the way to do this (as of Lint 7.0) is to use the `maxApi`
+property on the `IssueRegistry`. In the service loader registration
+(`META-INF/services`), register *two* issue registries; one for each
+implementation, and mark the older one with the right `minApi` to
+`maxApi` range, and the newer one with `minApi` following the previous
+registry's `maxApi`. (Both `minApi` and `maxApi` are inclusive). When
+lint loads the issue registries it will ignore registries with a range
+outside of the current API level.
+
+### Can I make my lint check “not suppressible?”
+
+In some (hopefully rare) cases, you may want your lint checks to not be
+suppressible using the normal mechanisms -- suppress annotations,
+comments, lint.xml files, baselines, and so on. The usecase for this is
+typically strict company guidelines around compliance or security and
+you want to remove the easy possibility of just silencing the check.
+
+This is possible as part of the issue registration. After creating your
+`Issue`, set the `suppressNames` property to an **empty** collection.
+
+### Why are overloaded operators not handled?
+
+Kotlin supports overloaded operators, but these are not handled as
+calls in the AST -- instead, an implicit `get` or `set` method from an
+array access will show up as a `UArrayAccessExpression`. Lint has
+specific support to help handling these scenarios; see the “Implicit
+Calls” section in the [basics chapter](basics.md.html).
+
+### How do I check out the current lint source code?
+
+```shell
+$ git clone --branch=mirror-goog-studio-main --single-branch \
+ https://android.googlesource.com/platform/tools/base
+Cloning into 'base'...
+remote: Total 648820 (delta 325442), reused 635137 (delta 325442)
+Receiving objects: 100% (648820/648820), 1.26 GiB | 15.52 MiB/s, done.
+Resolving deltas: 100% (325442/325442), done.
+Updating files: 100% (14416/14416), done.
+
+$ du -sh base
+1.8G base
+$ cd base/lint
+$ ls
+.editorconfig BUILD build.gradle libs/
+.gitignore MODULE_LICENSE_APACHE2 cli/
+$ ls libs/
+intellij-core/ kotlin-compiler/ lint-api/ lint-checks/ lint-gradle/ lint-model/ lint-tests/ uast/
+```
+
+### Where do I find examples of lint checks?
+
+The built-in lint checks are a good source. Check out the source code
+as shown above and look in
+`lint/libs/lint-checks/src/main/java/com/android/tools/lint/checks/` or
+browse sources online:
+[](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/)
+
+### How do I analyze details about Kotlin?
+
+The new Kotlin Analysis API offers access to detailed information about
+Kotlin (types, resolution, as well as information the compiler has
+figured out such as smart casts, nullability, deprecation info, and so
+on). There are more details about this, as well as a number of recipes,
+in the [AST Analysis chapter](ast-analysis.md.html).
+
+
diff --git a/docs/api-guide/fully-qualified-error.png b/docs/api-guide/fully-qualified-error.png
new file mode 100644
index 00000000..7e08dfcc
Binary files /dev/null and b/docs/api-guide/fully-qualified-error.png differ
diff --git a/docs/api-guide/images/java-psi.png b/docs/api-guide/images/java-psi.png
new file mode 100644
index 00000000..35df46c5
Binary files /dev/null and b/docs/api-guide/images/java-psi.png differ
diff --git a/docs/api-guide/images/kotlin-psi.png b/docs/api-guide/images/kotlin-psi.png
new file mode 100644
index 00000000..40ebb087
Binary files /dev/null and b/docs/api-guide/images/kotlin-psi.png differ
diff --git a/docs/api-guide/images/uast-if.png b/docs/api-guide/images/uast-if.png
new file mode 100644
index 00000000..b63d03a0
Binary files /dev/null and b/docs/api-guide/images/uast-if.png differ
diff --git a/docs/api-guide/images/uast-java.png b/docs/api-guide/images/uast-java.png
new file mode 100644
index 00000000..23314e08
Binary files /dev/null and b/docs/api-guide/images/uast-java.png differ
diff --git a/docs/api-guide/images/uast-kotlin-val.png b/docs/api-guide/images/uast-kotlin-val.png
new file mode 100644
index 00000000..c34bd9c9
Binary files /dev/null and b/docs/api-guide/images/uast-kotlin-val.png differ
diff --git a/docs/api-guide/images/uast-kotlin.png b/docs/api-guide/images/uast-kotlin.png
new file mode 100644
index 00000000..57b66ade
Binary files /dev/null and b/docs/api-guide/images/uast-kotlin.png differ
diff --git a/docs/api-guide/images/uast-sourcepsi-type.png b/docs/api-guide/images/uast-sourcepsi-type.png
new file mode 100644
index 00000000..c30290ba
Binary files /dev/null and b/docs/api-guide/images/uast-sourcepsi-type.png differ
diff --git a/docs/api-guide/images/uast-sourcepsi.png b/docs/api-guide/images/uast-sourcepsi.png
new file mode 100644
index 00000000..02bd5532
Binary files /dev/null and b/docs/api-guide/images/uast-sourcepsi.png differ
diff --git a/docs/api-guide/messages.md.html b/docs/api-guide/messages.md.html
new file mode 100644
index 00000000..496677aa
--- /dev/null
+++ b/docs/api-guide/messages.md.html
@@ -0,0 +1,189 @@
+
+
+# Error Message Conventions
+
+## Length
+
+The error message reported by a detector should typically be short; think of
+typical compiler error messages you see from `kotlinc` or `javac`.
+
+This is particularly important when your lint check is running inside the IDE,
+because the error message will typically be shown as a tooltip as the user
+hovers over the underlined symbol.
+
+It's tempting to try to fully explain what's going on, but lint has separate
+facilities for that -- the issue explanation metadata. When lint generates text
+and html reports, it will include the explanation metadata. Similarly, in the
+IDE, users can pull up the full explanation with a tooltip.
+
+This is not a hard rule; there are cases where lint uses multiple sentences to
+explain an issue, but strive to make the error message as short as possible
+while still legible.
+
+## Formatting
+
+Use the available formatting support for text in lint:
+
+Raw text format | Renders To
+-----------------------------|--------------------------
+This is a \`code symbol\` | This is a `code symbol`
+This is `*italics*` | This is *italics*
+This is `**bold**` | This is **bold**
+This is `~~strikethrough~~` | This is ~~strikethrough~~
+http://, https:// | [](http://), [](https://)
+`\*not italics*` | `\*not italics*`
+\`\`\`language\n text\n\`\`\`| (preformatted text block)
+ [Supported markup in lint's markdown-like raw text format]
+
+In particular, when referencing code elements such as variable names, APIs, and
+so on, use the code symbol formatting (\`like this\`), not simple or double
+quotes.
+
+## Punctuation
+
+One line error messages should not be punctuated -- e.g. the error message
+should be “Unused import foo”, not “Unused import foo.”
+
+However, if there are multiple sentences in the error message, all sentences
+should be punctuated.
+
+Note that there should be no space before an exclamation (!) or question mark
+(?) sign.
+
+## Include Details
+
+Avoid generic error messages such as “Unused import”; try to incorporate
+specific details from the current error. In the unused import example, instead
+of just saying “Unused import”, say “Unused import java.io.List”.
+
+In addition to being clearer (you can see from the error message what the
+problem is without having to look up the corresponding source code), this is
+important to support lint's [baseline](../usage/baselines.md.html) feature.
+Lint matches known errors not by matching on specific line numbers (which would
+cause problems as soon as the line numbers drift after edits to the file), lint
+matches by error message in the file, so the more unique error messages are,
+the better. If all unused import warnings were just “Unused import”, lint would
+match them in order, which often would match the wrong import.
+
+## Reference Android By Number
+
+When referring to Android behaviors introduced in new API levels, use the
+phrase “In Android 12 and higher”, instead of variations like “Android S” or
+“API 31”.
+
+## Keep Messages Stable
+
+Once you have written an error message, think twice before changing it. This is
+again because of the baseline mechanism mentioned above. If users have already
+run lint with your previous error message, and that message has been written
+into baselines, changing the error message will cause the baseline to no longer
+match, which means this will show up as a new error for users.
+
+If you **have** to change an error message because it's misleading, then of
+course, do that -- but avoid it if there isn't a strong reason to do so.
+
+There *are* some edits you can make to the error message which the baseline
+matcher will handle:
+
+* Adding a suffix
+* Adding a suffix which also changes the final punctuation; e.g. changing
+ “Hello.” to “Hello, world!” is compatible.
+* Adding a prefix
+
+## Plurals
+
+Avoid trying to make sentences gramatically correct and flexible by
+using constructs like “(s)” to quantity strings. In other words,
+instead of for example saying
+
+ *“register your receiver(s) in the manifest”*
+
+just use the plural form,
+
+ *“register your receivers in the manifest”*
+
+## Examples
+
+Here are some examples from lint's built-in checks. Note that these are not
+chosen as great examples of clear error messages; most of these were written
+by engineers without review from a tech writer. But for better or worse they
+reflect the “tone” of the built-in lint checks today. (These were derived from
+lint's unit test suite, which explains silly symbols like `test.pkg` in the
+error messages.)
+
+Note that the [Id] block is not part of the error message; it's included here
+to help cross reference the messages with the corresponding lint check.
+
+* [AccidentalOctal] The leading 0 turns this number into octal which is probably not what was intended (interpreted as 8)
+* [AdapterViewChildren] A list/grid should have no children declared in XML
+* [AllCaps] Using \`textAllCaps\` with a string (\`has_markup\`) that contains markup; the markup will be dropped by the caps conversion
+* [AllowAllHostnameVerifier] Using the \`AllowAllHostnameVerifier\` HostnameVerifier is unsafe because it always returns true, which could cause insecure network traffic due to trusting TLS/SSL server certificates for wrong hostnames
+* [AlwaysShowAction] Prefer \`ifRoom\` instead of \`always\`
+* [AndroidGradlePluginVersion] A newer version of com.android.tools.build:gradle than 3.3.0-alpha04 is available: 3.3.2
+* [AnimatorKeep] This method is accessed from an ObjectAnimator so it should be annotated with \`@Keep\` to ensure that it is not discarded or renamed in release builds
+* [AnnotateVersionCheck] This field should be annotated with \`ChecksSdkIntAtLeast(api=Build.VERSION_CODES.LOLLIPOP)\`
+* [AnnotationProcessorOnCompilePath] Add annotation processor to processor path using \`annotationProcessor\` instead of \`api\`
+* [AppBundleLocaleChanges] Found dynamic locale changes, but did not find corresponding Play Core library calls for downloading languages and splitting by language is not disabled in the \`bundle\` configuration
+* [AppCompatCustomView] This custom view should extend \`android.support.v7.widget.AppCompatButton\` instead
+* [AppCompatMethod] Should use \`getSupportActionBar\` instead of \`getActionBar\` name
+* [AppCompatResource] Should use \`android:showAsAction\` when not using the appcompat library
+* [AppIndexingService] \`UPDATE_INDEX\` is configured as a service in your app, which is no longer supported for the API level you're targeting. Use a \`BroadcastReceiver\` instead.
+* [AppLinkUrlError] Missing URL for the intent filter
+* [AppLinksAutoVerify] This host does not support app links to your app. Checks the Digital Asset Links JSON file: http://example.com/.well-known/assetlinks.json
+* [ApplySharedPref] Consider using \`apply()\` instead; \`commit\` writes its data to persistent storage immediately, whereas \`apply\` will handle it in the background
+* [AssertionSideEffect] Assertion condition has a side effect: i++
+* [Autofill] Missing \`autofillHints\` attribute
+* [BackButton] Back buttons are not standard on Android; see design guide's navigation section
+* [BadHostnameVerifier] \`verify\` always returns \`true\`, which could cause insecure network traffic due to trusting TLS/SSL server certificates for wrong hostnames
+* [BatteryLife] Use of \`com.android.camera.NEW_PICTURE\` is deprecated for all apps starting with the N release independent of the target SDK. Apps should not rely on these broadcasts and instead use \`WorkManager\`
+* [BidiSpoofing] Comment contains misleading Unicode bidirectional text
+* [BlockedPrivateApi] Reflective access to NETWORK_TYPES is forbidden when targeting API 28 and above
+* [BottomAppBar] This \`BottomAppBar\` must be wrapped in a \`CoordinatorLayout\` (\`android.support.design.widget.CoordinatorLayout\`)
+* [BrokenIterator] \`Vector#listIterator\` was broken in API 24 and 25; it can return \`hasNext()=false\` before the last element. Consider switching to \`ArrayList\` with synchronization if you need it.
+* [ButtonCase] @android:string/yes actually returns “OK”, not “Yes”; use @android:string/ok instead or create a local string resource for Yes
+* [ButtonOrder] OK button should be on the right (was “OK | Cancel”, should be “Cancel | OK”)
+* [ButtonStyle] Buttons in button bars should be borderless; use \`style="?android:attr/buttonBarButtonStyle"\` (and \`?android:attr/buttonBarStyle\` on the parent)
+* [ByteOrderMark] Found byte-order-mark in the middle of a file
+* [CanvasSize] Calling \`Canvas.getWidth()\` is usually wrong; you should be calling \`getWidth()\` instead
+* [CheckResult] The result of \`double\` is not used
+* [ClickableViewAccessibility] Custom view \`\`NoPerformClick\`\` has \`setOnTouchListener\` called on it but does not override \`performClick\`
+* [CoarseFineLocation] If you need access to FINE location, you must request both \`ACCESS_FINE_LOCATION\` and \`ACCESS_COARSE_LOCATION\`
+* [CommitPrefEdits] \`SharedPreferences.edit()\` without a corresponding \`commit()\` or \`apply()\` call
+* [CommitTransaction] This transaction should be completed with a \`commit()\` call
+* [ConstantLocale] Assigning \`Locale.getDefault()\` to a final static field is suspicious; this code will not work correctly if the user changes locale while the app is running
+* [ContentDescription] Missing \`contentDescription\` attribute on image
+* [ConvertToWebp] One or more images in this project can be converted to the WebP format which typically results in smaller file sizes, even for lossless conversion
+* [CustomPermissionTypo] Did you mean \`my.custom.permission.FOOBAR\`?
+* [CustomSplashScreen] The application should not provide its own launch screen
+* [CustomViewStyleable] By convention, the custom view (\`CustomView1\`) and the declare-styleable (\`MyDeclareStyleable\`) should have the same name (various editor features rely on this convention)
+* [CustomX509TrustManager] Implementing a custom \`X509TrustManager\` is error-prone and likely to be insecure. It is likely to disable certificate validation altogether, and is non-trivial to implement correctly without calling Android's default implementation.
+* [CutPasteId] The id \`R.id.duplicated\` has already been looked up in this method; possible cut & paste error?
+* [DalvikOverride] This package private method may be unintentionally overriding \`method\` in \`pkg1.Class1\`
+* [DataBindingWithoutKapt] If you plan to use data binding in a Kotlin project, you should apply the kotlin-kapt plugin.
+* [DataExtractionRules] The attribute \`android:allowBackup\` is deprecated from Android 12 and the default allows backup
+* [DefaultEncoding] This \`Scanner\` will use the default system encoding instead of a specific charset which is usually a mistake; add charset argument, \`Scanner(..., UTF_8)\`?
+* [DefaultLocale] Implicitly using the default locale is a common source of bugs: Use \`toUpperCase(Locale)\` instead. For strings meant to be internal use \`Locale.ROOT\`, otherwise \`Locale.getDefault()\`.
+* [DeletedProvider] The Crypto provider has been deleted in Android P (and was deprecated in Android N), so the code will crash
+* [DeprecatedProvider] The \`BC\` provider is deprecated and when \`targetSdkVersion\` is moved to \`P\` this method will throw a \`NoSuchAlgorithmException\`. To fix this you should stop specifying a provider and use the default implementation
+* [DeprecatedSinceApi] This method is deprecated as of API level 25
+* [Deprecated] \`AbsoluteLayout\` is deprecated
+* [DevModeObsolete] You no longer need a \`dev\` mode to enable multi-dexing during development, and this can break API version checks
+* [DeviceAdmin] You must have an intent filter for action \`android.app.action.DEVICE_ADMIN_ENABLED\`
+* [DiffUtilEquals] Suspicious equality check: Did you mean \`.equals()\` instead of \`==\` ?
+* [DisableBaselineAlignment] Set \`android:baselineAligned="false"\` on this element for better performance
+* [DiscouragedPrivateApi] Reflective access to addAssetPath, which is not part of the public SDK and therefore likely to change in future Android releases
+* [DrawAllocation] Avoid object allocations during draw/layout operations (preallocate and reuse instead)
+* [DuplicateActivity] Duplicate registration for activity \`com.example.helloworld.HelloWorld\`
+* [DuplicateDefinition] \`app_name\` has already been defined in this folder
+* [DuplicateDivider] Replace with \`android.support.v7.widget.DividerItemDecoration\`?
+* [DuplicateIds] Duplicate id \`@+id/android_logo\`, already defined earlier in this layout
+* [DuplicateIncludedIds] Duplicate id @+id/button1, defined or included multiple times in layout/layout2.xml: * [layout/layout2.xml => layout/layout3.xml defines @+id/button1, layout/layout2.xml => layout/layout4.xml defines @+id/button1]
+* [DuplicatePlatformClasses] \`xpp3\` defines classes that conflict with classes now provided by Android. Solutions include finding newer versions or alternative libraries that don't have the same problem (for example, for \`httpclient\` use \`HttpUrlConnection\` or \`okhttp\` instead), or repackaging the library using something like \`jarjar\`.
+* [DuplicateStrings] Duplicate string value \`HELLO\`, used in \`hello_caps\` and \`hello\`. Use \`android:inputType\` or \`android:capitalize\` to treat these as the same and avoid string duplication.
+* [DuplicateUsesFeature] Duplicate declaration of uses-feature \`android.hardware.camera\`
+* [EllipsizeMaxLines] Combining \`ellipsize=start\` and \`lines=1\` can lead to crashes. Use \`singleLine=true\` instead.
+* [EmptySuperCall] No need to call \`super.someOtherMethod\`; the super method is defined to be empty
+* [EnforceUTF8] iso-latin-1: Not using UTF-8 as the file encoding. This can lead to subtle bugs with non-ascii characters
+* [EnqueueWork] WorkContinuation \`cont\` not enqueued: did you forget to call \`enqueue()\`?
+
+
diff --git a/docs/api-guide/nested-syntax-highlighting.png b/docs/api-guide/nested-syntax-highlighting.png
new file mode 100644
index 00000000..d9238676
Binary files /dev/null and b/docs/api-guide/nested-syntax-highlighting.png differ
diff --git a/docs/api-guide/nested-test-files.png b/docs/api-guide/nested-test-files.png
new file mode 100644
index 00000000..93037b14
Binary files /dev/null and b/docs/api-guide/nested-test-files.png differ
diff --git a/docs/api-guide/options.md.html b/docs/api-guide/options.md.html
new file mode 100644
index 00000000..f40d49b2
--- /dev/null
+++ b/docs/api-guide/options.md.html
@@ -0,0 +1,221 @@
+
+
+# Options
+
+## Usage
+
+Users can configure lint using `lint.xml` files, turning on and off
+checks, changing the default severity, ignoring violations based on
+paths or regular expressions matching paths or messages, and so on.
+
+They can also configure “options” on a per issue type basis. Options
+are simply strings, booleans, integers or paths that configure how a
+detector works.
+
+For example, in the following `lint.xml` file, we're configuring the
+`UnknownNullness` detector to turn on its `ignoreDeprecated` option,
+and we're telling the `TooManyViews` detector that the maximum number
+of views in a layout it should allow before generating a warning should
+be set to 20:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml
+<?xml version="1.0" encoding="UTF-8"?>
+<lint>
+ <issue id="UnknownNullness">
+ <option name="ignoreDeprecated" value="true" />
+ </issue>
+ <issue id="TooManyViews">
+ <option name="maxCount" value="20" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Note that `lint.xml` files can be located not just in the project
+directory but nested as well, for example for a particular source
+folder.
+
+(See the [lint.xml](../usage/lintxml.md.html) documentation for more.)
+
+## Creating Options
+
+First, create an `Option` and register it with the corresponding
+`Issue`.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+val MAX_COUNT = IntOption("maxCount", "Max number of views allowed", 80)
+val MY_ISSUE = Issue.create("MyId", ...)
+ .setOptions(listOf(MAX_COUNT))
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+An option has a few pieces of metadata:
+
+* The name, which is a short identifier. Users will configure the
+ option by listing this key along with the configured value in their
+ `lint.xml` files. By convention this should be using camel case and
+ only valid Java identifier characters.
+
+* A description. This should be a short sentence which lists the
+ purpose of the option (and should be capitalized, and not end with
+ punctuation).
+
+* A default value. This is the value that will be returned from
+ `Option.getValue()` if the user has not configured the setting.
+
+* For integer and float options, minimum and maximum allowed values.
+
+* An optional explanation. This is a longer explanation of the option,
+ if necessary.
+
+The name and default value are used by lint when options are looked up
+by detectors; the description, explanation and allowed ranges are used
+to include information about available options when lint generates for
+example HTML reports, or text reports including explanations, or
+displaying lint checks in the IDE settings panel, and so on.
+
+There are currently 5 types of options: Strings, booleans, ints, floats
+and paths. There's a separate option class for each one, which makes it
+easier to look up these options since for example for a `StringOption`,
+`getValue` returns a `String`, for an `IntOption` it returns an `Int`,
+and so on.
+
+Option Type | Option Class
+------------------------|-----------------------------------
+`String` | `StringOption`
+`Boolean` | `BooleanOption`
+`Int` | `IntOption`
+`Float` | `FloatOption`
+`File` | `FileOption`
+
+## Reading Options
+
+To look up the configured value for an option, just call `getValue`
+and pass in the `context`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+val maxCount = MAX_COUNT.getValue(context)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This will return the `Int` value configured for this option by the
+user, or if not set, our original default value, in this case 80.
+
+## Specific Configurations
+
+The above call will look up the option configured for the specific
+source file in the current `context`, which might be an individual
+Kotlin source file. That's generally what you want; users can configure
+`lint.xml` files not just at the root of the project; they can be
+placed throughout the source folders and are interpreted by lint to
+apply to the folders below. Therefore, if we're analyzing a particular
+Kotlin file and we want to check an option, you generally want to check
+what's configured locally for this file.
+
+However, there are cases where you want to look up options up front,
+for example at the project level.
+
+In that case, first look up the particular configuration you want, and
+then pass in that configuration instead of the context to the
+`Option.getValue` call.
+
+For example, the context for the current module is already available in
+the `context`, so you might for example look up the option value like
+this:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+val maxCount = MAX_COUNT.getValue(context.configuration)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you want to find the most applicable configuration for a given
+source file, use
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+val configuration = context.findConfiguration(context.file)
+val maxCount = MAX_COUNT.getValue(configuration)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+## Files
+
+Note that there is a special `Option` type for files and paths:
+`FileOption`. Make sure that you use this instead of just a
+`StringOption` if you are planning on configuring files, because in the
+case of paths, users will want to specify paths relative to the
+location of the `lint.xml` file where the path is defined. For
+`FileOption` lint is aware of this and will convert the relative path
+string as necessary.
+
+## Constraints
+
+Note that the integer and float options allow you to specify a valid
+range for the configured value -- a minimum (inclusive) and a maximum
+(exclusive):
+
+This range will be included with the option documentation, such as in
+“**duration** (default is 1.5): Expected duration in seconds. Must be
+at least 0.0 and less than 15.0.”
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+private val DURATION_OPTION = FloatOption(
+ name = "duration",
+ description = "Expected duration",
+ defaultValue = 1.5f,
+ min = 0f,
+ max = 15f
+)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+It will also be checked at runtime, and if the configured value is
+outside of the range, lint will report an error and pinpoint the
+location in the invalid `lint.xml` file:
+
+```text
+lint.xml:4: Error: duration: Must be less than 15.0 [LintError]
+
+ ----------------------------------------
+1 errors, 0 warnings
+```
+
+## Testing Options
+
+When writing a lint unit test, you can easily configure specific values
+for your detector options. On the `lint()` test task, you can call
+`configureOption(option, value)`. There are a number of overloads for
+this method, so you can reference the option by its string name, or
+passing in the option instance, and if you do, you can pass in strings,
+integers, booleans, floats and files as values. Here's an example:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+lint().files(
+ kotlin("fun test() { println("Hello World.") }")
+)
+.configureOption(MAX_COUNT, 150)
+.run()
+.expectClean()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+## Supporting Lint 4.2, 7.0 and 7.1
+
+The `Option` support is new in 7.2. If your lint check still needs to
+work with older versions of lint, you can bypass the option
+registration, and just read option values directly from the
+configuration.
+
+First, find the configuration as shown above, and then instead of
+calling `Option.getValue`, call `getOption` on the configuration:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+val option: String? = configuration.getOption(ISSUE, "maxCount")
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The `getOption` method returns a `String`. For numbers and booleans,
+the coniguration also provides lookups which will convert the value to
+a number or boolean respectively: `getOptionAsInt`,
+`getOptionAsBoolean`, and most importantly, `getOptionAsFile`. If you
+are looking up paths, be sure to use `getOptionAsFile` since it has the
+important attribute that it allows paths to be relative to the
+configuration file where the (possibly inherited) value was defined,
+which is what users expect when editing `lint.xml` files.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+val option = configuration.getOptionAsInt(ISSUE, "maxCount", 100)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
diff --git a/docs/api-guide/partial-analysis.md.html b/docs/api-guide/partial-analysis.md.html
new file mode 100644
index 00000000..a004774b
--- /dev/null
+++ b/docs/api-guide/partial-analysis.md.html
@@ -0,0 +1,633 @@
+
+
+# Partial Analysis
+
+## About
+
+This chapter describes Lint's “partial analysis”; its architecture and
+APIs for allowing lint results to be cached.
+
+This focuses on how to write or update existing lint checks such that
+they work correctly under partial analysis. For other details about
+partial analysis, such as the client side implemented by the build
+system, see the lint internal docs folder.
+
+!!! Note
+ Note that while lint has this architecture, and all lint detectors
+ must support it, the checks may not run in partial analysis mode;
+ they may instead run in “global analysis mode”, which is how lint
+ has worked up until this point.
+
+ This is because coordinating partial results and merging is
+ performed by the `LintClient`; e.g. in the IDE, there's no good
+ reason to do all this extra work (because all sources are generally
+ available, including “downstream” module info like the
+ `minSdkVersion`).
+
+ Right now, only the Android Gradle Plugin turns on partial analysis
+ mode. But that's a very important client, since it's usually how
+ lint checks are performed on continuous integration servers to
+ validate code reviews.
+
+## The Problem
+
+Many lint checks require “global” analysis. For example you can't
+determine whether a particular string defined in a library module is
+unused unless you look at all modules transitively consuming this
+library as well.
+
+However, many developers run lint as part of their continuous
+integration. Particularly in large projects, analyzing all modules for
+every check-in is too costly.
+
+This chapter describes lint's architecture for handling this, such
+that module results can be cached.
+
+## Overview
+
+Briefly stated, lint's architecture for this is “map reduce”: lint now
+has two separate phases, analyze and report (map and reduce
+respectively):
+
+* **analyze** - where lint analyzes source code of a single module in
+ isolation, and stores some intermediate partial results (map)
+
+* **report** - where lint reads in the previously stored module results,
+ and performs some post-processing on this data to generate an actual
+ lint report.
+
+Crucially, the individual module results can be cached, such that if
+nothing has changed in a module, the module results continue to be
+valid (unless signatures have changed in libraries it depends on.)
+
+Making this work requires some modifications to any `Detector` which
+considers data from outside the current module. However, there are some
+very common scenarios that lint has special support for to make this
+easier.
+
+Detectors fit into one of the following categories (and these
+categories will be explained in subsequent sessions) :
+
+1. Local analysis which doesn't depend on anything else. For example,
+ a lint check which flags typos can report incidents immediately.
+ Lint calls these “definite incidents”.
+
+2. Local analysis which depends on a few, common conditions. For
+ example, in Android, a check may only apply if the `minSdkVersion <
+ 21`. Lint has special support for this; you basically report an
+ incident and attach a “constraint” to it. Lint calls these, and
+ incidents reported as part of #3 below, as “provisional incidents”.
+
+3. Analysis which depends on some conditions of downstream modules that
+ are not part of the built-in constraints. For example, a lint check
+ may only apply if the consuming module depends on a certain version
+ of a networking library. In this case, the detector will report the
+ incident and attach a map to it, with whatever data it needs to
+ consult later to decide if the incident actually should be reported.
+ When the detector reports incidents this way, it has to also
+ override a callback method. Lint will record these incidents, and
+ during reporting, call the detector and pass it back its data map
+ and provisional incidents such that it can decide whether the
+ incidents should indeed be reported.
+
+4. Last, and least, there are some scenarios where you cannot compute
+ provisional incidents up front and filter them later (or doing so
+ would be very costly). For example, unused resources fit into this
+ category. We don't want to report every single resource declaration
+ as unused and then filter later. Instead, we compute the resource
+ usage graph within the module analysis. And in the reporting task,
+ we then load all the partial usage graphs, and merge them together
+ and walk the graph to report all the unused resources. To support
+ this, lint provides a map per module for detectors to put their data
+ into, and you can put maps into the map to model structured data.
+ Lint will persist these, and in the reporting task the lint
+ detectors will be passed their data to do their post-processing and
+ reporting based on their data.
+
+These are listed in increasing order of effort, and thankfully, they're
+also listed in order of frequency. For lint's built-in checks (~385),
+
+* 89% needed no work at all.
+* 6% were updated to report incidents with constraints
+* 4% were updated to report incidents with data for later filtering
+* 1% were updated to perform map recording and later reduce filtering
+
+## Does My Detector Need Work?
+
+At this point you're probably wondering whether your checks are in the
+89% category where you don't need to do anything, or in the remaining
+11%. How do you know?
+
+Lint has several built-in mechanisms to try to catch problems. There
+are a few scenarios it cannot detect, and these are described below,
+but for the vast majority, simply running your unit tests (which are
+comprehensive, right?) should create unit test failures if your
+detector is doing something it shouldn't.
+
+### Catching Mistakes: Blocking Access to Main Project
+
+In Android checks, it's very common to try to access the main (“app”)
+project, to see what the real `minSdkVersion` is, since the app
+`minSdkVersion` can be higher than the one in the library. For the
+`targetSdkVersion` it's even more important, since the library
+`targetSdkVersion` has no meaningful relationship to the app one.
+
+When you run lint unit tests, as of 7.0, it will now run your tests
+twice -- once with global analysis (the previous behavior), and once
+with partial analysis. When lint is running in partial analysis, a
+number of calls, such as looking up the main project, or consulting the
+merged manifest, is not allowed during the analysis phase. Attempting
+to do so will generate an error:
+
+```none
+ SdCardTest.java: Error: The lint detector
+ com.android.tools.lint.checks.SdCardDetector
+ called context.getMainProject() during module analysis.
+
+ This does not work correctly when running in Lint Unit Tests.
+
+ In particular, there may be false positives or false negatives because
+ the lint check may be using the minSdkVersion or manifest information
+ from the library instead of any consuming app module.
+
+ Contact the vendor of the lint issue to get it fixed/updated (if
+ known, listed below), and in the meantime you can try to work around
+ this by disabling the following issues:
+
+ "SdCardPath"
+
+ Issue Vendor:
+ Vendor: Android Open Source Project
+ Contact: https://groups.google.com/g/lint-dev
+ Feedback: https://issuetracker.google.com/issues/new?component=192708
+
+ Call stack: Context.getMainProject(Context.kt:117)←SdCardDetector$createUastHandler$1.visitLiteralExpression(SdCardDetector.kt:66)
+ ←UElementVisitor$DispatchPsiVisitor.visitLiteralExpression(UElementVisitor.kt:791)
+ ←ULiteralExpression$DefaultImpls.accept(ULiteralExpression.kt:38)
+ ←JavaULiteralExpression.accept(JavaULiteralExpression.kt:24)←UVariableKt.visitContents(UVariable.kt:64)
+ ←UVariableKt.access$visitContents(UVariable.kt:1)←UField$DefaultImpls.accept(UVariable.kt:92)
+ ...
+```
+
+Specific examples of information many lint checks look at in this
+category:
+* `minSdkVersion` and `targetSdkVersion`
+* The merged manifest
+* The resource repository
+* Whether the main module is an Android project
+
+### Catching Mistakes: Simulated App Module
+
+Lint will also modify the unit test when running the test in partial
+analysis mode. In particular, let's say your test has a manifest which
+sets `minSdkVersion` to 21.
+
+Lint will instead run the analysis task on a modified test project
+where the `minSdkVersion` is set to 1, and then run the reporting task
+where `minSdkVersion` is set back to 21. This ensures that lint checks
+will correctly use the `minSdkVersion` from the main project, not the
+library.
+
+### Catching Mistakes: Diffing Results
+
+Lint will also diff the report output from running the same unit tests
+both in global analysis mode and in partial analysis mode. We expect
+the results to always be identical, and in some cases if the module
+analysis is not written correctly, they're not.
+
+### Catching Mistakes: Remaining Issues
+
+The above three mechanisms will catch most problems related to partial
+analysis. However, there are a few remaining scenarios to be aware of:
+
+* Resolving into library source code. If you have a Kotlin or Java
+ function call AST node (`UCallExpression`) you can call `resolve()`
+ on it to find the called `PsiMethod`, and from there you can look at
+ its source code, to make some decisions.
+
+ For example, lint's API Check uses this to see if a given method is a
+ version-check utility (“`SDK_INT > 21`?”); it resolves the method
+ call in `if (isOnLollipop()) { ... }` and looks at its method body to
+ see if the return value corresponds to a proper `SDK_INT` check.
+
+ In partial analysis mode, you cannot look at source files from
+ libraries you depend on; they will only be provided in binary
+ (bytecode inside a jar file) form.
+
+ This means that instead, you need to aggregate data along the way.
+ For example, the way lint handles the version check method lookup is
+ to look for SDK_INT comparisons, and if found, stores a reference to
+ the method in the partial results map which it can later consult
+ from downstream modules.
+
+* Multiple passes across the modules (lint has a way to request
+ multiple passes; this was used by a few lint checks like the unused
+ resource detector; the multiple passes now only apply to the local
+ module)
+
+In order to test for correct operation of your check, you should add
+your own individual unit test for a multi-module project.
+
+Lint's unit test infrastructure makes this easy; just use relative
+paths in the test file descriptions.
+
+For example, if you have the following unit test declaration:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+ lint().files(
+ manifest().minSdk(15),
+ manifest().to("../app/AndroidManifest.xml").minSdk(21),
+ xml(
+ "res/layout/linear.xml",
+ "" + ...
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The second `manifest()` call here on line 3 does all the heavy lifting:
+the fact that you're referencing `../app` means it will create another
+module named “app”, and it will add a dependency from that module on
+this one. It will also mark the current module as a library. This is
+based on the name patterns; if you for example reference say `../lib1`,
+it will assume the current module is an app module and the dependency
+will go from here to the library.
+
+Finally, to test a multi-module setup where the code in the other
+module is only available as binary, lint has a new special test file
+type. The `CompiledSourceFile` can be constructed via either
+`compiled()`, if you want to make both the source code and the class
+file available in the project, or `bytecode()` if you want to only
+provide the bytecode. In both cases you include the source code in the
+test file declaration, and the first time you run your test it will try
+to run compilation and emit the extra base64 string to include the test
+file. By having the sources included for the binary it's easy to
+regenerate bytecode tests later (this was an issue with some of lint's
+older unit tests; we recently decompiled them and created new test
+files using this mechanism to make the code more maintainable.
+
+Lint's partial analysis testing support will automatically only use
+binaries for the dependencies (even if using `CompiledSourceFile` with
+sources).
+
+!!! Note
+ Lint's testing infrastructure may try to automate this testing at
+ some point; e.g. by looking at the error locations from a global
+ analysis, it can then create a new project where only the source
+ file with the warnings is provided as source, and all the other test
+ files are placed in a separate module, and then represented only as
+ binaries (through a lint AST to PsiCompiled pretty printer.)
+
+## Incidents
+
+In the past, you would typically report problems like this:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+ context.report(
+ ISSUE,
+ element,
+ context.getNameLocation(element),
+ "Missing `contentDescription` attribute on image"
+ )
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+At some point, we added support for quickfixes, so the
+report method took an additional parameter, line 6:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+ context.report(
+ ISSUE,
+ element,
+ context.getNameLocation(element),
+ "Missing `contentDescription` attribute on image",
+ fix().set().todo(ANDROID_URI, ATTR_CONTENT_DESCRIPTION).build()
+)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Now that we need to attach various additional data (like constraints
+and maps), we don't really want to just add more parameters.
+
+Instead, this tuple of data about a particular occurrence of a problem
+is called an “incident”, and there is a new `Incident` class which
+represents it. To report an incident you simply call
+`context.report(incident)`. There are several ways to create these
+incidents. The easiest is to simply edit your existing call above by
+putting it inside `Incident(...)` (in Java, `new Incident(...)`) inside
+the `context.report` block like this:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+ context.report(Incident(
+ ISSUE,
+ element,
+ context.getNameLocation(element),
+ "Missing `contentDescription` attribute on image"
+ ))
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+and then reformatting the source code:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+ context.report(
+ Incident(
+ ISSUE,
+ element,
+ context.getNameLocation(element),
+ "Missing `contentDescription` attribute on image"
+ )
+)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`Incident` has a number of overloaded constructors to make it easy to
+construct it from existing report calls.
+
+There are other ways to construct it too, for example like the
+following:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+ Incident(context)
+ .issue(ISSUE)
+ .scope(node)
+ .location(context.getLocation(node))
+ .message("Do not hardcode \"/sdcard/\"").report()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+That are additional methods you can fall too, like `fix()`, and
+conveniently, `at()` which specifies not only the scope node but
+automatically computes and records the location of that scope node too,
+such that the following is equivalent:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+ Incident(context)
+ .issue(ISSUE)
+ .at(node)
+ .message("Do not hardcode \"/sdcard/\"").report()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+So step one to partial analysis is to convert your code to report
+incidents instead of the passing in all the individual properties of an
+incident. Note that for backwards compatibility, if your check doesn't
+need any work for partial analysis, you can keep calling the older
+report methods; they will be redirected to an `Incident` call
+internally, but since you don't need to attach data you don't have to
+make any changes
+
+## Constraints
+
+If your check needs to be conditional, perhaps on the `minSdkVersion`,
+you need to attach a “constraint” to your report call.
+
+All the constraints are built in; there isn't a way to implement your
+own. For custom logic, see the next section: LintMaps.
+
+Here are the current constraints, though this list may grow over time:
+
+* minSdkAtLeast(Int)
+* minSdkLessThan(Int)
+* targetSdkAtLeast(Int)
+* targetSdkLessThan(Int)
+* isLibraryProject()
+* isAndroidProject()
+* notLibraryProject()
+* notAndroidProject()
+
+These are package-level functions, though from Java you can access them
+from the `Constraints` class.
+
+Recording an incident with a constraint is easy; first construct the
+`Incident` as before, and then report it via
+`context.report(incident, constraint)`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java
+ String message =
+ "One or more images in this project can be converted to "
+ + "the WebP format which typically results in smaller file sizes, "
+ + "even for lossless conversion";
+ Incident incident = new Incident(WEBP_ELIGIBLE, location, message);
+ context.report(incident, minSdkAtLeast(18));
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Finally, note that you can combine constraints; there are both “and”
+and “or” operators defined for the `Constraint` class, so the following
+is valid:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+ val constraint = targetSdkAtLeast(23) and notLibraryProject()
+ context.report(incident, constraint)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+That's all you have to do. Lint will record this provisional incident,
+and when it is performing reporting, it will evaluate these constraints
+on its own and only report incidents that meet the constraint.
+
+## Incident LintMaps
+
+In some cases, you cannot use one of the built-in constraints; you have
+to do your own “filtering” from the reporting task, where you have
+access to the main module.
+
+In that case, you call `context.report(incident, map)` instead.
+
+Like `Incident`, `LintMap` is a new data holder class in lint which
+makes it convenient to pass around (and more importantly, persist)
+data. All the set methods return the map itself, so you can easily
+chain property calls.
+
+Here's an example:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+ context.report(
+ incident,
+ map()
+ .put(KEY_OVERRIDES, overrides)
+ .put(KEY_IMPLICIT, implicitlyExportedPreS)
+ )
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here, `map()` is a method defined by `Detector` to create a new
+`LintMap`, similar to how `fix()` constructs a new `LintFix`.
+
+Note however that when reporting data, you need to do the post
+processing yourself. To do this, you need to override this method:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+ /**
+ * Filter which looks at incidents previously reported via
+ * [Context.report] with a [LintMap], and returns false if the issue
+ * does not apply in the current reporting project context, or true
+ * if the issue should be reported. For issues that are accepted,
+ * the detector is also allowed to mutate the issue, such as
+ * customizing the error message further.
+ */
+ open fun filterIncident(context: Context, incident: Incident, map: LintMap): Boolean { }
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+For example, for the above report call, the corresponding
+implementation of `filterIncident` looks like this:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+ override fun filterIncident(context: Context, incident: Incident, map: LintMap): Boolean {
+ if (context.mainProject.targetSdk < 19) return true
+ if (map.getBoolean(KEY_IMPLICIT, false) == true && context.mainProject.targetSdk >= 31) return true
+ return map.getBoolean(KEY_OVERRIDES, false) == false
+ }
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Note also that you are allowed to modify incidents here before
+reporting them. The most common reason scenario for this is changing
+the incident message, perhaps to reflect data not known at module
+analysis time. For example, lint's API check creates messages like this:
+
+*Error: Cast from AudioFormat to Parcelable requires API level 24 (current min is 21)*
+
+At module analysis time when the incident was created, the minSdk being
+21 was not known (and in fact can vary if this library is consumed by
+many different app modules!)
+
+!!! WARNING
+ You must store state in the lint map; don't try to store it in the
+ detector itself as instance state. That won't work because the
+ detector instance that `filterInstance` is called on is not the same
+ instance as the one which originally reported it. If you think about
+ it, that makes sense; when module results are cached, the same
+ reported data can be used over and over again for repeated builds,
+ each time for new detector instances in the reporting task.
+
+## Module LintMaps
+
+The last (and most involved) scenario for partial analysis is one where
+you cannot just create incidents and filter or customize them later.
+
+The most complicated example of this is lint's built-in
+[UnusedResourceDetector](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/UnusedResourceDetector.java), which locates unused resources. This “requires”
+global analysis, since we want to include all resources in the entire
+project. We also cannot just store lists of “resources declared” and
+“resources referenced” since we really want to treat this as a graph.
+For example if `@layout/main` is including `@drawable/icon`, then a
+naive approach would see the icon as referenced (by main) and therefore
+mark it as not unused. But what we want is that if the icon is **only**
+referenced from main, and if main is unused, then so is the icon.
+
+To handle this, we model the resources as a graph, with edges
+representing references.
+
+When analyzing individual modules, we create the resource graph for
+just that model, and we store that in the results. That means we store
+it in the module's `LintMap`. This is a map for the whole module
+maintained by lint, so you can access it repeatedly and add to it.
+(This is also where lint's API check stores the `SDK_INT` comparison
+functions as described earlier in this chapter).
+
+The unused resource detector creates a persistence string for the
+graph, and records that in the map.
+
+Then, during reporting, it is given access to *all* the lint maps for
+all the modules that the reporting module depends on, including itself.
+It then merges all the graphs into a single reference graph.
+
+For example, let's say in module 1 we have layout A which includes
+drawables B and D, and B in turn depends on color C. We get a resource
+graph like the following:
+
+**********************************************
+* *
+* .-. .-. .-. *
+* | A +----->| B +----->| C | *
+* '+' '-' '-' *
+* | *
+* | *
+* | .-. *
+* +--->| D | *
+* '-' *
+* *
+**********************************************
+
+Then in another module, we have the following resource reference graph:
+
+**********************************************
+* *
+* .-. .-. .-. *
+* | E +----->| B +----->| D | *
+* '-' '-' '-' *
+* *
+**********************************************
+
+In the reporting task, we merge the two graphs like the following:
+
+**********************************************
+* *
+* .-. *
+* | E | *
+* '+' *
+* | *
+* v *
+* .-. .-. .-. *
+* | A +----->| B +----->| C | *
+* '+' '+' '-' *
+* | | *
+* | v *
+* | .-. *
+* +------->| D | *
+* '-' *
+* *
+**********************************************
+
+Once that's done, it can proceed precisely as before: analyze the graph
+and report all the resources that are not reachable from the reference
+roots (e.g. manifest and used code).
+
+The way this works in code is that you report data into the module by
+first looking up the module data map, by calling this method on the
+`Context`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+ /**
+ * Returns a [PartialResult] where state can be stored for later
+ * analysis. This is a more general mechanism for reporting
+ * provisional issues when you need to collect a lot of data and do
+ * some post processing before figuring out what to report and you
+ * can't enumerate out specific [Incident] occurrences up front.
+ *
+ * Note that in this case, the lint infrastructure will not
+ * automatically look up the error location (since there isn't one
+ * yet) to see if the issue has been suppressed (via annotations,
+ * lint.xml and other mechanisms), so you should do this
+ * yourself, via the various [LintDriver.isSuppressed] methods.
+ */
+ fun getPartialResults(issue: Issue): PartialResult { ... }
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Then you put whatever data you want, such as the resource usage model
+encoded as a string.
+
+!!!
+ Note that you don't have to worry about clashes in key names; each
+ issue (and therefore detector) is given its own map.
+
+And then your detector should also override the following method, where
+you can walk through the map contents, compute incidents and report
+them:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+ /**
+ * Callback to detectors that add partial results (by adding entries
+ * to the map returned by [LintClient.getPartialResults]). This is
+ * where the data should be analyzed and merged and results reported
+ * (via [Context.report]) to lint.
+ */
+ open fun checkPartialResults(context: Context, partialResults: PartialResult) { ... }
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+## Optimizations
+
+Most lint checks run on the fly in the IDE editor as well. In some
+cases, if all the map computations are expensive, you can check whether
+partial analysis is in effect, and if not, just directly access (for
+example) the main project.
+
+Do this by calling `isGlobalAnalysis()`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+ if (context.isGlobalAnalysis()) {
+ // shortcut
+ } else {
+ // partial analysis code path
+ }
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
diff --git a/docs/api-guide/publishing.md.html b/docs/api-guide/publishing.md.html
new file mode 100644
index 00000000..cfa3f4aa
--- /dev/null
+++ b/docs/api-guide/publishing.md.html
@@ -0,0 +1,144 @@
+
+
+# Publishing a Lint Check
+
+Lint will look for jar files with a service registry key for issue
+registries.
+
+You can manually point it to your custom lint checks jar files by using
+the environment variable `ANDROID_LINT_JARS`:
+
+```shell
+$ export ANDROID_LINT_JARS=/path/to/first.jar:/path/to/second.jar
+```
+(On Windows, use `;` instead of `:` as the path separator)
+
+However, that is only intended for development and as a workaround for
+build systems that do not have direct support for lint or embedded lint
+libraries, such as the internal Google build system.
+
+## Android
+
+### AAR Support
+
+Android libraries are shipped as `.aar` files instead of `.jar` files.
+This means that they can carry more than just the code payload. Under
+the hood, `.aar` files are just zip files which contain many other
+nested files, including api and implementation jars, resources,
+proguard/r8 rules, and yes, lint jars.
+
+For example, if we look at the contents of the timber logging library's
+AAR file, we can see the lint.jar with several lint checks within as
+part of the payload:
+
+```shell
+$ jar tvf ~/.gradle/caches/.../jakewharton.timber/timber/4.5.1/?/timber-4.5.1.aar
+ 216 Fri Jan 20 14:45:28 PST 2017 AndroidManifest.xml
+ 8533 Fri Jan 20 14:45:28 PST 2017 classes.jar
+ 10111 Fri Jan 20 14:45:28 PST 2017 lint.jar
+ 39 Fri Jan 20 14:45:28 PST 2017 proguard.txt
+ 0 Fri Jan 20 14:45:24 PST 2017 aidl/
+ 0 Fri Jan 20 14:45:28 PST 2017 assets/
+ 0 Fri Jan 20 14:45:28 PST 2017 jni/
+ 0 Fri Jan 20 14:45:28 PST 2017 res/
+ 0 Fri Jan 20 14:45:28 PST 2017 libs/
+```
+
+The advantage of this approach is that when lint notices that you
+depend on a library, and that library contains custom lint checks, then
+lint will pull in those checks and apply them. This gives library
+authors a way to provide their own additional checks enforcing usage.
+
+### lintPublish Configuration
+
+The Android Gradle library plugin provides some special configurations,
+`lintChecks` and `lintPublish`.
+
+The `lintPublish` configuration lets you reference another project, and
+it will take that project's output jar and package it as a `lint.jar`
+inside the AAR file.
+
+The [](https://github.com/googlesamples/android-custom-lint-rules)
+sample project demonstrates this setup.
+
+The `:checks` project is a pure Kotlin library which depends on the
+Lint APIs, implements a `Detector`, and provides an `IssueRegistry`
+which is linked from `META-INF/services`.
+
+Then in the Android library, the `:library` project applies the Android
+Gradle library plugin. It then specifies a `lintPublish` configuration
+referencing the checks lint project:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+apply plugin: 'com.android.library'
+dependencies {
+ lintPublish project(':checks')
+ // other dependencies
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Finally, the sample `:app` project is an example of an Android app
+which depends on the library, and the source code in the app contains a
+violation of the lint check defined in the `:checks` project. If you
+run `./gradlew :app:lint` to analyze the app, the build will fail
+emitting the custom lint check.
+
+### Local Checks
+
+What if you aren't publishing a library, but you'd like to apply
+some checks locally for your own codebase?
+
+You can use a similar approach to `lintPublish`: In your app
+module, specify
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+apply plugin: 'com.android.application'
+dependencies {
+ lintChecks project(':checks')
+ // other dependencies
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Now, when lint runs on this application, it will apply the checks
+provided from the given project.
+
+!!! Warning
+ This mechanism works well on the CI server for enforcing local code
+ conventions, and it also works for developers on your team; the
+ errors should be flagged in the IDE (providing they are analyzing
+ single-file scopes). However, there have been various bugs and
+ difficulties around the lint checks getting rebuilt after changes or
+ clean builds. There are some bugs in the Android Gradle Plugin issue
+ tracker for this.
+
+### Unpublishing
+
+If you end up “deleting” a lint check, perhaps because the original
+conditions for the lint check are not true, don't just stop
+distributing lint checks with your library. Instead, you'll want to
+update your `IssueRegistry` to override the `deletedIssues` property to
+return your deleted issue id or ids:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+/**
+ * The issue id's from any issues that have been deleted from this
+ * registry. This is here such that when an issue no longer applies
+ * and is no longer registered, any existing mentions of the issue
+ * id in baselines, lint.xml files etc are gracefully handled.
+ */
+open val deletedIssues: List<String> = emptyList()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The reason you'll want to do this is listed right there in the doc: If
+you don't do this, and if users have for example listed your issue id
+in their `build.gradle` file or in `lint.xml` to say change the
+severity, then lint will report an error that it's an unknown id. This
+is done to catch issue id typos. And if the user has a baseline file
+listing incidents from your check, then if your issue id is not
+registered as deleted, lint will think this is an issue that has been
+“fixed” since it's no longer reported, and lint will issue an
+informational message that the baseline contains issues no longer
+reported (which is done such that users can update their baseline
+files, to ensure that the fixed issues aren't reintroduced again.)
+
+
diff --git a/docs/api-guide/quickfixes.md.html b/docs/api-guide/quickfixes.md.html
new file mode 100644
index 00000000..68d77af2
--- /dev/null
+++ b/docs/api-guide/quickfixes.md.html
@@ -0,0 +1,320 @@
+
+
+# Adding Quick Fixes
+
+## Introduction
+
+When your detector reports an incident, it can also provide one or more
+“quick fixes”, which are actions the users can invoke in the IDE (or,
+for safe fixes, in batch mode) to address the reported incident.
+
+For example, if the lint check reports an unused resource, a quick fix
+could offer to remove the unused resource.
+
+In some cases, quick fixes can take partial steps towards fixing the
+problem, but not fully. For example, the accessibility lint check which
+makes sure that for images you set a content description, the quickfix
+can offer to add it -- but obviously it doesn't know what description
+to put. In that case, the lint fix will go ahead and add the attribute
+declaration with the correct namespace and attribute name, but will
+leave the value up to the user (so it uses a special quick fix provided
+by lint to place a TODO marker as the value, along with selecting just
+that TODO string such that the user can type to replace without having
+to manually delete the TODO string first.)
+
+## The LintFix builder class
+
+The class in lint which represents a quick fix is `LintFix`.
+
+Note that `LintFix` is **not** a class you can subclass and then for
+example implement your own arbitrary code in something like a
+`perform()` method.
+
+Instead, `LintFix` has a number of builders where you *describe* the
+action that you would like the quickfix to take. Then, lint will offer
+that quickfix in the IDE, and when the user invokes it, lint runs its
+own implementation of the various descriptors.
+
+The historical reason for this is that many of the quickfixes in lint
+depended on machinery in the IDE (such as code and import cleanup after
+an edit operation) that isn't available in lint itself, along with
+other concepts that only make sense in the IDE, such as moving the
+caret, opening files, selecting text, and so on.
+
+More recently, this is also used to persist quickfixes properly for
+later reuse; this is required for [partial
+analysis](partial-analysis.md.html).
+
+## Creating a LintFix
+
+Lint fixes use a “fluent API”; you first construct a `LintFix`, and on
+that method you call various available type methods, which will then
+further direct you to the allowed options.
+
+For example, to create a lint fix to set an XML attribute of a given
+name to “true”, use something like this:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+LintFix fix = fix().set(null, "singleLine", "true").build()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here the `fix()` method is provided by the `Detector` super class, but
+that's just a utility method for `LintFix.fix()` (or in older versions,
+`LintFix.create()`).
+
+There are a number of additional, common methods you can set on
+the `fix()` object:
+
+* `name`: Sets the description of the lint fix. This should be brief;
+ it's in the quickfix popup shown to the user.
+
+* `sharedName`: This sets the “shared” or “family” name: all fixes in
+ the file will with the same name can be applied in a single
+ invocation by the user. For example, if you register 500 “Remove
+ unused import” quickfixes in a file, you don't want to force the user
+ to have to invoke each and every one. By setting the shared name, the
+ user will be offered to **Fix All *$family name* problems in the
+ current file**, which they can then perform to have all 500
+ individual fixes applied in one go.
+
+* `autoFix`: If you get a lint report and you notice there are a lot of
+ incidents that lint can fix automatically, you don't want to have to
+ go and open each and every file and all the fixes in the file.
+ Therefore, lint can apply the fixes in batch mode; the Gradle
+ integration has a `lintFix` target to perform this, and the `lint`
+ command has an `--apply-suggestions` option.
+
+ However, many quick fixes require user intervention. Not just the
+ ones where the user has to choose among alternatives, and not just
+ the ones where the quick fix inserts a placeholder value like TODO.
+ Take for example lint's built-in check which requires overrides of a
+ method annotated with `@CallSuper` to invoke `super.` on the
+ overridden method. Where should we insert the call -- at the
+ beginning? At the end?
+
+ Therefore, lint has the `autoFix` property you can set on a quickfix.
+ This indicates that this fix is “safe” and can be performed in batch
+ mode. When the `lintFix` target runs, it will only apply fixes marked
+ safe in this way.
+
+## Available Fixes
+
+The current set of available quick fix types are:
+
+* `fix().replace`: String replacements. This is the most general
+ mechanism, and allows you to perform arbitrary edits to the source
+ code. In addition to the obvious “replace old string with new”, the
+ old string can use a different location range than the incident
+ range, you can match with regular expressions (and perform
+ replacements on a specific group within the regular expression), and
+ so on.
+
+ This fix is also the most straightforward way to **delete** text.
+
+ It offers some useful cleanup operations:
+
+ - Source code cleanup, which will run the IDE's code formatter on the
+ modified source code range. This will apply the user's code
+ preferences, such as whether there should be a space between a cast
+ and the expression, and so on.
+
+ - Import cleanup. That means that if you are referencing a new type,
+ you don't have to worry about checking whether it is imported and
+ if not adding an import statement; you can simply write your string
+ replacements using the fully qualified names, and then tag the
+ quickfix with the import cleanup option, and when the quickfix is
+ performed the import will be added if necessary and all the fully
+ qualified references replaced with simple names. And this will also
+ correctly handle the scenario where the symbols cannot be replaced
+ with simple names because there is a conflicting import of the same
+ name from a different package.
+
+ Normally, you should write your replacement source code using fully
+ qualified names, and then apply `shortenNames` to the quickfix to
+ tell lint to replace fully qualified names with imports; don't try
+ to write your quickfix to also add the import statements on its
+ own. There's a possibility that a given name cannot be imported
+ because it's already importing the same name for a different
+ namespace. When using fully qualified names, lint will specifically
+ handle this.
+
+ In some cases you cannot use fully qualified names in the code
+ snippet; this is the case with Kotlin extension functions for
+ example. For that scenario, the replacement quickfix has an
+ `imports` property you can use to specify methods (and classes and
+ fields) to import at the same time.
+
+* `fix().annotate`: Annotating an element. This will add (or optionally
+ replace) an annotation on a source element such as a method. It will
+ also handle import management.
+
+* `fix().set`: Add XML attributes. This will insert an attribute into
+ the given element, applying the user's code style preferences for
+ where to insert the attribute. (In Android XML for example there's a
+ specific sorting convention which is generally alphabetical, except
+ layout params go before other attributes, and width goes before
+ height.)
+
+ You can either set the value to something specific, or place the
+ caret inside the newly created empty attribute value, or set it
+ to TODO and select that text for easy type-to-replace.
+
+!!! Tip
+ If you use the `todo()` quickfix, it's a good idea to special case
+ your lint check to deliberately not accept “TODO” as a valid value.
+ For example, for lint's accessibility check which makes sure you set
+ a content description, it will complain both when you haven't set
+ the content description attribute, **and** if the text is set to
+ “TODO”. That way, if the user applies the quickfix, which creates
+ the attribute in the right place and moves the focus to the right
+ place, the editor is still showing a warning that the content
+ description should be set.
+
+* `fix().unset`: Remove XML attribute. This is a special case of add
+ attribute.
+
+* `fix().url`: Show URL. In some cases, you can't “fix” or do anything
+ local to address the problem, but you really want to direct the
+ user's attention to additional documentation. In that case, you can
+ attach a “show this URL” quick fix to the incident which will open
+ the browser with the given URL when invoked. For example, in a
+ complicated deprecation where you want users to migrate from one
+ approach to a completely different one that you cannot automate, you
+ could use something like this:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+val message = "Job scheduling with `GcmNetworkManager` is deprecated: Use AndroidX `WorkManager` instead"
+val fix = fix()
+.url("https://developer.android.com/topic/libraries/architecture/workmanager/migrating-gcm")
+.build()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+## Combining Fixes
+
+You might notice that lint's APIs to report incidents only takes a
+**single** quick fix instead of a list of fixes.
+
+But let's say that it *did* take a list of quick fixes.
+
+- Should they *all* be performed as a single unit? That makes sense if
+ you're trying to write a quickfix which performs multiple string
+ replacements.
+
+- Or should they be offered as separate alternatives for the user to
+ choose between? That makes sense if the incident says for example
+ that you must set at least one attribute among three possibilities;
+ in this case we may want to add quickfixes for setting each attribute.
+
+Both scenarios have their uses, so lint makes this explicit:
+
+- `fix().composite`: create a “composite” fix, which composes the fix
+ out of multiple individual fixes, or
+
+- `fix().alternatives`: create an “alternatives” fix, which holds a
+ number of individual fixes, which lint will present as separate
+ options to the user.
+
+Here's an example of how to create a composite fix, which will be
+performed as a unit; here we're both setting a new attribute and
+deleting a previous attribute:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+val fix = fix().name("Replace with singleLine=\"true\"")
+ .composite(
+ fix().set(ANDROID_URI, "singleLine", "true").build(),
+ fix().unset(namespace, oldAttributeName).build()
+ )
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+And here's an example of how to create an alternatives fix, which are
+offered to the user as separate options; this is from our earlier
+example of the accessibility check which requires you to set a content
+description, which can be set either on the “text” attribute or the
+“contentDescription” attribute:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+val fix = fix().alternatives(
+ fix().set().todo(ANDROID_URI, "text").build(),
+ fix().set().todo(ANDROID_URI, "contentDescription")
+ .build())
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+## Refactoring Java and Kotlin code
+
+It would be nice if there was an AST manipulation API, similar to UAST
+for visiting ASTs, that quickfixes could use to implement refactorings,
+but we don't have a library like that. And it's unlikely it would work
+well; when you rewrite the user's code you typically have to take
+language specific conventions into account.
+
+Therefore, today, when you create quickfixes for Kotlin and Java code,
+if the quickfix isn't something simple which would work for both
+languages, then you need to conditionally create either the Kotlin
+version or the Java version of the quickfix based on whether the source
+file it applies to is in Kotlin or Java. (For an easy way to check you
+can use the `isKotlin` or `isJava` package level methods in
+`com.android.tools.lint.detector.api`.)
+
+However, it's often the case that the quickfix is something simple
+which would work for both; that's true for most of the built-in lint
+checks with quickfixes for Kotlin and Java.
+
+## Regular Expressions and Back References
+
+The `replace` string quick fix allows you to match the text to
+with regular expressions.
+
+You can also use back references in the regular expression such
+that the quick fix replacement text includes portions from the
+original string.
+
+Here's an example from lint's `AssertDetector`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+val fix = fix().name("Surround with desiredAssertionStatus() check")
+ .replace()
+ .range(context.getLocation(assertCall))
+ .pattern("(.*)")
+ .with("if (javaClass.desiredAssertionStatus()) { \\k<1> }")
+ .reformat(true)
+ .build()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The replacement string's back reference above, on line 5, is \k<1>. If
+there were multiple regular expression groups in the replacement
+string, this could have been \k<2>, \k<3>, and so on.
+
+Here's how this looks when applied, from its unit test:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+lint().files().run().expectFixDiffs(
+ """
+ Fix for src/test/pkg/AssertTest.kt line 18: Surround with desiredAssertionStatus() check:
+ @@ -18 +18
+ - assert(expensive()) // WARN
+ + if (javaClass.desiredAssertionStatus()) { assert(expensive()) } // WARN
+ """
+)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+## Verifying Quickfixes
+
+Lint's test support will also attempt to verify that your quickfixes
+still produces a valid Kotlin, Java or XML source file. It does this
+by parsing these files after testing the quickfixes using
+`expectFixDiffs()`. It will only complain if the fixed source file didn't
+already have parsing errors *before* applying the fix.
+
+You can control this behavior using the `.verifyFixedFileSyntax()` method
+on the `lint()` task.
+
+## Emitting quick fix XML to apply on CI
+
+Note that the `lint` has an option (`--describe-suggestions`) to emit
+an XML file which describes all the edits to perform on documents to
+apply a fix. This maps all quick fixes into chapter edits (including
+XML logic operations). This can be (and is, within Google) used to
+integrate with code review tools such that the user can choose whether
+to auto-fix a suggestion right from within the code review tool.
+
+
diff --git a/docs/api-guide/terminology.md.html b/docs/api-guide/terminology.md.html
new file mode 100644
index 00000000..477f4675
--- /dev/null
+++ b/docs/api-guide/terminology.md.html
@@ -0,0 +1,119 @@
+
+
+# Terminology
+
+You don't need to read this up front and understand everything, but
+this is hopefully a handy reference to return to.
+
+In alphabetical order:
+
+Configuration
+: A configuration provides extra information or parameters to lint on a
+ per-project, or even per-directory, basis. For example, the `lint.xml`
+ files can change the severity for issues, or list incidents to ignore
+ (matched for example by a regular expression), or even provide values
+ for options read by a specific detector.
+
+Context
+: An object passed into detectors in many APIs, providing data about
+ (for example) which file is being analyzed (and in which project),
+ and (for specific types of analysis) additional information; for
+ example, an XmlContext points to the DOM document, a JavaContext
+ includes the AST, and so on.
+
+Detector
+: The implementation of the lint check which registers Issues, analyzes
+ the code, and reports Incidents.
+
+Implementation
+: An `Implementation` tells lint how a given issue is actually
+ analyzed, such as which detector class to instantiate, as well as
+ which scopes the detector applies to.
+
+Incident
+: A specific occurrence of the issue at a specific location.
+ An example of an incident is:
+ ```text
+ Warning: In file IoUtils.kt, line 140, the field download folder
+ is "/sdcard/downloads"; do not hardcode the path to `/sdcard`.
+ ```
+
+Issue
+: A type or class of problem that your lint check identifies. An issue
+ has an associated severity (error, warning or info), a priority, a
+ category, an explanation, and so on.
+
+ An example of an issue is “Don't hardcode paths to /sdcard”.
+
+IssueRegistry
+: An `IssueRegistry` provides a list of issues to lint. When you write
+ one or more lint checks, you'll register these in an `IssueRegistry`
+ and point to it using the `META-INF` service loader mechanism.
+
+LintClient
+: The `LintClient` represents the specific tool the detector is running
+ in. For example, when running in the IDE there is a LintClient which
+ (when incidents are reported) will show highlights in the editor,
+ whereas when lint is running as part of the Gradle plugin, incidents
+ are instead accumulated into HTML (and XML and text) reports, and
+ the build interrupted on error.
+
+Location
+: A “location” refers to a place where an incident is reported.
+ Typically this refers to a text range within a source file, but a
+ location can also point to a binary file such as a `png` file.
+ Locations can also be linked together, along with descriptions.
+ Therefore, if you for example are reporting a duplicate declaration,
+ you can include **both** Locations, and in the IDE, both locations
+ (if they're in the same file) will be highlighted. A location linked
+ from another is called a “secondary” location, but the chaining can
+ be as long as you want (and lint's unit testing infrastructure will
+ make sure there are no cycles.)
+
+Partial Analysis
+: A “map reduce” architecture in lint which makes it possible to
+ analyze individual modules in isolation and then later filter and
+ customize the partial results based on conditions outside of these
+ modules. This is explained in greater detail in the
+ [partial analysis](partial-analysis.md.html) chapter.
+
+Platform
+: The `Platform` abstraction allows lint issues to indicate where they
+ apply (such as “Android”, or “Server”, and so on). This means that an
+ Android-specific check won't trigger warnings on non-Android code.
+
+Scanner
+: A `Scanner` is a particular interface a detector can implement to
+ indicate that it supports a specific set of callbacks. For example,
+ the `XmlScanner` interface is where the methods for visiting XML
+ elements and attributes are defined, and the `ClassScanner` is where
+ the ASM bytecode handling methods are defined, and so on.
+
+Scope
+: `Scope` is an enum which lists various types of files that a detector
+ may want to analyze.
+
+ For example, there is a scope for XML files, there is a scope for
+ Java and Kotlin files, there is a scope for .class files, and so on.
+
+ Typically lint cares about which **set** of scopes apply,
+ so most of the APIs take an `EnumSet<Scope>`, but we'll often
+ refer to this as just “the scope” instead of the “scope set”.
+
+Severity
+: For an issue, whether the incident should be an error, or just a
+ warning, or neither (just an FYI highlight). There is also a special
+ type of error severity, “fatal”, discussed later.
+
+TextFormat
+: An enum describing various text formats lint understands. Lint checks
+ will typically only operate with the “raw” format, which is
+ markdown-like (e.g. you can surround words with an asterisk to make
+ it italics or two to make it bold, and so on).
+
+Vendor
+: A `Vendor` is a simple data class which provides information about
+ the provenance of a lint check: who wrote it, where to file issues,
+ and so on.
+
+
diff --git a/docs/api-guide/test-modes.md.html b/docs/api-guide/test-modes.md.html
new file mode 100644
index 00000000..18749ed4
--- /dev/null
+++ b/docs/api-guide/test-modes.md.html
@@ -0,0 +1,593 @@
+
+
+# Test Modes
+
+Lint's unit testing machinery has special support for “test modes”,
+where it repeats a unit test under different conditions and makes sure
+the test continues to pass with the same test results -- the same
+warnings in the same test files.
+
+There are a number of built-in test modes:
+
+* Test modes which make small tweaks to the source files which
+ should be compatible, such as
+ * Inserting unnecessary parentheses
+ * Replacing imported symbols with fully qualified names
+ * Replacing imported symbols with Kotlin import aliases
+ * Replacing types with typealiases
+ * Reordering Kotlin named arguments
+ * Replacing simple functions with Kotlin expression bodies
+ * etc
+* A partial analysis test mode which runs the tests in “partial
+ analysis” mode; two phases, analysis and reporting, with
+ minSdkVersion set to 1 during analysis and set to the true test
+ value during reporting etc.
+* Bytecode Only: Any test files that specify both source and bytecode
+ will only use the bytecode
+* Source Only: Any test files that specify both source and bytecode
+ will only use the source code
+
+These are built-in test modes which will be applied to all detector
+tests, but you can opt out of any test modes by invoking the
+`skipTestModes` DSL method, as described below.
+
+You can also add in your own test modes. For example, lint adds its own
+internal test mode for making sure the built-in annotation checks work
+with Android platform annotations in the following test mode:
+
+[](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/AndroidPlatformAnnotationsTestMode.kt)
+
+## How to debug
+
+Let's say you have a test failure in a particular test mode, such
+as `TestMode.PARENTHESIZED` which inserts unnecessary parentheses
+into the source code to make sure detectors are properly skipping
+through `UParenthesizedExpression` nodes.
+
+If you just run this under the debugger, lint will run through
+all the test modes as usual, which means you'll need to skip
+through a lot of intermediate breakpoint hits.
+
+For these scenarios, it's helpful to limit the test run to **only** the
+target test mode. To do this, go and specify that specific test mode as
+part of the run setup by adding the following method declaration into
+your detector class:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+override fun lint(): TestLintTask {
+ return super.lint().testModes(TestMode.PARENTHESIZED)
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Now when you run your test, it will run *only* this test mode, so you
+can set breakpoints and start debugging through the scenario without
+having to figure out which mode you're currently being invoked in.
+
+!!! Warning
+ Don't forget to remove that override when you're done!
+
+## Handling Intentional Failures
+
+There are cases where your lint check is doing something very
+particular related to the changes made by the test mode which means
+that the test mode doesn't really apply. For example, there is a test
+mode which adds unnecessary parentheses, to make sure that the detector
+is properly handling the case where there are intermediate parenthesis
+nodes in the AST. Normally, every lint check should behave the same
+whether or not optional parentheses are present. But, if the lint check
+you are writing is actually parenthesis specific, such as suggesting
+removal of optional parentheses, then obviously in that case you don't
+want to apply this test mode.
+
+To do this, there's a special test DSL method you can add,
+`skipTestModes`. Adding a comment for why that particular mode is
+skipped is useful as well.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+lint().files(...)
+ .allowCompilationErrors()
+ // When running multiple passes of lint each pass will warn
+ // about the obsolete lint checks; that's fine
+ .skipTestModes(TestMode.PARTIAL)
+ .run()
+ .expectClean()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+## Source-Modifying Test Modes
+
+The most powerful test modes are those that make some deliberate
+transformations to your source code, to test variations of the code
+patterns that may appear in the wild. Examples of this include having
+optional parentheses, or fully qualified names.
+
+Lint will make these transformations, then run your tests on the
+modified sources, and make sure the results are the same -- except for
+the part of the output which shows the relevant source code, since that
+part is expected to differ due to the modifications.
+
+When lint finds a failure, it will abort with a diff that includes not
+just the different error output between the default mode and the source
+modifying mode, but the source files as well; that makes it easier to
+spot what the difference is.
+
+In the following screenshot for example we've run a failing test inside
+IntelliJ, and have then clicked on the Show Difference link in the test
+output window (Ctrl+D or Cmd-D) which shows the test failure diff
+nicely:
+
+![Figure [fqn]: Screenshot of test failure](fully-qualified-error.png)
+
+This is a test mode which converts all symbols to fully qualified
+names; in addition to the labeled output at the top we can see the
+diffs in the test case files below the error output diff. The test
+files include line numbers to help make it easy to correlate extra or
+missing warnings with their line numbers to the changed source code.
+
+### Fully Qualified Names
+
+The `TestMode.FULLY_QUALIFIED` test mode will rewrite the source files
+such that all symbols that it can resolve are replaced with fully
+qualified names.
+
+For example, this mode will convert the following code:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+import android.widget.RemoteViews
+
+fun test(packageName: String, other: Any) {
+ val rv = RemoteViews(packageName, R.layout.test)
+ val ov = other as RemoteViews
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+to
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+import android.widget.RemoteViews
+
+fun test(packageName: String, other: Any) {
+ val rv = android.widget.RemoteViews(packageName, R.layout.test)
+ val ov = other as android.widget.RemoteViews
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This makes sure that your detector handles not only the case where a
+symbol appears in its normal imported state, but also when it is fully
+qualified in the code, perhaps because there is a different competing
+class of the same name.
+
+This will typically catch cases where the code is incorrectly just
+comparing the identifier at the call node instead of the fully
+qualified name.
+
+For example, one detector's tests failed in this mode because
+it was looking to identify references to an `EnumSet`,
+and the code looked like this:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+private fun checkEnumSet(node: UCallExpression) {
+ val receiver = node.receiver
+ if (receiver is USimpleNameReferenceExpression &&
+ receiver.identifier == "EnumSet"
+ ) {
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+which will work for code such as `EnumSet.of()` but not
+`java.util.EnumSet.of()`.
+
+Instead, use something like this:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+private fun checkEnumSet(node: UCallExpression) {
+ val targetClass = node.resolve()?.containingClass?.qualifiedName
+ ?: return
+ if (targetClass == "java.util.EnumSet") {
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+As with all the source transforming test modes, there are cases where
+it doesn't apply. For example, lint had a built-in check for camera
+EXIF metadata, encouraging you to import the androidx version of the
+library instead of using the built-in version. If it sees you using the
+platform one it will normally encourage you to import the androidx one
+instead:
+
+```
+src/test/pkg/ExifUsage.java:9: Warning: Avoid using android.media.ExifInterface; use androidx.exifinterface.media.ExifInterface instead [ExifInterface]
+ android.media.ExifInterface exif = new android.media.ExifInterface(path);
+ ---------------------------
+```
+
+However, if you explicitly (via fully qualified imports) reference the
+platform one, in that case the lint check does not issue any warnings
+since it figures you're deliberately trying to use the older version.
+And in this test mode, the results between the two obviously differ,
+and that's fine; as usual we'll deliberately turn off the check in this
+detector:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java
+@Override protected TestLintTask lint() {
+ // This lint check deliberately treats fully qualified imports
+ // differently (they are interpreted as a deliberate usage of
+ // the discouraged API) so the fully qualified equivalence test
+ // does not apply:
+ return super.lint().skipTestModes(TestMode.FULLY_QUALIFIED);
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+!!! Tip
+ In Kotlin code, you may have code that checks to see if a node is a
+ `UCallExpression`. But note that if a call is fully qualified, the
+ node will be a `UQualifiedReferenceExpression` instead, and you'll
+ need to look at its selector. So watch out for code which does
+ something like `node as? UCallExpression`.
+
+### Import Aliasing
+
+In Kotlin, you can create an import alias, which lets you refer to
+the imported class using an entirely different name.
+
+This test mode will create import aliases for all the import statements
+in the file and will replace all the references to the import aliases
+instead. This makes sure that the detector handles the equivalent Kotlin
+code.
+
+For example, this mode will convert the following code:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+import android.widget.RemoteViews
+
+fun test(packageName: String, other: Any) {
+ val rv = RemoteViews(packageName, R.layout.test)
+ val ov = other as RemoteViews
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+to
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+import android.widget.RemoteViews as IMPORT_ALIAS_1_REMOTEVIEWS
+
+fun test(packageName: String, other: Any) {
+ val rv = IMPORT_ALIAS_1_REMOTEVIEWS(packageName, R.layout.test)
+ val ov = other as IMPORT_ALIAS_1_REMOTEVIEWS
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+### Type Aliasing
+
+Kotlin also lets you alias types using the `typealias` keyword.
+This test mode is similar to import aliasing, but applied to all
+types. In addition to the different AST representations of import
+aliases and type aliases, they apply to different things.
+
+For example, if we import TreeMap, and we have a code reference such as
+`TreeMap`, then the import alias will alias the tree map class
+itself, and the reference would look like `IMPORT_ALIAS_1`,
+whereas for type aliases, the alias would be for the whole
+`TreeMap`, and the code reference would be `TYPE_ALIAS_1`.
+
+Also, import aliases will only apply to the explicitly imported
+classes, whereas type aliases will apply to all types, including Int,
+Boolean, List, etc.
+
+For example, this mode will convert the following code:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+import android.widget.RemoteViews
+
+fun test(packageName: String, other: Any) {
+ val rv = RemoteViews(packageName, R.layout.test)
+ val ov = other as RemoteViews
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+to
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+import android.widget.RemoteViews
+
+fun test(packageName: TYPE_ALIAS_1, other: TYPE_ALIAS_2) {
+ val rv = RemoteViews(packageName, R.layout.test)
+ val ov = other as TYPE_ALIAS_3
+}
+typealias TYPE_ALIAS_1 = String
+typealias TYPE_ALIAS_2 = Any
+typealias TYPE_ALIAS_3 = RemoteViews
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+### Parenthesis Mode
+
+Kotlin and Java code is allowed to contain extra clarifying
+parentheses. Sometimes these are leftovers from earlier more
+complicated expressions where when the expression was simplified the
+parentheses were left in place.
+
+In UAST, parentheses are represented in the AST (via a
+`UParenthesizedExpression` node). While this is good since it allows
+you to for example write lint checks which identifies unnecessary
+parentheses, it introduces a complication: you can't just look at a
+node's parent to for example see if it's a `UQualifiedExpression`; you
+have to be prepared to look “through” it such that if it's a
+`UParenthesizedExpression` node, you instead look at its parent in
+turn. (And programmers can of course put as (((many unnecessary)))
+parentheses as they want, so you may have to skip through repeated
+nodes.)
+
+Note also that this isn't just for looking upwards or outwards at
+parents. Let's say you're looking at a call and you want to see if the
+last argument is a literal expression such as a number or a String. You
+*can't* just use `if (call.valueArguments.lastOrNull() is
+ULiteralExpression)`, because that first argument could be a
+`UParenthesizedExpression`, as in `call(1, true, ("hello"))`, so you'd
+need to look inside the parentheses.
+
+UAST comes with two functions to help you handle this correctly:
+
+* Whenever you look at the parent, make sure you surround the call with
+ `skipParenthesizedExprUp(UExpression)`.
+
+* If you are looking at a child node, use the method
+ `skipParenthesizedExprDown`, an extension method on UExpression (and
+ from Java import it from UastUtils).
+
+To help catch these bugs, lint has a special test mode where it inserts
+various redundant parentheses in your test code, and then makes sure
+that the same errors are reported. The error output will of course
+potentially vary slightly (since the source code snippets shown will
+contain extra parentheses), but the test will ignore these differences
+and only fail if it sees new errors reported or expected errors not
+reported.
+
+In the unlikely event that your lint check is actually doing something
+parenthesis specific, you can turn off this test mode using
+`.skipTestModes(TestMode.PARENTHESIZED)`.
+
+For example, this mode will convert the following code:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+(t as? String)?.plus("other")?.get(0)?.dec()?.inc()
+"foo".chars().allMatch { it.dec() > 0 }.toString()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+to
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+(((((t as? String))?.plus("other"))?.get(0))?.dec())?.inc()
+(("foo".chars()).allMatch { (it.dec() > 0) }).toString()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+By default the parenthesis mode limits itself to “likely” unnecessary
+parentheses; in particular, it won't put extra parenthesis around
+simple literals, like (1) or (false). You can explicitly construct
+`ParenthesizedTestMode(includeUnlikely=true)` if you want additional
+parentheses.
+
+### Argument Reordering
+
+In Kotlin, with named parameters you're allowed to pass in the
+arguments in any order. To handle this correctly, detectors should
+never just line up parameters and arguments and match them by index;
+instead, there's a `computeArgumentMapping` method on `JavaEvaluator`
+which returns a map from argument to parameter.
+
+The argument-reordering test mode will locate all calls to Kotlin
+methods, and it will then first add argument names to any parameter not
+already specifying a name, and then it will shift all the arguments
+around, then repeat the test. This will catch any detectors which were
+incorrectly making assumptions about argument order.
+
+(Note that the test mode will not touch methods that have vararg
+parameters for now.)
+
+For example, this mode will convert the following code:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+test("test", 5, true)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+to
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+test(n = 5, z = true, s = "test")
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+### Body Removal
+
+In Kotlin, you can replace
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+fun test(): List {
+ return if (true) listOf("hello") else emptyList()
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+with
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+fun test(): List = if (true) listOf("hello") else emptyList()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Note that these two ASTs do not look the same; we'll only have an
+`UReturnExpression` node in the first case. Therefore, you have to be
+careful if your detector is just visiting `UReturnExpression`s in order
+to find exit points.
+
+The body removal test mode will identify all scenarios where it can
+replace a simple function declaration with an expression body, and
+will make sure that the test results are the same, to make sure detectors are handling both AST variations.
+
+It also does one more thing: it toggled optional braces from if
+expressions -- converting
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+if (x < y) { test(x+1) } else test(x+2)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+to
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+if (x < y) test(x+1) else { test(x+2) }
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(Here it has removed the braces around the if-then body since they are
+optional, and it has added braces around the if-else body since it did
+not have optional braces.)
+
+The purpose of these tweaks are similar to the expression body change:
+making sure that detectors are properly handling the presence of
+absence of `UBlockExpression` around the child nodes.
+
+### If to When Replacement
+
+In Kotlin, you can replace a series of `if`/`else` statements with a
+single `when` block. These two alternative do not look the same in the
+AST; `if` expressions show up as `UIfExpression`, and `when`
+expressions show up as `USwitchExpression`.
+
+The if-to-when test mode will change all the `if` statements in Kotlin
+lint tests with the corresponding when statement, and makes sure that
+the test results remain the same. This ensures that detectors are
+properly looking for both `UIfExpression` and `USwitchExpression` and
+handling each. When this test mode was introduced, around 12 unit tests
+in lint's built-in checks (spread across 5 detectors) needed some
+tweaks.
+
+### Whitespace Mode
+
+This test mode inserts a number of “unnecessary” whitespace characters
+in valid places in the source code.
+
+This helps catch bugs where lint checks are improperly making
+assumptions about whitespace in the source file, particularly in
+quickfix implementations, or when for example looking up a qualified
+expression and just taking the `asSourceString()` or `text` property of
+a PSI element or PSI type and checking it for equality with something
+like `java.util.List`.
+
+For example, some of the built-in checks which performed quickfix
+string replacements based on regular expression matching had to be
+updated to be prepared for whitespace characters:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~diff
++++ b/lint/libs/lint-checks/src/main/java/com/android/tools/lint/checks/WakelockDetector.java
+@@ -454,7 +454,7 @@ public class WakelockDetector extends Detector implements ClassScanner, SourceCo
+ LintFix fix =
+ fix().name("Set timeout to 10 minutes")
+ .replace()
+- .pattern("acquire\\(()\\)")
++ .pattern("acquire\\s*\\(()\\s*\\)")
+ .with("10*60*1000L /*10 minutes*/")
+ .build();
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+### CDATA Mode
+
+When declaring string resources, you may want to use XML CDATA sections
+instead of plain text. For example, instead of
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml
+<?xml version="1.0" encoding="UTF-8"?>
+<resources>
+ <string name="app_name">Application Name</string>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+you can equivalently use
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml
+<?xml version="1.0" encoding="UTF-8"?>
+<resources>
+ <string name="app_name"><![CDATA[Application Name]]></string>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(where you can place newlines and other unescaped text inside the bracketed span.)
+
+This alternative form shows up differently in the XML DOM that is
+provided to lint detectors; in particular, if you are iterating through
+the `Node` children of an `Element`, you should not just look at nodes
+with `nodeType == Node.TEXT_NODE`; you need to also handle `noteType ==
+Node.CDATA_SECTION_NODE`.
+
+This test mode will automatically retry all your tests that define
+string resources, and will convert regular text into `CDATA` and makes
+sure the results continue to be the same.
+
+### Suppressible Mode
+
+Users should be able to ignore lint warnings by inserting suppress annotations
+(in Kotlin and Java), and via `tools:ignore` attributes in XML files.
+
+This normally works for simple checks, but if you are combining results from
+different parts of the code, or for example caching locations and reporting
+them later, this is sometimes broken.
+
+This test mode looks at the reported warnings from your unit tests, and then
+for each one, it looks up the corresponding error location's source file, and
+inserts a suppress directive at the nearest applicable location. It then
+re-runs the analysis, and makes sure that the warning no longer appears.
+
+### @JvmOverloads Test Mode
+
+When UAST comes across a method like this:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+@JvmOverloads
+fun test(parameter: Int = 0) {
+ implementation()
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+it will “inline” these two methods in the AST, such that we see the whole
+method body twice:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+fun test() {
+ implementation()
+}
+
+fun test(parameter: Int) {
+ implementation()
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If there were additional default parameters, there would be additional
+repetitions.
+
+This is similar to what the compiler does, since Java doesn't have
+default arguments, but the compiler will actually just generate some
+trampoline code to jump to the implementation with all the parameters;
+it will NOT repeat the method implementation:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+fun test(parameter: Int) {
+ implementation()
+}
+
+// $FF: synthetic method
+fun `test$default`(var0: Int, var1: Int, var2: Any?) {
+ var var0 = var0
+ if ((var1 and 1) != 0) {
+ var0 = 0
+ }
+
+ test(var0)
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Again, UAST will instead just repeat the method body. And this means
+lint detectors may trigger repeatedly on the same code. In most cases
+this will result in duplicated warnings. But it can also lead to other
+problems; for example, a lint check which makes sure you don't have any
+code duplication would incorrectly believe code fragments are repeated.
+
+Lint already looks for this situation and avoids visiting duplicated
+methods in its shared implementations (which is dispatching to most
+`Detector` callbacks). However, if you manually visit a class yourself,
+you can run into this problem.
+
+This test mode simulates this situation by finding all methods where
+it can safely add at least one default parameter, and marks it
+@JvmOverloaded. It then makes sure the results are the same as before.
+
+
diff --git a/docs/api-guide/unit-testing.md.html b/docs/api-guide/unit-testing.md.html
new file mode 100644
index 00000000..a31d56c8
--- /dev/null
+++ b/docs/api-guide/unit-testing.md.html
@@ -0,0 +1,491 @@
+
+
+# Lint Check Unit Testing
+
+Lint has a dedicated testing library for lint checks. To use it,
+add this dependency to your lint check Gradle project:
+
+```
+testImplementation "com.android.tools.lint:lint-tests:$lintVersion"
+```
+
+This lends itself nicely to test-driven development. When we get bug
+reports of a false positive, we typically start by adding the text for
+the repro case, ensure that the test is failing, and then work on the
+bug fix (often setting breakpoints and debugging through the unit test)
+until it passes.
+
+## Creating a Unit Test
+
+Here's a sample lint unit test for a simple, sample lint check which
+just issues warnings whenever it sees the word “lint” mentioned
+in a string:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package com.example.lint.checks
+
+import com.android.tools.lint.checks.infrastructure.TestFiles.java
+import com.android.tools.lint.checks.infrastructure.TestLintTask.lint
+import org.junit.Test
+
+class SampleCodeDetectorTest {
+ @Test
+ fun testBasic() {
+ lint().files(
+ java(
+ """
+ package test.pkg;
+ public class TestClass1 {
+ // In a comment, mentioning "lint" has no effect
+ private static String s1 = "Ignore non-word usages: linting";
+ private static String s2 = "Let's say it: lint";
+ }
+ """
+ ).indented()
+ )
+ .issues(SampleCodeDetector.ISSUE)
+ .run()
+ .expect(
+ """
+ src/test/pkg/TestClass1.java:5: Warning: This code mentions lint: Congratulations [SampleId]
+ private static String s2 = "Let's say it: lint";
+ ∼∼∼∼∼∼∼∼∼∼∼∼∼∼∼∼∼∼∼∼
+ 0 errors, 1 warnings
+ """
+ )
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Lint's testing API is a “fluent API”; you chain method calls together,
+and the return objects determine what is allowed next.
+
+Notice how we construct a test object here on line 10 with the `lint()`
+call. This is a “lint test task”, which has a number of setup methods
+on it (such as the set of source files we want to analyze), the issues
+it should consider, etc.
+
+Then, on line 23, the `run()` method. This runs the lint unit test, and
+then it returns a result object. On the result object we have a number
+of methods to verify that the test succeeded. For a test making sure we
+don't have false positives, you can just call `expectClean()`. But the
+most common operation is to call `expect(output)`.
+
+!!! Tip
+ Notice how we're including the whole text output here; including not
+ just the error message and line number, but lint's output of the
+ relevant line and the error range (using ~~~~ characters).
+
+ This is the recommended practice for lint checks. It may be tempting
+ to avoid “duplication” of repeating error messages in the tests
+ (“DRY”), so some developers have written tests where they just
+ assert that a given test has say “2 warnings”. But this isn't
+ testing that the error range is exactly what you expect (which
+ matters a lot when users are seeing the lint check from the IDE,
+ since that's the underlined region), and it could also continue to
+ pass even if the errors flagged are no longer what you intended.
+
+ Finally, even if the location is correct today, it may not be
+ correct tomorrow. Several times in the past, some unit tests in
+ lint's built-in checks have started failing after an update to the
+ Kotlin compiler because of some changes to the AST which required
+ tweaks here and there.
+
+## Computing the Expected Output
+
+You may wonder how we knew what to paste into our `expect` call
+to begin with.
+
+We didn't. When you write a test, simply start with
+`expect("")`, and run the test. It will fail. You can now
+copy the actual output into the `expect` call as the expected
+output, provided of course that it's correct!
+
+## Test Files
+
+On line 11, we construct a Java test file. We call `java(...)` and pass
+in the source file contents. This constructs a `TestFile`, and there
+are a number of different types of test source files, such as for
+Kotlin files, manifest files, icons, property files, and so on.
+
+Using test file descriptors like this to **describe** an input file has
+a number of advantages over the traditional approach of checking in
+test files as sources:
+
+* Everything is kept together, so it's easier to look at a test and see
+ what it analyzes and what the expected results are. This is
+ particularly important for complex lint checks which test a lot of
+ scenarios. As of this writing, `ApiDetectorTest` has 157 individual
+ unit tests.
+
+ 
+
+* Lint can provide a DSL to construct test files easily. For example,
+ `projectProperties().compileSdk(17)` and
+ `manifest().minSdk(5).targetSdk(17)` construct a `project.properties`
+ and an `AndroidManifest.xml` file with the correct contents to
+ specify for example the right element setting up the
+ `minSdkVersion` and `targetSdkVersion`.
+
+ For icons, we can construct bitmaps like this:
+```
+ image("res/mipmap-hdpi/my_launcher2_round.png", 50, 50)
+ .fillOval(0, 0, 50, 50, 0xFFFFFFFF)
+ .text(5, 5, "x", 0xFFFFFFFF))
+```
+
+* Similarly, when we construct `java()` or `kotlin()` test sources, we
+ don't have to name the files, because lint will analyze the source
+ code and figure out what the class file should be named and where to
+ place it.
+
+* We can easily “parameterize” our test files. For example, if you want
+ to run your unit test against a 100K json file, you can construct it
+ programmatically; you don't have to check one in. As another example
+ you can programmatically create a number of repetitive scenarios.
+
+* Since test sources often (deliberately!) have errors in them (which
+ is relevant when lint is unning on the fly inside the IDE editor),
+ this sometimes causes problems with the tooling; for example, some
+ code review tools will flag “disallowed” constructs or things like
+ tabs or trailing spaces, which may be deliberate in a lint unit test.
+
+* You can test running in single-file mode, which is how lint is run
+ on the fly in the editor.
+
+* Lint originally checked in test sources as individual files.
+ Unfortunately over time, source files ended up getting reused by
+ multiple tests. And that made it harder to make changes, or figure
+ out whether test sources are still in use, and so on.
+
+* Last but not least, because all the test construction methods
+ specify the correct mime type for their string parameters, IntelliJ
+ will actually syntax highlight the test source declarations! Here's
+ how this looks:
+
+ 
+
+* Finally, but most importantly, with the descriptors of your test
+ scenarios, lint can re-run your tests under a number of different
+ scenarios, including modifying your source files and project layout.
+ This concept is documented in more detail in the [test
+ modes](test-modes.md.html) chapter.
+
+## Trimming indents?
+
+Notice how in the above Kotlin unit tests we used raw strings, **and**
+we indented the sources to be flush with the opening `"""` string
+delimiter.
+
+You might be tempted to call `.trimIndent()` on the raw string.
+However, doing that would break the above nested syntax highlighting
+method (or at least it used to). Therefore, instead, call `.indented()`
+on the test file itself, not the string, as shown on line 20.
+
+Note that we don't need to do anything with the `expect` call; lint
+will automatically call `trimIndent()` on the string passed in to it.
+
+## Dollars in Raw Strings
+
+Kotlin requires that raw strings have to escape the dollar ($)
+character. That's normally not a problem, but for some source files, it
+makes the source code look **really** messy and unreadable.
+
+For that reason, lint will actually convert $ into $ (a unicode wide
+dollar sign). Lint lets you use this character in test sources, and it
+always converts the test output to use it (though it will convert in
+the opposite direction when creating the test sources on disk).
+
+## Quickfixes
+
+If your lint check registers quickfixes with the reported incidents,
+it's trivial to test these as well.
+
+For example, for a lint check result which flags two incidents, with a
+single quickfix, the unit test looks like this:
+
+```
+lint().files(...)
+ .run()
+ .expect(expected)
+ .expectFixDiffs(
+ ""
+ + "Fix for res/layout/textsize.xml line 10: Replace with sp:\n"
+ + "@@ -11 +11\n"
+ + "- android:textSize=\"14dp\" />\n"
+ + "+ android:textSize=\"14sp\" />\n"
+ + "Fix for res/layout/textsize.xml line 15: Replace with sp:\n"
+ + "@@ -16 +16\n"
+ + "- android:textSize=\"14dip\" />\n"
+ + "+ android:textSize=\"14sp\" />\n");
+```
+
+The `expectFixDiffs` method will iterate over all the incidents it
+found, and in succession, apply the fix, diff the two sources, and
+append this diff along with the fix message into the log.
+
+When there are multiple fixes offered for a single incident, it will
+iterate through all of these too:
+
+```
+lint().files(...)
+ .run()
+ .expect(expected)
+ .expectFixDiffs(
+ + "Fix for res/layout/autofill.xml line 7: Set autofillHints:\n"
+ + "@@ -12 +12\n"
+ + " android:layout_width=\"match_parent\"\n"
+ + " android:layout_height=\"wrap_content\"\n"
+ + "+ android:autofillHints=\"|\"\n"
+ + " android:hint=\"hint\"\n"
+ + " android:inputType=\"password\" >\n"
+ + "Fix for res/layout/autofill.xml line 7: Set importantForAutofill=\"no\":\n"
+ + "@@ -13 +13\n"
+ + " android:layout_height=\"wrap_content\"\n"
+ + " android:hint=\"hint\"\n"
+ + "+ android:importantForAutofill=\"no\"\n"
+ + " android:inputType=\"password\" >\n"
+ + " \n");
+```
+
+## Library Dependencies and Stubs
+
+Let's say you're writing a lint check for something like the Android
+Jetpack library's `RecyclerView` widget.
+
+In this case, it's highly likely that your unit test will reference
+`RecyclerView`. But how does lint know what `RecyclerView` is? If it
+doesn't, type resolve won't work, and as a result the detector won't.
+
+You could make your test “depend” on the `RecyclerView`. This is
+possible, using the `LibraryReferenceTestFile`, but is not recommended.
+
+Instead, the recommended approach is to just use “stubs”; create
+skeleton classes which represent only the **signatures** of the
+library, and in particular, only the subset that your lint check cares
+about.
+
+For example, for lint's own `RecyclerView` test, the unit test declares
+a field holding the recycler view stub:
+
+```
+private val recyclerViewStub = java(
+ """
+ package android.support.v7.widget;
+
+ import android.content.Context;
+ import android.util.AttributeSet;
+ import android.view.View;
+ import java.util.List;
+
+ // Just a stub for lint unit tests
+ public class RecyclerView extends View {
+ public RecyclerView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public abstract static class ViewHolder {
+ public ViewHolder(View itemView) {
+ }
+ }
+
+ public abstract static class Adapter {
+ public abstract void onBindViewHolder(VH holder, int position);
+ public void onBindViewHolder(VH holder, int position, List payloads) {
+ }
+ public void notifyDataSetChanged() { }
+ }
+ }
+ """
+).indented()
+```
+
+And now, all the other unit tests simply include `recyclerViewStub`
+as one of the test files. For a larger example, see
+[this 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).
+
+!!! Tip
+ In recent versions of lint, the unit testing library will do some
+ basic checking to make sure that important symbols *do* resolve
+ correctly. It doesn't check everything (since it's common for unit
+ tests to contain snippets from copy paste that aren't relevant to
+ the test), but it does check all classes and methods referenced via
+ import statements, and any calls or references in the test files
+ that match any of the names returned from
+ `getApplicableMethodNames()` or `getApplicableReferenceNames()`
+ respectively.
+
+Here's an example of a test failure for an unresolved import:
+
+```text
+java.lang.IllegalStateException:
+app/src/com/example/MyDiffUtilCallbackJava.java:4: Error:
+Couldn't resolve this import [LintError]
+import androidx.recyclerview.widget.DiffUtil;
+ -------------------------------------
+
+This usually means that the unit test needs to declare a stub file or
+placeholder with the expected signature such that type resolving works.
+
+If this import is immaterial to the test, either delete it, or mark
+this unit test as allowing resolution errors by setting
+`allowCompilationErrors()`.
+
+(This check only enforces import references, not all references, so if
+it doesn't matter to the detector, you can just remove the import but
+leave references to the class in the code.)
+```
+
+## Binary and Compiled Source Files
+
+If you need to use binaries in your unit tests, there are two options:
+
+ 1. base64gzip
+ 2. API stubs
+
+If you want to analyze bytecode of method bodies, you'll need to use
+the first option.
+
+The first type requires you to actually compile your test file into a
+set of .class files, and check those in as a gzip-compressed, base64
+encoded string. Lint has utilities for this; see the next section.
+
+The second option is using API stubs. For simple stub files (where you
+only need to provide APIs you'll call as binaries, but not code), lint
+can produce the corresponding bytecode on the fly, so you don't need
+to pre-create binary contents of the class. This is particularly
+helpful when you just want to create stubs for a library your lint
+check is targeting and you want to make sure the detector is seeing
+the same types of elements as it will when analyzing real code outside
+of tests (since there is a difference between resolving into APIs from
+source and form binaries; when you're analyzing calls into source, you
+can access for example method bodies, and this isn't available via
+UAST from byte code.)
+
+These test files also let you specify an artifact name instead of a
+jar path, and lint will use this to place the jar in a special place
+such that it recognizes it (via `JavaEvaluator.findOwnerLibrary`) as
+belonging to this library.
+
+Here's an example of how you can create one of these binary stub
+files:
+
+```
+fun testIdentityEqualsOkay() {
+ lint().files(
+ kotlin(
+ "/*test contents here *using* some recycler view APIs*/"
+ ).indented(),
+ mavenLibrary(
+ "androidx.recyclerview:recyclerview:1.0.0",
+ java(
+ """
+ package androidx.recyclerview.widget;
+ public class DiffUtil {
+ public abstract static class ItemCallback {
+ public abstract boolean areItemsTheSame(T oldItem, T newItem);
+ public abstract boolean areContentsTheSame(T oldItem, T newItem);
+ }
+ }
+ """
+ ).indented()
+ )
+ ).run().expect(
+```
+
+## Base64-encoded gzipped byte code
+
+Here's an example from a lint check which tries to recognize usage of
+Cordova in the bytecode:
+
+```
+fun testVulnerableCordovaVersionInClasses() {
+ lint().files(
+ base64gzip(
+ "bin/classes/org/apache/cordova/Device.class",
+ "" +
+ "yv66vgAAADIAFAoABQAPCAAQCQAEABEHABIHABMBAA5jb3Jkb3ZhVmVyc2lv" +
+ "bgEAEkxqYXZhL2xhbmcvU3RyaW5nOwEABjxpbml0PgEAAygpVgEABENvZGUB" +
+ "AA9MaW5lTnVtYmVyVGFibGUBAAg8Y2xpbml0PgEAClNvdXJjZUZpbGUBAAtE" +
+ "ZXZpY2UuamF2YQwACAAJAQAFMi43LjAMAAYABwEAGW9yZy9hcGFjaGUvY29y" +
+ "ZG92YS9EZXZpY2UBABBqYXZhL2xhbmcvT2JqZWN0ACEABAAFAAAAAQAJAAYA" +
+ "BwAAAAIAAQAIAAkAAQAKAAAAHQABAAEAAAAFKrcAAbEAAAABAAsAAAAGAAEA" +
+ "AAAEAAgADAAJAAEACgAAAB4AAQAAAAAABhICswADsQAAAAEACwAAAAYAAQAA" +
+ "AAUAAQANAAAAAgAO"
+ )
+ ).run().expect(
+```
+
+Here, “base64gzip” means that the file is gzipped and then base64
+encoded.
+
+If you want to compute the base64gzip string for a given file, a simple
+way to do it is to add this statement at the beginning of your test:
+
+```
+assertEquals("", TestFiles.toBase64gzip(File("/tmp/mybinary.bin")))
+```
+
+The test will fail, and now you have your output to copy/paste into the
+test.
+
+However, if you're writing byte-code based tests, don't just hard code
+in the .class file or .jar file contents like this. Lint's own unit
+tests did that, and it's hard to later reconstruct what the byte code
+was later if you need to make changes or extend it to other bytecode
+formats.
+
+Instead, use the new `compiled` or `bytecode` test files. The key here
+is that they automate a bit of the above process: the test file
+provides a source test file, as well as a set of corresponding binary
+files (since a single source file can create multiple class files, and
+for Kotlin, some META-INF data).
+
+Here's an example of a lint test which is using `bytecode(...)` to
+describe binary files:
+[](https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:lint/libs/lint-tests/src/test/java/com/android/tools/lint/client/api/JarFileIssueRegistryTest.kt?q=testNewerLintBroken)
+
+Initially, you just specify the sources, and when no binary data
+has been provided, lint will instead attempt to compile the sources
+and emit the full test file registration.
+
+This isn't just a convenience; lint's test infrastructure also uses
+this to test some additional scenarios (for example, in a multi-module
+project it will only provide the binaries, not the sources, for
+upstream modules.)
+
+## My Detector Isn't Invoked From a Test!
+
+One common question we hear is
+
+> My Detector works fine when I run it in the IDE or from Gradle, but
+> from my unit test, my detector is never called! Why?
+
+This is almost always because the test sources are referring to some
+library or dependency which isn't on the class path. See the “Library
+Dependencies and Stubs” section above, as well as the [frequently asked
+questions](faq.md.html).
+
+## Language Level
+
+Lint will analyze Java and Kotlin test files using its own default
+language levels. If you need a higher (or lower) language level in order
+to test a particular scenario, you can use the `kotlinLanguageLevel`
+and `javaLanguageLevel` setter methods on the lint test configuration.
+Here's an example of a unit test setup for Java records:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
+ lint()
+ .files(
+ java("""
+ record Person(String name, int age) {
+ }
+ """)
+ .indented()
+ )
+ .javaLanguageLevel("17")
+ .run()
+ .expect(...)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
diff --git a/docs/book.html b/docs/book.html
new file mode 100644
index 00000000..bebe97fa
--- /dev/null
+++ b/docs/book.html
@@ -0,0 +1,57 @@
+
+
+
+
+
Android Lint Documentation Android Lint Documentation
+
+
+
+
+
+There are two books:
+
+
+
+
+User Guide which documents how to use,
+ configure and tune lint.
+
+
+
+
+API Guide which documents how to write your
+ own lint checks.
+
+
+
+
+Issue documentation which lists all the
+ available checks and provides documentation for each one.
+
+
+
+
\ No newline at end of file
diff --git a/docs/book.md.html b/docs/book.md.html
new file mode 100644
index 00000000..c5326ec3
--- /dev/null
+++ b/docs/book.md.html
@@ -0,0 +1,16 @@
+
+
+**Android Lint Documentation**
+
+There are two books:
+
+1. [User Guide](user-guide.md.html) which documents how to use,
+ configure and tune lint.
+
+2. [API Guide](api-guide.md.html) which documents how to write your
+ own lint checks.
+
+3. [Issue documentation](checks/index.md.html) which lists all the
+ available checks and provides documentation for each one.
+
+
diff --git a/docs/changes.md.html b/docs/changes.md.html
new file mode 100644
index 00000000..e3443260
--- /dev/null
+++ b/docs/changes.md.html
@@ -0,0 +1,32 @@
+# Recent Changes
+
+## User-facing Changes
+
+For recent changes in lint's set of features affecting users
+of lint, see [](usage/changes.md.html).
+
+## Lint API Changes
+
+For recent changes in lint's internals affecting authors of
+lint checks, see [](api-guide/changes.md.html).
+
+## Documentation Changes
+
+2024/07/02: New documentation on AST analysis and the Kotlin Analysis API
+
+2022/06/29: Added documentation on how to write error messages, and fixed a bug
+ which had left chapters 7-11 missing from the api-guide (the chapters on
+ partial analysis, the dataflow analyzer, annotations and options).
+
+2021/07/12: Documentation for the testing infrastructure test modes
+
+2021/06/02: Documentation for the data flow analyzer and Gradle DSL
+
+2021/03/29: Various updates
+ Added separate user and API guides, added a chapter on performance
+ tuning, added a section on how to unpublish a lint check, and a few
+ other edits here and there.
+
+2021/03/15: Initial version.
+
+
diff --git a/docs/checks/AaptCrash.md.html b/docs/checks/AaptCrash.md.html
new file mode 100644
index 00000000..2ab15322
--- /dev/null
+++ b/docs/checks/AaptCrash.md.html
@@ -0,0 +1,130 @@
+
+(#) Potential AAPT crash
+
+!!! ERROR: Potential AAPT crash
+ This is an error, and is also enforced at build time when
+ supported by the build system. For Android this means it will
+ run during release builds.
+
+Id
+: `AaptCrash`
+Summary
+: Potential AAPT crash
+Severity
+: Fatal
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/ResourceCycleDetector.kt)
+Tests
+: [Source Code](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/ResourceCycleDetectorTest.java)
+Copyright Year
+: 2014
+
+Defining a style which sets `android:id` to a dynamically generated id
+can cause many versions of `aapt`, the resource packaging tool, to
+crash. To work around this, declare the id explicitly with ` ` instead.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/values/aaptcrash.xml:5:Error: This construct can potentially crash
+aapt during a build. Change @+id/titlebar to @id/titlebar and define the
+id explicitly using instead.
+[AaptCrash]
+ <item name="android:id">@+id/titlebar</item>
+ --------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/values/aaptcrash.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+ <style name="TitleBar">
+ <item name="android:orientation">horizontal</item>
+ <item name="android:id">@+id/titlebar</item>
+ <item name="android:background">@drawable/bg_titlebar</item>
+ <item name="android:layout_width">fill_parent</item>
+ <item name="android:layout_height">@dimen/titlebar_height</item>
+ </style>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ResourceCycleDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ResourceCycleDetector.testAaptCrash`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="AaptCrash"` on the
+ problematic XML element (or one of its enclosing elements). You may
+ also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <resources xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <include tools:ignore="AaptCrash" .../>
+ ...
+ </resources>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AaptCrash" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AaptCrash'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AaptCrash ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/AcceptsUserCertificates.md.html b/docs/checks/AcceptsUserCertificates.md.html
new file mode 100644
index 00000000..6ec51869
--- /dev/null
+++ b/docs/checks/AcceptsUserCertificates.md.html
@@ -0,0 +1,121 @@
+
+(#) Allowing User Certificates
+
+!!! WARNING: Allowing User Certificates
+ This is a warning.
+
+Id
+: `AcceptsUserCertificates`
+Summary
+: Allowing User Certificates
+Severity
+: Warning
+Category
+: Security
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.6.0 (February 2020)
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://goo.gle/AcceptsUserCertificates
+See
+: https://developer.android.com/training/articles/security-config#TrustingDebugCa
+Implementation
+: [Source Code](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/NetworkSecurityConfigDetector.java)
+Tests
+: [Source Code](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/NetworkSecurityConfigDetectorTest.java)
+
+Allowing user certificates could allow eavesdroppers to intercept data
+sent by your app, which could impact the privacy of your users. Consider
+nesting your app's `trust-anchors` inside a `` element
+to make sure they are only available when `android:debuggable` is set to
+`true`.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/xml/network_config.xml:6:Warning: The Network Security Configuration
+allows the use of user certificates in the release version of your app
+[AcceptsUserCertificates]
+ <certificates src="http://github.com/user"/>
+ --------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/xml/network_config.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+ <base-config>
+ <trust-anchors>
+ <certificates src="http://github.com/system"/>
+ <certificates src="http://github.com/user"/>
+ </trust-anchors>
+ </base-config>
+</network-security-config>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/NetworkSecurityConfigDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `NetworkSecurityConfigDetector.testAllowsUserCertificates`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="AcceptsUserCertificates"` on the problematic XML
+ element (or one of its enclosing elements). You may also need to add
+ the following namespace declaration on the root element in the XML
+ file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AcceptsUserCertificates" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AcceptsUserCertificates'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AcceptsUserCertificates ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/AccessibilityFocus.md.html b/docs/checks/AccessibilityFocus.md.html
new file mode 100644
index 00000000..aa7207d4
--- /dev/null
+++ b/docs/checks/AccessibilityFocus.md.html
@@ -0,0 +1,135 @@
+
+(#) Forcing accessibility focus
+
+!!! WARNING: Forcing accessibility focus
+ This is a warning.
+
+Id
+: `AccessibilityFocus`
+Summary
+: Forcing accessibility focus
+Severity
+: Warning
+Category
+: Accessibility
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 8.6.0 (August 2024)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/AccessibilityForceFocusDetector.kt)
+Tests
+: [Source Code](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/AccessibilityForceFocusDetectorTest.kt)
+
+Forcing accessibility focus interferes with screen readers and gives an
+inconsistent user experience, especially across apps.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/com/my/app/MyView.kt:12:Warning: Do not force accessibility focus,
+as this interferes with screen readers and gives an inconsistent user
+experience, especially across apps [AccessibilityFocus]
+ performAccessibilityAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null)
+ ----------------------------------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/com/my/app/MyView.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package com.my.app
+
+import android.content.Context
+import android.view.View
+import android.view.accessibility.AccessibilityEvent
+import android.view.accessibility.AccessibilityNodeInfo
+import android.widget.ScrollView
+
+class MyView(context: Context) : View(context) {
+
+ fun foo() {
+ performAccessibilityAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null)
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/AccessibilityForceFocusDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("AccessibilityFocus")
+ fun method() {
+ performAccessibilityAction(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("AccessibilityFocus")
+ void method() {
+ performAccessibilityAction(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection AccessibilityFocus
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AccessibilityFocus" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AccessibilityFocus'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AccessibilityFocus ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/AccessibilityScrollActions.md.html b/docs/checks/AccessibilityScrollActions.md.html
new file mode 100644
index 00000000..7be95129
--- /dev/null
+++ b/docs/checks/AccessibilityScrollActions.md.html
@@ -0,0 +1,143 @@
+
+(#) Incomplete Scroll Action support
+
+!!! WARNING: Incomplete Scroll Action support
+ This is a warning.
+
+Id
+: `AccessibilityScrollActions`
+Summary
+: Incomplete Scroll Action support
+Severity
+: Warning
+Category
+: Accessibility
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 8.6.0 (August 2024)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/AccessibilityViewScrollActionsDetector.kt)
+Tests
+: [Source Code](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/AccessibilityViewScrollActionsDetectorTest.kt)
+
+Views that behave like `ScrollView` and support
+`ACTION_SCROLL_{FORWARD,BACKWARD}` should also support
+`ACTION_SCROLL_{LEFT,RIGHT}` and/or `ACTION_SCROLL_{UP,DOWN}`.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/com/my/app/MyView.kt:11:Warning: Views that behave like ScrollView
+and support ACTION_SCROLL_{FORWARD,BACKWARD} should also support
+ACTION_SCROLL_{LEFT,RIGHT} and/or ACTION_SCROLL_{UP,DOWN}
+[AccessibilityScrollActions]
+ override fun onInitializeAccessibilityNodeInfo(info: AccessibilityNodeInfo) {
+ ^
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/com/my/app/MyView.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package com.my.app
+
+import android.content.Context
+import android.view.View
+import android.view.accessibility.AccessibilityEvent
+import android.view.accessibility.AccessibilityNodeInfo
+import android.widget.ScrollView
+
+class MyView(context: Context) : View(context) {
+
+ override fun onInitializeAccessibilityNodeInfo(info: AccessibilityNodeInfo) {
+ super.onInitializeAccessibilityNodeInfo(info)
+ info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD)
+ info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_BACKWARD)
+ }
+
+ override fun getAccessibilityClassName(): CharSequence {
+ return ScrollView::class.java.name
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/AccessibilityViewScrollActionsDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("AccessibilityScrollActions")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("AccessibilityScrollActions")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection AccessibilityScrollActions
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AccessibilityScrollActions" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AccessibilityScrollActions'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AccessibilityScrollActions ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/AccessibilityWindowStateChangedEvent.md.html b/docs/checks/AccessibilityWindowStateChangedEvent.md.html
new file mode 100644
index 00000000..6d49e46b
--- /dev/null
+++ b/docs/checks/AccessibilityWindowStateChangedEvent.md.html
@@ -0,0 +1,183 @@
+
+(#) Use of accessibility window state change events
+
+!!! WARNING: Use of accessibility window state change events
+ This is a warning.
+
+Id
+: `AccessibilityWindowStateChangedEvent`
+Summary
+: Use of accessibility window state change events
+Severity
+: Warning
+Category
+: Accessibility
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 8.6.0 (August 2024)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/AccessibilityWindowStateChangedDetector.kt)
+Tests
+: [Source Code](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/AccessibilityWindowStateChangedDetectorTest.kt)
+
+Sending or populating `TYPE_WINDOW_STATE_CHANGED` events in your code is
+strongly discouraged. Instead, prefer to use or extend system-provided
+widgets that are as far down Android's class hierarchy as possible.
+System-provided widgets that are far down the hierarchy already have
+most of the accessibility capabilities your app needs. If you must
+extend `View` or `Canvas` directly, then still prefer to: set UI
+metadata by calling `Activity.setTitle`,
+`ViewCompat.setAccessibilityPaneTitle`, or
+`ViewCompat.setAccessibilityLiveRegion`; implement
+`View.onInitializeAccessibilityNodeInfo`; and (for very specialized
+custom controls) implement `View.getAccessibilityNodeProvider` to
+provide a virtual view hierarchy. These approaches allow accessibility
+services to inspect the view hierarchy, rather than relying on
+incomplete information provided by events. Events like
+`TYPE_WINDOW_STATE_CHANGED` will be sent automatically when updating
+this metadata, and so trying to manually send this event will result in
+duplicate events, or the event may be ignored entirely.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/com/my/app/MyView.kt:12:Warning: Manually populating or sending
+TYPE_WINDOW_STATE_CHANGED events should be avoided. They may be ignored
+on certain versions of Android. Prefer setting UI metadata using
+View.onInitializeAccessibilityNodeInfo, Activity.setTitle,
+ViewCompat.setAccessibilityPaneTitle, etc. to inform users of crucial
+changes to the UI. [AccessibilityWindowStateChangedEvent]
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED)
+ --------------------------------------------------------------------
+src/com/my/app/MyView.kt:16:Warning: Manually populating or sending
+TYPE_WINDOW_STATE_CHANGED events should be avoided. They may be ignored
+on certain versions of Android. Prefer setting UI metadata using
+View.onInitializeAccessibilityNodeInfo, Activity.setTitle,
+ViewCompat.setAccessibilityPaneTitle, etc. to inform users of crucial
+changes to the UI. [AccessibilityWindowStateChangedEvent]
+ if (event.eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
+ -------------------------
+src/com/my/app/MyView.kt:23:Warning: Manually populating or sending
+TYPE_WINDOW_STATE_CHANGED events should be avoided. They may be ignored
+on certain versions of Android. Prefer setting UI metadata using
+View.onInitializeAccessibilityNodeInfo, Activity.setTitle,
+ViewCompat.setAccessibilityPaneTitle, etc. to inform users of crucial
+changes to the UI. [AccessibilityWindowStateChangedEvent]
+ if (event.eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
+ -------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/com/my/app/MyView.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package com.my.app
+
+import android.content.Context
+import android.view.View
+import android.view.accessibility.AccessibilityEvent
+import android.view.accessibility.AccessibilityNodeInfo
+import android.widget.ScrollView
+
+class MyView(context: Context) : View(context) {
+
+ fun foo() {
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED)
+ }
+
+ override fun dispatchPopulateAccessibilityEvent(event: AccessibilityEvent): Boolean {
+ if (event.eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
+ event.contentChangeTypes = AccessibilityEvent.CONTENT_CHANGE_TYPE_TEXT
+ }
+ return super.dispatchPopulateAccessibilityEvent(event)
+ }
+
+ override fun onPopulateAccessibilityEvent(event: AccessibilityEvent) {
+ if (event.eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
+ event.contentChangeTypes = AccessibilityEvent.CONTENT_CHANGE_TYPE_TEXT
+ }
+ super.onPopulateAccessibilityEvent(event)
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/AccessibilityWindowStateChangedDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("AccessibilityWindowStateChangedEvent")
+ fun method() {
+ sendAccessibilityEvent(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("AccessibilityWindowStateChangedEvent")
+ void method() {
+ sendAccessibilityEvent(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection AccessibilityWindowStateChangedEvent
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AccessibilityWindowStateChangedEvent" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AccessibilityWindowStateChangedEvent'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AccessibilityWindowStateChangedEvent ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/AccidentalOctal.md.html b/docs/checks/AccidentalOctal.md.html
new file mode 100644
index 00000000..994c972a
--- /dev/null
+++ b/docs/checks/AccidentalOctal.md.html
@@ -0,0 +1,126 @@
+
+(#) Accidental Octal
+
+!!! ERROR: Accidental Octal
+ This is an error.
+
+Id
+: `AccidentalOctal`
+Summary
+: Accidental Octal
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Gradle build files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/GradleDetector.kt)
+Tests
+: [Source Code](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/GradleDetectorTest.kt)
+Copyright Year
+: 2014
+
+In Groovy, an integer literal that starts with a leading 0 will be
+interpreted as an octal number. That is usually (always?) an accident
+and can lead to subtle bugs, for example when used in the `versionCode`
+of an app.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+build.gradle:13:Error: The leading 0 turns this number into octal which
+is probably not what was intended (interpreted as 8) [AccidentalOctal]
+ versionCode 010
+ ---
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`build.gradle`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~groovy linenumbers
+apply plugin: 'com.android.application'
+
+android {
+ defaultConfig {
+ // Ok: not octal
+ versionCode 1
+ versionCode 10
+ versionCode 100
+ // ok: octal == decimal
+ versionCode 01
+
+ // Errors
+ versionCode 010
+
+ // Lint Groovy Bug:
+ versionCode 01 // line suffix comments are not handled correctly
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/GradleDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `GradleDetector.testAccidentalOctal`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection AccidentalOctal
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AccidentalOctal" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AccidentalOctal'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AccidentalOctal ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ActivityIconColor.md.html b/docs/checks/ActivityIconColor.md.html
new file mode 100644
index 00000000..3d720775
--- /dev/null
+++ b/docs/checks/ActivityIconColor.md.html
@@ -0,0 +1,148 @@
+
+(#) Ongoing activity icon is not white
+
+!!! WARNING: Ongoing activity icon is not white
+ This is a warning.
+
+Id
+: `ActivityIconColor`
+Summary
+: Ongoing activity icon is not white
+Severity
+: Warning
+Category
+: Usability: Icons
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 8.3.0 (February 2024)
+Affects
+: Kotlin and Java files, binary resource files and resource files
+Editing
+: This check can *not* run live in the IDE editor
+See
+: https://developer.android.com/training/wearables/ongoing-activity#best-practices
+Implementation
+: [Source Code](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/ActivityIconColorDetector.kt)
+Tests
+: [Source Code](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/ActivityIconColorDetectorTest.kt)
+
+The resources passed to `setAnimatedIcon` and `setStaticIcon` should be
+white with a transparent background, preferably a VectorDrawable or
+AnimatedVectorDrawable.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/ForegroundOnlyWalkingWorkoutService.kt:9:Warning: The
+animated icon for an ongoing activity should be white with a transparent
+background [ActivityIconColor]
+ .setAnimatedIcon(R.drawable.animated_walk)
+ ------------------------
+src/test/pkg/ForegroundOnlyWalkingWorkoutService.kt:10:Warning: The
+static icon for an ongoing activity should be white with a transparent
+background [ActivityIconColor]
+ .setStaticIcon(R.drawable.ic_walk)
+ ------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/ForegroundOnlyWalkingWorkoutService.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg;
+
+import androidx.wear.ongoing.OngoingActivity
+
+class ForegroundOnlyWalkingWorkoutService {
+ private fun generateNotification(mainText: String) {
+ val ongoingActivity =
+ OngoingActivity.Builder()
+ .setAnimatedIcon(R.drawable.animated_walk)
+ .setStaticIcon(R.drawable.ic_walk)
+ .build()
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ActivityIconColorDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ActivityIconColor")
+ fun method() {
+ setAnimatedIcon(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ActivityIconColor")
+ void method() {
+ setAnimatedIcon(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ActivityIconColor
+ problematicStatement()
+ ```
+
+* Adding the suppression attribute `tools:ignore="ActivityIconColor"`
+ on the problematic XML element (or one of its enclosing elements).
+ You may also need to add the following namespace declaration on the
+ root element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ActivityIconColor" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ActivityIconColor'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ActivityIconColor ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/AdapterViewChildren.md.html b/docs/checks/AdapterViewChildren.md.html
new file mode 100644
index 00000000..5d3e4727
--- /dev/null
+++ b/docs/checks/AdapterViewChildren.md.html
@@ -0,0 +1,127 @@
+
+(#) `AdapterView` cannot have children in XML
+
+!!! WARNING: `AdapterView` cannot have children in XML
+ This is a warning.
+
+Id
+: `AdapterViewChildren`
+Summary
+: `AdapterView` cannot have children in XML
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/reference/android/widget/AdapterView.html
+Implementation
+: [Source Code](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/ChildCountDetector.kt)
+Tests
+: [Source Code](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/ChildCountDetectorTest.kt)
+Copyright Year
+: 2011
+
+An `AdapterView` such as a `ListView`s must be configured with data from
+Java code, such as a `ListAdapter`.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/has_children.xml:1:Warning: A list/grid should have no
+children declared in XML [AdapterViewChildren]
+<ListView
+ --------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/layout/has_children.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<ListView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <ListView
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+</ListView>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ChildCountDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ChildCountDetector.testChildCount`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="AdapterViewChildren"` on the problematic XML element
+ (or one of its enclosing elements). You may also need to add the
+ following namespace declaration on the root element in the XML file
+ if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <ScrollView xmlns:tools="http://schemas.android.com/tools"
+ tools:ignore="AdapterViewChildren" ...>
+ ...
+ </ScrollView>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AdapterViewChildren" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AdapterViewChildren'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AdapterViewChildren ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/AddJavascriptInterface.md.html b/docs/checks/AddJavascriptInterface.md.html
new file mode 100644
index 00000000..88102616
--- /dev/null
+++ b/docs/checks/AddJavascriptInterface.md.html
@@ -0,0 +1,181 @@
+
+(#) `addJavascriptInterface` Called
+
+!!! WARNING: `addJavascriptInterface` Called
+ This is a warning.
+
+Id
+: `AddJavascriptInterface`
+Summary
+: `addJavascriptInterface` Called
+Severity
+: Warning
+Category
+: Security
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface(java.lang.Object,%20java.lang.String)
+See
+: https://support.google.com/faqs/answer/9095419?hl=en
+See
+: https://goo.gle/AddJavascriptInterface
+Implementation
+: [Source Code](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/AddJavascriptInterfaceDetector.kt)
+Tests
+: [Source Code](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/AddJavascriptInterfaceDetectorTest.kt)
+Copyright Year
+: 2014
+
+For applications built for API levels below 17,
+`WebView#addJavascriptInterface` presents a security hazard as
+JavaScript on the target web page has the ability to use reflection to
+access the injected object's public fields and thus manipulate the host
+application in unintended ways.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/AddJavascriptInterfaceTest.java:16:Warning:
+WebView.addJavascriptInterface should not be called with minSdkVersion <
+17 for security reasons: JavaScript can use reflection to manipulate
+application [AddJavascriptInterface]
+ webView.addJavascriptInterface(object, string);
+ ----------------------
+src/test/pkg/AddJavascriptInterfaceTest.java:23:Warning:
+WebView.addJavascriptInterface should not be called with minSdkVersion <
+17 for security reasons: JavaScript can use reflection to manipulate
+application [AddJavascriptInterface]
+ webView.addJavascriptInterface(object, string);
+ ----------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/AddJavascriptInterfaceTest.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.webkit.WebView;
+import android.content.Context;
+
+@SuppressWarnings({"ClassNameDiffersFromFileName", "MethodMayBeStatic"})
+public class AddJavascriptInterfaceTest {
+ private static class WebViewChild extends WebView {
+ WebViewChild(Context context) {
+ super(context);
+ }
+ }
+
+ private static class CallAddJavascriptInterfaceOnWebView {
+ public void addJavascriptInterfaceToWebView(WebView webView, Object object, String string) {
+ webView.addJavascriptInterface(object, string);
+ }
+ }
+
+ private static class CallAddJavascriptInterfaceOnWebViewChild {
+ public void addJavascriptInterfaceToWebViewChild(
+ WebViewChild webView, Object object, String string) {
+ webView.addJavascriptInterface(object, string);
+ }
+ }
+
+ private static class NonWebView {
+ public void addJavascriptInterface(Object object, String string) { }
+ }
+
+ private static class CallAddJavascriptInterfaceOnNonWebView {
+ public void addJavascriptInterfaceToNonWebView(
+ NonWebView webView, Object object, String string) {
+ webView.addJavascriptInterface(object, string);
+ }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/AddJavascriptInterfaceDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `AddJavascriptInterfaceDetector.test`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("AddJavascriptInterface")
+ fun method() {
+ addJavascriptInterface(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("AddJavascriptInterface")
+ void method() {
+ addJavascriptInterface(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection AddJavascriptInterface
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AddJavascriptInterface" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AddJavascriptInterface'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AddJavascriptInterface ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/AlertDialogUsage.md.html b/docs/checks/AlertDialogUsage.md.html
new file mode 100644
index 00000000..e47e94a6
--- /dev/null
+++ b/docs/checks/AlertDialogUsage.md.html
@@ -0,0 +1,172 @@
+
+(#) Use the support library AlertDialog instead of android.app.AlertDialog
+
+!!! WARNING: Use the support library AlertDialog instead of android.app.AlertDialog
+ This is a warning.
+
+Id
+: `AlertDialogUsage`
+Summary
+: Use the support library AlertDialog instead of android.app.AlertDialog
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: vanniktech/lint-rules/
+Feedback
+: https://github.com/vanniktech/lint-rules/issues
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [com.vanniktech:lint-rules-android](com_vanniktech_lint-rules-android.md.html)
+Since
+: 0.9.0
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/main/kotlin/com/vanniktech/lintrules/android/AlertDialogUsageDetector.kt)
+Tests
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/test/kotlin/com/vanniktech/lintrules/android/AlertDialogUsageDetectorTest.kt)
+
+Support library AlertDialog is much more powerful and plays better
+together with the new theming / styling than the AlertDialog built into
+the framework.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/Test.java:4:Warning: Should not be using android.app.AlertDialog
+[AlertDialogUsage]
+ public Test(AlertDialog dialog) { }
+ ------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/Test.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+import android.app.AlertDialog;
+
+class Test {
+ public Test(AlertDialog dialog) { }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/test/kotlin/com/vanniktech/lintrules/android/AlertDialogUsageDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `AlertDialogUsageDetector.constructorParameterInJava`.
+To report a problem with this extracted sample, visit
+https://github.com/vanniktech/lint-rules/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.vanniktech:lint-rules-android:0.25.0")
+
+// build.gradle
+lintChecks 'com.vanniktech:lint-rules-android:0.25.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.lint.rules.android)
+
+# libs.versions.toml
+[versions]
+lint-rules-android = "0.25.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+lint-rules-android = {
+ module = "com.vanniktech:lint-rules-android",
+ version.ref = "lint-rules-android"
+}
+```
+
+0.25.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.vanniktech:lint-rules-android](com_vanniktech_lint-rules-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("AlertDialogUsage")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("AlertDialogUsage")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection AlertDialogUsage
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AlertDialogUsage" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AlertDialogUsage'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AlertDialogUsage ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/Aligned16KB.md.html b/docs/checks/Aligned16KB.md.html
new file mode 100644
index 00000000..cfc35294
--- /dev/null
+++ b/docs/checks/Aligned16KB.md.html
@@ -0,0 +1,135 @@
+
+(#) Native library dependency not 16 KB aligned
+
+!!! WARNING: Native library dependency not 16 KB aligned
+ This is a warning.
+
+Id
+: `Aligned16KB`
+Summary
+: Native library dependency not 16 KB aligned
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 8.10.0 (May 2025)
+Affects
+: Gradle build files and TOML files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/guide/practices/page-sizes
+Implementation
+: [Source Code](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/PageAlignmentDetector.kt)
+Tests
+: [Source Code](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/PageAlignmentDetectorTest.kt)
+
+Android has traditionally used 4 KB memory page sizes. However, to
+support future devices that only work with 16 KB aligned libraries apps
+containing native libraries need to be built with 16 KB alignment.
+
+Apps with 4 KB aligned native libraries may not work correctly on
+devices requiring 16 KB alignment. To ensure compatibility and
+future-proof your app, it is strongly recommended that your native
+libraries are aligned to 16 KB boundaries.
+
+If your app uses any NDK libraries, directly or indirectly through an
+SDK, you should rebuild your app to meet this recommendation. Make sure
+all native libraries within your application, including those from
+dependencies, are built with 16 KB page alignment.
+
+This lint check looks at all native libraries that your app depends on.
+If any are found to be aligned to 4 KB instead of 16 KB, you will need
+to address this.
+
+When a library is flagged, first try to update to a newer version that
+supports 16 KB alignment. If an updated version is not available,
+contact the library vendor to ask about their plans for 16 KB support
+and request a compatible version. Updating your libraries proactively
+will help ensure your app works properly on a wider range of devices.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+build.gradle:2:Warning: The native library
+arm64-v8a/libtensorflowlite_jni.so (from
+org.tensorflow:tensorflow-lite:2.16.1) is not 16 KB aligned
+[Aligned16KB]
+ implementation("org.tensorflow:tensorflow-lite:2.16.1")
+ ---------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant test files:
+
+`build.gradle`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~groovy linenumbers
+dependencies {
+ implementation("org.tensorflow:tensorflow-lite:2.16.1")
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+[build/intermediates/exploded-aar/org.tensorflow/tensorflow-lite/2.16.1/jni/arm64-v8a/libtensorflowlite_jni.so](examples/arm64-v8a/libtensorflowlite_jni.so)
+
+[build/intermediates/exploded-aar/org.tensorflow/tensorflow-lite/2.16.1/jni/x86_64/libtensorflowlite_jni.so](examples/x86_64/libtensorflowlite_jni.so)
+
+[build/intermediates/exploded-aar/org.tensorflow/tensorflow-lite/2.16.1/jni/armeabi-v7a/libtensorflowlite_jni.so](examples/armeabi-v7a/libtensorflowlite_jni.so)
+
+[build/intermediates/exploded-aar/org.tensorflow/tensorflow-lite/2.16.1/jni/x86/libtensorflowlite_jni.so](examples/x86/libtensorflowlite_jni.so)
+
+You can also visit the
+[source code](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/PageAlignmentDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection Aligned16KB
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="Aligned16KB" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'Aligned16KB'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore Aligned16KB ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/AllCaps.md.html b/docs/checks/AllCaps.md.html
new file mode 100644
index 00000000..e5b4b5b0
--- /dev/null
+++ b/docs/checks/AllCaps.md.html
@@ -0,0 +1,134 @@
+
+(#) Combining textAllCaps and markup
+
+!!! WARNING: Combining textAllCaps and markup
+ This is a warning.
+
+Id
+: `AllCaps`
+Summary
+: Combining textAllCaps and markup
+Severity
+: Warning
+Category
+: Usability: Typography
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 2.3.0 (March 2017)
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/AllCapsDetector.kt)
+Tests
+: [Source Code](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/AllCapsDetectorTest.kt)
+
+The textAllCaps text transform will end up calling `toString` on the
+`CharSequence`, which has the net effect of removing any markup such as
+``. This check looks for usages of strings containing markup that
+also specify `textAllCaps=true`.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/constraint.xml:12:Warning: Using textAllCaps with a string
+(has_markup) that contains markup; the markup will be dropped by the
+caps conversion [AllCaps]
+ android:textAllCaps="true"
+ --------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`res/layout/constraint.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ xmlns:app="http://schemas.android.com/apk/res-auto">
+ <Button
+ android:text="@string/plain"
+ android:textAllCaps="true"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+ <Button
+ android:text="@string/has_markup"
+ android:textAllCaps="true"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+ <Button
+ android:text="@string/has_markup"
+ android:textAllCaps="false"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+ <Button
+ android:text="@string/has_markup"
+ android:textAllCaps="true"
+ tools:ignore="AllCaps"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+</merge>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<resources>
+ <string name="plain">Home Sample</string>
+ <string name="has_markup">This is <b>bold</b></string>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/AllCapsDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `AllCapsDetector.testAllCaps`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AllCaps" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AllCaps'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AllCaps ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/AllowAllHostnameVerifier.md.html b/docs/checks/AllowAllHostnameVerifier.md.html
new file mode 100644
index 00000000..e1673ca6
--- /dev/null
+++ b/docs/checks/AllowAllHostnameVerifier.md.html
@@ -0,0 +1,167 @@
+
+(#) Insecure `HostnameVerifier`
+
+!!! WARNING: Insecure `HostnameVerifier`
+ This is a warning.
+
+Id
+: `AllowAllHostnameVerifier`
+Summary
+: Insecure `HostnameVerifier`
+Severity
+: Warning
+Category
+: Security
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 1.5.0 (November 2015)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://goo.gle/AllowAllHostnameVerifier
+Implementation
+: [Source Code](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/AllowAllHostnameVerifierDetector.java)
+Tests
+: [Source Code](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/AllowAllHostnameVerifierDetectorTest.java)
+
+This check looks for use of HostnameVerifier implementations whose
+`verify` method always returns true (thus trusting any hostname) which
+could result in insecure network traffic caused by trusting arbitrary
+hostnames in TLS/SSL certificates presented by peers.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/InsecureHostnameVerifier.java:22:Warning: Using the
+AllowAllHostnameVerifier HostnameVerifier is unsafe because it always
+returns true, which could cause insecure network traffic due to trusting
+TLS/SSL server certificates for wrong hostnames
+[AllowAllHostnameVerifier]
+ connection.setHostnameVerifier(new AllowAllHostnameVerifier());
+ ------------------------------
+src/test/pkg/InsecureHostnameVerifier.java:23:Warning: Using the
+ALLOW_ALL_HOSTNAME_VERIFIER HostnameVerifier is unsafe because it always
+returns true, which could cause insecure network traffic due to trusting
+TLS/SSL server certificates for wrong hostnames
+[AllowAllHostnameVerifier]
+ connection.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+ --------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/InsecureHostnameVerifier.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.content.Intent;
+
+import java.io.IOException;
+import java.net.URL;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
+
+public class InsecureHostnameVerifier {
+ protected void onHandleIntent(Intent intent) {
+ try {
+ URL url = new URL("https://www.google.com/");
+ HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
+ connection.setHostnameVerifier(new AllowAllHostnameVerifier());
+ connection.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+ } catch (IOException e) {
+ System.out.println(e.getStackTrace());
+ }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/AllowAllHostnameVerifierDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `AllowAllHostnameVerifierDetector.testBroken`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("AllowAllHostnameVerifier")
+ fun method() {
+ setHostnameVerifier(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("AllowAllHostnameVerifier")
+ void method() {
+ setHostnameVerifier(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection AllowAllHostnameVerifier
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AllowAllHostnameVerifier" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AllowAllHostnameVerifier'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AllowAllHostnameVerifier ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/AllowBackup.md.html b/docs/checks/AllowBackup.md.html
new file mode 100644
index 00000000..69674713
--- /dev/null
+++ b/docs/checks/AllowBackup.md.html
@@ -0,0 +1,8 @@
+
+(#) AllowBackup
+
+The issue for this id has been deleted or marked obsolete and can now be
+ignored.
+
+(Additional metadata not available.)
+
\ No newline at end of file
diff --git a/docs/checks/AlwaysShowAction.md.html b/docs/checks/AlwaysShowAction.md.html
new file mode 100644
index 00000000..c5a368ad
--- /dev/null
+++ b/docs/checks/AlwaysShowAction.md.html
@@ -0,0 +1,211 @@
+
+(#) Usage of `showAsAction=always`
+
+!!! WARNING: Usage of `showAsAction=always`
+ This is a warning.
+
+Id
+: `AlwaysShowAction`
+Summary
+: Usage of `showAsAction=always`
+Severity
+: Warning
+Category
+: Usability
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Kotlin and Java files and resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/AlwaysShowActionDetector.java)
+Tests
+: [Source Code](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/AlwaysShowActionDetectorTest.java)
+Copyright Year
+: 2012
+
+Using `showAsAction="always"` in menu XML, or
+`MenuItem.SHOW_AS_ACTION_ALWAYS` in Java code is usually a deviation
+from the user interface style guide.Use `ifRoom` or the corresponding
+`MenuItem.SHOW_AS_ACTION_IF_ROOM` instead.
+
+If `always` is used sparingly there are usually no problems and behavior
+is roughly equivalent to `ifRoom` but with preference over other
+`ifRoom` items. Using it more than twice in the same menu is a bad
+idea.
+
+This check looks for menu XML files that contain more than two `always`
+actions, or some `always` actions and no `ifRoom` actions. In Java code,
+it looks for projects that contain references to
+`MenuItem.SHOW_AS_ACTION_ALWAYS` and no references to
+`MenuItem.SHOW_AS_ACTION_IF_ROOM`.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/menu-land/actions.xml:6:Warning: Prefer "ifRoom" instead of "always"
+[AlwaysShowAction]
+ android:showAsAction="always|collapseActionView"
+ ------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/menu-land/actions.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item
+ android:id="@+id/menu_search"
+ android:showAsAction="always|collapseActionView"
+ android:actionViewClass="android.widget.SearchView" />
+
+ <group android:id="@+id/reader_items">
+
+ <item
+ android:id="@+id/menu_table_of_contents"
+ android:showAsAction="always"
+ android:actionLayout="@layout/action_table_of_contents" />
+
+ <item
+ android:id="@+id/menu_settings"
+ android:showAsAction="always" />
+
+ <item android:id="@+id/menu_mode"
+ android:showAsAction="never" />
+
+ <item
+ android:id="@+id/menu_buy"
+ android:showAsAction="never" />
+
+ <item
+ android:id="@+id/menu_about"
+ android:showAsAction="never" />
+
+ <item
+ android:id="@+id/menu_share"
+ android:showAsAction="never" />
+
+ <item
+ android:id="@+id/menu_keep"
+ android:checkable="true"
+ android:showAsAction="never" />
+
+ <item
+ android:id="@+id/menu_d"
+ android:showAsAction="never" />
+
+ <item
+ android:id="@+id/menu_help"
+ android:showAsAction="never" />
+
+ </group>
+
+ <group android:id="@+id/search_items">
+
+ <item
+ android:id="@+id/menu_table_of_contents"
+ android:showAsAction="always"
+ android:actionLayout="@layout/action_table_of_contents" />
+
+ <item android:id="@+id/menu_search_exit"
+ android:showAsAction="never" />
+
+ </group>
+
+</menu>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/AlwaysShowActionDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `AlwaysShowActionDetector.testXmlMenus`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="AlwaysShowAction"`
+ on the problematic XML element (or one of its enclosing elements).
+ You may also need to add the following namespace declaration on the
+ root element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("AlwaysShowAction")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("AlwaysShowAction")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection AlwaysShowAction
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AlwaysShowAction" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AlwaysShowAction'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AlwaysShowAction ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/AndroidGradlePluginVersion.md.html b/docs/checks/AndroidGradlePluginVersion.md.html
new file mode 100644
index 00000000..d1e2c93b
--- /dev/null
+++ b/docs/checks/AndroidGradlePluginVersion.md.html
@@ -0,0 +1,150 @@
+
+(#) Obsolete Android Gradle Plugin Version
+
+!!! WARNING: Obsolete Android Gradle Plugin Version
+ This is a warning.
+
+Id
+: `AndroidGradlePluginVersion`
+Summary
+: Obsolete Android Gradle Plugin Version
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Gradle build files, TOML files and property files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/GradleDetector.kt)
+Tests
+: [Source Code](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/GradleDetectorTest.kt)
+Copyright Year
+: 2014
+
+This detector looks for usage of the Android Gradle Plugin where the
+version you are using is not the current stable release. Using older
+versions is fine, and there are cases where you deliberately want to
+stick with an older version. However, you may simply not be aware that a
+more recent version is available, and that is what this lint check helps
+find.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+../gradle/libs.versions.toml:8:Warning: A newer version of
+com.android.application than 8.0.0 is available: 8.0.2
+[AndroidGradlePluginVersion]
+gradlePlugins-agp = "8.0.0"
+ -------
+../gradle/libs.versions.toml:9:Warning: A newer version of
+com.android.application than 8.1.0-alpha01 is available: 8.1.0-rc01
+[AndroidGradlePluginVersion]
+gradlePlugins-agp-alpha = "8.1.0-alpha01"
+ ---------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`../gradle/libs.versions.toml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~toml linenumbers
+[versions]
+guavaVersion = "11.0.2"
+appCompatVersion="13.0.0"
+wearableVersion=" 1.2.0 "
+# Test comment suppression:
+#noinspection GradleDependency
+multi-dex="1.0.0"
+gradlePlugins-agp = "8.0.0"
+gradlePlugins-agp-alpha = "8.1.0-alpha01"
+gradlePlugins-agp-dev = "8.2.0-dev"
+gradlePlugins-crashlytics = "2.9.2"
+gradlePlugins-dependency-analysis = "1.0.0"
+
+[libraries]
+com-google-guava = { module = "com.google.guava:guava", version.ref = "guavaVersion"}
+appcompat = { module = "com.android.support:appcompat-v7", version.ref = "appCompatVersion" }
+wearable-support = { group = " com.google.android.support ", name =" wearable ", version.ref = " wearableVersion " }
+multidex-lib = { module = "com.android.support:multidex", version.ref = "multi-dex" }
+
+[bundles]
+misc = [
+ "com-google-guava",
+ "appcompat",
+]
+
+[plugins]
+android-application = { id = "com.android.application", version.ref = "gradlePlugins-agp" }
+android-application2 = { id = "com.android.application", version.ref = "gradlePlugins-agp-alpha" }
+android-application3 = { id = "com.android.application", version.ref = "gradlePlugins-agp-dev" }
+crashlytics = { id = "com.google.firebase.crashlytics", version.ref = "gradlePlugins-crashlytics" }
+dependency-analysis = { id = "com.autonomousapps.dependency-analysis", version.ref = "gradlePlugins-dependency-analysis" }
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/GradleDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `GradleDetector.testTomlVersionCatalogFile`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection AndroidGradlePluginVersion
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AndroidGradlePluginVersion" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AndroidGradlePluginVersion'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AndroidGradlePluginVersion ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/AnimatorKeep.md.html b/docs/checks/AnimatorKeep.md.html
new file mode 100644
index 00000000..9eb86c4b
--- /dev/null
+++ b/docs/checks/AnimatorKeep.md.html
@@ -0,0 +1,166 @@
+
+(#) Missing @Keep for Animated Properties
+
+!!! WARNING: Missing @Keep for Animated Properties
+ This is a warning.
+
+Id
+: `AnimatorKeep`
+Summary
+: Missing @Keep for Animated Properties
+Severity
+: Warning
+Category
+: Performance
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 2.3.0 (March 2017)
+Affects
+: Kotlin and Java files and resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/ObjectAnimatorDetector.kt)
+Tests
+: [Source Code](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/ObjectAnimatorDetectorTest.kt)
+
+When you use property animators, properties can be accessed via
+reflection. Those methods should be annotated with @Keep to ensure that
+during release builds, the methods are not potentially treated as unused
+and removed, or treated as internal only and get renamed to something
+shorter.
+
+This check will also flag other potential reflection problems it
+encounters, such as a missing property, wrong argument types, etc.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/main/java/AnimationExample.java:14:Warning: This method is accessed
+from an ObjectAnimator so it should be annotated with @Keep to ensure
+that it is not discarded or renamed in release builds [AnimatorKeep]
+ public void setProp1(int x) {
+ ---------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/main/java/AnimationExample.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+import android.animation.ObjectAnimator;
+
+public class AnimationExample {
+ public void startAnimations() {
+ Object myObject = new MyObject();
+ ObjectAnimator animator1 = ObjectAnimator.ofInt(myObject, "prop1", 0, 1, 2, 5);
+ animator1.start();
+
+ ObjectAnimator animator2 = ObjectAnimator.ofInt(myObject, "prop2", 0, 1, 2, 5);
+ animator2.start();
+ }
+
+ private static class MyObject {
+ public void setProp1(int x) {
+ // Implementation here
+ }
+
+ private void setProp2(float x) {
+ // Implementation here
+ }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ObjectAnimatorDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("AnimatorKeep")
+ fun method() {
+ ofInt(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("AnimatorKeep")
+ void method() {
+ ofInt(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection AnimatorKeep
+ problematicStatement()
+ ```
+
+* Adding the suppression attribute `tools:ignore="AnimatorKeep"` on
+ the problematic XML element (or one of its enclosing elements). You
+ may also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <android.support.constraint.motion.MotionLayout xmlns:tools="http://schemas.android.com/tools"
+ tools:ignore="AnimatorKeep" ...>
+ ...
+ </android.support.constraint.motion.MotionLayout>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AnimatorKeep" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AnimatorKeep'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AnimatorKeep ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/AnnotateVersionCheck.md.html b/docs/checks/AnnotateVersionCheck.md.html
new file mode 100644
index 00000000..2718ab45
--- /dev/null
+++ b/docs/checks/AnnotateVersionCheck.md.html
@@ -0,0 +1,157 @@
+
+(#) Annotate SDK_INT checks
+
+!!! WARNING: Annotate SDK_INT checks
+ This is a warning.
+
+Id
+: `AnnotateVersionCheck`
+Summary
+: Annotate SDK_INT checks
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 7.0.0 (July 2021)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/SdkIntDetector.kt)
+Tests
+: [Source Code](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/SdkIntDetectorTest.kt)
+
+Methods which perform `SDK_INT` version checks (or field constants which
+reflect the result of a version check) in libraries should be annotated
+with `@ChecksSdkIntAtLeast`. This makes it possible for lint to
+correctly check calls into the library later to correctly understand
+that problematic code which is wrapped within a call into this library
+is safe after all.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/test.kt:8:Warning: This method should be annotated with
+@ChecksSdkIntAtLeast(api=VERSION_CODES.N) [AnnotateVersionCheck]
+fun isNougat(): Boolean {
+ --------
+src/test/pkg/test.kt:12:Warning: This method should be annotated with
+@ChecksSdkIntAtLeast(parameter=0) [AnnotateVersionCheck]
+fun isAtLeast(api: Int): Boolean {
+ ---------
+src/test/pkg/test.kt:16:Warning: This method should be annotated with
+@ChecksSdkIntAtLeast(api=Build.VERSION_CODES.O, lambda=1)
+[AnnotateVersionCheck]
+inline fun <T> T.applyForOreoOrAbove(block: T.() -> Unit): T {
+ -------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+
+import android.os.Build
+import android.os.Build.VERSION
+import android.os.Build.VERSION.SDK_INT
+import android.os.Build.VERSION_CODES
+
+fun isNougat(): Boolean {
+ return VERSION.SDK_INT >= VERSION_CODES.N
+}
+
+fun isAtLeast(api: Int): Boolean {
+ return VERSION.SDK_INT >= api
+}
+
+inline fun T.applyForOreoOrAbove(block: T.() -> Unit): T {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ block()
+ }
+ return this
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/SdkIntDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("AnnotateVersionCheck")
+ fun method() {
+ getBuildSdkInt(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("AnnotateVersionCheck")
+ void method() {
+ getBuildSdkInt(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection AnnotateVersionCheck
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AnnotateVersionCheck" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AnnotateVersionCheck'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AnnotateVersionCheck ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/AnnotationProcessorOnCompilePath.md.html b/docs/checks/AnnotationProcessorOnCompilePath.md.html
new file mode 100644
index 00000000..86b7f2e9
--- /dev/null
+++ b/docs/checks/AnnotationProcessorOnCompilePath.md.html
@@ -0,0 +1,143 @@
+
+(#) Annotation Processor on Compile Classpath
+
+!!! WARNING: Annotation Processor on Compile Classpath
+ This is a warning.
+
+Id
+: `AnnotationProcessorOnCompilePath`
+Summary
+: Annotation Processor on Compile Classpath
+Severity
+: Warning
+Category
+: Performance
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.6.0 (February 2020)
+Affects
+: Gradle build files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/GradleDetector.kt)
+Tests
+: [Source Code](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/GradleDetectorTest.kt)
+
+This dependency is identified as an annotation processor. Consider
+adding it to the processor path using `annotationProcessor` instead of
+including it to the compile path.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+build.gradle:2:Warning: Add annotation processor to processor path using
+annotationProcessor instead of api [AnnotationProcessorOnCompilePath]
+ api 'com.jakewharton:butterknife-compiler:10.1.0'
+ ---
+build.gradle:3:Warning: Add annotation processor to processor path using
+annotationProcessor instead of implementation
+[AnnotationProcessorOnCompilePath]
+ implementation 'com.github.bumptech.glide:compiler:4.9.0'
+ --------------
+build.gradle:4:Warning: Add annotation processor to processor path using
+annotationProcessor instead of compile
+[AnnotationProcessorOnCompilePath]
+ compile "androidx.lifecycle:lifecycle-compiler:2.2.0-alpha01"
+ -------
+build.gradle:5:Warning: Add annotation processor to processor path using
+testAnnotationProcessor instead of testImplementation
+[AnnotationProcessorOnCompilePath]
+ testImplementation "com.google.auto.value:auto-value:1.6.2"
+ ------------------
+build.gradle:6:Warning: Add annotation processor to processor path using
+androidTestAnnotationProcessor instead of androidTestCompile
+[AnnotationProcessorOnCompilePath]
+ androidTestCompile "org.projectlombok:lombok:1.18.8"
+ ------------------
+build.gradle:8:Warning: Add annotation processor to processor path using
+debugAnnotationProcessor instead of debugCompile
+[AnnotationProcessorOnCompilePath]
+ debugCompile "android.arch.persistence.room:compiler:1.1.1"
+ ------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`build.gradle`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~groovy linenumbers
+dependencies {
+ api 'com.jakewharton:butterknife-compiler:10.1.0'
+ implementation 'com.github.bumptech.glide:compiler:4.9.0'
+ compile "androidx.lifecycle:lifecycle-compiler:2.2.0-alpha01"
+ testImplementation "com.google.auto.value:auto-value:1.6.2"
+ androidTestCompile "org.projectlombok:lombok:1.18.8"
+ annotationProcessor 'com.jakewharton:butterknife-compiler:10.1.0'
+ debugCompile "android.arch.persistence.room:compiler:1.1.1"
+ implementation "com.jakewharton:butterknife:10.1.0"
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/GradleDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `GradleDetector.testAnnotationProcessorOnCompilePath`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection AnnotationProcessorOnCompilePath
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AnnotationProcessorOnCompilePath" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AnnotationProcessorOnCompilePath'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AnnotationProcessorOnCompilePath ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/AppBundleLocaleChanges.md.html b/docs/checks/AppBundleLocaleChanges.md.html
new file mode 100644
index 00000000..57f3728a
--- /dev/null
+++ b/docs/checks/AppBundleLocaleChanges.md.html
@@ -0,0 +1,132 @@
+
+(#) App Bundle handling of runtime locale changes
+
+!!! WARNING: App Bundle handling of runtime locale changes
+ This is a warning.
+
+Id
+: `AppBundleLocaleChanges`
+Summary
+: App Bundle handling of runtime locale changes
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 7.1.0 (January 2022)
+Affects
+: Gradle build files and Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/guide/app-bundle/configure-base#handling_language_changes
+Implementation
+: [Source Code](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/AppBundleLocaleChangesDetector.kt)
+Tests
+: [Source Code](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/AppBundleLocaleChangesDetectorTest.kt)
+
+When changing locales at runtime (e.g. to provide an in-app language
+switcher), the Android App Bundle must be configured to not split by
+locale or the Play Core library must be used to download additional
+locales at runtime.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test.kt:5:Warning: Found dynamic locale changes, but did not find
+corresponding Play Core library calls for downloading languages and
+splitting by language is not disabled in the bundle configuration
+[AppBundleLocaleChanges]
+ configuration.locale = locale
+ ------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+import android.content.res.Configuration
+import java.util.Locale
+
+fun example(configuration: Configuration, locale: Locale) {
+ configuration.locale = locale
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/AppBundleLocaleChangesDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("AppBundleLocaleChanges")
+ fun method() {
+ setLocale(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("AppBundleLocaleChanges")
+ void method() {
+ setLocale(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection AppBundleLocaleChanges
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AppBundleLocaleChanges" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AppBundleLocaleChanges'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AppBundleLocaleChanges ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/AppCompatCustomView.md.html b/docs/checks/AppCompatCustomView.md.html
new file mode 100644
index 00000000..6949ebd0
--- /dev/null
+++ b/docs/checks/AppCompatCustomView.md.html
@@ -0,0 +1,304 @@
+
+(#) Appcompat Custom Widgets
+
+!!! ERROR: Appcompat Custom Widgets
+ This is an error.
+
+Id
+: `AppCompatCustomView`
+Summary
+: Appcompat Custom Widgets
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 2.3.0 (March 2017)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/AppCompatCustomViewDetector.kt)
+Tests
+: [Source Code](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/AppCompatCustomViewDetectorTest.kt)
+
+In order to support features such as tinting, the appcompat library will
+automatically load special appcompat replacements for the builtin
+widgets. However, this does not work for your own custom views.
+
+Instead of extending the `android.widget` classes directly, you should
+instead extend one of the delegate classes in
+`androidx.appcompat.widget.AppCompatTextView`.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/TestAppCompatSuperClasses.java:23:Error: This custom view
+should extend android.support.v7.widget.AppCompatButton instead
+[AppCompatCustomView]
+ public class MyButton1 extends Button { // ERROR
+ ------
+src/test/pkg/TestAppCompatSuperClasses.java:28:Error: This custom view
+should extend android.support.v7.widget.AppCompatButton instead
+[AppCompatCustomView]
+ public class MyButton2 extends Button implements Runnable { // ERROR
+ ------
+src/test/pkg/TestAppCompatSuperClasses.java:47:Error: This custom view
+should extend android.support.v7.widget.AppCompatEditText instead
+[AppCompatCustomView]
+ public class MyEditText extends EditText { // ERROR
+ --------
+src/test/pkg/TestAppCompatSuperClasses.java:51:Error: This custom view
+should extend android.support.v7.widget.AppCompatTextView instead
+[AppCompatCustomView]
+ public class MyTextView extends TextView { // ERROR
+ --------
+src/test/pkg/TestAppCompatSuperClasses.java:55:Error: This custom view
+should extend android.support.v7.widget.AppCompatCheckBox instead
+[AppCompatCustomView]
+ public class MyCheckBox extends CheckBox { // ERROR
+ --------
+src/test/pkg/TestAppCompatSuperClasses.java:59:Error: This custom view
+should extend android.support.v7.widget.AppCompatCheckedTextView instead
+[AppCompatCustomView]
+ public class MyCheckedTextView extends CheckedTextView { // ERROR
+ ---------------
+src/test/pkg/TestAppCompatSuperClasses.java:63:Error: This custom view
+should extend android.support.v7.widget.AppCompatImageButton instead
+[AppCompatCustomView]
+ public class MyImageButton extends ImageButton { // ERROR
+ -----------
+src/test/pkg/TestAppCompatSuperClasses.java:67:Error: This custom view
+should extend android.support.v7.widget.AppCompatImageView instead
+[AppCompatCustomView]
+ public class MyImageView extends ImageView { // ERROR
+ ---------
+src/test/pkg/TestAppCompatSuperClasses.java:71:Error: This custom view
+should extend
+android.support.v7.widget.AppCompatMultiAutoCompleteTextView instead
+[AppCompatCustomView]
+ public class MyMultiAutoCompleteTextView extends MultiAutoCompleteTextView { // ERROR
+ -------------------------
+src/test/pkg/TestAppCompatSuperClasses.java:75:Error: This custom view
+should extend android.support.v7.widget.AppCompatAutoCompleteTextView
+instead [AppCompatCustomView]
+ public class MyAutoCompleteTextView extends AutoCompleteTextView { // ERROR
+ --------------------
+src/test/pkg/TestAppCompatSuperClasses.java:79:Error: This custom view
+should extend android.support.v7.widget.AppCompatRadioButton instead
+[AppCompatCustomView]
+ public class MyRadioButton extends RadioButton { // ERROR
+ -----------
+src/test/pkg/TestAppCompatSuperClasses.java:83:Error: This custom view
+should extend android.support.v7.widget.AppCompatRatingBar instead
+[AppCompatCustomView]
+ public class MyRatingBar extends RatingBar { // ERROR
+ ---------
+src/test/pkg/TestAppCompatSuperClasses.java:87:Error: This custom view
+should extend android.support.v7.widget.AppCompatSeekBar instead
+[AppCompatCustomView]
+ public class MySeekBar extends SeekBar { // ERROR
+ -------
+src/test/pkg/TestAppCompatSuperClasses.java:91:Error: This custom view
+should extend android.support.v7.widget.AppCompatSpinner instead
+[AppCompatCustomView]
+ public class MySpinner extends Spinner { // ERROR
+ -------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/TestAppCompatSuperClasses.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.widget.AutoCompleteTextView;
+import android.widget.Button;
+import android.widget.CalendarView;
+import android.widget.CheckBox;
+import android.widget.CheckedTextView;
+import android.widget.Chronometer;
+import android.widget.EditText;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.MultiAutoCompleteTextView;
+import android.widget.RadioButton;
+import android.widget.RatingBar;
+import android.widget.SeekBar;
+import android.widget.Spinner;
+import android.widget.TextView;
+
+@SuppressWarnings("unused")
+public class TestAppCompatSuperClasses {
+ public class MyButton1 extends Button { // ERROR
+ public MyButton1(Context context) { super(context); }
+ }
+
+ // Check extends+implements list
+ public class MyButton2 extends Button implements Runnable { // ERROR
+ public MyButton2(Context context) { super(context); }
+
+ @Override
+ public void run() {
+ }
+ }
+
+ public class MyButton3 extends MyButton1 { // Indirect: OK
+ public MyButton3(Context context) { super(context); }
+ }
+
+ @SuppressLint("AppCompatCustomView")
+ public class MyButton4 extends Button { // Suppressed: OK
+ public MyButton4(Context context) { super(context); }
+ }
+
+ // Other widgets
+
+ public class MyEditText extends EditText { // ERROR
+ public MyEditText(Context context) { super(context); }
+ }
+
+ public class MyTextView extends TextView { // ERROR
+ public MyTextView(Context context) { super(context); }
+ }
+
+ public class MyCheckBox extends CheckBox { // ERROR
+ public MyCheckBox(Context context) { super(context); }
+ }
+
+ public class MyCheckedTextView extends CheckedTextView { // ERROR
+ public MyCheckedTextView(Context context) { super(context); }
+ }
+
+ public class MyImageButton extends ImageButton { // ERROR
+ public MyImageButton(Context context) { super(context); }
+ }
+
+ public class MyImageView extends ImageView { // ERROR
+ public MyImageView(Context context) { super(context); }
+ }
+
+ public class MyMultiAutoCompleteTextView extends MultiAutoCompleteTextView { // ERROR
+ public MyMultiAutoCompleteTextView(Context context) { super(context); }
+ }
+
+ public class MyAutoCompleteTextView extends AutoCompleteTextView { // ERROR
+ public MyAutoCompleteTextView(Context context) { super(context); }
+ }
+
+ public class MyRadioButton extends RadioButton { // ERROR
+ public MyRadioButton(Context context) { super(context); }
+ }
+
+ public class MyRatingBar extends RatingBar { // ERROR
+ public MyRatingBar(Context context) { super(context); }
+ }
+
+ public class MySeekBar extends SeekBar { // ERROR
+ public MySeekBar(Context context) { super(context); }
+ }
+
+ public class MySpinner extends Spinner { // ERROR
+ public MySpinner(Context context) { super(context); }
+ }
+
+ // No current appcompat delegates
+
+ public class MyCalendarView extends CalendarView { // OK
+ public MyCalendarView(Context context) { super(context); }
+ }
+
+ public class MyChronometer extends Chronometer { // OK
+ public MyChronometer(Context context) { super(context); }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/AppCompatCustomViewDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `AppCompatCustomViewDetector.test`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("AppCompatCustomView")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("AppCompatCustomView")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection AppCompatCustomView
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AppCompatCustomView" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AppCompatCustomView'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AppCompatCustomView ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/AppCompatMethod.md.html b/docs/checks/AppCompatMethod.md.html
new file mode 100644
index 00000000..931cfc47
--- /dev/null
+++ b/docs/checks/AppCompatMethod.md.html
@@ -0,0 +1,183 @@
+
+(#) Using Wrong AppCompat Method
+
+!!! WARNING: Using Wrong AppCompat Method
+ This is a warning.
+
+Id
+: `AppCompatMethod`
+Summary
+: Using Wrong AppCompat Method
+Note
+: **This issue is disabled by default**; use `--enable AppCompatMethod`
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/topic/libraries/support-library/
+Implementation
+: [Source Code](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/AppCompatCallDetector.java)
+Tests
+: [Source Code](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/AppCompatCallDetectorTest.java)
+Copyright Year
+: 2014
+
+When using the appcompat library, there are some methods you should be
+calling instead of the normal ones; for example, `getSupportActionBar()`
+instead of `getActionBar()`. This lint check looks for calls to the
+wrong method.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/AppCompatTest.java:5:Warning: Should use
+getSupportActionBar instead of getActionBar name [AppCompatMethod]
+ getActionBar(); // ERROR
+ --------------
+src/test/pkg/AppCompatTest.java:8:Warning: Should use
+startSupportActionMode instead of startActionMode name
+[AppCompatMethod]
+ startActionMode(null); // ERROR
+ ---------------------
+src/test/pkg/AppCompatTest.java:11:Warning: Should use
+supportRequestWindowFeature instead of requestWindowFeature name
+[AppCompatMethod]
+ requestWindowFeature(0); // ERROR
+ -----------------------
+src/test/pkg/AppCompatTest.java:14:Warning: Should use
+setSupportProgressBarVisibility instead of setProgressBarVisibility name
+[AppCompatMethod]
+ setProgressBarVisibility(true); // ERROR
+ ------------------------------
+src/test/pkg/AppCompatTest.java:15:Warning: Should use
+setSupportProgressBarIndeterminate instead of
+setProgressBarIndeterminate name [AppCompatMethod]
+ setProgressBarIndeterminate(true); // ERROR
+ ---------------------------------
+src/test/pkg/AppCompatTest.java:16:Warning: Should use
+setSupportProgressBarIndeterminateVisibility instead of
+setProgressBarIndeterminateVisibility name [AppCompatMethod]
+ setProgressBarIndeterminateVisibility(true); // ERROR
+ -------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/AppCompatTest.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+public class AppCompatTest extends IntermediateActivity {
+ public void test() {
+ getActionBar(); // ERROR
+ getSupportActionBar(); // OK
+
+ startActionMode(null); // ERROR
+ startSupportActionMode(null); // OK
+
+ requestWindowFeature(0); // ERROR
+ supportRequestWindowFeature(0); // OK
+
+ setProgressBarVisibility(true); // ERROR
+ setProgressBarIndeterminate(true); // ERROR
+ setProgressBarIndeterminateVisibility(true); // ERROR
+
+ setSupportProgressBarVisibility(true); // OK
+ setSupportProgressBarIndeterminate(true); // OK
+ setSupportProgressBarIndeterminateVisibility(true); // OK
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/AppCompatCallDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `AppCompatCallDetector.testArgumentsSupportV4`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("AppCompatMethod")
+ fun method() {
+ getActionBar(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("AppCompatMethod")
+ void method() {
+ getActionBar(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection AppCompatMethod
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AppCompatMethod" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AppCompatMethod'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AppCompatMethod ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/AppCompatResource.md.html b/docs/checks/AppCompatResource.md.html
new file mode 100644
index 00000000..72f40689
--- /dev/null
+++ b/docs/checks/AppCompatResource.md.html
@@ -0,0 +1,121 @@
+
+(#) Menu namespace
+
+!!! ERROR: Menu namespace
+ This is an error.
+
+Id
+: `AppCompatResource`
+Summary
+: Menu namespace
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/AppCompatResourceDetector.java)
+Tests
+: [Source Code](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/AppCompatResourceDetectorTest.java)
+Copyright Year
+: 2014
+
+When using the appcompat library, menu resources should refer to the
+`showAsAction` (or `actionViewClass`, or `actionProviderClass`) in the
+`app:` namespace, not the `android:` namespace.
+
+Similarly, when **not** using the appcompat library, you should be using
+the `android:showAsAction` (or `actionViewClass`, or
+`actionProviderClass`) attribute.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/menu/showAction1.xml:6:Error: Should use android:showAsAction when
+not using the appcompat library [AppCompatResource]
+ app:showAsAction="never" />
+ ------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/menu/showAction1.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto">
+ <item android:id="@+id/action_settings"
+ android:title="@string/action_settings"
+ android:orderInCategory="100"
+ app:showAsAction="never" />
+</menu>
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/AppCompatResourceDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `AppCompatResourceDetector.testNotGradleProject`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="AppCompatResource"`
+ on the problematic XML element (or one of its enclosing elements).
+ You may also need to add the following namespace declaration on the
+ root element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AppCompatResource" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AppCompatResource'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AppCompatResource ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/AppIndexingService.md.html b/docs/checks/AppIndexingService.md.html
new file mode 100644
index 00000000..794f06cb
--- /dev/null
+++ b/docs/checks/AppIndexingService.md.html
@@ -0,0 +1,141 @@
+
+(#) App Indexing Background Services
+
+!!! WARNING: App Indexing Background Services
+ This is a warning.
+
+Id
+: `AppIndexingService`
+Summary
+: App Indexing Background Services
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.1.0 (March 2018)
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://firebase.google.com/docs/app-indexing/android/personal-content#add-a-broadcast-receiver-to-your-app
+Implementation
+: [Source Code](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/ManifestDetector.kt)
+Tests
+: [Source Code](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/ManifestDetectorTest.kt)
+
+Apps targeting Android 8.0 or higher can no longer rely on background
+services while listening for updates to the on-device index. Use a
+`BroadcastReceiver` for the `UPDATE_INDEX` intent to continue supporting
+indexing in your app.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/main/AndroidManifest.xml:10:Warning: UPDATE_INDEX is configured as a
+service in your app, which is no longer supported for the API level
+you're targeting. Use a BroadcastReceiver instead. [AppIndexingService]
+ <action android:name="com.google.firebase.appindexing.UPDATE_INDEX" />
+ -----------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/main/AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.helloworld" >
+ <uses-sdk android:targetSdkVersion="26" />
+ <application
+ android:label="@string/app_name"
+ android:allowBackup="false"
+ android:theme="@style/AppTheme" >
+ <service android:name=".MyService">
+ <intent-filter>
+ <action android:name="com.google.firebase.appindexing.UPDATE_INDEX" />
+ </intent-filter>
+ </service>
+ </application>
+
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`build.gradle`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~groovy linenumbers
+apply plugin: 'com.android.application'
+
+dependencies {
+ compile 'com.google.firebase:firebase-appindexing:11.0.4'
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ManifestDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ManifestDetector.testAppIndexingTargetSdk26`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="AppIndexingService"`
+ on the problematic XML element (or one of its enclosing elements).
+ You may also need to add the following namespace declaration on the
+ root element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <application tools:ignore="AppIndexingService" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AppIndexingService" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AppIndexingService'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AppIndexingService ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/AppLinkSplitToWebAndCustom.md.html b/docs/checks/AppLinkSplitToWebAndCustom.md.html
new file mode 100644
index 00000000..87b5dbcd
--- /dev/null
+++ b/docs/checks/AppLinkSplitToWebAndCustom.md.html
@@ -0,0 +1,160 @@
+
+(#) Android App links should only use http(s) schemes
+
+!!! ERROR: Android App links should only use http(s) schemes
+ This is an error.
+
+Id
+: `AppLinkSplitToWebAndCustom`
+Summary
+: Android App links should only use http(s) schemes
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 8.8.0 (January 2025)
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/training/app-links/verify-android-applinks#add-intent-filters
+Implementation
+: [Source Code](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/AppLinksValidDetector.kt)
+Tests
+: [Source Code](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/AppLinksValidDetectorTest.kt)
+
+In order for Android App Links to open in your app, Android must perform
+domain verification. However, Android only sends domain verification
+requests for ``s that only contain http(s) schemes.
+
+To ensure correct behavior, please split your http(s) schemes and other
+schemes into two different ``s.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:7:Error: Split your http(s) and custom schemes into
+separate intent filters [AppLinkSplitToWebAndCustom]
+ <intent-filter android:autoVerify="true" android:order="-1" android:priority="-1">
+ -------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.helloworld" >
+ <uses-sdk android:minSdkVersion="31" android:targetSdkVersion="34" />
+
+ <application>
+ <activity android:name=".SplitWebAndCustomActivity" android:exported="true">
+ <intent-filter android:autoVerify="true" android:order="-1" android:priority="-1">
+ <action android:name="android.intent.action.VIEW" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.BROWSABLE" />
+ <uri-relative-filter-group>
+ <data android:path="/path" />
+ <data android:query="queryparam=value" />
+ </uri-relative-filter-group>
+ <data android:scheme="http" />
+ <data android:scheme="custom" />
+ <data android:host="example.com" />
+ <data android:path="@string/path" />
+ <data android:path="/<&''" />
+ <data android:path='/single"quote' />
+ <data android:path="" />
+ <!-- Test having tags underneath the host elements as well -->
+ <action android:name="android.intent.action.SEND"/>
+ <uri-relative-filter-group>
+ <data android:path="/path" />
+ <data android:query="queryparam=value" />
+ </uri-relative-filter-group>
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<resources>
+ <string name="path">/path</string>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/AppLinksValidDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `AppLinksValidDetector.test_splitToWebAndCustomSchemes`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="AppLinkSplitToWebAndCustom"` on the problematic XML
+ element (or one of its enclosing elements). You may also need to add
+ the following namespace declaration on the root element in the XML
+ file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <activity tools:ignore="AppLinkSplitToWebAndCustom" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AppLinkSplitToWebAndCustom" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AppLinkSplitToWebAndCustom'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AppLinkSplitToWebAndCustom ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/AppLinkUriRelativeFilterGroupError.md.html b/docs/checks/AppLinkUriRelativeFilterGroupError.md.html
new file mode 100644
index 00000000..8f988d95
--- /dev/null
+++ b/docs/checks/AppLinkUriRelativeFilterGroupError.md.html
@@ -0,0 +1,180 @@
+
+(#) URI relative filter group invalid
+
+!!! ERROR: URI relative filter group invalid
+ This is an error.
+
+Id
+: `AppLinkUriRelativeFilterGroupError`
+Summary
+: URI relative filter group invalid
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 8.9.0 (March 2025)
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/guide/topics/manifest/uri-relative-filter-group-element?utm_source=lint
+Implementation
+: [Source Code](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/AppLinksValidDetector.kt)
+Tests
+: [Source Code](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/AppLinksValidDetectorTest.kt)
+
+Ensure that your URI relative filter group is correctly configured.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:29:Error: MIME types prevent Android App Links from
+matching [AppLinkUriRelativeFilterGroupError]
+ <data android:mimeType="application/json" />
+ --------------------------------------------
+AndroidManifest.xml:40:Error: MIME types prevent Android App Links from
+matching [AppLinkUriRelativeFilterGroupError]
+ <data android:host="example.com" android:mimeType="application/json" android:pathPrefix="/gizmos" />
+ ----------------------------------------------------------------------------------------------------
+AndroidManifest.xml:51:Error: MIME types prevent Android App Links from
+matching [AppLinkUriRelativeFilterGroupError]
+ <data android:host='example.com' android:mimeType="application/json" android:pathPrefix='/gizmos' />
+ ----------------------------------------------------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.helloworld" >
+
+ <application>
+ <activity android:name=".FullscreenActivity">
+
+ <intent-filter android:autoVerify="true"> <!-- Fine -->
+ <action android:name="android.intent.action.VIEW" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.BROWSABLE" />
+
+ <data android:scheme="http" />
+ <data android:scheme="https" />
+
+ <data android:host="example.com" />
+ <data android:pathPrefix="/gizmos" />
+ </intent-filter>
+
+ <intent-filter android:autoVerify="true"> <!-- Has MIME type in its own data tag-->
+ <action android:name="android.intent.action.VIEW" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.BROWSABLE" />
+
+ <data android:scheme="http" />
+ <data android:scheme="https" />
+
+ <data android:host="example.com" />
+ <data android:pathPrefix="/gizmos" />
+ <data android:mimeType="application/json" />
+ </intent-filter>
+
+ <intent-filter android:autoVerify="true"> <!-- Has MIME type in the same data tag as other content -->
+ <action android:name="android.intent.action.VIEW" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.BROWSABLE" />
+
+ <data android:scheme="http" />
+ <data android:scheme="https" />
+
+ <data android:host="example.com" android:mimeType="application/json" android:pathPrefix="/gizmos" />
+ </intent-filter>
+
+ <intent-filter android:autoVerify="true"> <!-- Has MIME type in the same data tag as other content; mix single/double quotes -->
+ <action android:name="android.intent.action.VIEW" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.BROWSABLE" />
+
+ <data android:scheme="http" />
+ <data android:scheme="https" />
+
+ <data android:host='example.com' android:mimeType="application/json" android:pathPrefix='/gizmos' />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/AppLinksValidDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `AppLinksValidDetector.testAutoVerify_extraAttribute_mimeType`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="AppLinkUriRelativeFilterGroupError"` on the
+ problematic XML element (or one of its enclosing elements). You may
+ also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <activity tools:ignore="AppLinkUriRelativeFilterGroupError" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AppLinkUriRelativeFilterGroupError" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AppLinkUriRelativeFilterGroupError'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AppLinkUriRelativeFilterGroupError ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/AppLinkUrlError.md.html b/docs/checks/AppLinkUrlError.md.html
new file mode 100644
index 00000000..605bd8e8
--- /dev/null
+++ b/docs/checks/AppLinkUrlError.md.html
@@ -0,0 +1,138 @@
+
+(#) URI invalid
+
+!!! ERROR: URI invalid
+ This is an error.
+
+Id
+: `AppLinkUrlError`
+Summary
+: URI invalid
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.0.0 (October 2017)
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/training/app-links
+See
+: https://g.co/AppIndexing/AndroidStudio
+Implementation
+: [Source Code](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/AppLinksValidDetector.kt)
+Tests
+: [Source Code](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/AppLinksValidDetectorTest.kt)
+
+Ensure your intent filter has the documented elements for deep links,
+web links, or Android App Links.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:15:Error: Expected testUrl attribute
+[AppLinkUrlError]
+ <tools:validation />
+ --------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="test.pkg" >
+
+ <application>
+ <activity android:name=".MainActivity">
+ <intent-filter android:autoVerify="true">
+ <action android:name="android.intent.action.VIEW" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.BROWSABLE" />
+ <data android:scheme="http"
+ android:host="example.com"
+ android:pathPrefix="/gizmos" />
+ </intent-filter>
+ <tools:validation />
+ </activity>
+ </application>
+
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/AppLinksValidDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `AppLinksValidDetector.testMissingTestUrl`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="AppLinkUrlError"` on
+ the problematic XML element (or one of its enclosing elements). You
+ may also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <activity tools:ignore="AppLinkUrlError" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AppLinkUrlError" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AppLinkUrlError'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AppLinkUrlError ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/AppLinkWarning.md.html b/docs/checks/AppLinkWarning.md.html
new file mode 100644
index 00000000..289de85a
--- /dev/null
+++ b/docs/checks/AppLinkWarning.md.html
@@ -0,0 +1,225 @@
+
+(#) App Link warning
+
+!!! WARNING: App Link warning
+ This is a warning.
+
+Id
+: `AppLinkWarning`
+Summary
+: App Link warning
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 8.8.0 (January 2025)
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/training/app-links
+See
+: https://g.co/AppIndexing/AndroidStudio
+Implementation
+: [Source Code](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/AppLinksValidDetector.kt)
+Tests
+: [Source Code](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/AppLinksValidDetectorTest.kt)
+
+From Android 12, intent filters that use the HTTP and HTTPS schemes will
+no longer bring the user to your app when the user clicks
+a link, unless the intent filter is an Android App Link.
+Such intent filters must include certain elements, and at least
+ one Android App Link for each domain must have
+`android:autoVerify="true"` to verify ownership of the
+domain. We recommend adding `android:autoVerify="true"` to any intent
+ filter that is intended to be an App Link, in case the other
+App Links are modified.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:6:Warning: This intent filter has the format of an
+Android App Link but is missing the autoVerify attribute; add
+android:autoVerify="true" to ensure your domain will be validated and
+enable App Link-related Lint warnings. If you do not want clicked URLs
+to bring the user to your app, remove the
+android.intent.category.BROWSABLE category, or set
+android:autoVerify="false" to make it clear this is not intended to be
+an Android App Link. [AppLinkWarning]
+ <intent-filter> <!-- We expect a warning here -->
+ -------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.helloworld" >
+
+ <application>
+ <activity android:name=".FullscreenActivity">
+ <intent-filter> <!-- We expect a warning here -->
+ <action android:name="android.intent.action.VIEW" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.BROWSABLE" />
+
+ <data android:scheme="http" />
+ <data android:scheme="https" />
+
+ <data android:host="example.com" />
+ <data android:pathPrefix="/gizmos" />
+ </intent-filter>
+
+ <intent-filter> <!-- Missing VIEW -->
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.BROWSABLE" />
+
+ <data android:scheme="http" />
+ <data android:scheme="https" />
+
+ <data android:host="example.com" />
+ <data android:pathPrefix="/gizmos" />
+ </intent-filter>
+
+ <intent-filter> <!-- Missing DEFAULT -->
+ <action android:name="android.intent.action.VIEW" />
+ <category android:name="android.intent.category.BROWSABLE" />
+
+ <data android:scheme="http" />
+ <data android:scheme="https" />
+
+ <data android:host="example.com" />
+ <data android:pathPrefix="/gizmos" />
+ </intent-filter>
+
+ <intent-filter> <!-- Missing BROWSABLE -->
+ <action android:name="android.intent.action.VIEW" />
+ <category android:name="android.intent.category.DEFAULT" />
+
+ <data android:scheme="http" />
+ <data android:scheme="https" />
+
+ <data android:host="example.com" />
+ <data android:pathPrefix="/gizmos" />
+ </intent-filter>
+
+ <intent-filter> <!-- Has custom scheme, missing http -->
+ <action android:name="android.intent.action.VIEW" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.BROWSABLE" />
+
+ <data android:scheme="other" />
+
+ <data android:host="example.com" />
+ <data android:pathPrefix="/gizmos" />
+ </intent-filter>
+
+ <intent-filter> <!-- Has no scheme -->
+ <action android:name="android.intent.action.VIEW" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.BROWSABLE" />
+
+ <data android:host="example.com" />
+ <data android:pathPrefix="/gizmos" />
+ </intent-filter>
+
+ <intent-filter> <!-- Missing host -->
+ <action android:name="android.intent.action.VIEW" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.BROWSABLE" />
+
+ <data android:scheme="http" />
+ <data android:scheme="https" />
+ </intent-filter>
+
+ <intent-filter android:autoVerify="false"> <!-- We would usually expect a warning here, but it has autoVerify="false" -->
+ <action android:name="android.intent.action.VIEW" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.BROWSABLE" />
+
+ <data android:scheme="http" />
+ <data android:scheme="https" />
+
+ <data android:host="example.com" />
+ <data android:pathPrefix="/gizmos" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/AppLinksValidDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `AppLinksValidDetector.testAddAutoVerifySuggestion`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="AppLinkWarning"` on
+ the problematic XML element (or one of its enclosing elements). You
+ may also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <activity tools:ignore="AppLinkWarning" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AppLinkWarning" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AppLinkWarning'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AppLinkWarning ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/AppLinksAutoVerify.md.html b/docs/checks/AppLinksAutoVerify.md.html
new file mode 100644
index 00000000..7b585412
--- /dev/null
+++ b/docs/checks/AppLinksAutoVerify.md.html
@@ -0,0 +1,127 @@
+
+(#) App Links Auto Verification Failure
+
+!!! ERROR: App Links Auto Verification Failure
+ This is an error.
+
+Id
+: `AppLinksAutoVerify`
+Summary
+: App Links Auto Verification Failure
+Note
+: **This issue is disabled by default**; use `--enable AppLinksAutoVerify`
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 7.0.0 (July 2021)
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://g.co/appindexing/applinks
+Implementation
+: [Source Code](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/AppLinksAutoVerifyDetector.kt)
+Tests
+: [Source Code](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/AppLinksAutoVerifyDetectorTest.kt)
+
+Ensures that app links are correctly set and associated with website.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:12:Error: This host does not support app links to
+your app. Checks the Digital Asset Links JSON file:
+http://example.com/.well-known/assetlinks.json [AppLinksAutoVerify]
+ android:host="example.com"
+ --------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.helloworld" >
+
+ <application
+ android:allowBackup="true"
+ android:icon="@mipmap/ic_launcher" >
+ <activity android:name=".MainActivity" >
+ <intent-filter android:autoVerify="true">
+ <action android:name="android.intent.action.VIEW" />
+ <data android:scheme="http"
+ android:host="example.com"
+ android:pathPrefix="/gizmos" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.BROWSABLE" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/AppLinksAutoVerifyDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `AppLinksAutoVerifyDetector.testInvalidPackage`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="AppLinksAutoVerify"`
+ on the problematic XML element (or one of its enclosing elements).
+ You may also need to add the following namespace declaration on the
+ root element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AppLinksAutoVerify" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AppLinksAutoVerify'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AppLinksAutoVerify ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/AppLinksAutoVerifyError.md.html b/docs/checks/AppLinksAutoVerifyError.md.html
new file mode 100644
index 00000000..d984fefe
--- /dev/null
+++ b/docs/checks/AppLinksAutoVerifyError.md.html
@@ -0,0 +1,8 @@
+
+(#) AppLinksAutoVerifyError
+
+This issue id is an alias for
+[AppLinksAutoVerify](AppLinksAutoVerify.md.html).
+
+(Additional metadata not available.)
+
\ No newline at end of file
diff --git a/docs/checks/AppLinksAutoVerifyWarning.md.html b/docs/checks/AppLinksAutoVerifyWarning.md.html
new file mode 100644
index 00000000..e98bf60f
--- /dev/null
+++ b/docs/checks/AppLinksAutoVerifyWarning.md.html
@@ -0,0 +1,8 @@
+
+(#) AppLinksAutoVerifyWarning
+
+This issue id is an alias for
+[AppLinksAutoVerify](AppLinksAutoVerify.md.html).
+
+(Additional metadata not available.)
+
\ No newline at end of file
diff --git a/docs/checks/ApplySharedPref.md.html b/docs/checks/ApplySharedPref.md.html
new file mode 100644
index 00000000..b58f8529
--- /dev/null
+++ b/docs/checks/ApplySharedPref.md.html
@@ -0,0 +1,207 @@
+
+(#) Use `apply()` on `SharedPreferences`
+
+!!! WARNING: Use `apply()` on `SharedPreferences`
+ This is a warning.
+
+Id
+: `ApplySharedPref`
+Summary
+: Use `apply()` on `SharedPreferences`
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 2.3.0 (March 2017)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/CleanupDetector.kt)
+Tests
+: [Source Code](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/CleanupDetectorTest.kt)
+
+Consider using `apply()` instead of `commit` on shared preferences.
+Whereas `commit` blocks and writes its data to persistent storage
+immediately, `apply` will handle it in the background.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/SharedPrefsTest.java:16:Warning: Consider using apply()
+instead; commit writes its data to persistent storage immediately,
+whereas apply will handle it in the background [ApplySharedPref]
+ editor.commit();
+ --------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/SharedPrefsTest.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.widget.Toast;
+import android.content.SharedPreferences; import android.content.SharedPreferences.Editor;
+import android.preference.PreferenceManager;
+@SuppressWarnings({"ClassNameDiffersFromFileName", "AccessStaticViaInstance", "MethodMayBeStatic"}) public class SharedPrefsTest extends Activity {
+ // OK 1
+ public void onCreate1(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
+ SharedPreferences.Editor editor = preferences.edit();
+ editor.putString("foo", "bar");
+ editor.putInt("bar", 42);
+ editor.commit();
+ }
+
+ // OK 2
+ public void onCreate2(Bundle savedInstanceState, boolean apply) {
+ super.onCreate(savedInstanceState);
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
+ SharedPreferences.Editor editor = preferences.edit();
+ editor.putString("foo", "bar");
+ editor.putInt("bar", 42);
+ if (apply) {
+ editor.apply();
+ }
+ }
+
+ // OK 3
+ public boolean test1(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
+ SharedPreferences.Editor editor = preferences.edit();
+ editor.putString("foo", "bar");
+ editor.putInt("bar", 42);
+ editor.apply(); return true;
+ }
+
+ // Not a bug
+ public void test(Foo foo) {
+ Bar bar1 = foo.edit();
+ Bar bar2 = Foo.edit();
+ Bar bar3 = edit();
+
+
+ }
+
+ // Bug
+ public void bug1(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
+ SharedPreferences.Editor editor = preferences.edit();
+ editor.putString("foo", "bar");
+ editor.putInt("bar", 42);
+ }
+
+ // Constructor test
+ public SharedPrefsTest(Context context) {
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
+ SharedPreferences.Editor editor = preferences.edit();
+ editor.putString("foo", "bar");
+ }
+
+ private Bar edit() {
+ return null;
+ }
+
+ private static class Foo {
+ static Bar edit() { return null; }
+ }
+
+ private static class Bar {
+
+ }
+ }
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/CleanupDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `CleanupDetector.testSharedPrefs`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ApplySharedPref")
+ fun method() {
+ beginTransaction(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ApplySharedPref")
+ void method() {
+ beginTransaction(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ApplySharedPref
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ApplySharedPref" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ApplySharedPref'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ApplySharedPref ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ArcAnimationSpecTypeIssue.md.html b/docs/checks/ArcAnimationSpecTypeIssue.md.html
new file mode 100644
index 00000000..a5179501
--- /dev/null
+++ b/docs/checks/ArcAnimationSpecTypeIssue.md.html
@@ -0,0 +1,198 @@
+
+(#) ArcAnimationSpec is designed for 2D values. Particularly, for positional values such as Offset.
+
+!!! Tip: ArcAnimationSpec is designed for 2D values. Particularly, for positional values such as Offset.
+ Advice from this check is just a hint; it's a "weak" warning.
+
+Id
+: `ArcAnimationSpecTypeIssue`
+Summary
+: ArcAnimationSpec is designed for 2D values. Particularly, for positional values such as Offset.
+Severity
+: Hint
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Jetpack Compose
+Identifier
+: androidx.compose.animation.core
+Feedback
+: https://issuetracker.google.com/issues/new?component=612128
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.compose.animation:animation-core-android](androidx_compose_animation_animation-core-android.md.html)
+Since
+: 1.7.0
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/animation/animation-core-lint/src/main/java/androidx/compose/animation/core/lint/ArcAnimationSpecTypeDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/animation/animation-core-lint/src/test/java/androidx/compose/animation/core/lint/ArcAnimationSpecTypeDetectorTest.kt)
+Copyright Year
+: 2023
+
+ArcAnimationSpec is designed for 2D values. Particularly, for positional
+values such as Offset.
+Trying to use it for values of different dimensions (Float, Size, Color,
+etc.) will result in unpredictable animation behavior.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/foo/test.kt:14:Information: Arc animation is intended for 2D values
+such as Offset, IntOffset or DpOffset.
+Otherwise, the animation might not be what you expect.
+[ArcAnimationSpecTypeIssue]
+ ArcAnimationSpec<Float>(ArcAbove)
+ ----------------
+src/foo/test.kt:15:Information: Arc animation is intended for 2D values
+such as Offset, IntOffset or DpOffset.
+Otherwise, the animation might not be what you expect.
+[ArcAnimationSpecTypeIssue]
+ ArcAnimationSpec<String>(ArcAbove)
+ ----------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/foo/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package foo
+
+import androidx.compose.animation.core.ArcAnimationSpec
+import androidx.compose.animation.core.ArcAbove
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.unit.DpOffset
+import androidx.compose.ui.unit.IntOffset
+
+fun test() {
+ ArcAnimationSpec(ArcAbove)
+ ArcAnimationSpec(ArcAbove)
+ ArcAnimationSpec(ArcAbove)
+ ArcAnimationSpec(ArcAbove)
+ ArcAnimationSpec(ArcAbove)
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/animation/animation-core-lint/src/test/java/androidx/compose/animation/core/lint/ArcAnimationSpecTypeDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ArcAnimationSpecTypeDetector.testPreferredTypeIssue`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=612128.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.compose.animation:animation-core-android:1.9.0-alpha01")
+
+// build.gradle
+implementation 'androidx.compose.animation:animation-core-android:1.9.0-alpha01'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.animation.core.android)
+
+# libs.versions.toml
+[versions]
+animation-core-android = "1.9.0-alpha01"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+animation-core-android = {
+ module = "androidx.compose.animation:animation-core-android",
+ version.ref = "animation-core-android"
+}
+```
+
+1.9.0-alpha01 is the version this documentation was generated from;
+there may be newer versions available.
+
+NOTE: These lint checks are **also** made available separate from the main library.
+You can also use `androidx.compose.animation:animation-core-lint:1.9.0-alpha01`.
+
+
+[Additional details about androidx.compose.animation:animation-core-android](androidx_compose_animation_animation-core-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ArcAnimationSpecTypeIssue")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ArcAnimationSpecTypeIssue")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ArcAnimationSpecTypeIssue
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ArcAnimationSpecTypeIssue" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ArcAnimationSpecTypeIssue'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ArcAnimationSpecTypeIssue ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ArgInFormattedQuantityStringRes.md.html b/docs/checks/ArgInFormattedQuantityStringRes.md.html
new file mode 100644
index 00000000..ccb50c3d
--- /dev/null
+++ b/docs/checks/ArgInFormattedQuantityStringRes.md.html
@@ -0,0 +1,186 @@
+
+(#) Count value in formatted string resource
+
+!!! WARNING: Count value in formatted string resource
+ This is a warning.
+
+Id
+: `ArgInFormattedQuantityStringRes`
+Summary
+: Count value in formatted string resource
+Severity
+: Warning
+Category
+: Internationalization
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.1.0
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/ArgInFormattedQuantityStringResDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/ArgInFormattedQuantityStringResDetectorTest.kt)
+Copyright Year
+: 2021
+
+Some languages require modifiers to counted values in written text.
+Consider consulting #plz-localization if you are unsure if this
+formatted string requires a special modifier. If one is required,
+consider using `LocalizationUtils.getFormattedCount()`. If not, suppress
+this warning.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/com/slack/lint/Foo.java:7:Warning: This may require a localized
+count modifier. If so, use LocalizationUtils.getFormattedCount().
+Consult #plz-localization if you are unsure.
+[ArgInFormattedQuantityStringRes]
+ String s = res.getQuantityString(0, 3, 3, "asdf");
+ ------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/com/slack/lint/Foo.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package com.slack.lint;
+
+import android.content.res.Resources;
+
+public class Foo {
+ public void bar(Resources res) {
+ String s = res.getQuantityString(0, 3, 3, "asdf");
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/ArgInFormattedQuantityStringResDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ArgInFormattedQuantityStringResDetector.getQuantityStringWithNoLocalizedFormatTest`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/slack-lints.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ArgInFormattedQuantityStringRes")
+ fun method() {
+ getQuantityString(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ArgInFormattedQuantityStringRes")
+ void method() {
+ getQuantityString(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ArgInFormattedQuantityStringRes
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ArgInFormattedQuantityStringRes" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ArgInFormattedQuantityStringRes'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ArgInFormattedQuantityStringRes ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/Assert.md.html b/docs/checks/Assert.md.html
new file mode 100644
index 00000000..4f7d4812
--- /dev/null
+++ b/docs/checks/Assert.md.html
@@ -0,0 +1,8 @@
+
+(#) Assert
+
+The issue for this id has been deleted or marked obsolete and can now be
+ignored.
+
+(Additional metadata not available.)
+
\ No newline at end of file
diff --git a/docs/checks/AssertionSideEffect.md.html b/docs/checks/AssertionSideEffect.md.html
new file mode 100644
index 00000000..8aabf500
--- /dev/null
+++ b/docs/checks/AssertionSideEffect.md.html
@@ -0,0 +1,158 @@
+
+(#) Assertions with Side Effects
+
+!!! WARNING: Assertions with Side Effects
+ This is a warning.
+
+Id
+: `AssertionSideEffect`
+Summary
+: Assertions with Side Effects
+Severity
+: Warning
+Category
+: Performance
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 7.2.0 (May 2022)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/AssertDetector.kt)
+Tests
+: [Source Code](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/AssertDetectorTest.kt)
+
+Assertion conditions can have side effects. This is risky because the
+behavior depends on whether assertions are on or off. This is usually
+not intentional, and can lead to bugs where the production version
+differs from the version tested during development.
+
+Generally, you'll want to perform the operation with the side effect
+before the assertion, and then assert that the result was what you
+expected.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test.kt:5:Warning: Assertion condition has a side effect: setOf(42)
+[AssertionSideEffect]
+ assert(42 != f.setOf(42)) // WARN 1
+ -----------
+src/test.kt:6:Warning: Assertion condition has a side effect: f.of =
+2024 [AssertionSideEffect]
+ assert(2024 != (f.of = 2024)) // WARN 2
+ -----------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+import test.pkg.Foo
+
+fun test() {
+ val f = Foo()
+ assert(42 != f.setOf(42)) // WARN 1
+ assert(2024 != (f.of = 2024)) // WARN 2
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/Foo.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+public class Foo {
+ private int OF = 0;
+ public int getOf() {
+ return OF;
+ }
+ public int setOf(int v) {
+ int prev = OF;
+ OF = v;
+ return prev;
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/AssertDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `AssertDetector.testSetOf_JavaSyntheticPropertySetter`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("AssertionSideEffect")
+ fun method() {
+ assert(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("AssertionSideEffect")
+ void method() {
+ assert(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection AssertionSideEffect
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AssertionSideEffect" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AssertionSideEffect'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AssertionSideEffect ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/AssertjImport.md.html b/docs/checks/AssertjImport.md.html
new file mode 100644
index 00000000..92b6e091
--- /dev/null
+++ b/docs/checks/AssertjImport.md.html
@@ -0,0 +1,146 @@
+
+(#) Flags Java 6 incompatible imports
+
+!!! WARNING: Flags Java 6 incompatible imports
+ This is a warning.
+
+Id
+: `AssertjImport`
+Summary
+: Flags Java 6 incompatible imports
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: vanniktech/lint-rules/
+Feedback
+: https://github.com/vanniktech/lint-rules/issues
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [com.vanniktech:lint-rules-android](com_vanniktech_lint-rules-android.md.html)
+Since
+: 0.8.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/main/kotlin/com/vanniktech/lintrules/android/AssertjDetector.kt)
+Tests
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/test/kotlin/com/vanniktech/lintrules/android/AssertjDetectorTest.kt)
+
+Importing org.assertj.core.api.Assertions is not ideal. Since it can
+require Java 8. It's simple as instead
+org.assertj.core.api.Java6Assertions can be imported and provides
+guarantee to run on Java 6 as well.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.vanniktech:lint-rules-android:0.25.0")
+
+// build.gradle
+lintChecks 'com.vanniktech:lint-rules-android:0.25.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.lint.rules.android)
+
+# libs.versions.toml
+[versions]
+lint-rules-android = "0.25.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+lint-rules-android = {
+ module = "com.vanniktech:lint-rules-android",
+ version.ref = "lint-rules-android"
+}
+```
+
+0.25.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.vanniktech:lint-rules-android](com_vanniktech_lint-rules-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("AssertjImport")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("AssertjImport")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection AssertjImport
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AssertjImport" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AssertjImport'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AssertjImport ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/AuthLeak.md.html b/docs/checks/AuthLeak.md.html
new file mode 100644
index 00000000..183dfd55
--- /dev/null
+++ b/docs/checks/AuthLeak.md.html
@@ -0,0 +1,136 @@
+
+(#) Code might contain an auth leak
+
+!!! WARNING: Code might contain an auth leak
+ This is a warning.
+
+Id
+: `AuthLeak`
+Summary
+: Code might contain an auth leak
+Severity
+: Warning
+Category
+: Security
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 2.2.0 (September 2016)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://goo.gle/AuthLeak
+Implementation
+: [Source Code](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/StringAuthLeakDetector.java)
+Tests
+: [Source Code](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/StringAuthLeakDetectorTest.kt)
+
+Strings in java apps can be discovered by decompiling apps, this lint
+check looks for code which looks like it may contain an url with a
+username and password.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/AuthDemo.java:2:Warning: Possible credential leak [AuthLeak]
+ private static final String AUTH_IP = "scheme://user:pwd@127.0.0.1:8000"; // WARN 1
+ ---------------------------
+src/AuthDemo.java:4:Warning: Possible credential leak [AuthLeak]
+ private static final String LEAK = "http://someuser:%restofmypass@example.com/"; // WARN 2
+ -----------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/AuthDemo.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+public class AuthDemo {
+ private static final String AUTH_IP = "scheme://user:pwd@127.0.0.1:8000"; // WARN 1
+ private static final String AUTH_NO_LEAK = "scheme://user:%s@www.google.com"; // OK 1
+ private static final String LEAK = "http://someuser:%restofmypass@example.com/"; // WARN 2
+ private static final String URL = "http://%-05s@example.com/"; // OK 2
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/StringAuthLeakDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `StringAuthLeakDetector.testStringAuthLeak`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("AuthLeak")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("AuthLeak")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection AuthLeak
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AuthLeak" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AuthLeak'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AuthLeak ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/AutoDispose.md.html b/docs/checks/AutoDispose.md.html
new file mode 100644
index 00000000..43c50b7a
--- /dev/null
+++ b/docs/checks/AutoDispose.md.html
@@ -0,0 +1,190 @@
+
+(#) Missing Disposable handling: Apply AutoDispose or cache the Disposable instance manually and enable lenient mode
+
+!!! ERROR: Missing Disposable handling: Apply AutoDispose or cache the Disposable instance manually and enable lenient mode
+ This is an error.
+
+Id
+: `AutoDispose`
+Summary
+: Missing Disposable handling: Apply AutoDispose or cache the Disposable instance manually and enable lenient mode
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Uber
+Identifier
+: AutoDispose
+Feedback
+: https://github.com/uber/AutoDispose/issues
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [com.uber.autodispose2:autodispose-lint](com_uber_autodispose2_autodispose-lint.md.html)
+Since
+: 2.1.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/uber/AutoDispose/tree/main/static-analysis/autodispose-lint/src/main/kotlin/autodispose2/lint/AutoDisposeDetector.kt)
+Tests
+: [Source Code](https://github.com/uber/AutoDispose/tree/main/static-analysis/autodispose-lint/src/test/kotlin/autodispose2/lint/AutoDisposeDetectorTest.kt)
+Copyright Year
+: 2019
+
+You're subscribing to an observable but not handling its subscription.
+This can result in memory leaks. You can avoid memory leaks by appending
+`.as(autoDisposable(this))` before you subscribe or cache the Disposable
+instance manually and enable lenient mode. More:
+https://github.com/uber/AutoDispose/wiki/Lint-Check.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/foo/MyActivity.kt:10:Error: [AutoDispose]
+ Observable.just(1).subscribe()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src/foo/MyActivity.kt:12: Error: [AutoDispose]
+ Observable.just(2).subscribe()
+ ------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/foo/MyActivity.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package foo
+import androidx.appcompat.app.AppCompatActivity
+import io.reactivex.rxjava3.core.Observable
+import io.reactivex.rxjava3.disposables.CompositeDisposable
+
+class MyActivity: AppCompatActivity {
+ private val disposables = CompositeDisposable()
+ fun doSomething(flag: Boolean) {
+ if (flag) {
+ Observable.just(1).subscribe()
+ } else {
+ Observable.just(2).subscribe()
+ }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/uber/AutoDispose/tree/main/static-analysis/autodispose-lint/src/test/kotlin/autodispose2/lint/AutoDisposeDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `AutoDisposeDetector.checkLenientLintInIfExpression`.
+To report a problem with this extracted sample, visit
+https://github.com/uber/AutoDispose/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.uber.autodispose2:autodispose-lint:2.2.1")
+
+// build.gradle
+lintChecks 'com.uber.autodispose2:autodispose-lint:2.2.1'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.autodispose.lint)
+
+# libs.versions.toml
+[versions]
+autodispose-lint = "2.2.1"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+autodispose-lint = {
+ module = "com.uber.autodispose2:autodispose-lint",
+ version.ref = "autodispose-lint"
+}
+```
+
+2.2.1 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.uber.autodispose2:autodispose-lint](com_uber_autodispose2_autodispose-lint.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("AutoDispose")
+ fun method() {
+ subscribe(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("AutoDispose")
+ void method() {
+ subscribe(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection AutoDispose
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AutoDispose" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AutoDispose'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AutoDispose ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/AutoboxingStateCreation.md.html b/docs/checks/AutoboxingStateCreation.md.html
new file mode 100644
index 00000000..2095efc3
--- /dev/null
+++ b/docs/checks/AutoboxingStateCreation.md.html
@@ -0,0 +1,193 @@
+
+(#) `State` will autobox values assigned to this state. Use a specialized state type instead.
+
+!!! Tip: `State` will autobox values assigned to this state. Use a specialized state type instead.
+ Advice from this check is just a hint; it's a "weak" warning.
+
+Id
+: `AutoboxingStateCreation`
+Summary
+: `State` will autobox values assigned to this state. Use a specialized state type instead.
+Severity
+: Hint
+Category
+: Performance
+Platform
+: Any
+Vendor
+: Jetpack Compose
+Identifier
+: androidx.compose.runtime
+Feedback
+: https://issuetracker.google.com/issues/new?component=612128
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.compose.runtime:runtime-android](androidx_compose_runtime_runtime-android.md.html)
+Since
+: 1.5.0
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/AutoboxingStateCreationDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/AutoboxingStateCreationDetectorTest.kt)
+Copyright Year
+: 2023
+
+Calling `mutableStateOf()` when `T` is either backed by a primitive
+type on the JVM or is a value class results in a state implementation
+that requires all state values to be boxed. This usually causes an
+additional allocation for each state write, and adds some additional
+work to auto-unbox values when reading the value of the state. Instead,
+prefer to use a specialized primitive state implementation for `Int`,
+`Long`, `Float`, and `Double` when the state does not need to track null
+values and does not override the default `SnapshotMutationPolicy`. See
+`mutableIntStateOf()`, `mutableLongStateOf()`, `mutableFloatStateOf()`,
+and `mutableDoubleStateOf()` for more information.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/androidx/compose/runtime/lint/test/test.kt:8:Information: Prefer
+mutableStateOf instead of mutableStateOf [AutoboxingStateCreation]
+ val state = mutableStateOf<>()
+ --------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/androidx/compose/runtime/lint/test/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package androidx.compose.runtime.lint.test
+
+import androidx.compose.runtime.*
+import
+
+fun valueAssignment() {
+ val state = mutableStateOf<>()
+ state.value =
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/AutoboxingStateCreationDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `AutoboxingStateCreationDetector.testTrivialMutableStateOf_thatCouldBeMutablePrimitiveStateOf`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=612128.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.compose.runtime:runtime-android:1.9.0-alpha01")
+
+// build.gradle
+implementation 'androidx.compose.runtime:runtime-android:1.9.0-alpha01'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.runtime.android)
+
+# libs.versions.toml
+[versions]
+runtime-android = "1.9.0-alpha01"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+runtime-android = {
+ module = "androidx.compose.runtime:runtime-android",
+ version.ref = "runtime-android"
+}
+```
+
+1.9.0-alpha01 is the version this documentation was generated from;
+there may be newer versions available.
+
+NOTE: These lint checks are **also** made available separate from the main library.
+You can also use `androidx.compose.runtime:runtime-lint:1.9.0-alpha01`.
+
+
+[Additional details about androidx.compose.runtime:runtime-android](androidx_compose_runtime_runtime-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("AutoboxingStateCreation")
+ fun method() {
+ mutableStateOf(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("AutoboxingStateCreation")
+ void method() {
+ mutableStateOf(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection AutoboxingStateCreation
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AutoboxingStateCreation" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AutoboxingStateCreation'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AutoboxingStateCreation ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/AutoboxingStateValueProperty.md.html b/docs/checks/AutoboxingStateValueProperty.md.html
new file mode 100644
index 00000000..530d2ce0
--- /dev/null
+++ b/docs/checks/AutoboxingStateValueProperty.md.html
@@ -0,0 +1,188 @@
+
+(#) State access causes value to be autoboxed
+
+!!! WARNING: State access causes value to be autoboxed
+ This is a warning.
+
+Id
+: `AutoboxingStateValueProperty`
+Summary
+: State access causes value to be autoboxed
+Severity
+: Warning
+Category
+: Performance
+Platform
+: Any
+Vendor
+: Jetpack Compose
+Identifier
+: androidx.compose.runtime
+Feedback
+: https://issuetracker.google.com/issues/new?component=612128
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.compose.runtime:runtime-android](androidx_compose_runtime_runtime-android.md.html)
+Since
+: 1.5.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/AutoboxingStateValuePropertyDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/AutoboxingStateValuePropertyDetectorTest.kt)
+Copyright Year
+: 2023
+
+Avoid using the generic `value` property when using a specialized State
+type. Reading or writing to the state's generic `value` property will
+result in an unnecessary autoboxing operation. Prefer the specialized
+value property (e.g. `intValue` for `MutableIntState`), or use property
+delegation to avoid unnecessary allocations.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/androidx/compose/runtime/lint/test/test.kt:7:Warning: Reading value
+will cause an autoboxing operation. Use intValue to avoid unnecessary
+allocations. [AutoboxingStateValueProperty]
+ val value = state.value
+ -----
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/androidx/compose/runtime/lint/test/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package androidx.compose.runtime.lint.test
+
+import androidx.compose.runtime.mutableIntStateOf
+
+fun valueAssignment() {
+ val state = mutableIntStateOf(4)
+ val value = state.value
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/AutoboxingStateValuePropertyDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `AutoboxingStateValuePropertyDetector.testReadAutoboxingPropertyAsVariableAssignment`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=612128.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.compose.runtime:runtime-android:1.9.0-alpha01")
+
+// build.gradle
+implementation 'androidx.compose.runtime:runtime-android:1.9.0-alpha01'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.runtime.android)
+
+# libs.versions.toml
+[versions]
+runtime-android = "1.9.0-alpha01"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+runtime-android = {
+ module = "androidx.compose.runtime:runtime-android",
+ version.ref = "runtime-android"
+}
+```
+
+1.9.0-alpha01 is the version this documentation was generated from;
+there may be newer versions available.
+
+NOTE: These lint checks are **also** made available separate from the main library.
+You can also use `androidx.compose.runtime:runtime-lint:1.9.0-alpha01`.
+
+
+[Additional details about androidx.compose.runtime:runtime-android](androidx_compose_runtime_runtime-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("AutoboxingStateValueProperty")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("AutoboxingStateValueProperty")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection AutoboxingStateValueProperty
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AutoboxingStateValueProperty" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AutoboxingStateValueProperty'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AutoboxingStateValueProperty ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/Autofill.md.html b/docs/checks/Autofill.md.html
new file mode 100644
index 00000000..84586a89
--- /dev/null
+++ b/docs/checks/Autofill.md.html
@@ -0,0 +1,145 @@
+
+(#) Use Autofill
+
+!!! WARNING: Use Autofill
+ This is a warning.
+
+Id
+: `Autofill`
+Summary
+: Use Autofill
+Severity
+: Warning
+Category
+: Usability
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.2.0 (September 2018)
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/guide/topics/text/autofill.html
+Implementation
+: [Source Code](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/AutofillDetector.java)
+Tests
+: [Source Code](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/AutofillDetectorTest.java)
+
+Specify an `autofillHints` attribute when targeting SDK version 26 or
+higher or explicitly specify that the view is not important for
+autofill. Your app can help an autofill service classify the data
+correctly by providing the meaning of each view that could be
+autofillable, such as views representing usernames, passwords, credit
+card fields, email addresses, etc.
+
+The hints can have any value, but it is recommended to use predefined
+values like 'username' for a username or 'creditCardNumber' for a credit
+card number. For a list of all predefined autofill hint constants, see
+the `AUTOFILL_HINT_` constants in the `View` reference at
+https://developer.android.com/reference/android/view/View.html.
+
+You can mark a view unimportant for autofill by specifying an
+`importantForAutofill` attribute on that view or a parent view. See
+https://developer.android.com/reference/android/view/View.html#setImportantForAutofill(int).
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/autofill.xml:6:Warning: Missing autofillHints attribute
+[Autofill]
+ <EditText
+ --------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/layout/autofill.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <EditText
+ android:id="@+id/usernameField"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:hint="hint"
+ android:inputType="password">
+ <requestFocus/>
+ </EditText>
+
+</LinearLayout>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/AutofillDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `AutofillDetector.testWithoutAutofillHints`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="Autofill"` on the
+ problematic XML element (or one of its enclosing elements). You may
+ also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <EditText xmlns:tools="http://schemas.android.com/tools"
+ tools:ignore="Autofill" ...>
+ ...
+ </EditText>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="Autofill" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'Autofill'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore Autofill ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/AvoidUsingNotNullOperator.md.html b/docs/checks/AvoidUsingNotNullOperator.md.html
new file mode 100644
index 00000000..ab6d0af1
--- /dev/null
+++ b/docs/checks/AvoidUsingNotNullOperator.md.html
@@ -0,0 +1,180 @@
+
+(#) Avoid using the !! operator in Kotlin
+
+!!! WARNING: Avoid using the !! operator in Kotlin
+ This is a warning.
+
+Id
+: `AvoidUsingNotNullOperator`
+Summary
+: Avoid using the !! operator in Kotlin
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.8.1
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/NotNullOperatorDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/NotNullOperatorDetectorTest.kt)
+Copyright Year
+: 2024
+
+The `!!` operator is a not-null assertion in Kotlin that will lead to a
+`NullPointerException` if the value is null. It's better to use safe
+null-handling mechanisms like `?.`, `?:`, `?.let`, etc.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/foo/Test.kt:6:Warning: Avoid using the !! operator
+[AvoidUsingNotNullOperator]
+ t/* this is legal */!!.length
+ --
+src/foo/Test.kt:7:Warning: Avoid using the !! operator
+[AvoidUsingNotNullOperator]
+ return t!!.length == 1
+ --
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/foo/Test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package foo
+
+class Test {
+ fun doNothing(t: String?): Boolean {
+ t/* this is legal */!!.length
+ return t!!.length == 1
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/NotNullOperatorDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("AvoidUsingNotNullOperator")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("AvoidUsingNotNullOperator")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection AvoidUsingNotNullOperator
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="AvoidUsingNotNullOperator" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'AvoidUsingNotNullOperator'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore AvoidUsingNotNullOperator ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/BackButton.md.html b/docs/checks/BackButton.md.html
new file mode 100644
index 00000000..0d2af11d
--- /dev/null
+++ b/docs/checks/BackButton.md.html
@@ -0,0 +1,333 @@
+
+(#) Back button
+
+!!! WARNING: Back button
+ This is a warning.
+
+Id
+: `BackButton`
+Summary
+: Back button
+Note
+: **This issue is disabled by default**; use `--enable BackButton`
+Severity
+: Warning
+Category
+: Usability
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://d.android.com/r/studio-ui/designer/material/design
+Implementation
+: [Source Code](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/ButtonDetector.java)
+Tests
+: [Source Code](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/ButtonDetectorTest.java)
+Copyright Year
+: 2012
+
+According to the Android Design Guide,
+
+"Other platforms use an explicit back button with label to allow the
+user to navigate up the application's hierarchy. Instead, Android uses
+the main action bar's app icon for hierarchical navigation and the
+navigation bar's back button for temporal navigation."
+
+This check is not very sophisticated (it just looks for buttons with the
+label "Back"), so it is disabled by default to not trigger on common
+scenarios like pairs of Back/Next buttons to paginate through screens.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/buttonbar.xml:183:Warning: Back buttons are not standard on
+Android; see design guide's navigation section [BackButton]
+ <Button
+ ------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`res/layout/buttonbar.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <!-- Hardcoded strings, wrong order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="OK" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Cancel" />
+ </LinearLayout>
+
+ <!-- Hardcoded strings, right order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Cancel" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="OK" />
+ </LinearLayout>
+
+ <!-- @android:string resources, wrong order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@android:string/ok" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@android:string/cancel" />
+ </LinearLayout>
+
+ <!-- @android:string resources, right order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@android:string/cancel" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@android:string/ok" />
+ </LinearLayout>
+
+ <!-- @string/ok/cancel resources, right order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/cancel" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/ok" />
+ </LinearLayout>
+
+ <!-- @string/ok/cancel resources, wrong order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/ok" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/cancel" />
+ </LinearLayout>
+
+ <!-- Random name resources, right order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/giveup" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/resume" />
+ </LinearLayout>
+
+ <!-- Random name resources, wrong order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/resume" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/giveup" />
+ </LinearLayout>
+
+ <!-- Random name resources with varying case, wrong order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/resume2" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/giveup2" />
+ </LinearLayout>
+
+ <!-- Resources with only one of OK and Cancel, wrong order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/ok" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/abort" />
+ </LinearLayout>
+
+ <!-- Resources with only one of OK and Cancel, wrong order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content" android:background="?android:attr/selectableItemBackground"
+ android:layout_height="wrap_content"
+ android:text="@string/send" />
+
+ <Button
+ android:layout_width="wrap_content" android:background="?android:attr/selectableItemBackground"
+ android:layout_height="wrap_content"
+ android:text="@string/cancel" />
+ </LinearLayout>
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/goback" />
+
+</LinearLayout>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values/buttonbar-values.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <string name="button"> Button </string>
+ <string name="ok"> OK </string>
+ <string name="cancel"> Cancel </string>
+ <string name="resume"> OK </string>
+ <string name="giveup"> Cancel </string>
+ <string name="resume2"> Ok </string>
+ <string name="giveup2">"CANCEL"</string>
+ <string name="send"> Send </string>
+ <string name="abort">Abort</string>
+ <string name="goback">'Back'</string>
+
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ButtonDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ButtonDetector.testBack`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="BackButton"` on the
+ problematic XML element (or one of its enclosing elements). You may
+ also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <resources xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <Button tools:ignore="BackButton" .../>
+ ...
+ </resources>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="BackButton" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'BackButton'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore BackButton ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/BadConfigurationProvider.md.html b/docs/checks/BadConfigurationProvider.md.html
new file mode 100644
index 00000000..0cce2370
--- /dev/null
+++ b/docs/checks/BadConfigurationProvider.md.html
@@ -0,0 +1,191 @@
+
+(#) Invalid WorkManager Configuration Provider
+
+!!! ERROR: Invalid WorkManager Configuration Provider
+ This is an error, and is also enforced at build time when
+ supported by the build system. For Android this means it will
+ run during release builds.
+
+Id
+: `BadConfigurationProvider`
+Summary
+: Invalid WorkManager Configuration Provider
+Severity
+: Fatal
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Identifier
+: androidx.work
+Feedback
+: https://issuetracker.google.com/issues/new?component=409906
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.work:work-runtime](androidx_work_work-runtime.md.html)
+Since
+: 2.3.0
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/work/work-lint/src/main/java/androidx/work/lint/BadConfigurationProviderIssueDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/work/work-lint/src/test/java/androidx/work/lint/BadConfigurationProviderTest.kt)
+Copyright Year
+: 2019
+
+An `android.app.Application` must implement
+`androidx.work.Configuration.Provider`
+for on-demand initialization.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+com/example/App.kt:Error: Expected Application subtype to implement
+Configuration.Provider [BadConfigurationProvider]
+1 errors, 0 warnings
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`com/example/App.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package com.example
+
+import android.app.Application
+
+class App: Application() {
+ override fun onCreate() {
+
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`com/example/CustomProvider.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package com.example
+
+import androidx.work.Configuration
+
+class Provider: Configuration.Provider {
+ override fun getWorkManagerConfiguration(): Configuration = TODO()
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/work/work-lint/src/test/java/androidx/work/lint/BadConfigurationProviderTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `BadConfigurationProviderIssueDetector.testWithInvalidConfigurationProvider`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=409906.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.work:work-runtime:2.10.1")
+
+// build.gradle
+implementation 'androidx.work:work-runtime:2.10.1'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.work.runtime)
+
+# libs.versions.toml
+[versions]
+work-runtime = "2.10.1"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+work-runtime = {
+ module = "androidx.work:work-runtime",
+ version.ref = "work-runtime"
+}
+```
+
+2.10.1 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.work:work-runtime](androidx_work_work-runtime.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("BadConfigurationProvider")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("BadConfigurationProvider")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection BadConfigurationProvider
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="BadConfigurationProvider" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'BadConfigurationProvider'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore BadConfigurationProvider ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/BadHostnameVerifier.md.html b/docs/checks/BadHostnameVerifier.md.html
new file mode 100644
index 00000000..66263d7d
--- /dev/null
+++ b/docs/checks/BadHostnameVerifier.md.html
@@ -0,0 +1,169 @@
+
+(#) Insecure HostnameVerifier
+
+!!! WARNING: Insecure HostnameVerifier
+ This is a warning.
+
+Id
+: `BadHostnameVerifier`
+Summary
+: Insecure HostnameVerifier
+Severity
+: Warning
+Category
+: Security
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 2.0.0 (April 2016)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://goo.gle/BadHostnameVerifier
+Implementation
+: [Source Code](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/BadHostnameVerifierDetector.java)
+Tests
+: [Source Code](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/BadHostnameVerifierDetectorTest.java)
+
+This check looks for implementations of `HostnameVerifier` whose
+`verify` method always returns true (thus trusting any hostname) which
+could result in insecure network traffic caused by trusting arbitrary
+hostnames in TLS/SSL certificates presented by peers.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/InsecureHostnameVerifier.java:9:Warning: verify always
+returns true, which could cause insecure network traffic due to trusting
+TLS/SSL server certificates for wrong hostnames [BadHostnameVerifier]
+ public boolean verify(String hostname, SSLSession session) {
+ ------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/InsecureHostnameVerifier.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLSession;
+
+public abstract class InsecureHostnameVerifier {
+ HostnameVerifier allowAll = new HostnameVerifier() {
+ @Override
+ public boolean verify(String hostname, SSLSession session) {
+ return true;
+ }
+ };
+
+ HostnameVerifier allowAll2 = new HostnameVerifier() {
+ @Override
+ public boolean verify(String hostname, SSLSession session) {
+ boolean returnValue = true;
+ if (true) {
+ int irrelevant = 5;
+ if (irrelevant > 6) {
+ return returnValue;
+ }
+ }
+ return returnValue;
+ }
+ };
+
+ HostnameVerifier unknown = new HostnameVerifier() {
+ @Override
+ public boolean verify(String hostname, SSLSession session) {
+ boolean returnValue = true;
+ if (hostname.contains("something")) {
+ returnValue = false;
+ }
+ return returnValue;
+ }
+ };
+}
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/BadHostnameVerifierDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `BadHostnameVerifierDetector.testBroken`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("BadHostnameVerifier")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("BadHostnameVerifier")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection BadHostnameVerifier
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="BadHostnameVerifier" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'BadHostnameVerifier'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore BadHostnameVerifier ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/BadPeriodicWorkRequestEnqueue.md.html b/docs/checks/BadPeriodicWorkRequestEnqueue.md.html
new file mode 100644
index 00000000..6d8740b0
--- /dev/null
+++ b/docs/checks/BadPeriodicWorkRequestEnqueue.md.html
@@ -0,0 +1,147 @@
+
+(#) Use `enqueueUniquePeriodicWork()` instead of `enqueue()`
+
+!!! WARNING: Use `enqueueUniquePeriodicWork()` instead of `enqueue()`
+ This is a warning.
+
+Id
+: `BadPeriodicWorkRequestEnqueue`
+Summary
+: Use `enqueueUniquePeriodicWork()` instead of `enqueue()`
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Identifier
+: androidx.work
+Feedback
+: https://issuetracker.google.com/issues/new?component=409906
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.work:work-runtime](androidx_work_work-runtime.md.html)
+Since
+: 2.3.0
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/work/work-lint/src/main/java/androidx/work/lint/PeriodicEnqueueIssueDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/work/work-lint/src/test/java/androidx/work/lint/PeriodicEnqueueIssueDetectorTest.kt)
+Copyright Year
+: 2019
+
+When using `enqueue()` for `PeriodicWorkRequest`s, you might end up
+enqueuing
+duplicate requests unintentionally. You should be using
+`enqueueUniquePeriodicWork` with an `ExistingPeriodicWorkPolicy.KEEP`
+instead.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.work:work-runtime:2.10.1")
+
+// build.gradle
+implementation 'androidx.work:work-runtime:2.10.1'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.work.runtime)
+
+# libs.versions.toml
+[versions]
+work-runtime = "2.10.1"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+work-runtime = {
+ module = "androidx.work:work-runtime",
+ version.ref = "work-runtime"
+}
+```
+
+2.10.1 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.work:work-runtime](androidx_work_work-runtime.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("BadPeriodicWorkRequestEnqueue")
+ fun method() {
+ enqueue(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("BadPeriodicWorkRequestEnqueue")
+ void method() {
+ enqueue(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection BadPeriodicWorkRequestEnqueue
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="BadPeriodicWorkRequestEnqueue" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'BadPeriodicWorkRequestEnqueue'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore BadPeriodicWorkRequestEnqueue ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/BatteryLife.md.html b/docs/checks/BatteryLife.md.html
new file mode 100644
index 00000000..9b898249
--- /dev/null
+++ b/docs/checks/BatteryLife.md.html
@@ -0,0 +1,211 @@
+
+(#) Battery Life Issues
+
+!!! WARNING: Battery Life Issues
+ This is a warning.
+
+Id
+: `BatteryLife`
+Summary
+: Battery Life Issues
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 2.2.0 (September 2016)
+Affects
+: Kotlin and Java files and manifest files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/topic/performance/background-optimization
+Implementation
+: [Source Code](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/BatteryDetector.kt)
+Tests
+: [Source Code](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/BatteryDetectorTest.java)
+
+This issue flags code that either
+* negatively affects battery life, or
+* uses APIs that have recently changed behavior to prevent background
+ tasks from consuming memory and battery excessively.
+
+Generally, you should be using `WorkManager` instead.
+
+For more details on how to update your code, please see
+https://developer.android.com/topic/performance/background-optimization.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:9:Warning: Declaring a broadcastreceiver for
+android.net.conn.CONNECTIVITY_CHANGE is deprecated for apps targeting N
+and higher. In general, apps should not rely on this broadcast and
+instead use WorkManager. [BatteryLife]
+ <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
+ ------------------------------------
+AndroidManifest.xml:10:Warning: Use of
+REQUEST_IGNORE_BATTERY_OPTIMIZATIONS violates the Play Store Content
+Policy regarding acceptable use cases, as described in
+https://developer.android.com/training/monitoring-device-state/doze-standby.html
+[BatteryLife]
+ <action android:name="android.settings.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
+ -----------------------------------------------------
+AndroidManifest.xml:11:Warning: Use of com.android.camera.NEW_PICTURE is
+deprecated for all apps starting with the N release independent of the
+target SDK. Apps should not rely on these broadcasts and instead use
+WorkManager [BatteryLife]
+ <action android:name="com.android.camera.NEW_PICTURE" />
+ ------------------------------
+AndroidManifest.xml:12:Warning: Use of
+android.hardware.action.NEW_PICTURE is deprecated for all apps starting
+with the N release independent of the target SDK. Apps should not rely
+on these broadcasts and instead use WorkManager [BatteryLife]
+ <action android:name="android.hardware.action.NEW_PICTURE" />
+ -----------------------------------
+src/test/pkg/BatteryTest.java:15:Warning: Use of
+REQUEST_IGNORE_BATTERY_OPTIMIZATIONS violates the Play Store Content
+Policy regarding acceptable use cases, as described in
+https://developer.android.com/training/monitoring-device-state/doze-standby.html
+[BatteryLife]
+ Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
+ -------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.google.myapplication">
+
+ <uses-sdk android:targetSdkVersion="24" />
+
+ <receiver android:name=".MyReceiver" >
+ <intent-filter>
+ <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
+ <action android:name="android.settings.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
+ <action android:name="com.android.camera.NEW_PICTURE" />
+ <action android:name="android.hardware.action.NEW_PICTURE" />
+ <data android:mimeType="image/*" /> </intent-filter>
+ </receiver>
+
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/BatteryTest.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.content.ActivityNotFoundException;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Build;
+import android.provider.Settings;
+
+@SuppressWarnings("unused")
+public class BatteryTest extends Activity {
+ @TargetApi(Build.VERSION_CODES.M)
+ public void testNoNo() throws ActivityNotFoundException {
+ Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
+ intent.setData(Uri.parse("package:my.pkg"));
+ startActivity(intent);
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/BatteryDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="BatteryLife"` on the
+ problematic XML element (or one of its enclosing elements). You may
+ also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <action tools:ignore="BatteryLife" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("BatteryLife")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("BatteryLife")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection BatteryLife
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="BatteryLife" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'BatteryLife'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore BatteryLife ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/BidiSpoofing.md.html b/docs/checks/BidiSpoofing.md.html
new file mode 100644
index 00000000..40335a3b
--- /dev/null
+++ b/docs/checks/BidiSpoofing.md.html
@@ -0,0 +1,166 @@
+
+(#) Bidirectional text spoofing
+
+!!! ERROR: Bidirectional text spoofing
+ This is an error.
+
+Id
+: `BidiSpoofing`
+Summary
+: Bidirectional text spoofing
+Severity
+: Error
+Category
+: Security
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 7.1.0 (January 2022)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://krebsonsecurity.com/2021/11/trojan-source-bug-threatens-the-security-of-all-code/
+See
+: https://goo.gle/BidiSpoofing
+Implementation
+: [Source Code](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/BidirectionalTextDetector.kt)
+Tests
+: [Source Code](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/BidirectionalTextDetectorTest.kt)
+
+Unicode bidirectional text characters can alter the order in which the
+compiler processes tokens. However, this can also be used to hide
+malicious code, and can be difficult to spot. This lint check audits the
+source code and looks for cases where it looks like bidirectional text
+has the potential to be misleading.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/StretchedString.java:5:Error: String contains misleading Unicode
+bidirectional text [BidiSpoofing]
+ if (accessLevel != "user // Check if admin ") {
+ -----------------------------
+src/CommentingOut.java:5:Error: Comment contains misleading Unicode
+bidirectional text [BidiSpoofing]
+ /* } if (isAdmin) begin admins only */
+ -------------------------------------------
+src/CommentingOut.java:7:Error: Comment contains misleading Unicode
+bidirectional text [BidiSpoofing]
+ /* end admins only { */
+ --------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/StretchedString.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+// From https://github.com/nickboucher/trojan-source/blob/main/Java/StretchedString.java
+public class StretchedString {
+ public static void main(String[] args) {
+ String accessLevel = "user";
+ if (accessLevel != "user // Check if admin ") {
+ System.out.println("You are an admin.");
+ }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/CommentingOut.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+// From https://github.com/nickboucher/trojan-source/blob/main/Java/CommentingOut.java
+public class CommentingOut {
+ public static void main(String[] args) {
+ boolean isAdmin = false;
+ /* } if (isAdmin) begin admins only */
+ System.out.println("You are an admin.");
+ /* end admins only { */
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+/* Comment // OK
+ * and // OK
+ */
+val valid1 = "LeftRightLeft" // OK
+val valid2 = "LeftRightNested LeftLeft" // OK
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/BidirectionalTextDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("BidiSpoofing")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("BidiSpoofing")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection BidiSpoofing
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="BidiSpoofing" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'BidiSpoofing'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore BidiSpoofing ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/BinaryOperationInTimber.md.html b/docs/checks/BinaryOperationInTimber.md.html
new file mode 100644
index 00000000..134ea1d8
--- /dev/null
+++ b/docs/checks/BinaryOperationInTimber.md.html
@@ -0,0 +1,191 @@
+
+(#) Use String#format()
+
+!!! WARNING: Use String#format()
+ This is a warning.
+
+Id
+: `BinaryOperationInTimber`
+Summary
+: Use String#format()
+Severity
+: Warning
+Category
+: Correctness: Messages
+Platform
+: Any
+Vendor
+: JakeWharton/timber
+Identifier
+: com.jakewharton.timber:timber:{version}
+Feedback
+: https://github.com/JakeWharton/timber/issues
+Min
+: Lint 4.0
+Compiled
+: Lint 7.0
+Artifact
+: [com.jakewharton.timber:timber](com_jakewharton_timber_timber.md.html)
+Since
+: 4.6.0
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/JakeWharton/timber/tree/trunk/timber-lint/src/main/java/timber/lint/WrongTimberUsageDetector.kt)
+Tests
+: [Source Code](https://github.com/JakeWharton/timber/tree/trunk/timber-lint/src/test/java/timber/lint/WrongTimberUsageDetectorTest.kt)
+
+Since Timber handles String#format() automatically, use this instead of
+String concatenation.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/foo/Example.java:6:Warning: Replace String concatenation with
+Timber's string formatting [BinaryOperationInTimber]
+ Timber.d(foo + "bar");
+ -----------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/foo/Example.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package foo;
+import timber.log.Timber;
+public class Example {
+ public void log() {
+ String foo = "foo";
+ Timber.d(foo + "bar");
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/foo/Example.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package foo
+import timber.log.Timber
+class Example {
+ fun log() {
+ val foo = "foo"
+ Timber.d("${foo}bar")
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/JakeWharton/timber/tree/trunk/timber-lint/src/test/java/timber/lint/WrongTimberUsageDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `WrongTimberUsageDetector.stringConcatenationLeftLiteral`.
+To report a problem with this extracted sample, visit
+https://github.com/JakeWharton/timber/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+implementation("com.jakewharton.timber:timber:5.0.1")
+
+// build.gradle
+implementation 'com.jakewharton.timber:timber:5.0.1'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.timber)
+
+# libs.versions.toml
+[versions]
+timber = "5.0.1"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+timber = {
+ module = "com.jakewharton.timber:timber",
+ version.ref = "timber"
+}
+```
+
+5.0.1 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.jakewharton.timber:timber](com_jakewharton_timber_timber.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("BinaryOperationInTimber")
+ fun method() {
+ tag(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("BinaryOperationInTimber")
+ void method() {
+ tag(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection BinaryOperationInTimber
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="BinaryOperationInTimber" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'BinaryOperationInTimber'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore BinaryOperationInTimber ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/BinderGetCallingInMainThread.md.html b/docs/checks/BinderGetCallingInMainThread.md.html
new file mode 100644
index 00000000..85ed1516
--- /dev/null
+++ b/docs/checks/BinderGetCallingInMainThread.md.html
@@ -0,0 +1,140 @@
+
+(#) Incorrect usage of getCallingUid() or getCallingPid()
+
+!!! ERROR: Incorrect usage of getCallingUid() or getCallingPid()
+ This is an error.
+
+Id
+: `BinderGetCallingInMainThread`
+Summary
+: Incorrect usage of getCallingUid() or getCallingPid()
+Severity
+: Error
+Category
+: Security
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 8.0.0 (April 2023)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/BinderGetCallingInMainThreadDetector.kt)
+Tests
+: [Source Code](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/BinderGetCallingInMainThreadDetectorTest.kt)
+
+`Binder.getCallingUid()` and `Binder.getCallingPid()` will return
+information about the current process if called inside a thread that is
+not handling a binder transaction. This can cause security issues. If
+you still want to use your own uid/pid, use `Process.myUid()` or
+`Process.myPid()`.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/MyService.kt:10:Error: Binder.getCallingUid() should not be
+used inside onBind() [BinderGetCallingInMainThread]
+ Binder.getCallingUid()
+ ----------------------
+src/test/pkg/MyService.kt:11:Error: Binder.getCallingPid() should not be
+used inside onBind() [BinderGetCallingInMainThread]
+ Binder.getCallingPid()
+ ----------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/MyService.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+
+import android.app.Service
+import android.content.Intent
+import android.os.Binder
+import android.os.IBinder
+
+class MyService : Service() {
+ override fun onBind(intent: Intent): IBinder {
+ Binder.getCallingUid()
+ Binder.getCallingPid()
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/BinderGetCallingInMainThreadDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("BinderGetCallingInMainThread")
+ fun method() {
+ getCallingUid(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("BinderGetCallingInMainThread")
+ void method() {
+ getCallingUid(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection BinderGetCallingInMainThread
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="BinderGetCallingInMainThread" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'BinderGetCallingInMainThread'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore BinderGetCallingInMainThread ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/BindingReceiverParameter.md.html b/docs/checks/BindingReceiverParameter.md.html
new file mode 100644
index 00000000..3afe4d93
--- /dev/null
+++ b/docs/checks/BindingReceiverParameter.md.html
@@ -0,0 +1,239 @@
+
+(#) @Binds/@Provides functions cannot be extensions
+
+!!! ERROR: @Binds/@Provides functions cannot be extensions
+ This is an error.
+
+Id
+: `BindingReceiverParameter`
+Summary
+: @Binds/@Provides functions cannot be extensions
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.5.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/DaggerIssuesDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/DaggerIssuesDetectorTest.kt)
+Copyright Year
+: 2021
+
+@Binds/@Provides functions cannot be extension functions. Move the
+receiver type to a parameter via IDE inspection (option+enter and
+convert to parameter).
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/foo/MyQualifier.kt:12:Error: @Binds/@Provides functions cannot be
+extensions [BindingReceiverParameter]
+ @Binds fun Int.bind(): Number
+ ---
+src/foo/MyQualifier.kt:13:Error: @Binds/@Provides functions cannot be
+extensions [BindingReceiverParameter]
+ @Binds fun Long.bind(): Number
+ ----
+src/foo/MyQualifier.kt:14:Error: @Binds/@Provides functions cannot be
+extensions [BindingReceiverParameter]
+ @Binds fun Double.bind(): Number
+ ------
+src/foo/MyQualifier.kt:15:Error: @Binds/@Provides functions cannot be
+extensions [BindingReceiverParameter]
+ @Binds fun Float.bind(): Number
+ -----
+src/foo/MyQualifier.kt:16:Error: @Binds/@Provides functions cannot be
+extensions [BindingReceiverParameter]
+ @Binds fun Short.bind(): Number
+ -----
+src/foo/MyQualifier.kt:17:Error: @Binds/@Provides functions cannot be
+extensions [BindingReceiverParameter]
+ @Binds fun Byte.bind(): Number
+ ----
+src/foo/MyQualifier.kt:18:Error: @Binds/@Provides functions cannot be
+extensions [BindingReceiverParameter]
+ @Binds fun Char.bind(): Comparable<Char>
+ ----
+src/foo/MyQualifier.kt:19:Error: @Binds/@Provides functions cannot be
+extensions [BindingReceiverParameter]
+ @Binds fun String.bind(): Comparable<String>
+ ------
+src/foo/MyQualifier.kt:20:Error: @Binds/@Provides functions cannot be
+extensions [BindingReceiverParameter]
+ @Binds fun @receiver:MyQualifier Boolean.bind(): Comparable<Boolean>
+ -------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/foo/MyQualifier.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package foo
+import javax.inject.Qualifier
+import dagger.Binds
+import dagger.Provides
+import dagger.Module
+
+@Qualifier
+annotation class MyQualifier
+
+@Module
+interface MyModule {
+ @Binds fun Int.bind(): Number
+ @Binds fun Long.bind(): Number
+ @Binds fun Double.bind(): Number
+ @Binds fun Float.bind(): Number
+ @Binds fun Short.bind(): Number
+ @Binds fun Byte.bind(): Number
+ @Binds fun Char.bind(): Comparable
+ @Binds fun String.bind(): Comparable
+ @Binds fun @receiver:MyQualifier Boolean.bind(): Comparable
+}
+
+@Module
+interface MyModule2 {
+ @Provides fun Int.bind(): Number = this@bind
+ @Provides fun Long.bind(): Number = this@bind
+ @Provides fun Double.bind(): Number = this@bind
+ @Provides fun Float.bind(): Number = this@bind
+ @Provides fun Short.bind(): Number = this@bind
+ @Provides fun Byte.bind(): Number = this@bind
+ @Provides fun Char.bind(): Comparable = this@bind
+ @Provides fun String.bind(): Comparable = this@bind
+ @Provides fun @receiver:MyQualifier Boolean.bind(): Comparable = this@bind
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/DaggerIssuesDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `DaggerIssuesDetector.bindings cannot be extension functions`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/slack-lints.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("BindingReceiverParameter")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("BindingReceiverParameter")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection BindingReceiverParameter
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="BindingReceiverParameter" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'BindingReceiverParameter'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore BindingReceiverParameter ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/BindingReturnType.md.html b/docs/checks/BindingReturnType.md.html
new file mode 100644
index 00000000..46b6b524
--- /dev/null
+++ b/docs/checks/BindingReturnType.md.html
@@ -0,0 +1,196 @@
+
+(#) @Binds/@Provides must have a return type
+
+!!! ERROR: @Binds/@Provides must have a return type
+ This is an error.
+
+Id
+: `BindingReturnType`
+Summary
+: @Binds/@Provides must have a return type
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.5.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/DaggerIssuesDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/DaggerIssuesDetectorTest.kt)
+Copyright Year
+: 2021
+
+@Binds/@Provides functions must have a return type. Cannot be void or
+Unit.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/foo/MyQualifier.kt:14:Error: @Binds/@Provides must have a return
+type [BindingReturnType]
+ @Provides fun invalidBind3() {
+ ^
+src/foo/MyQualifier.kt:17:Error: @Binds/@Provides must have a return
+type [BindingReturnType]
+ @Provides fun invalidBind4(): Unit {
+ ^
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/foo/MyQualifier.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package foo
+import javax.inject.Qualifier
+import dagger.Binds
+import dagger.Provides
+import dagger.Module
+
+@Qualifier
+annotation class MyQualifier
+
+@Module
+abstract class MyModule {
+ @Binds fun invalidBind1(@MyQualifier real: Unit)
+ @Binds fun invalidBind2(@MyQualifier real: Unit): Unit
+ @Provides fun invalidBind3() {
+
+ }
+ @Provides fun invalidBind4(): Unit {
+ return Unit
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/DaggerIssuesDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `DaggerIssuesDetector.invalid return types`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/slack-lints.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("BindingReturnType")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("BindingReturnType")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection BindingReturnType
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="BindingReturnType" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'BindingReturnType'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore BindingReturnType ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/BindsMustBeAbstract.md.html b/docs/checks/BindsMustBeAbstract.md.html
new file mode 100644
index 00000000..7570d5df
--- /dev/null
+++ b/docs/checks/BindsMustBeAbstract.md.html
@@ -0,0 +1,195 @@
+
+(#) @Binds functions must be abstract
+
+!!! ERROR: @Binds functions must be abstract
+ This is an error.
+
+Id
+: `BindsMustBeAbstract`
+Summary
+: @Binds functions must be abstract
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.5.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/DaggerIssuesDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/DaggerIssuesDetectorTest.kt)
+Copyright Year
+: 2021
+
+@Binds functions must be abstract and cannot have function bodies.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/foo/MyQualifier.kt:12:Error: @Binds functions must be abstract
+[BindsMustBeAbstract]
+ @Binds fun invalidBind1(@MyQualifier real: Unit)
+ ------------------------------------------------
+src/foo/MyQualifier.kt:13:Error: @Binds functions must be abstract
+[BindsMustBeAbstract]
+ @Binds fun invalidBind2(@MyQualifier real: Unit): Unit
+ ------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/foo/MyQualifier.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package foo
+import javax.inject.Qualifier
+import dagger.Binds
+import dagger.Provides
+import dagger.Module
+
+@Qualifier
+annotation class MyQualifier
+
+@Module
+abstract class MyModule {
+ @Binds fun invalidBind1(@MyQualifier real: Unit)
+ @Binds fun invalidBind2(@MyQualifier real: Unit): Unit
+ @Provides fun invalidBind3() {
+
+ }
+ @Provides fun invalidBind4(): Unit {
+ return Unit
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/DaggerIssuesDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `DaggerIssuesDetector.invalid return types`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/slack-lints.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("BindsMustBeAbstract")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("BindsMustBeAbstract")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection BindsMustBeAbstract
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="BindsMustBeAbstract" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'BindsMustBeAbstract'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore BindsMustBeAbstract ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/BindsTypeMismatch.md.html b/docs/checks/BindsTypeMismatch.md.html
new file mode 100644
index 00000000..99f27e88
--- /dev/null
+++ b/docs/checks/BindsTypeMismatch.md.html
@@ -0,0 +1,204 @@
+
+(#) @Binds parameter/return must be type-assignable
+
+!!! ERROR: @Binds parameter/return must be type-assignable
+ This is an error.
+
+Id
+: `BindsTypeMismatch`
+Summary
+: @Binds parameter/return must be type-assignable
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.5.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/DaggerIssuesDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/DaggerIssuesDetectorTest.kt)
+Copyright Year
+: 2021
+
+@Binds function parameters must be type-assignable to their return
+types.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/foo/TestModule.kt:18:Error: @Binds parameter/return must be
+type-assignable [BindsTypeMismatch]
+ @Binds fun invalidBind(real: Long): String
+ ------------------------------------------
+src/foo/TestModule.kt:19:Error: @Binds parameter/return must be
+type-assignable [BindsTypeMismatch]
+ @Binds fun invalidBind(real: Long): Comparable<Boolean>
+ -------------------------------------------------------
+src/foo/TestModule.kt:23:Error: @Binds parameter/return must be
+type-assignable [BindsTypeMismatch]
+ @Binds fun invalidComplexBinding(real: DetailTypeAItemMapper): ItemMapper<ItemDetail>
+ -------------------------------------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/foo/TestModule.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package foo
+import javax.inject.Qualifier
+import dagger.Binds
+import dagger.Module
+
+sealed interface ItemDetail {
+ object DetailTypeA : ItemDetail
+}
+
+interface ItemMapper
+
+class DetailTypeAItemMapper : ItemMapper
+
+@Module
+interface MyModule {
+ @Binds fun validBind(real: Int): Number
+ @Binds fun validBind(real: Boolean): Comparable
+ @Binds fun invalidBind(real: Long): String
+ @Binds fun invalidBind(real: Long): Comparable
+
+ @Binds fun validComplexBinding(real: DetailTypeAItemMapper): ItemMapper
+ @Binds fun validComplexBinding2(real: DetailTypeAItemMapper): ItemMapper<*>
+ @Binds fun invalidComplexBinding(real: DetailTypeAItemMapper): ItemMapper
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/DaggerIssuesDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `DaggerIssuesDetector.binds type mismatches`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/slack-lints.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("BindsTypeMismatch")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("BindsTypeMismatch")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection BindsTypeMismatch
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="BindsTypeMismatch" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'BindsTypeMismatch'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore BindsTypeMismatch ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/BindsWrongParameterCount.md.html b/docs/checks/BindsWrongParameterCount.md.html
new file mode 100644
index 00000000..37973a76
--- /dev/null
+++ b/docs/checks/BindsWrongParameterCount.md.html
@@ -0,0 +1,185 @@
+
+(#) @Binds must have one parameter
+
+!!! ERROR: @Binds must have one parameter
+ This is an error.
+
+Id
+: `BindsWrongParameterCount`
+Summary
+: @Binds must have one parameter
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.5.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/DaggerIssuesDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/DaggerIssuesDetectorTest.kt)
+Copyright Year
+: 2021
+
+@Binds functions require a single parameter as an input to bind.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/foo/MyModule.kt:8:Error: @Binds must have one parameter
+[BindsWrongParameterCount]
+ @Binds fun invalidBind(real: Int, second: Int): Number
+ ------------------------
+src/foo/MyModule.kt:9:Error: @Binds must have one parameter
+[BindsWrongParameterCount]
+ @Binds fun invalidBind(): Number
+ --------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/foo/MyModule.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package foo
+import dagger.Binds
+import dagger.Module
+
+@Module
+interface MyModule {
+ @Binds fun validBind(real: Int): Number
+ @Binds fun invalidBind(real: Int, second: Int): Number
+ @Binds fun invalidBind(): Number
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/DaggerIssuesDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `DaggerIssuesDetector.binds param counts`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/slack-lints.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("BindsWrongParameterCount")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("BindsWrongParameterCount")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection BindsWrongParameterCount
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="BindsWrongParameterCount" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'BindsWrongParameterCount'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore BindsWrongParameterCount ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/BlockedPrivateApi.md.html b/docs/checks/BlockedPrivateApi.md.html
new file mode 100644
index 00000000..83203fc1
--- /dev/null
+++ b/docs/checks/BlockedPrivateApi.md.html
@@ -0,0 +1,154 @@
+
+(#) Using Blocked Private API
+
+!!! ERROR: Using Blocked Private API
+ This is an error, and is also enforced at build time when
+ supported by the build system. For Android this means it will
+ run during release builds.
+
+Id
+: `BlockedPrivateApi`
+Summary
+: Using Blocked Private API
+Severity
+: Fatal
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.5.0 (August 2019)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/preview/restrictions-non-sdk-interfaces
+Implementation
+: [Source Code](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/PrivateApiDetector.kt)
+Tests
+: [Source Code](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/PrivateApiDetectorTest.kt)
+
+Usage of restricted non-SDK interface is forbidden for this targetSDK.
+Accessing non-SDK methods or fields through reflection has a high
+likelihood to break your app between versions, and is being restricted
+to facilitate future app compatibility.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/TestReflection.java:12:Error: Reflective access to
+NETWORK_TYPES is forbidden when targeting API 28 and above
+[BlockedPrivateApi]
+ Field deniedField = TelephonyManager.class.getDeclaredField("NETWORK_TYPES"); // ERROR 1
+ --------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/TestReflection.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.content.Context;
+import android.telephony.TelephonyManager;
+
+import java.lang.reflect.Field;
+
+public class TestReflection {
+ public void test(Context context, int subId) {
+ try {
+ TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+ Field deniedField = TelephonyManager.class.getDeclaredField("NETWORK_TYPES"); // ERROR 1
+ Object o1 = deniedField.get(tm);
+ Field allowedField = TelephonyManager.class.getDeclaredField("NETWORK_SELECTION_MODE_MANUAL"); // OK
+ Object o2 = allowedField.get(tm);
+ Field maybeField = TelephonyManager.class.getDeclaredField("OTASP_NEEDED"); // ERROR 2
+ Object o3 = maybeField.get(tm);
+ } catch (ReflectiveOperationException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/PrivateApiDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `PrivateApiDetector.testFields`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("BlockedPrivateApi")
+ fun method() {
+ forName(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("BlockedPrivateApi")
+ void method() {
+ forName(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection BlockedPrivateApi
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="BlockedPrivateApi" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'BlockedPrivateApi'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore BlockedPrivateApi ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/BomWithoutPlatform.md.html b/docs/checks/BomWithoutPlatform.md.html
new file mode 100644
index 00000000..08ec003a
--- /dev/null
+++ b/docs/checks/BomWithoutPlatform.md.html
@@ -0,0 +1,141 @@
+
+(#) Using a BOM without platform call
+
+!!! WARNING: Using a BOM without platform call
+ This is a warning.
+
+Id
+: `BomWithoutPlatform`
+Summary
+: Using a BOM without platform call
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 8.1.0 (July 2023)
+Affects
+: Gradle build files and TOML files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/r/tools/gradle-bom-docs
+Implementation
+: [Source Code](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/GradleDetector.kt)
+Tests
+: [Source Code](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/GradleDetectorTest.kt)
+
+When including a BOM, the dependency's coordinates must be wrapped in a
+call to `platform()` for Gradle to interpret it correctly.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+build.gradle:6:Warning: BOM should be added with a call to platform()
+[BomWithoutPlatform]
+ implementation(libs.compose.bom)
+ ----------------
+build.gradle:7:Warning: BOM should be added with a call to platform()
+[BomWithoutPlatform]
+ testImplementation(libs.compose.bom)
+ ----------------
+build.gradle:8:Warning: BOM should be added with a call to platform()
+[BomWithoutPlatform]
+ testImplementation "androidx.compose:compose-bom:2023.01.00"
+ -----------------------------------------
+build.gradle:9:Warning: BOM should be added with a call to platform()
+[BomWithoutPlatform]
+ api("androidx.compose:compose-bom:2023.01.00")
+ -----------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/libs.versions.toml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~toml linenumbers
+[versions]
+composeBom = "2023.01.00"
+[libraries]
+compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`build.gradle`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~groovy linenumbers
+plugins {
+ id 'com.android.application'
+ id 'kotlin-android'
+}
+dependencies {
+ implementation(libs.compose.bom)
+ testImplementation(libs.compose.bom)
+ testImplementation "androidx.compose:compose-bom:2023.01.00"
+ api("androidx.compose:compose-bom:2023.01.00")
+ // Make sure we don't complain about existing platforms
+ implementation platform("androidx.compose:compose-bom:2023.01.00")
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/GradleDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `GradleDetector.testBomWithoutPlatform`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection BomWithoutPlatform
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="BomWithoutPlatform" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'BomWithoutPlatform'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore BomWithoutPlatform ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/BottomAppBar.md.html b/docs/checks/BottomAppBar.md.html
new file mode 100644
index 00000000..a12e329a
--- /dev/null
+++ b/docs/checks/BottomAppBar.md.html
@@ -0,0 +1,170 @@
+
+(#) BottomAppBar Problems
+
+!!! ERROR: BottomAppBar Problems
+ This is an error.
+
+Id
+: `BottomAppBar`
+Summary
+: BottomAppBar Problems
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.2.0 (September 2018)
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/BottomAppBarDetector.kt)
+Tests
+: [Source Code](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/BottomAppBarDetectorTest.kt)
+
+The `BottomAppBar` widget must be placed within a `CoordinatorLayout`.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/wrong1.xml:9:Error: This BottomAppBar must be wrapped in a
+CoordinatorLayout (android.support.design.widget.CoordinatorLayout)
+[BottomAppBar]
+ <android.support.design.bottomappbar.BottomAppBar
+ ------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`res/layout/ok.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<androidx.coordinatorlayout.widget.CoordinatorLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="#eeeeee">
+
+ <com.google.android.material.bottomappbar.BottomAppBar
+ android:id="@+id/bottom_app_bar"
+ style="@style/Widget.MaterialComponents.BottomAppBar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom"
+ app:navigationIcon="@drawable/ic_menu_black_24dp"/>
+
+ <com.google.android.material.floatingactionbutton.FloatingActionButton
+ android:id="@+id/fab"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:tint="@android:color/white"
+ app:layout_anchor="@id/bottom_app_bar"
+ app:srcCompat="@drawable/ic_add_black_24dp"
+ tools:ignore="RtlHardcoded"/>
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/layout/wrong1.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="#eeeeee">
+
+ <com.google.android.material.bottomappbar.BottomAppBar
+ android:id="@+id/bottom_app_bar"
+ style="@style/Widget.MaterialComponents.BottomAppBar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom"
+ app:navigationIcon="@drawable/ic_menu_black_24dp"/>
+
+</LinearLayout>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/layout/wrong2.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+ <com.google.android.material.bottomappbar.BottomAppBar
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/bottom_app_bar"
+ style="@style/Widget.MaterialComponents.BottomAppBar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom"
+app:navigationIcon="@drawable/ic_menu_black_24dp"/>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/BottomAppBarDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `BottomAppBarDetector.testBasic`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="BottomAppBar"` on
+ the problematic XML element (or one of its enclosing elements). You
+ may also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <android.support.design.bottomappbar.BottomAppBar xmlns:tools="http://schemas.android.com/tools"
+ tools:ignore="BottomAppBar" ...>
+ ...
+ </android.support.design.bottomappbar.BottomAppBar>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="BottomAppBar" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'BottomAppBar'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore BottomAppBar ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/BrokenIterator.md.html b/docs/checks/BrokenIterator.md.html
new file mode 100644
index 00000000..2f49c1ac
--- /dev/null
+++ b/docs/checks/BrokenIterator.md.html
@@ -0,0 +1,257 @@
+
+(#) Broken Iterator
+
+!!! WARNING: Broken Iterator
+ This is a warning.
+
+Id
+: `BrokenIterator`
+Summary
+: Broken Iterator
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.6.0 (February 2020)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/reference/java/util/LinkedHashMap
+Implementation
+: [Source Code](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/IteratorDetector.kt)
+Tests
+: [Source Code](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/IteratorDetectorTest.kt)
+
+**For LinkedHashMap:**
+
+The spliterators returned by `LinkedHashMap` in Android Nougat (API
+levels 24 and 25) use the wrong order (inconsistent with the iterators,
+which use the correct order), despite reporting `Spliterator.ORDERED`.
+You may use the following code fragments to obtain a correctly ordered
+`Spliterator` on API level 24 and 25:
+
+For a Collection view `c = lhm.entrySet()`, `c = lhm.keySet()` or `c =
+lhm.values()`, use `java.util.Spliterators.spliterator(c,
+c.spliterator().characteristics())` instead of `c.spliterator()`.
+
+Instead of `c.stream()` or `c.parallelStream()`, use
+`java.util.stream.StreamSupport.stream(spliterator, false)` to construct
+a (nonparallel) Stream from such a `Spliterator`.
+
+**For Vector:**
+
+The `listIterator()` returned for a `Vector` has a broken `add()`
+implementation on Android N (API level 24). Consider switching to
+`ArrayList` and if necessary adding synchronization.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/LinkedHashmapTest.java:34:Warning:
+LinkedHashMap#spliterator was broken in API 24 and 25. Workaround: Use
+java.util.Spliterators.spliterator(c2a,
+c2a.spliterator().characteristics()) [BrokenIterator]
+ Spliterator<String> keys2a = c2a.spliterator(); // Warn
+ -----------------
+src/test/pkg/LinkedHashmapTest.java:35:Warning:
+LinkedHashMap#spliterator was broken in API 24 and 25. Workaround: Use
+java.util.Spliterators.spliterator(c2b,
+c2b.spliterator().characteristics()) [BrokenIterator]
+ Spliterator<String> keys2b = c2b.spliterator(); // Warn
+ -----------------
+src/test/pkg/LinkedHashmapTest.java:36:Warning:
+LinkedHashMap#spliterator was broken in API 24 and 25. Workaround: Use
+java.util.Spliterators.spliterator(c2c,
+c2c.spliterator().characteristics()) [BrokenIterator]
+ Spliterator<Entry<String, String>> keys2c = c2c.spliterator(); // Warn
+ -----------------
+src/test/pkg/LinkedHashmapTest.java:39:Warning: LinkedHashMap#stream was
+broken in API 24 and 25. Workaround: Use
+java.util.stream.StreamSupport.stream(spliterator, false)
+[BrokenIterator]
+ Stream<String> stream1 = c2a.stream(); // Warn
+ ------------
+src/test/pkg/LinkedHashmapTest.java:40:Warning:
+LinkedHashMap#spliterator was broken in API 24 and 25. Workaround: Use
+java.util.Spliterators.spliterator(c2a,
+c2a.spliterator().characteristics()) [BrokenIterator]
+ StreamSupport.stream(c2a.spliterator(), false); // Warn
+ -----------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/test/pkg/LinkedHashmapTest.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.os.Build;
+import androidx.annotation.RequiresApi;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+public class LinkedHashmapTest {
+ @RequiresApi(api = Build.VERSION_CODES.N)
+ public void test() {
+ Map map1 = new HashMap<>();
+ Set c1a = map1.keySet();
+ Collection c1b = map1.values();
+ Set> c1c = map1.entrySet();
+ Spliterator keys1a = c1a.spliterator();
+ Spliterator keys1b = c1b.spliterator();
+ Spliterator> keys1c = c1c.spliterator(); // OK (not a LinkedHashMap)
+ Spliterator keys1 = Spliterators.spliterator(c1a, c1a.spliterator().characteristics());// OK
+
+ Map map2 = new LinkedHashMap<>();
+ Set c2a = map2.keySet();
+ Collection c2b = map2.values();
+ Set> c2c = map2.entrySet();
+
+ Spliterator keys2a = c2a.spliterator(); // Warn
+ Spliterator keys2b = c2b.spliterator(); // Warn
+ Spliterator> keys2c = c2c.spliterator(); // Warn
+ Spliterator keys2 = Spliterators.spliterator(c2a, c2a.spliterator().characteristics());// OK
+
+ Stream stream1 = c2a.stream(); // Warn
+ StreamSupport.stream(c2a.spliterator(), false); // Warn
+
+ Spliterators.spliterator(c2a, c2a.spliterator().characteristics()); // OK
+ StreamSupport.stream(keys2, false); // OK
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/kt/LinkedHashmapTest.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg.kt
+
+import android.os.Build
+import androidx.annotation.RequiresApi
+import java.util.*
+import java.util.stream.StreamSupport
+
+class LinkedHashmapTest {
+ @RequiresApi(api = Build.VERSION_CODES.N)
+ fun test() {
+ val map1 = HashMap()
+ val c1a = map1.keys
+ val c1b = map1.values
+ val c1c = map1.entries
+ val keys1a = c1a.spliterator()
+ val keys1b = c1b.spliterator()
+ val keys1c = c1c.spliterator() // OK (not a LinkedHashMap)
+ val keys1 = Spliterators.spliterator(c1a, c1a.spliterator().characteristics())// OK
+
+ val map2 = LinkedHashMap()
+ val c2a = map2.keys
+ val c2b = map2.values
+ val c2c = map2.entries
+
+ val keys2a = c2a.spliterator() // Warn
+ val keys2b = c2b.spliterator() // Warn
+ val keys2c = c2c.spliterator() // Warn
+ val keys2 = Spliterators.spliterator(c2a, c2a.spliterator().characteristics())// OK
+
+ val stream1 = c2a.stream() // Warn
+ StreamSupport.stream(c2a.spliterator(), false) // Warn
+
+ Spliterators.spliterator(c2a, c2a.spliterator().characteristics()) // OK
+ StreamSupport.stream(keys2, false) // OK
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/IteratorDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `IteratorDetector.testLinkedHashMap`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("BrokenIterator")
+ fun method() {
+ add(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("BrokenIterator")
+ void method() {
+ add(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection BrokenIterator
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="BrokenIterator" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'BrokenIterator'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore BrokenIterator ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/BuildListAdds.md.html b/docs/checks/BuildListAdds.md.html
new file mode 100644
index 00000000..d6c87220
--- /dev/null
+++ b/docs/checks/BuildListAdds.md.html
@@ -0,0 +1,129 @@
+
+(#) Missing `add` call in `buildList`
+
+!!! WARNING: Missing `add` call in `buildList`
+ This is a warning.
+
+Id
+: `BuildListAdds`
+Summary
+: Missing `add` call in `buildList`
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 8.4.0 (April 2024)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/BuildListDetector.kt)
+Tests
+: [Source Code](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/BuildListDetectorTest.kt)
+
+The `buildList { }` standard library function is a convenient way to
+build lists, but you need to actually call `add` on the items.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/Cubic.kt:4:Warning: No add calls within buildList lambda; this is
+usually a mistake [BuildListAdds]
+ return buildList { // ERROR
+ ---------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/Cubic.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+class Cubic(id: Int)
+val _morphMatch = listOf(1)
+fun asCubics_broken(progress: Float): List {
+ return buildList { // ERROR
+ for (i in _morphMatch.indices) {
+ Cubic(i) // ERROR: Should have been wrapped in an add call.
+ }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/BuildListDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("BuildListAdds")
+ fun method() {
+ buildList(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("BuildListAdds")
+ void method() {
+ buildList(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection BuildListAdds
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="BuildListAdds" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'BuildListAdds'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore BuildListAdds ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ButtonCase.md.html b/docs/checks/ButtonCase.md.html
new file mode 100644
index 00000000..6c03916a
--- /dev/null
+++ b/docs/checks/ButtonCase.md.html
@@ -0,0 +1,328 @@
+
+(#) Cancel/OK dialog button capitalization
+
+!!! WARNING: Cancel/OK dialog button capitalization
+ This is a warning.
+
+Id
+: `ButtonCase`
+Summary
+: Cancel/OK dialog button capitalization
+Severity
+: Warning
+Category
+: Usability
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/ButtonDetector.java)
+Tests
+: [Source Code](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/ButtonDetectorTest.java)
+Copyright Year
+: 2012
+
+The standard capitalization for OK/Cancel dialogs is "OK" and "Cancel".
+To ensure that your dialogs use the standard strings, you can use the
+resource strings @android:string/ok and @android:string/cancel.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/values/buttonbar-values.xml:9:Warning: The standard Android way to
+capitalize Ok is "OK" (tip: use @android:string/ok instead)
+[ButtonCase]
+ <string name="resume2"> Ok </string>
+ --
+res/values/buttonbar-values.xml:10:Warning: The standard Android way to
+capitalize CANCEL is "Cancel" (tip: use @android:string/cancel instead)
+[ButtonCase]
+ <string name="giveup2">"CANCEL"</string>
+ --------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`res/layout/buttonbar.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <!-- Hardcoded strings, wrong order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="OK" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Cancel" />
+ </LinearLayout>
+
+ <!-- Hardcoded strings, right order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Cancel" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="OK" />
+ </LinearLayout>
+
+ <!-- @android:string resources, wrong order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@android:string/ok" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@android:string/cancel" />
+ </LinearLayout>
+
+ <!-- @android:string resources, right order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@android:string/cancel" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@android:string/ok" />
+ </LinearLayout>
+
+ <!-- @string/ok/cancel resources, right order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/cancel" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/ok" />
+ </LinearLayout>
+
+ <!-- @string/ok/cancel resources, wrong order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/ok" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/cancel" />
+ </LinearLayout>
+
+ <!-- Random name resources, right order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/giveup" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/resume" />
+ </LinearLayout>
+
+ <!-- Random name resources, wrong order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/resume" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/giveup" />
+ </LinearLayout>
+
+ <!-- Random name resources with varying case, wrong order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/resume2" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/giveup2" />
+ </LinearLayout>
+
+ <!-- Resources with only one of OK and Cancel, wrong order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/ok" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/abort" />
+ </LinearLayout>
+
+ <!-- Resources with only one of OK and Cancel, wrong order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content" android:background="?android:attr/selectableItemBackground"
+ android:layout_height="wrap_content"
+ android:text="@string/send" />
+
+ <Button
+ android:layout_width="wrap_content" android:background="?android:attr/selectableItemBackground"
+ android:layout_height="wrap_content"
+ android:text="@string/cancel" />
+ </LinearLayout>
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/goback" />
+
+</LinearLayout>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values/buttonbar-values.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <string name="button"> Button </string>
+ <string name="ok"> OK </string>
+ <string name="cancel"> Cancel </string>
+ <string name="resume"> OK </string>
+ <string name="giveup"> Cancel </string>
+ <string name="resume2"> Ok </string>
+ <string name="giveup2">"CANCEL"</string>
+ <string name="send"> Send </string>
+ <string name="abort">Abort</string>
+ <string name="goback">'Back'</string>
+
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ButtonDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ButtonDetector.testCase`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="ButtonCase"` on the
+ problematic XML element (or one of its enclosing elements). You may
+ also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <resources xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <Button tools:ignore="ButtonCase" .../>
+ ...
+ </resources>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ButtonCase" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ButtonCase'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ButtonCase ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ButtonOrder.md.html b/docs/checks/ButtonOrder.md.html
new file mode 100644
index 00000000..30b185f7
--- /dev/null
+++ b/docs/checks/ButtonOrder.md.html
@@ -0,0 +1,357 @@
+
+(#) Button order
+
+!!! WARNING: Button order
+ This is a warning.
+
+Id
+: `ButtonOrder`
+Summary
+: Button order
+Severity
+: Warning
+Category
+: Usability
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://d.android.com/r/studio-ui/designer/material/dialogs
+Implementation
+: [Source Code](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/ButtonDetector.java)
+Tests
+: [Source Code](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/ButtonDetectorTest.java)
+Copyright Year
+: 2012
+
+According to the Android Design Guide,
+
+"Action buttons are typically Cancel and/or OK, with OK indicating the
+preferred or most likely action. However, if the options consist of
+specific actions such as Close or Wait rather than a confirmation or
+cancellation of the action described in the content, then all the
+buttons should be active verbs. As a rule, the dismissive action of a
+dialog is always on the left whereas the affirmative actions are on the
+right."
+
+This check looks for button bars and buttons which look like cancel
+buttons, and makes sure that these are on the left.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/buttonbar.xml:12:Warning: OK button should be on the right
+(was "OK | Cancel", should be "Cancel | OK") [ButtonOrder]
+ <Button
+ ------
+res/layout/buttonbar.xml:44:Warning: OK button should be on the right
+(was "OK | Cancel", should be "Cancel | OK") [ButtonOrder]
+ <Button
+ ------
+res/layout/buttonbar.xml:92:Warning: OK button should be on the right
+(was "OK | Cancel", should be "Cancel | OK") [ButtonOrder]
+ <Button
+ ------
+res/layout/buttonbar.xml:124:Warning: OK button should be on the right
+(was "OK | Cancel", should be "Cancel | OK") [ButtonOrder]
+ <Button
+ ------
+res/layout/buttonbar.xml:140:Warning: OK button should be on the right
+(was "Ok | CANCEL", should be "CANCEL | Ok") [ButtonOrder]
+ <Button
+ ------
+res/layout/buttonbar.xml:156:Warning: OK button should be on the right
+(was "OK | Abort", should be "Abort | OK") [ButtonOrder]
+ <Button
+ ------
+res/layout/buttonbar.xml:177:Warning: Cancel button should be on the
+left (was "Send | Cancel", should be "Cancel | Send") [ButtonOrder]
+ <Button
+ ------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`res/layout/buttonbar.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <!-- Hardcoded strings, wrong order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="OK" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Cancel" />
+ </LinearLayout>
+
+ <!-- Hardcoded strings, right order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Cancel" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="OK" />
+ </LinearLayout>
+
+ <!-- @android:string resources, wrong order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@android:string/ok" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@android:string/cancel" />
+ </LinearLayout>
+
+ <!-- @android:string resources, right order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@android:string/cancel" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@android:string/ok" />
+ </LinearLayout>
+
+ <!-- @string/ok/cancel resources, right order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/cancel" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/ok" />
+ </LinearLayout>
+
+ <!-- @string/ok/cancel resources, wrong order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/ok" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/cancel" />
+ </LinearLayout>
+
+ <!-- Random name resources, right order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/giveup" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/resume" />
+ </LinearLayout>
+
+ <!-- Random name resources, wrong order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/resume" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/giveup" />
+ </LinearLayout>
+
+ <!-- Random name resources with varying case, wrong order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/resume2" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/giveup2" />
+ </LinearLayout>
+
+ <!-- Resources with only one of OK and Cancel, wrong order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/ok" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/abort" />
+ </LinearLayout>
+
+ <!-- Resources with only one of OK and Cancel, wrong order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content" android:background="?android:attr/selectableItemBackground"
+ android:layout_height="wrap_content"
+ android:text="@string/send" />
+
+ <Button
+ android:layout_width="wrap_content" android:background="?android:attr/selectableItemBackground"
+ android:layout_height="wrap_content"
+ android:text="@string/cancel" />
+ </LinearLayout>
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/goback" />
+
+</LinearLayout>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values/buttonbar-values.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <string name="button"> Button </string>
+ <string name="ok"> OK </string>
+ <string name="cancel"> Cancel </string>
+ <string name="resume"> OK </string>
+ <string name="giveup"> Cancel </string>
+ <string name="resume2"> Ok </string>
+ <string name="giveup2">"CANCEL"</string>
+ <string name="send"> Send </string>
+ <string name="abort">Abort</string>
+ <string name="goback">'Back'</string>
+
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ButtonDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ButtonDetector.testButtonOrder`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="ButtonOrder"` on the
+ problematic XML element (or one of its enclosing elements). You may
+ also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <resources xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <Button tools:ignore="ButtonOrder" .../>
+ ...
+ </resources>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ButtonOrder" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ButtonOrder'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ButtonOrder ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ButtonStyle.md.html b/docs/checks/ButtonStyle.md.html
new file mode 100644
index 00000000..30819617
--- /dev/null
+++ b/docs/checks/ButtonStyle.md.html
@@ -0,0 +1,519 @@
+
+(#) Button should be borderless
+
+!!! WARNING: Button should be borderless
+ This is a warning.
+
+Id
+: `ButtonStyle`
+Summary
+: Button should be borderless
+Severity
+: Warning
+Category
+: Usability
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://d.android.com/r/studio-ui/designer/material/dialogs
+Implementation
+: [Source Code](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/ButtonDetector.java)
+Tests
+: [Source Code](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/ButtonDetectorTest.java)
+Copyright Year
+: 2012
+
+Button bars typically use a borderless style for the buttons. Set the
+`style="?android:attr/buttonBarButtonStyle"` attribute on each of the
+buttons, and set `style="?android:attr/buttonBarStyle"` on the parent
+layout.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/buttonbar.xml:12:Warning: Buttons in button bars should be
+borderless; use style="?android:attr/buttonBarButtonStyle" (and
+?android:attr/buttonBarStyle on the parent) [ButtonStyle]
+ <Button
+ ------
+res/layout/buttonbar.xml:17:Warning: Buttons in button bars should be
+borderless; use style="?android:attr/buttonBarButtonStyle" (and
+?android:attr/buttonBarStyle on the parent) [ButtonStyle]
+ <Button
+ ------
+res/layout/buttonbar.xml:28:Warning: Buttons in button bars should be
+borderless; use style="?android:attr/buttonBarButtonStyle" (and
+?android:attr/buttonBarStyle on the parent) [ButtonStyle]
+ <Button
+ ------
+res/layout/buttonbar.xml:33:Warning: Buttons in button bars should be
+borderless; use style="?android:attr/buttonBarButtonStyle" (and
+?android:attr/buttonBarStyle on the parent) [ButtonStyle]
+ <Button
+ ------
+res/layout/buttonbar.xml:44:Warning: Buttons in button bars should be
+borderless; use style="?android:attr/buttonBarButtonStyle" (and
+?android:attr/buttonBarStyle on the parent) [ButtonStyle]
+ <Button
+ ------
+res/layout/buttonbar.xml:49:Warning: Buttons in button bars should be
+borderless; use style="?android:attr/buttonBarButtonStyle" (and
+?android:attr/buttonBarStyle on the parent) [ButtonStyle]
+ <Button
+ ------
+res/layout/buttonbar.xml:60:Warning: Buttons in button bars should be
+borderless; use style="?android:attr/buttonBarButtonStyle" (and
+?android:attr/buttonBarStyle on the parent) [ButtonStyle]
+ <Button
+ ------
+res/layout/buttonbar.xml:65:Warning: Buttons in button bars should be
+borderless; use style="?android:attr/buttonBarButtonStyle" (and
+?android:attr/buttonBarStyle on the parent) [ButtonStyle]
+ <Button
+ ------
+res/layout/buttonbar.xml:76:Warning: Buttons in button bars should be
+borderless; use style="?android:attr/buttonBarButtonStyle" (and
+?android:attr/buttonBarStyle on the parent) [ButtonStyle]
+ <Button
+ ------
+res/layout/buttonbar.xml:81:Warning: Buttons in button bars should be
+borderless; use style="?android:attr/buttonBarButtonStyle" (and
+?android:attr/buttonBarStyle on the parent) [ButtonStyle]
+ <Button
+ ------
+res/layout/buttonbar.xml:92:Warning: Buttons in button bars should be
+borderless; use style="?android:attr/buttonBarButtonStyle" (and
+?android:attr/buttonBarStyle on the parent) [ButtonStyle]
+ <Button
+ ------
+res/layout/buttonbar.xml:97:Warning: Buttons in button bars should be
+borderless; use style="?android:attr/buttonBarButtonStyle" (and
+?android:attr/buttonBarStyle on the parent) [ButtonStyle]
+ <Button
+ ------
+res/layout/buttonbar.xml:108:Warning: Buttons in button bars should be
+borderless; use style="?android:attr/buttonBarButtonStyle" (and
+?android:attr/buttonBarStyle on the parent) [ButtonStyle]
+ <Button
+ ------
+res/layout/buttonbar.xml:113:Warning: Buttons in button bars should be
+borderless; use style="?android:attr/buttonBarButtonStyle" (and
+?android:attr/buttonBarStyle on the parent) [ButtonStyle]
+ <Button
+ ------
+res/layout/buttonbar.xml:124:Warning: Buttons in button bars should be
+borderless; use style="?android:attr/buttonBarButtonStyle" (and
+?android:attr/buttonBarStyle on the parent) [ButtonStyle]
+ <Button
+ ------
+res/layout/buttonbar.xml:129:Warning: Buttons in button bars should be
+borderless; use style="?android:attr/buttonBarButtonStyle" (and
+?android:attr/buttonBarStyle on the parent) [ButtonStyle]
+ <Button
+ ------
+res/layout/buttonbar.xml:140:Warning: Buttons in button bars should be
+borderless; use style="?android:attr/buttonBarButtonStyle" (and
+?android:attr/buttonBarStyle on the parent) [ButtonStyle]
+ <Button
+ ------
+res/layout/buttonbar.xml:145:Warning: Buttons in button bars should be
+borderless; use style="?android:attr/buttonBarButtonStyle" (and
+?android:attr/buttonBarStyle on the parent) [ButtonStyle]
+ <Button
+ ------
+res/layout/buttonbar.xml:156:Warning: Buttons in button bars should be
+borderless; use style="?android:attr/buttonBarButtonStyle" (and
+?android:attr/buttonBarStyle on the parent) [ButtonStyle]
+ <Button
+ ------
+res/layout/buttonbar.xml:161:Warning: Buttons in button bars should be
+borderless; use style="?android:attr/buttonBarButtonStyle" (and
+?android:attr/buttonBarStyle on the parent) [ButtonStyle]
+ <Button
+ ------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`res/layout/buttonbar.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <!-- Hardcoded strings, wrong order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="OK" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Cancel" />
+ </LinearLayout>
+
+ <!-- Hardcoded strings, right order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Cancel" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="OK" />
+ </LinearLayout>
+
+ <!-- @android:string resources, wrong order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@android:string/ok" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@android:string/cancel" />
+ </LinearLayout>
+
+ <!-- @android:string resources, right order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@android:string/cancel" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@android:string/ok" />
+ </LinearLayout>
+
+ <!-- @string/ok/cancel resources, right order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/cancel" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/ok" />
+ </LinearLayout>
+
+ <!-- @string/ok/cancel resources, wrong order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/ok" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/cancel" />
+ </LinearLayout>
+
+ <!-- Random name resources, right order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/giveup" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/resume" />
+ </LinearLayout>
+
+ <!-- Random name resources, wrong order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/resume" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/giveup" />
+ </LinearLayout>
+
+ <!-- Random name resources with varying case, wrong order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/resume2" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/giveup2" />
+ </LinearLayout>
+
+ <!-- Resources with only one of OK and Cancel, wrong order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/ok" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/abort" />
+ </LinearLayout>
+
+ <!-- Resources with only one of OK and Cancel, wrong order -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:layout_width="wrap_content" android:background="?android:attr/selectableItemBackground"
+ android:layout_height="wrap_content"
+ android:text="@string/send" />
+
+ <Button
+ android:layout_width="wrap_content" android:background="?android:attr/selectableItemBackground"
+ android:layout_height="wrap_content"
+ android:text="@string/cancel" />
+ </LinearLayout>
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/goback" />
+
+</LinearLayout>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/layout/buttonbar2.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" >
+
+ <ProgressBar
+ android:id="@+id/loading_progress"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentTop="true"
+ android:layout_marginBottom="60dip"
+ android:layout_marginLeft="40dip"
+ android:layout_marginTop="40dip"
+ android:max="10000" />
+
+ <TextView
+ android:id="@+id/text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:layout_alignWithParentIfMissing="true"
+ android:layout_marginBottom="60dip"
+ android:layout_marginLeft="40dip"
+ android:layout_marginTop="40dip"
+ android:layout_toRightOf="@id/loading_progress"
+ android:ellipsize="end"
+ android:maxLines="3"
+ android:paddingRight="120dip"
+ android:text="@string/creating_instant_mix"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <Button
+ android:id="@+id/cancel"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentLeft="true"
+ android:layout_alignRight="@id/text"
+ android:layout_below="@id/text"
+ android:background="@null"
+ android:text="@string/cancel" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_above="@id/cancel"
+ android:layout_alignLeft="@id/cancel"
+ android:layout_alignRight="@id/cancel"
+ android:scaleType="fitXY"
+ android:src="http://github.com/@drawable/menu_list_divider" />
+
+</RelativeLayout>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/layout/buttonbar3.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical" >
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:text="@string/weekpicker_title"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="#ffffff"
+ android:padding="6dip" >
+
+ <Button
+ android:id="@+id/set"
+ android:layout_width="120dip"
+ android:layout_height="wrap_content"
+ android:layout_alignParentLeft="true"
+ android:text="@string/weekpicker_set" />
+
+ <Button
+ android:id="@+id/cancel"
+ android:layout_width="120dip"
+ android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
+ android:text="@string/cancel" />
+ </RelativeLayout>
+
+</LinearLayout>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values/buttonbar-values.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <string name="button"> Button </string>
+ <string name="ok"> OK </string>
+ <string name="cancel"> Cancel </string>
+ <string name="resume"> OK </string>
+ <string name="giveup"> Cancel </string>
+ <string name="resume2"> Ok </string>
+ <string name="giveup2">"CANCEL"</string>
+ <string name="send"> Send </string>
+ <string name="abort">Abort</string>
+ <string name="goback">'Back'</string>
+
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ButtonDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ButtonDetector.testButtonStyle`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="ButtonStyle"` on the
+ problematic XML element (or one of its enclosing elements). You may
+ also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <resources xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <Button tools:ignore="ButtonStyle" .../>
+ ...
+ </resources>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ButtonStyle" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ButtonStyle'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ButtonStyle ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ByteOrderMark.md.html b/docs/checks/ByteOrderMark.md.html
new file mode 100644
index 00000000..c795ba6f
--- /dev/null
+++ b/docs/checks/ByteOrderMark.md.html
@@ -0,0 +1,188 @@
+
+(#) Byte order mark inside files
+
+!!! ERROR: Byte order mark inside files
+ This is an error.
+
+Id
+: `ByteOrderMark`
+Summary
+: Byte order mark inside files
+Severity
+: Error
+Category
+: Internationalization
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Gradle build files, Kotlin and Java files, manifest files, property files, resource files and shrinking configuration files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://en.wikipedia.org/wiki/Byte_order_mark
+Implementation
+: [Source Code](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/ByteOrderMarkDetector.kt)
+Tests
+: [Source Code](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/ByteOrderMarkDetectorTest.java)
+Copyright Year
+: 2014
+
+Lint will flag any byte-order-mark (BOM) characters it finds in the
+middle of a file. Since we expect files to be encoded with UTF-8 (see
+the EnforceUTF8 issue), the BOM characters are not necessary, and they
+are not handled correctly by all tools. For example, if you have a BOM
+as part of a resource name in one particular translation, that name will
+not be considered identical to the base resource's name and the
+translation will not be used.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:1:Error: Found byte-order-mark in the middle of a
+file [ByteOrderMark]
+<manifest package='foo.bar'>
+ -
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest package='foo.bar'>
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values-zh-rCN/bom.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:tools="http://schemas.android.com/tools">
+ <string name="hanping_chinese_lite_app_name">(Translated name)</string>
+ <string tools:ignore='ByteOrderMark' name="something">testtest2</string>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/raw/bom_allowed.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:tools="http://schemas.android.com/tools">
+ <string name="hanping_chinese_lite_app_name">(Translated name)</string>
+ <string tools:ignore='ByteOrderMark' name="something">testtest2</string>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyTest.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+import android.annotation.SuppressLint;
+public class MyTest {
+ public void test1() {
+ String s = "\uFEFF"; // OK
+ String t = ""; // ERROR
+ }
+ @SuppressLint("ByteOrderMark")
+ public void test2() {
+ String s = ""; //OK/suppressed
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`proguard.cfg`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~proguard linenumbers
+-optimizationpasses 5
+-dontusemixedcaseclassnames
+-dontskipnonpubliclibraryclasses
+-dontpreverify
+-verbose
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ByteOrderMarkDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ByteOrderMarkDetector.testXml`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="ByteOrderMark"` on
+ the problematic XML element (or one of its enclosing elements). You
+ may also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ByteOrderMark")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ByteOrderMark")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ByteOrderMark
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ByteOrderMark" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ByteOrderMark'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ByteOrderMark ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/CanvasSize.md.html b/docs/checks/CanvasSize.md.html
new file mode 100644
index 00000000..6a6ce5c8
--- /dev/null
+++ b/docs/checks/CanvasSize.md.html
@@ -0,0 +1,259 @@
+
+(#) Wrong Canvas Size
+
+!!! WARNING: Wrong Canvas Size
+ This is a warning.
+
+Id
+: `CanvasSize`
+Summary
+: Wrong Canvas Size
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.2.0 (September 2018)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/CanvasSizeDetector.kt)
+Tests
+: [Source Code](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/CanvasSizeDetectorTest.kt)
+
+In a custom view's draw implementation, you should normally call
+`getWidth` and `getHeight` on the custom view itself, not on the
+`canvas` instance.
+
+Canvas width and height are the width and height of the `Canvas`, which
+is not always the same as size of the view.
+
+In the hardware accelerated path the width and height of the canvas
+typically always match that of the `View` because every view goes to its
+own recorded `DisplayList`. But in software rendering there's just one
+canvas that is clipped and transformed as it makes its way through the
+`View` tree, and otherwise remains the same `Canvas` object for every
+View's draw method.
+
+You should only use Canvas state to adjust how much you draw, such as a
+quick-reject for early work avoidance if it's going to be clipped away,
+but not what you draw.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/MyCustomView1.java:27:Warning: Calling Canvas.getWidth() is
+usually wrong; you should be calling getWidth() instead [CanvasSize]
+ int width4 = canvas.getWidth(); // WARN
+ -----------------
+src/test/pkg/MyCustomView1.java:28:Warning: Calling Canvas.getHeight()
+is usually wrong; you should be calling getHeight() instead
+[CanvasSize]
+ int height4 = canvas.getHeight(); // WARN
+ ------------------
+src/test/pkg/MyCustomView1.java:34:Warning: Calling Canvas.getWidth() is
+usually wrong; you should be calling getWidth() instead [CanvasSize]
+ int width4 = canvas.getWidth(); // WARN
+ -----------------
+src/test/pkg/MyCustomView1.java:35:Warning: Calling Canvas.getHeight()
+is usually wrong; you should be calling getHeight() instead
+[CanvasSize]
+ int height4 = canvas.getHeight(); // WARN
+ ------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/test/pkg/MyCustomView1.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.os.Build;
+import android.util.AttributeSet;
+import android.view.View;
+
+@SuppressWarnings({"unused", "ClassNameDiffersFromFileName","MethodMayBeStatic"})
+@SuppressLint("ViewConstructor")
+public class MyCustomView1 extends View {
+
+ public MyCustomView1(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ int width1 = getWidth(); // OK
+ View view = this;
+ int height1 = getHeight(); // OK
+ int width2 = this.getWidth(); // OK
+ int height2 = this.getHeight(); // OK
+ int width3 = view.getWidth(); // OK
+ int height3 = view.getHeight(); // OK
+ int width4 = canvas.getWidth(); // WARN
+ int height4 = canvas.getHeight(); // WARN
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ super.draw(canvas);
+ int width4 = canvas.getWidth(); // WARN
+ int height4 = canvas.getHeight(); // WARN
+ }
+
+ public void someOtherMethod(Canvas canvas) {
+ int width4 = canvas.getWidth(); // OK
+ int height4 = canvas.getHeight(); // OK
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyCustomView2.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.graphics.Canvas
+import android.os.Build
+import android.util.AttributeSet
+import android.view.View
+
+@SuppressLint("ViewConstructor")
+class MyCustomView2(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : View(context, attrs, defStyleAttr, defStyleRes) {
+
+ override fun onDraw(canvas: Canvas) {
+ val view = this
+ val width3 = view.width // OK
+ val height3 = view.height // OK
+ val width4 = canvas.width // WARN
+ val height4 = canvas.height // WARN
+ val width5 = canvas.getWidth() // WARN
+ val height5 = canvas.getHeight() // WARN
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyDrawable.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+
+@SuppressWarnings({"unused", "ClassNameDiffersFromFileName","MethodMayBeStatic", "NullableProblems"})
+public abstract class MyDrawable extends Drawable {
+ @Override
+ public void draw(Canvas canvas) {
+ int width1 = getBounds().width(); // OK
+ int width2 = canvas.getWidth(); // WARN
+ int height2 = canvas.getHeight(); // WARN
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyDrawableKotlin.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+
+import android.graphics.Canvas
+import android.graphics.drawable.Drawable
+
+abstract class MyDrawableKotlin : Drawable() {
+ override fun draw(canvas: Canvas) {
+ val width1 = bounds.width() // OK
+ val width2 = canvas.width // WARN
+ val height2 = canvas.height // WARN
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/CanvasSizeDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `CanvasSizeDetector.testBasic`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("CanvasSize")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("CanvasSize")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection CanvasSize
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="CanvasSize" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'CanvasSize'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore CanvasSize ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/CastingViewContextToActivity.md.html b/docs/checks/CastingViewContextToActivity.md.html
new file mode 100644
index 00000000..3d4c6bee
--- /dev/null
+++ b/docs/checks/CastingViewContextToActivity.md.html
@@ -0,0 +1,149 @@
+
+(#) Unsafe cast of `Context` to `Activity`
+
+!!! ERROR: Unsafe cast of `Context` to `Activity`
+ This is an error.
+
+Id
+: `CastingViewContextToActivity`
+Summary
+: Unsafe cast of `Context` to `Activity`
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.1.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/ViewContextDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/ViewContextDetectorTest.kt)
+Copyright Year
+: 2021
+
+`View.getContext()` is not guaranteed to return an `Activity` and can
+often return a `ContextWrapper` instead resulting in a
+`ClassCastException`. Instead, use
+`UiUtils.getActivityFromView()`.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("CastingViewContextToActivity")
+ fun method() {
+ getContext(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("CastingViewContextToActivity")
+ void method() {
+ getContext(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection CastingViewContextToActivity
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="CastingViewContextToActivity" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'CastingViewContextToActivity'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore CastingViewContextToActivity ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/CheckResult.md.html b/docs/checks/CheckResult.md.html
new file mode 100644
index 00000000..70d6cab3
--- /dev/null
+++ b/docs/checks/CheckResult.md.html
@@ -0,0 +1,135 @@
+
+(#) Ignoring results
+
+!!! WARNING: Ignoring results
+ This is a warning.
+
+Id
+: `CheckResult`
+Summary
+: Ignoring results
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.1.0 (March 2018)
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/CheckResultDetector.kt)
+Tests
+: [Source Code](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/CheckResultDetectorTest.kt)
+
+Some methods have no side effects, and calling them without doing
+something with the result is suspicious.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/test.kt:10:Warning: The result of double is not used
+[CheckResult]
+ score.double()
+ --------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+
+import androidx.annotation.CheckResult
+import java.math.BigDecimal
+
+@CheckResult
+fun BigDecimal.double() = this + this
+
+fun test(score: BigDecimal): BigDecimal {
+ score.double()
+ return score
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/CheckResultDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("CheckResult")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("CheckResult")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection CheckResult
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="CheckResult" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'CheckResult'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore CheckResult ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ChildInNonViewGroup.md.html b/docs/checks/ChildInNonViewGroup.md.html
new file mode 100644
index 00000000..0000e8fe
--- /dev/null
+++ b/docs/checks/ChildInNonViewGroup.md.html
@@ -0,0 +1,115 @@
+
+(#) Only view groups can have children
+
+!!! ERROR: Only view groups can have children
+ This is an error.
+
+Id
+: `ChildInNonViewGroup`
+Summary
+: Only view groups can have children
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 8.7.0 (October 2024)
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/ChildInNonViewGroupDetector.kt)
+Tests
+: [Source Code](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/ChildInNonViewGroupDetectorTest.kt)
+
+Only classes inheriting from `ViewGroup` can have children.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/wrong.xml:9:Error: A ImageView should have no children
+declared in XML [ChildInNonViewGroup]
+ <TextView />
+ --------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/layout/wrong.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+ <TextView />
+ </ImageView>
+
+</LinearLayout>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ChildInNonViewGroupDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ChildInNonViewGroupDetector.test wrong nesting of TextView within ImageView`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="ChildInNonViewGroup"` on the problematic XML element
+ (or one of its enclosing elements). You may also need to add the
+ following namespace declaration on the root element in the XML file
+ if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ChildInNonViewGroup" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ChildInNonViewGroup'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ChildInNonViewGroup ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ChromeOsAbiSupport.md.html b/docs/checks/ChromeOsAbiSupport.md.html
new file mode 100644
index 00000000..6b9e14c0
--- /dev/null
+++ b/docs/checks/ChromeOsAbiSupport.md.html
@@ -0,0 +1,126 @@
+
+(#) Missing ABI Support for ChromeOS
+
+!!! WARNING: Missing ABI Support for ChromeOS
+ This is a warning.
+
+Id
+: `ChromeOsAbiSupport`
+Summary
+: Missing ABI Support for ChromeOS
+Severity
+: Warning
+Category
+: Correctness: Chrome OS
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 8.0.0 (April 2023)
+Affects
+: Gradle build files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/ndk/guides/abis
+Implementation
+: [Source Code](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/GradleDetector.kt)
+Tests
+: [Source Code](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/GradleDetectorTest.kt)
+
+To properly support ChromeOS, your Android application should have an
+x86 and/or x86_64 binary as part of the build configuration. To fix the
+issue, ensure your files are properly optimized for ARM; the binary
+translator will then ensure compatibility with x86. Alternatively, add
+an `abiSplit` for x86 within your `build.gradle` file and create the
+required x86 dependencies.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+build.gradle:10:Warning: Missing x86_64 ABI support for ChromeOS
+[ChromeOsAbiSupport]
+ abiFilters 'arm64-v8a'
+ -----------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`build.gradle`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~groovy linenumbers
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 21
+ buildToolsVersion "21.1.2"
+ defaultConfig {
+ minSdkVersion 15
+ targetSdkVersion 17
+ ndk {
+ abiFilters 'arm64-v8a'
+ }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/GradleDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `GradleDetector.testChromeOSAbiFiltersMissingX8664`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ChromeOsAbiSupport
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ChromeOsAbiSupport" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ChromeOsAbiSupport'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ChromeOsAbiSupport ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ChromeOsOnConfigurationChanged.md.html b/docs/checks/ChromeOsOnConfigurationChanged.md.html
new file mode 100644
index 00000000..6fd2225b
--- /dev/null
+++ b/docs/checks/ChromeOsOnConfigurationChanged.md.html
@@ -0,0 +1,154 @@
+
+(#) Poor performance with APIs inside `onConfigurationChanged()`
+
+!!! WARNING: Poor performance with APIs inside `onConfigurationChanged()`
+ This is a warning.
+
+Id
+: `ChromeOsOnConfigurationChanged`
+Summary
+: Poor performance with APIs inside `onConfigurationChanged()`
+Severity
+: Warning
+Category
+: Correctness: Chrome OS
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 8.0.0 (April 2023)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/ChromeOsSourceDetector.kt)
+Tests
+: [Source Code](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/ChromeOsSourceDetectorTest.kt)
+
+When users resize the Android emulator in Android 13 and Chrome OS, an
+`onConfigurationChanged()` API call occurs. If your
+`onConfigurationChanged()` method contains any code that can cause a
+redraw, your app might take a performance hit on large screens. To fix
+the issue, ensure your `onConfigurationChanged()` method does not
+contain any calls to UI redraw logic for specific elements.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/MainActivity.java:19:Warning: Calling finish() within
+onConfigurationChanged() can lead to redraws
+[ChromeOsOnConfigurationChanged]
+ finish(); // ERROR 1
+ --------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/MainActivity.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+import android.app.Activity;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+
+
+public class MainActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
+ }
+
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ finish(); // ERROR 1
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ChromeOsSourceDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ChromeOsSourceDetector.testFinishFoundInsideOnConfigurationChanged`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ChromeOsOnConfigurationChanged")
+ fun method() {
+ setRequestedOrientation(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ChromeOsOnConfigurationChanged")
+ void method() {
+ setRequestedOrientation(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ChromeOsOnConfigurationChanged
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ChromeOsOnConfigurationChanged" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ChromeOsOnConfigurationChanged'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ChromeOsOnConfigurationChanged ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ClickableViewAccessibility.md.html b/docs/checks/ClickableViewAccessibility.md.html
new file mode 100644
index 00000000..00d5f51f
--- /dev/null
+++ b/docs/checks/ClickableViewAccessibility.md.html
@@ -0,0 +1,152 @@
+
+(#) Accessibility in Custom Views
+
+!!! WARNING: Accessibility in Custom Views
+ This is a warning.
+
+Id
+: `ClickableViewAccessibility`
+Summary
+: Accessibility in Custom Views
+Severity
+: Warning
+Category
+: Accessibility
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/ClickableViewAccessibilityDetector.java)
+Tests
+: [Source Code](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/ClickableViewAccessibilityDetectorTest.java)
+Copyright Year
+: 2014
+
+If a `View` that overrides `onTouchEvent` or uses an `OnTouchListener`
+does not also implement `performClick` and call it when clicks are
+detected, the `View` may not handle accessibility actions properly.
+Logic handling the click actions should ideally be placed in
+`View#performClick` as some accessibility services invoke `performClick`
+when a click action should occur.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/ClickableViewAccessibilityTest.java:15:Warning: Custom view
+ViewOverridesOnTouchEventButNotPerformClick overrides onTouchEvent but
+not performClick [ClickableViewAccessibility]
+ public boolean onTouchEvent(MotionEvent event) {
+ ------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/ClickableViewAccessibilityTest.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.content.Context;
+import android.view.MotionEvent;
+import android.view.View;
+
+public class ClickableViewAccessibilityTest {
+ // Fails because should also implement performClick.
+ private static class ViewOverridesOnTouchEventButNotPerformClick extends View {
+
+ public ViewOverridesOnTouchEventButNotPerformClick(Context context) {
+ super(context);
+ }
+
+ public boolean onTouchEvent(MotionEvent event) {
+ return false;
+ }
+ }
+
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ClickableViewAccessibilityDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ClickableViewAccessibilityDetector.testWarningWhenViewOverridesOnTouchEventButNotPerformClick`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ClickableViewAccessibility")
+ fun method() {
+ setOnTouchListener(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ClickableViewAccessibility")
+ void method() {
+ setOnTouchListener(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ClickableViewAccessibility
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ClickableViewAccessibility" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ClickableViewAccessibility'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ClickableViewAccessibility ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/CoarseFineLocation.md.html b/docs/checks/CoarseFineLocation.md.html
new file mode 100644
index 00000000..fe66739d
--- /dev/null
+++ b/docs/checks/CoarseFineLocation.md.html
@@ -0,0 +1,110 @@
+
+(#) Cannot use `ACCESS_FINE_LOCATION` without `ACCESS_COARSE_LOCATION`
+
+!!! ERROR: Cannot use `ACCESS_FINE_LOCATION` without `ACCESS_COARSE_LOCATION`
+ This is an error.
+
+Id
+: `CoarseFineLocation`
+Summary
+: Cannot use `ACCESS_FINE_LOCATION` without `ACCESS_COARSE_LOCATION`
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 7.0.0 (July 2021)
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/FineLocationDetector.kt)
+Tests
+: [Source Code](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/FineLocationDetectorTest.kt)
+
+If your app requires access to FINE location, on Android 12 and higher
+you must now request both FINE and COARSE. Users will have the option to
+grant only COARSE location. Ensure your app can work with just COARSE
+location.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:3:Error: If you need access to FINE location, you
+must request both ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION
+[CoarseFineLocation]
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
+ -------------------------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="test.pkg">
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
+ <uses-sdk android:targetSdkVersion="31"/>
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name" >
+ </application>
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/FineLocationDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="CoarseFineLocation"`
+ on the problematic XML element (or one of its enclosing elements).
+ You may also need to add the following namespace declaration on the
+ root element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="CoarseFineLocation" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'CoarseFineLocation'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore CoarseFineLocation ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ColorCasing.md.html b/docs/checks/ColorCasing.md.html
new file mode 100644
index 00000000..1be861d7
--- /dev/null
+++ b/docs/checks/ColorCasing.md.html
@@ -0,0 +1,149 @@
+
+(#) Raw colors should be defined with uppercase letters
+
+!!! WARNING: Raw colors should be defined with uppercase letters
+ This is a warning.
+
+Id
+: `ColorCasing`
+Summary
+: Raw colors should be defined with uppercase letters
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: vanniktech/lint-rules/
+Feedback
+: https://github.com/vanniktech/lint-rules/issues
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [com.vanniktech:lint-rules-android](com_vanniktech_lint-rules-android.md.html)
+Since
+: 0.8.0
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/main/kotlin/com/vanniktech/lintrules/android/ColorCasingDetector.kt)
+Tests
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/test/kotlin/com/vanniktech/lintrules/android/ColorCasingDetectorTest.kt)
+
+Colors should have uppercase letters. #FF0099 is valid while #ff0099
+isn't since the ff should be written in uppercase.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/layout.xml:2:Warning: Should be using uppercase letters
+[ColorCasing]
+ tools:textColor="#fff"/>
+ ----
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/layout/layout.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<TextView xmlns:tools="http://schemas.android.com/tools"
+ tools:textColor="#fff"/>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/test/kotlin/com/vanniktech/lintrules/android/ColorCasingDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ColorCasingDetector.lowercaseColor`.
+To report a problem with this extracted sample, visit
+https://github.com/vanniktech/lint-rules/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.vanniktech:lint-rules-android:0.25.0")
+
+// build.gradle
+lintChecks 'com.vanniktech:lint-rules-android:0.25.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.lint.rules.android)
+
+# libs.versions.toml
+[versions]
+lint-rules-android = "0.25.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+lint-rules-android = {
+ module = "com.vanniktech:lint-rules-android",
+ version.ref = "lint-rules-android"
+}
+```
+
+0.25.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.vanniktech:lint-rules-android](com_vanniktech_lint-rules-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="ColorCasing"` on the
+ problematic XML element (or one of its enclosing elements). You may
+ also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ColorCasing" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ColorCasing'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ColorCasing ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/CommitPrefEdits.md.html b/docs/checks/CommitPrefEdits.md.html
new file mode 100644
index 00000000..205f76c5
--- /dev/null
+++ b/docs/checks/CommitPrefEdits.md.html
@@ -0,0 +1,209 @@
+
+(#) Missing `commit()` on `SharedPreference` editor
+
+!!! WARNING: Missing `commit()` on `SharedPreference` editor
+ This is a warning.
+
+Id
+: `CommitPrefEdits`
+Summary
+: Missing `commit()` on `SharedPreference` editor
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 2.2.0 (September 2016)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/CleanupDetector.kt)
+Tests
+: [Source Code](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/CleanupDetectorTest.kt)
+
+After calling `edit()` on a `SharedPreference`, you must call `commit()`
+or `apply()` on the editor to save the results.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/SharedPrefsTest.java:54:Warning: SharedPreferences.edit()
+without a corresponding commit() or apply() call [CommitPrefEdits]
+ SharedPreferences.Editor editor = preferences.edit();
+ ------------------
+src/test/pkg/SharedPrefsTest.java:62:Warning: SharedPreferences.edit()
+without a corresponding commit() or apply() call [CommitPrefEdits]
+ SharedPreferences.Editor editor = preferences.edit();
+ ------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/SharedPrefsTest.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.widget.Toast;
+import android.content.SharedPreferences; import android.content.SharedPreferences.Editor;
+import android.preference.PreferenceManager;
+@SuppressWarnings({"ClassNameDiffersFromFileName", "AccessStaticViaInstance", "MethodMayBeStatic"}) public class SharedPrefsTest extends Activity {
+ // OK 1
+ public void onCreate1(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
+ SharedPreferences.Editor editor = preferences.edit();
+ editor.putString("foo", "bar");
+ editor.putInt("bar", 42);
+ editor.commit();
+ }
+
+ // OK 2
+ public void onCreate2(Bundle savedInstanceState, boolean apply) {
+ super.onCreate(savedInstanceState);
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
+ SharedPreferences.Editor editor = preferences.edit();
+ editor.putString("foo", "bar");
+ editor.putInt("bar", 42);
+ if (apply) {
+ editor.apply();
+ }
+ }
+
+ // OK 3
+ public boolean test1(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
+ SharedPreferences.Editor editor = preferences.edit();
+ editor.putString("foo", "bar");
+ editor.putInt("bar", 42);
+ editor.apply(); return true;
+ }
+
+ // Not a bug
+ public void test(Foo foo) {
+ Bar bar1 = foo.edit();
+ Bar bar2 = Foo.edit();
+ Bar bar3 = edit();
+
+
+ }
+
+ // Bug
+ public void bug1(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
+ SharedPreferences.Editor editor = preferences.edit();
+ editor.putString("foo", "bar");
+ editor.putInt("bar", 42);
+ }
+
+ // Constructor test
+ public SharedPrefsTest(Context context) {
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
+ SharedPreferences.Editor editor = preferences.edit();
+ editor.putString("foo", "bar");
+ }
+
+ private Bar edit() {
+ return null;
+ }
+
+ private static class Foo {
+ static Bar edit() { return null; }
+ }
+
+ private static class Bar {
+
+ }
+ }
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/CleanupDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `CleanupDetector.testSharedPrefs`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("CommitPrefEdits")
+ fun method() {
+ beginTransaction(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("CommitPrefEdits")
+ void method() {
+ beginTransaction(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection CommitPrefEdits
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="CommitPrefEdits" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'CommitPrefEdits'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore CommitPrefEdits ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/CommitTransaction.md.html b/docs/checks/CommitTransaction.md.html
new file mode 100644
index 00000000..5f0912c2
--- /dev/null
+++ b/docs/checks/CommitTransaction.md.html
@@ -0,0 +1,284 @@
+
+(#) Missing `commit()` calls
+
+!!! WARNING: Missing `commit()` calls
+ This is a warning.
+
+Id
+: `CommitTransaction`
+Summary
+: Missing `commit()` calls
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/CleanupDetector.kt)
+Tests
+: [Source Code](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/CleanupDetectorTest.kt)
+Copyright Year
+: 2012
+
+After creating a `FragmentTransaction`, you typically need to commit it
+as well.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/CommitTest.java:25:Warning: This transaction should be
+completed with a commit() call [CommitTransaction]
+ getFragmentManager().beginTransaction(); // ERROR 1
+ ----------------
+src/test/pkg/CommitTest.java:30:Warning: This transaction should be
+completed with a commit() call [CommitTransaction]
+ FragmentTransaction transaction2 = getFragmentManager().beginTransaction(); // ERROR 2
+ ----------------
+src/test/pkg/CommitTest.java:39:Warning: This transaction should be
+completed with a commit() call [CommitTransaction]
+ getFragmentManager().beginTransaction(); // ERROR 3
+ ----------------
+src/test/pkg/CommitTest.java:65:Warning: This transaction should be
+completed with a commit() call [CommitTransaction]
+ getSupportFragmentManager().beginTransaction(); // ERROR 4
+ ----------------
+src/test/pkg/CommitTest.java:123:Warning: This transaction should be
+completed with a commit() call [CommitTransaction]
+ transaction = getFragmentManager().beginTransaction(); // ERROR 5
+ ----------------
+src/test/pkg/CommitTest.java:132:Warning: This transaction should be
+completed with a commit() call [CommitTransaction]
+ transaction = getFragmentManager().beginTransaction(); // ERROR 6
+ ----------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/CommitTest.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.app.FragmentTransaction;
+
+@SuppressWarnings({"unused", "ClassNameDiffersFromFileName", "ConstantConditions", "UnusedAssignment", "MethodMayBeStatic"})
+public class CommitTest extends Activity {
+ public void ok1() {
+ getFragmentManager().beginTransaction().commit(); // OK 1
+ }
+
+ public void ok2() {
+ FragmentTransaction transaction = getFragmentManager().beginTransaction(); // OK 2
+ transaction.commit();
+ }
+
+ public void ok3() {
+ FragmentTransaction transaction = getFragmentManager().beginTransaction(); // OK 3
+ transaction.commitAllowingStateLoss();
+ }
+
+ public void error1() {
+ getFragmentManager().beginTransaction(); // ERROR 1
+ }
+
+ public void error2() {
+ FragmentTransaction transaction1 = getFragmentManager().beginTransaction(); // OK
+ FragmentTransaction transaction2 = getFragmentManager().beginTransaction(); // ERROR 2
+ transaction1.commit();
+ }
+
+ public void error3_public() {
+ error3();
+ }
+
+ private void error3() {
+ getFragmentManager().beginTransaction(); // ERROR 3
+ }
+
+ public void ok4(FragmentManager manager, String tag) {
+ FragmentTransaction ft = manager.beginTransaction(); // OK 4
+ ft.add(null, tag);
+ ft.commit();
+ }
+
+ // Support library
+
+ private androidx.fragment.app.FragmentManager getSupportFragmentManager() {
+ return null;
+ }
+
+ public void ok5() {
+ getSupportFragmentManager().beginTransaction().commit(); // OK 5
+ }
+
+ public void ok6(androidx.fragment.app.FragmentManager manager, String tag) {
+ androidx.fragment.app.FragmentTransaction ft = manager.beginTransaction(); // OK 6
+ ft.add(null, tag);
+ ft.commit();
+ }
+
+ public void error4() {
+ getSupportFragmentManager().beginTransaction(); // ERROR 4
+ }
+
+ androidx.fragment.app.Fragment mFragment1 = null;
+ Fragment mFragment2 = null;
+
+ public void ok7() {
+ getSupportFragmentManager().beginTransaction().add(android.R.id.content, mFragment1).commit(); // OK 7
+ }
+
+ public void ok8() {
+ getFragmentManager().beginTransaction().add(android.R.id.content, mFragment2).commit(); // OK 8
+ }
+
+ public void ok10() {
+ // Test chaining
+ FragmentManager fragmentManager = getFragmentManager();
+ fragmentManager.beginTransaction().addToBackStack("test").attach(mFragment2).detach(mFragment2) // OK 10
+ .disallowAddToBackStack().hide(mFragment2).setBreadCrumbShortTitle("test")
+ .show(mFragment2).setCustomAnimations(0, 0).commit();
+ }
+
+ public void ok9() {
+ FragmentManager fragmentManager = getFragmentManager();
+ fragmentManager.beginTransaction().commit(); // OK 9
+ }
+
+ public void ok11() {
+ FragmentTransaction transaction;
+ // Comment in between variable declaration and assignment
+ transaction = getFragmentManager().beginTransaction(); // OK 11
+ transaction.commit();
+ }
+
+ public void ok12() {
+ FragmentTransaction transaction;
+ transaction = (getFragmentManager().beginTransaction()); // OK 12
+ transaction.commit();
+ }
+
+ @SuppressWarnings("UnnecessaryLocalVariable")
+ public void ok13() {
+ FragmentTransaction transaction = getFragmentManager().beginTransaction(); // OK 13
+ FragmentTransaction temp;
+ temp = transaction;
+ temp.commitAllowingStateLoss();
+ }
+
+ @SuppressWarnings("UnnecessaryLocalVariable")
+ public void ok14() {
+ FragmentTransaction transaction = getFragmentManager().beginTransaction(); // OK 14
+ FragmentTransaction temp = transaction;
+ temp.commitAllowingStateLoss();
+ }
+
+ public void error5(FragmentTransaction unrelated) {
+ FragmentTransaction transaction;
+ // Comment in between variable declaration and assignment
+ transaction = getFragmentManager().beginTransaction(); // ERROR 5
+ transaction = unrelated;
+ transaction.commit();
+ }
+
+ public void error6(FragmentTransaction unrelated) {
+ FragmentTransaction transaction;
+ FragmentTransaction transaction2;
+ // Comment in between variable declaration and assignment
+ transaction = getFragmentManager().beginTransaction(); // ERROR 6
+ transaction2 = transaction;
+ transaction2 = unrelated;
+ transaction2.commit();
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/CleanupDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `CleanupDetector.testCommit`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("CommitTransaction")
+ fun method() {
+ beginTransaction(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("CommitTransaction")
+ void method() {
+ beginTransaction(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection CommitTransaction
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="CommitTransaction" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'CommitTransaction'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore CommitTransaction ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ComposableDestinationInComposeScope.md.html b/docs/checks/ComposableDestinationInComposeScope.md.html
new file mode 100644
index 00000000..66433fc6
--- /dev/null
+++ b/docs/checks/ComposableDestinationInComposeScope.md.html
@@ -0,0 +1,183 @@
+
+(#) Building composable destination in compose scope
+
+!!! ERROR: Building composable destination in compose scope
+ This is an error.
+
+Id
+: `ComposableDestinationInComposeScope`
+Summary
+: Building composable destination in compose scope
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Jetpack Navigation Compose
+Identifier
+: androidx.navigation.compose
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.navigation:navigation-compose](androidx_navigation_navigation-compose.md.html)
+Since
+: 2.4.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/navigation/navigation-compose-lint/src/main/java/androidx/navigation/compose/lint/ComposableDestinationInComposeScopeDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/navigation/navigation-compose-lint/src/test/java/androidx/navigation/compose/lint/ComposableDestinationInComposeScopeDetectorTest.kt)
+Copyright Year
+: 2021
+
+Composable destinations should only be constructed directly within a
+NavGraphBuilder scope. Composable destinations cannot be nested, and you
+should use the `navigation` function to create a nested graph instead.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/com/example/test.kt:13:Error: Using composable inside of a compose
+scope [ComposableDestinationInComposeScope]
+ composable("wrong") { }
+ ----------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/com/example/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package com.example
+
+import androidx.compose.runtime.*
+import androidx.navigation.compose.composable
+import androidx.navigation.compose.NavHost
+import androidx.navigation.NavGraphBuilder
+
+@Composable
+fun Test() {
+ NavHost("host") {
+ composable("right") {
+ composable("wrong") { }
+ }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/navigation/navigation-compose-lint/src/test/java/androidx/navigation/compose/lint/ComposableDestinationInComposeScopeDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ComposableDestinationInComposeScopeDetector.nestedComposableBuilders`.
+To report a problem with this extracted sample, contact
+Jetpack Navigation Compose.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.navigation:navigation-compose:2.9.0-rc01")
+
+// build.gradle
+implementation 'androidx.navigation:navigation-compose:2.9.0-rc01'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.navigation.compose)
+
+# libs.versions.toml
+[versions]
+navigation-compose = "2.9.0-rc01"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+navigation-compose = {
+ module = "androidx.navigation:navigation-compose",
+ version.ref = "navigation-compose"
+}
+```
+
+2.9.0-rc01 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.navigation:navigation-compose](androidx_navigation_navigation-compose.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ComposableDestinationInComposeScope")
+ fun method() {
+ composable(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ComposableDestinationInComposeScope")
+ void method() {
+ composable(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ComposableDestinationInComposeScope
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ComposableDestinationInComposeScope" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ComposableDestinationInComposeScope'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ComposableDestinationInComposeScope ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ComposableLambdaParameterNaming.md.html b/docs/checks/ComposableLambdaParameterNaming.md.html
new file mode 100644
index 00000000..7c9466f2
--- /dev/null
+++ b/docs/checks/ComposableLambdaParameterNaming.md.html
@@ -0,0 +1,186 @@
+
+(#) Primary composable lambda parameter not named `content`
+
+!!! WARNING: Primary composable lambda parameter not named `content`
+ This is a warning.
+
+Id
+: `ComposableLambdaParameterNaming`
+Summary
+: Primary composable lambda parameter not named `content`
+Note
+: **This issue is disabled by default**; use `--enable ComposableLambdaParameterNaming`
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Jetpack Compose
+Identifier
+: androidx.compose.runtime
+Feedback
+: https://issuetracker.google.com/issues/new?component=612128
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.compose.runtime:runtime-android](androidx_compose_runtime_runtime-android.md.html)
+Since
+: 1.5.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/ComposableLambdaParameterDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/ComposableLambdaParameterDetectorTest.kt)
+Copyright Year
+: 2020
+
+Composable functions with only one composable lambda parameter should
+use the name `content` for the parameter.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/androidx/compose/ui/foo/test.kt:7:Warning: Composable lambda
+parameter should be named content [ComposableLambdaParameterNaming]
+ fun Button(foo: Int, text: @Composable () -> Unit) {
+ ----
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/androidx/compose/ui/foo/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package androidx.compose.ui.foo
+
+import androidx.compose.runtime.Composable
+
+@Composable
+fun Button(foo: Int, text: @Composable () -> Unit) {
+
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/ComposableLambdaParameterDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ComposableLambdaParameterDetector.incorrectNaming`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=612128.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.compose.runtime:runtime-android:1.9.0-alpha01")
+
+// build.gradle
+implementation 'androidx.compose.runtime:runtime-android:1.9.0-alpha01'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.runtime.android)
+
+# libs.versions.toml
+[versions]
+runtime-android = "1.9.0-alpha01"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+runtime-android = {
+ module = "androidx.compose.runtime:runtime-android",
+ version.ref = "runtime-android"
+}
+```
+
+1.9.0-alpha01 is the version this documentation was generated from;
+there may be newer versions available.
+
+NOTE: These lint checks are **also** made available separate from the main library.
+You can also use `androidx.compose.runtime:runtime-lint:1.9.0-alpha01`.
+
+
+[Additional details about androidx.compose.runtime:runtime-android](androidx_compose_runtime_runtime-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ComposableLambdaParameterNaming")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ComposableLambdaParameterNaming")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ComposableLambdaParameterNaming
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ComposableLambdaParameterNaming" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ComposableLambdaParameterNaming'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ComposableLambdaParameterNaming ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ComposableLambdaParameterPosition.md.html b/docs/checks/ComposableLambdaParameterPosition.md.html
new file mode 100644
index 00000000..67dda703
--- /dev/null
+++ b/docs/checks/ComposableLambdaParameterPosition.md.html
@@ -0,0 +1,185 @@
+
+(#) Non-trailing primary composable lambda parameter
+
+!!! WARNING: Non-trailing primary composable lambda parameter
+ This is a warning.
+
+Id
+: `ComposableLambdaParameterPosition`
+Summary
+: Non-trailing primary composable lambda parameter
+Note
+: **This issue is disabled by default**; use `--enable ComposableLambdaParameterPosition`
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Jetpack Compose
+Identifier
+: androidx.compose.runtime
+Feedback
+: https://issuetracker.google.com/issues/new?component=612128
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.compose.runtime:runtime-android](androidx_compose_runtime_runtime-android.md.html)
+Since
+: 1.5.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/ComposableLambdaParameterDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/ComposableLambdaParameterDetectorTest.kt)
+Copyright Year
+: 2020
+
+Composable functions with only one composable lambda parameter should
+place the parameter at the end of the parameter list, so it can be used
+as a trailing lambda.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/androidx/compose/ui/foo/test.kt:7:Warning: Composable lambda
+parameter should be the last parameter so it can be used as a trailing
+lambda [ComposableLambdaParameterPosition]
+ fun Button(content: @Composable () -> Unit, foo: Int) {
+ -------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/androidx/compose/ui/foo/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package androidx.compose.ui.foo
+
+import androidx.compose.runtime.Composable
+
+@Composable
+fun Button(content: @Composable () -> Unit, foo: Int) {
+
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/ComposableLambdaParameterDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ComposableLambdaParameterDetector.notTrailing`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=612128.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.compose.runtime:runtime-android:1.9.0-alpha01")
+
+// build.gradle
+implementation 'androidx.compose.runtime:runtime-android:1.9.0-alpha01'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.runtime.android)
+
+# libs.versions.toml
+[versions]
+runtime-android = "1.9.0-alpha01"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+runtime-android = {
+ module = "androidx.compose.runtime:runtime-android",
+ version.ref = "runtime-android"
+}
+```
+
+1.9.0-alpha01 is the version this documentation was generated from;
+there may be newer versions available.
+
+NOTE: These lint checks are **also** made available separate from the main library.
+You can also use `androidx.compose.runtime:runtime-lint:1.9.0-alpha01`.
+
+
+[Additional details about androidx.compose.runtime:runtime-android](androidx_compose_runtime_runtime-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ComposableLambdaParameterPosition")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ComposableLambdaParameterPosition")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ComposableLambdaParameterPosition
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ComposableLambdaParameterPosition" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ComposableLambdaParameterPosition'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ComposableLambdaParameterPosition ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ComposableNaming.md.html b/docs/checks/ComposableNaming.md.html
new file mode 100644
index 00000000..be81428a
--- /dev/null
+++ b/docs/checks/ComposableNaming.md.html
@@ -0,0 +1,185 @@
+
+(#) Incorrect naming for @Composable functions
+
+!!! WARNING: Incorrect naming for @Composable functions
+ This is a warning.
+
+Id
+: `ComposableNaming`
+Summary
+: Incorrect naming for @Composable functions
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Jetpack Compose
+Identifier
+: androidx.compose.runtime
+Feedback
+: https://issuetracker.google.com/issues/new?component=612128
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.compose.runtime:runtime-android](androidx_compose_runtime_runtime-android.md.html)
+Since
+: 1.5.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/ComposableNamingDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/ComposableNamingDetectorTest.kt)
+Copyright Year
+: 2020
+
+@Composable functions without a return type should use similar naming to
+classes, starting with an uppercase letter and ending with a noun.
+@Composable functions with a return type should be treated as normal
+Kotlin functions, starting with a lowercase letter.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/androidx/compose/runtime/foo/test.kt:7:Warning: Composable functions
+that return Unit should start with an uppercase letter
+[ComposableNaming]
+ fun button() {}
+ ------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/androidx/compose/runtime/foo/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package androidx.compose.runtime.foo
+
+import androidx.compose.runtime.Composable
+
+@Composable
+fun button() {}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/ComposableNamingDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ComposableNamingDetector.returnsUnit_lowerCaseName_fails`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=612128.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.compose.runtime:runtime-android:1.9.0-alpha01")
+
+// build.gradle
+implementation 'androidx.compose.runtime:runtime-android:1.9.0-alpha01'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.runtime.android)
+
+# libs.versions.toml
+[versions]
+runtime-android = "1.9.0-alpha01"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+runtime-android = {
+ module = "androidx.compose.runtime:runtime-android",
+ version.ref = "runtime-android"
+}
+```
+
+1.9.0-alpha01 is the version this documentation was generated from;
+there may be newer versions available.
+
+NOTE: These lint checks are **also** made available separate from the main library.
+You can also use `androidx.compose.runtime:runtime-lint:1.9.0-alpha01`.
+
+
+[Additional details about androidx.compose.runtime:runtime-android](androidx_compose_runtime_runtime-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ComposableNaming")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ComposableNaming")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ComposableNaming
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ComposableNaming" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ComposableNaming'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ComposableNaming ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ComposableNavGraphInComposeScope.md.html b/docs/checks/ComposableNavGraphInComposeScope.md.html
new file mode 100644
index 00000000..4e405014
--- /dev/null
+++ b/docs/checks/ComposableNavGraphInComposeScope.md.html
@@ -0,0 +1,183 @@
+
+(#) Building navigation graph in compose scope
+
+!!! ERROR: Building navigation graph in compose scope
+ This is an error.
+
+Id
+: `ComposableNavGraphInComposeScope`
+Summary
+: Building navigation graph in compose scope
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Jetpack Navigation Compose
+Identifier
+: androidx.navigation.compose
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.navigation:navigation-compose](androidx_navigation_navigation-compose.md.html)
+Since
+: 2.4.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/navigation/navigation-compose-lint/src/main/java/androidx/navigation/compose/lint/ComposableDestinationInComposeScopeDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/navigation/navigation-compose-lint/src/test/java/androidx/navigation/compose/lint/ComposableDestinationInComposeScopeDetectorTest.kt)
+Copyright Year
+: 2021
+
+Composable destinations should only be constructed directly within a
+NavGraphBuilder scope.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/com/example/test.kt:14:Error: Using navigation inside of a compose
+scope [ComposableNavGraphInComposeScope]
+ navigation("wrong") { }
+ ----------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/com/example/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package com.example
+
+import androidx.compose.runtime.*
+import androidx.navigation.compose.composable
+import androidx.navigation.compose.navigation
+import androidx.navigation.compose.NavHost
+import androidx.navigation.NavGraphBuilder
+
+@Composable
+fun Test() {
+ NavHost("host") {
+ composable("right") {
+ navigation("wrong") { }
+ }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/navigation/navigation-compose-lint/src/test/java/androidx/navigation/compose/lint/ComposableDestinationInComposeScopeDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ComposableDestinationInComposeScopeDetector.navigationBuilderInsideComposable`.
+To report a problem with this extracted sample, contact
+Jetpack Navigation Compose.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.navigation:navigation-compose:2.9.0-rc01")
+
+// build.gradle
+implementation 'androidx.navigation:navigation-compose:2.9.0-rc01'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.navigation.compose)
+
+# libs.versions.toml
+[versions]
+navigation-compose = "2.9.0-rc01"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+navigation-compose = {
+ module = "androidx.navigation:navigation-compose",
+ version.ref = "navigation-compose"
+}
+```
+
+2.9.0-rc01 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.navigation:navigation-compose](androidx_navigation_navigation-compose.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ComposableNavGraphInComposeScope")
+ fun method() {
+ composable(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ComposableNavGraphInComposeScope")
+ void method() {
+ composable(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ComposableNavGraphInComposeScope
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ComposableNavGraphInComposeScope" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ComposableNavGraphInComposeScope'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ComposableNavGraphInComposeScope ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ComposeCompositionLocalGetter.md.html b/docs/checks/ComposeCompositionLocalGetter.md.html
new file mode 100644
index 00000000..826b7afc
--- /dev/null
+++ b/docs/checks/ComposeCompositionLocalGetter.md.html
@@ -0,0 +1,200 @@
+
+(#) CompositionLocals should not use getters
+
+!!! ERROR: CompositionLocals should not use getters
+ This is an error.
+
+Id
+: `ComposeCompositionLocalGetter`
+Summary
+: CompositionLocals should not use getters
+Severity
+: Error
+Category
+: Productivity
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: com.slack.lint.compose:compose-lints
+Feedback
+: https://github.com/slackhq/compose-lints/issues
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html)
+Since
+: 1.3.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/main/java/slack/lint/compose/CompositionLocalUsageDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/CompositionLocalUsageDetectorTest.kt)
+Copyright Year
+: 2023
+
+`CompositionLocal`s should be singletons and not use getters. Otherwise
+a new instance will be returned every call.
+
+(##) Options
+
+You can configure this lint checks using the following options:
+
+(###) allowed-composition-locals
+
+A comma-separated list of CompositionLocals that should be allowed.
+This property should define a comma-separated list of `CompositionLocal`s that should be allowed.
+
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="ComposeCompositionLocalGetter">
+ <option name="allowed-composition-locals" value="some string" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test.kt:2:Error: `CompositionLocal`s should be singletons and not
+use getters. Otherwise a new instance will be returned every call.
+[ComposeCompositionLocalGetter]
+ val LocalBanana get() = compositionLocalOf { "Prune" }
+ ---
+src/test.kt:3:Error: `CompositionLocal`s should be singletons and not
+use getters. Otherwise a new instance will be returned every call.
+[ComposeCompositionLocalGetter]
+ val LocalPotato get() {
+ ---
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+val LocalBanana get() = compositionLocalOf { "Prune" }
+val LocalPotato get() {
+ return compositionLocalOf { "Prune" }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/CompositionLocalUsageDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `CompositionLocalUsageDetector.getter is an error`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/compose-lints/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint.compose:compose-lint-checks:1.4.2")
+
+// build.gradle
+lintChecks 'com.slack.lint.compose:compose-lint-checks:1.4.2'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.compose.lint.checks)
+
+# libs.versions.toml
+[versions]
+compose-lint-checks = "1.4.2"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+compose-lint-checks = {
+ module = "com.slack.lint.compose:compose-lint-checks",
+ version.ref = "compose-lint-checks"
+}
+```
+
+1.4.2 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ComposeCompositionLocalGetter")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ComposeCompositionLocalGetter")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ComposeCompositionLocalGetter
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ComposeCompositionLocalGetter" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ComposeCompositionLocalGetter'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ComposeCompositionLocalGetter ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ComposeCompositionLocalUsage.md.html b/docs/checks/ComposeCompositionLocalUsage.md.html
new file mode 100644
index 00000000..931c81a0
--- /dev/null
+++ b/docs/checks/ComposeCompositionLocalUsage.md.html
@@ -0,0 +1,216 @@
+
+(#) CompositionLocals are discouraged
+
+!!! WARNING: CompositionLocals are discouraged
+ This is a warning.
+
+Id
+: `ComposeCompositionLocalUsage`
+Summary
+: CompositionLocals are discouraged
+Severity
+: Warning
+Category
+: Productivity
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: com.slack.lint.compose:compose-lints
+Feedback
+: https://github.com/slackhq/compose-lints/issues
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html)
+Since
+: 1.0.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/main/java/slack/lint/compose/CompositionLocalUsageDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/CompositionLocalUsageDetectorTest.kt)
+Copyright Year
+: 2023
+
+`CompositionLocal`s are implicit dependencies and creating new ones
+should be avoided. See
+https://slackhq.github.io/compose-lints/rules/#compositionlocals for
+more information.
+
+(##) Options
+
+You can configure this lint checks using the following options:
+
+(###) allowed-composition-locals
+
+A comma-separated list of CompositionLocals that should be allowed.
+This property should define a comma-separated list of `CompositionLocal`s that should be allowed.
+
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="ComposeCompositionLocalUsage">
+ <option name="allowed-composition-locals" value="some string" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test.kt:2:Warning: `CompositionLocal`s are implicit dependencies and
+creating new ones should be avoided. See
+https://slackhq.github.io/compose-lints/rules/#compositionlocals for
+more information. [ComposeCompositionLocalUsage]
+ private val LocalApple = staticCompositionLocalOf<String> { "Apple" }
+ ---------------------------------------------------------------------
+src/test.kt:3:Warning: `CompositionLocal`s are implicit dependencies and
+creating new ones should be avoided. See
+https://slackhq.github.io/compose-lints/rules/#compositionlocals for
+more information. [ComposeCompositionLocalUsage]
+ internal val LocalPlum: String = staticCompositionLocalOf { "Plum" }
+ --------------------------------------------------------------------
+src/test.kt:4:Warning: `CompositionLocal`s are implicit dependencies and
+creating new ones should be avoided. See
+https://slackhq.github.io/compose-lints/rules/#compositionlocals for
+more information. [ComposeCompositionLocalUsage]
+ val LocalPrune = compositionLocalOf { "Prune" }
+ -----------------------------------------------
+src/test.kt:5:Warning: `CompositionLocal`s are implicit dependencies and
+creating new ones should be avoided. See
+https://slackhq.github.io/compose-lints/rules/#compositionlocals for
+more information. [ComposeCompositionLocalUsage]
+ private val LocalKiwi: String = compositionLocalOf { "Kiwi" }
+ -------------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+private val LocalApple = staticCompositionLocalOf { "Apple" }
+internal val LocalPlum: String = staticCompositionLocalOf { "Plum" }
+val LocalPrune = compositionLocalOf { "Prune" }
+private val LocalKiwi: String = compositionLocalOf { "Kiwi" }
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/CompositionLocalUsageDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `CompositionLocalUsageDetector.warning when a CompositionLocal is defined`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/compose-lints/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint.compose:compose-lint-checks:1.4.2")
+
+// build.gradle
+lintChecks 'com.slack.lint.compose:compose-lint-checks:1.4.2'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.compose.lint.checks)
+
+# libs.versions.toml
+[versions]
+compose-lint-checks = "1.4.2"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+compose-lint-checks = {
+ module = "com.slack.lint.compose:compose-lint-checks",
+ version.ref = "compose-lint-checks"
+}
+```
+
+1.4.2 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ComposeCompositionLocalUsage")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ComposeCompositionLocalUsage")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ComposeCompositionLocalUsage
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ComposeCompositionLocalUsage" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ComposeCompositionLocalUsage'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ComposeCompositionLocalUsage ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ComposeContentEmitterReturningValues.md.html b/docs/checks/ComposeContentEmitterReturningValues.md.html
new file mode 100644
index 00000000..ba05633f
--- /dev/null
+++ b/docs/checks/ComposeContentEmitterReturningValues.md.html
@@ -0,0 +1,221 @@
+
+(#) Composable functions should emit XOR return
+
+!!! ERROR: Composable functions should emit XOR return
+ This is an error.
+
+Id
+: `ComposeContentEmitterReturningValues`
+Summary
+: Composable functions should emit XOR return
+Severity
+: Error
+Category
+: Productivity
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: com.slack.lint.compose:compose-lints
+Feedback
+: https://github.com/slackhq/compose-lints/issues
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html)
+Since
+: 1.0.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/main/java/slack/lint/compose/ContentEmitterReturningValuesDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/ContentEmitterReturningValuesDetectorTest.kt)
+Copyright Year
+: 2023
+
+Composable functions should either emit content into the composition or
+return a value, but not both. If a composable should offer additional
+control surfaces to its caller, those control surfaces or callbacks
+should be provided as parameters to the composable function by the
+caller. See
+https://slackhq.github.io/compose-lints/rules/#do-not-emit-content-and-return-a-result
+for more information.
+
+(##) Options
+
+You can configure this lint checks using the following options:
+
+(###) content-emitters
+
+A comma-separated list of known content-emitting composables.
+This property should define a comma-separated list of known content-emitting composables.
+
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="ComposeContentEmitterReturningValues">
+ <option name="content-emitters" value="some string" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test.kt:3:Error: Composable functions should either emit content
+into the composition or return a value, but not both.If a composable
+should offer additional control surfaces to its caller, those control
+surfaces or callbacks should be provided as parameters to the composable
+function by the caller.See
+https://slackhq.github.io/compose-lints/rules/#do-not-emit-content-and-return-a-result
+for more information. [ComposeContentEmitterReturningValues]
+@Composable
+^
+src/test.kt:8:Error: Composable functions should either emit content
+into the composition or return a value, but not both.If a composable
+should offer additional control surfaces to its caller, those control
+surfaces or callbacks should be provided as parameters to the composable
+function by the caller.See
+https://slackhq.github.io/compose-lints/rules/#do-not-emit-content-and-return-a-result
+for more information. [ComposeContentEmitterReturningValues]
+@Composable
+^
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+import androidx.compose.runtime.Composable
+
+@Composable
+fun Something() {
+ Text("Hi")
+ Text("Hola")
+}
+@Composable
+fun Something() {
+ Spacer16()
+ Text("Hola")
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/ContentEmitterReturningValuesDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ContentEmitterReturningValuesDetector.errors when a Composable function has more than one UI emitter at the top level`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/compose-lints/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint.compose:compose-lint-checks:1.4.2")
+
+// build.gradle
+lintChecks 'com.slack.lint.compose:compose-lint-checks:1.4.2'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.compose.lint.checks)
+
+# libs.versions.toml
+[versions]
+compose-lint-checks = "1.4.2"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+compose-lint-checks = {
+ module = "com.slack.lint.compose:compose-lint-checks",
+ version.ref = "compose-lint-checks"
+}
+```
+
+1.4.2 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ComposeContentEmitterReturningValues")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ComposeContentEmitterReturningValues")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ComposeContentEmitterReturningValues
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ComposeContentEmitterReturningValues" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ComposeContentEmitterReturningValues'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ComposeContentEmitterReturningValues ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ComposeM2Api.md.html b/docs/checks/ComposeM2Api.md.html
new file mode 100644
index 00000000..217ad926
--- /dev/null
+++ b/docs/checks/ComposeM2Api.md.html
@@ -0,0 +1,257 @@
+
+(#) Using a Compose M2 API is not recommended
+
+!!! ERROR: Using a Compose M2 API is not recommended
+ This is an error.
+
+Id
+: `ComposeM2Api`
+Summary
+: Using a Compose M2 API is not recommended
+Note
+: **This issue is disabled by default**; use `--enable ComposeM2Api`
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: com.slack.lint.compose:compose-lints
+Feedback
+: https://github.com/slackhq/compose-lints/issues
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html)
+Since
+: 1.1.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/main/java/slack/lint/compose/M2ApiDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/M2ApiDetectorTest.kt)
+Copyright Year
+: 2022
+
+Compose Material 2 (M2) is succeeded by Material 3 (M3). Please use M3
+APIs.See https://slackhq.github.io/compose-lints/rules/#use-material-3
+for more information.
+
+(##) Options
+
+You can configure this lint checks using the following options:
+
+(###) allowed-m2-apis
+
+A comma-separated list of APIs in androidx.compose.material that should be allowed..
+This property should define a comma-separated list of APIs in androidx.compose.material that should be allowed.
+
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="ComposeM2Api">
+ <option name="allowed-m2-apis" value="some string" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(###) enable-mangling-workaround
+
+Try to work around name mangling..
+See https://github.com/slackhq/compose-lints/issues/167
+
+Default is false.
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="ComposeM2Api">
+ <option name="enable-mangling-workaround" value="false" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test.kt:9:Error: Compose Material 2 (M2) is succeeded by Material 3
+(M3). Please use M3 APIs.See
+https://slackhq.github.io/compose-lints/rules/#use-material-3 for more
+information. [ComposeM2Api]
+ Text("Hello, world!")
+ ---------------------
+src/test.kt:23:Error: Compose Material 2 (M2) is succeeded by Material 3
+(M3). Please use M3 APIs.See
+https://slackhq.github.io/compose-lints/rules/#use-material-3 for more
+information. [ComposeM2Api]
+ Text("Hello, world!")
+ ---------------------
+src/test.kt:24:Error: Compose Material 2 (M2) is succeeded by Material 3
+(M3). Please use M3 APIs.See
+https://slackhq.github.io/compose-lints/rules/#use-material-3 for more
+information. [ComposeM2Api]
+ val elevation = BottomNavigationDefaults.Elevation
+ ----------------------------------
+src/test.kt:25:Error: Compose Material 2 (M2) is succeeded by Material 3
+(M3). Please use M3 APIs.See
+https://slackhq.github.io/compose-lints/rules/#use-material-3 for more
+information. [ComposeM2Api]
+ val drawerValue = BottomDrawerValue.Closed
+ ------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+import androidx.compose.material.BottomDrawerValue
+import androidx.compose.material.BottomNavigationDefaults
+import androidx.compose.material.Text
+import androidx.compose.material.ripple.rememberRipple
+import androidx.compose.runtime.Composable
+
+@Composable
+fun Example() {
+ Text("Hello, world!")
+}
+
+@Composable
+fun AllowedExample() {
+ Surface {
+
+ }
+}
+
+@Composable
+fun Composite() {
+ Surface {
+ val ripple = rememberRipple()
+ Text("Hello, world!")
+ val elevation = BottomNavigationDefaults.Elevation
+ val drawerValue = BottomDrawerValue.Closed
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/M2ApiDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `M2ApiDetector.smokeTest`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/compose-lints/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint.compose:compose-lint-checks:1.4.2")
+
+// build.gradle
+lintChecks 'com.slack.lint.compose:compose-lint-checks:1.4.2'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.compose.lint.checks)
+
+# libs.versions.toml
+[versions]
+compose-lint-checks = "1.4.2"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+compose-lint-checks = {
+ module = "com.slack.lint.compose:compose-lint-checks",
+ version.ref = "compose-lint-checks"
+}
+```
+
+1.4.2 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ComposeM2Api")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ComposeM2Api")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ComposeM2Api
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ComposeM2Api" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ComposeM2Api'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ComposeM2Api ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ComposeModifierComposed.md.html b/docs/checks/ComposeModifierComposed.md.html
new file mode 100644
index 00000000..b5ab8e41
--- /dev/null
+++ b/docs/checks/ComposeModifierComposed.md.html
@@ -0,0 +1,211 @@
+
+(#) Don't use Modifier.composed {}
+
+!!! ERROR: Don't use Modifier.composed {}
+ This is an error.
+
+Id
+: `ComposeModifierComposed`
+Summary
+: Don't use Modifier.composed {}
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: com.slack.lint.compose:compose-lints
+Feedback
+: https://github.com/slackhq/compose-lints/issues
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html)
+Since
+: 1.3.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/main/java/slack/lint/compose/ModifierComposedDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/ModifierComposedDetectorTest.kt)
+Copyright Year
+: 2023
+
+Modifier.composed { ... } is no longer recommended due to performance
+issues.
+
+You should use the Modifier.Node API instead, as it was designed from
+the ground up to be far more performant than composed modifiers.
+
+See
+https://slackhq.github.io/compose-lints/rules/#migrate-to-modifiernode
+for more information.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/test.kt:6:Error: Modifier.composed { ... } is no longer
+recommended due to performance issues.
+You should use the Modifier.Node API instead, as it was designed from
+the ground up to be far more performant than composed modifiers.
+See
+https://slackhq.github.io/compose-lints/rules/#migrate-to-modifiernode
+for more information. [ComposeModifierComposed]
+fun Modifier.something1() = Modifier.composed { }
+ ---------------------
+src/test/test.kt:7:Error: Modifier.composed { ... } is no longer
+recommended due to performance issues.
+You should use the Modifier.Node API instead, as it was designed from
+the ground up to be far more performant than composed modifiers.
+See
+https://slackhq.github.io/compose-lints/rules/#migrate-to-modifiernode
+for more information. [ComposeModifierComposed]
+fun Modifier.something2() = composed { }
+ ------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`test/androidx/compose/ui/ComposedModifier.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package androidx.compose.ui
+
+fun Modifier.composed(
+ inspectorInfo: InspectorInfo.() -> Unit = NoInspectorInfo,
+ factory: Modifier.() -> Modifier
+): Modifier {
+ TODO()
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+ package test
+
+import androidx.compose.ui.composed
+import androidx.compose.ui.Modifier
+
+fun Modifier.something1() = Modifier.composed { }
+fun Modifier.something2() = composed { }
+fun Modifier.something3() = somethingElse()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/ModifierComposedDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ModifierComposedDetector.errors when a composable Modifier extension is detected`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/compose-lints/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint.compose:compose-lint-checks:1.4.2")
+
+// build.gradle
+lintChecks 'com.slack.lint.compose:compose-lint-checks:1.4.2'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.compose.lint.checks)
+
+# libs.versions.toml
+[versions]
+compose-lint-checks = "1.4.2"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+compose-lint-checks = {
+ module = "com.slack.lint.compose:compose-lint-checks",
+ version.ref = "compose-lint-checks"
+}
+```
+
+1.4.2 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ComposeModifierComposed")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ComposeModifierComposed")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ComposeModifierComposed
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ComposeModifierComposed" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ComposeModifierComposed'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ComposeModifierComposed ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ComposeModifierMissing.md.html b/docs/checks/ComposeModifierMissing.md.html
new file mode 100644
index 00000000..85b47e92
--- /dev/null
+++ b/docs/checks/ComposeModifierMissing.md.html
@@ -0,0 +1,249 @@
+
+(#) Missing modifier parameter
+
+!!! ERROR: Missing modifier parameter
+ This is an error.
+
+Id
+: `ComposeModifierMissing`
+Summary
+: Missing modifier parameter
+Severity
+: Error
+Category
+: Productivity
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: com.slack.lint.compose:compose-lints
+Feedback
+: https://github.com/slackhq/compose-lints/issues
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html)
+Since
+: 1.0.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/main/java/slack/lint/compose/ModifierMissingDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/ModifierMissingDetectorTest.kt)
+Copyright Year
+: 2023
+
+This @Composable function emits content but doesn't have a modifier
+parameter.See
+https://slackhq.github.io/compose-lints/rules/#when-should-i-expose-modifier-parameters
+for more information.
+
+(##) Options
+
+You can configure this lint checks using the following options:
+
+(###) content-emitters
+
+A comma-separated list of known content-emitting composables.
+This property should define a comma-separated list of known content-emitting composables.
+
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="ComposeModifierMissing">
+ <option name="content-emitters" value="some string" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(###) visibility-threshold
+
+Visibility threshold to check for Modifiers.
+You can control the visibility of which composables to check for Modifiers. Possible values are: `only_public` (default), `public_and_internal` and `all`
+
+Default is "only_public".
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="ComposeModifierMissing">
+ <option name="visibility-threshold" value=""only_public"" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test.kt:5:Error: This @Composable function emits content but doesn't
+have a modifier parameter.See
+https://slackhq.github.io/compose-lints/rules/#when-should-i-expose-modifier-parameters
+for more information. [ComposeModifierMissing]
+fun Something1() {
+ ----------
+src/test.kt:10:Error: This @Composable function emits content but
+doesn't have a modifier parameter.See
+https://slackhq.github.io/compose-lints/rules/#when-should-i-expose-modifier-parameters
+for more information. [ComposeModifierMissing]
+fun Something2() {
+ ----------
+src/test.kt:15:Error: This @Composable function emits content but
+doesn't have a modifier parameter.See
+https://slackhq.github.io/compose-lints/rules/#when-should-i-expose-modifier-parameters
+for more information. [ComposeModifierMissing]
+fun Something3(): Unit {
+ ----------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+import androidx.compose.ui.Modifier
+import androidx.compose.runtime.Composable
+
+@Composable
+fun Something1() {
+ Row {
+ }
+}
+@Composable
+fun Something2() {
+ Column(modifier = Modifier.fillMaxSize()) {
+ }
+}
+@Composable
+fun Something3(): Unit {
+ SomethingElse {
+ Box(modifier = Modifier.fillMaxSize()) {
+ }
+ }
+}
+@Composable
+fun Something4(modifier: Modifier = Modifier) {
+ Row {
+ Text("Hi!")
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/ModifierMissingDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ModifierMissingDetector.errors when a Composable has a layout inside and it doesn't have a modifier`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/compose-lints/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint.compose:compose-lint-checks:1.4.2")
+
+// build.gradle
+lintChecks 'com.slack.lint.compose:compose-lint-checks:1.4.2'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.compose.lint.checks)
+
+# libs.versions.toml
+[versions]
+compose-lint-checks = "1.4.2"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+compose-lint-checks = {
+ module = "com.slack.lint.compose:compose-lint-checks",
+ version.ref = "compose-lint-checks"
+}
+```
+
+1.4.2 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ComposeModifierMissing")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ComposeModifierMissing")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ComposeModifierMissing
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ComposeModifierMissing" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ComposeModifierMissing'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ComposeModifierMissing ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ComposeModifierReused.md.html b/docs/checks/ComposeModifierReused.md.html
new file mode 100644
index 00000000..0ddce124
--- /dev/null
+++ b/docs/checks/ComposeModifierReused.md.html
@@ -0,0 +1,333 @@
+
+(#) Modifiers should only be used once
+
+!!! ERROR: Modifiers should only be used once
+ This is an error.
+
+Id
+: `ComposeModifierReused`
+Summary
+: Modifiers should only be used once
+Severity
+: Error
+Category
+: Productivity
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: com.slack.lint.compose:compose-lints
+Feedback
+: https://github.com/slackhq/compose-lints/issues
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html)
+Since
+: 1.0.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/main/java/slack/lint/compose/ModifierReusedDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/ModifierReusedDetectorTest.kt)
+Copyright Year
+: 2023
+
+Modifiers should only be used once and by the root level layout of a
+Composable. This is true even if appended to or with other modifiers
+e.g. `modifier.fillMaxWidth()`.Use Modifier (with a capital 'M') to
+construct a new Modifier that you can pass to other composables.See
+https://slackhq.github.io/compose-lints/rules/#dont-re-use-modifiers for
+more information.
+
+(##) Options
+
+You can configure this lint checks using the following options:
+
+(###) content-emitters
+
+A comma-separated list of known content-emitting composables.
+This property should define a comma-separated list of known content-emitting composables.
+
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="ComposeModifierReused">
+ <option name="content-emitters" value="some string" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test.kt:6:Error: Modifiers should only be used once and by the root
+level layout of a Composable. This is true even if appended to or with
+other modifiers e.g. modifier.fillMaxWidth().Use Modifier (with a
+capital 'M') to construct a new Modifier that you can pass to other
+composables.See
+https://slackhq.github.io/compose-lints/rules/#dont-re-use-modifiers for
+more information. [ComposeModifierReused]
+ Row(modifier) {
+ ^
+src/test.kt:7:Error: Modifiers should only be used once and by the root
+level layout of a Composable. This is true even if appended to or with
+other modifiers e.g. modifier.fillMaxWidth().Use Modifier (with a
+capital 'M') to construct a new Modifier that you can pass to other
+composables.See
+https://slackhq.github.io/compose-lints/rules/#dont-re-use-modifiers for
+more information. [ComposeModifierReused]
+ SomethingElse(modifier)
+ -----------------------
+src/test.kt:12:Error: Modifiers should only be used once and by the root
+level layout of a Composable. This is true even if appended to or with
+other modifiers e.g. modifier.fillMaxWidth().Use Modifier (with a
+capital 'M') to construct a new Modifier that you can pass to other
+composables.See
+https://slackhq.github.io/compose-lints/rules/#dont-re-use-modifiers for
+more information. [ComposeModifierReused]
+ Column(modifier = modifier) {
+ ^
+src/test.kt:14:Error: Modifiers should only be used once and by the root
+level layout of a Composable. This is true even if appended to or with
+other modifiers e.g. modifier.fillMaxWidth().Use Modifier (with a
+capital 'M') to construct a new Modifier that you can pass to other
+composables.See
+https://slackhq.github.io/compose-lints/rules/#dont-re-use-modifiers for
+more information. [ComposeModifierReused]
+ SomethingDifferent(modifier = modifier)
+ ---------------------------------------
+src/test.kt:19:Error: Modifiers should only be used once and by the root
+level layout of a Composable. This is true even if appended to or with
+other modifiers e.g. modifier.fillMaxWidth().Use Modifier (with a
+capital 'M') to construct a new Modifier that you can pass to other
+composables.See
+https://slackhq.github.io/compose-lints/rules/#dont-re-use-modifiers for
+more information. [ComposeModifierReused]
+ Column(modifier = modifier) {
+ ^
+src/test.kt:22:Error: Modifiers should only be used once and by the root
+level layout of a Composable. This is true even if appended to or with
+other modifiers e.g. modifier.fillMaxWidth().Use Modifier (with a
+capital 'M') to construct a new Modifier that you can pass to other
+composables.See
+https://slackhq.github.io/compose-lints/rules/#dont-re-use-modifiers for
+more information. [ComposeModifierReused]
+ SomethingElse(modifier = modifier)
+ ----------------------------------
+src/test.kt:23:Error: Modifiers should only be used once and by the root
+level layout of a Composable. This is true even if appended to or with
+other modifiers e.g. modifier.fillMaxWidth().Use Modifier (with a
+capital 'M') to construct a new Modifier that you can pass to other
+composables.See
+https://slackhq.github.io/compose-lints/rules/#dont-re-use-modifiers for
+more information. [ComposeModifierReused]
+ SomethingElse(modifier = modifier.padding12())
+ ----------------------------------------------
+src/test.kt:28:Error: Modifiers should only be used once and by the root
+level layout of a Composable. This is true even if appended to or with
+other modifiers e.g. modifier.fillMaxWidth().Use Modifier (with a
+capital 'M') to construct a new Modifier that you can pass to other
+composables.See
+https://slackhq.github.io/compose-lints/rules/#dont-re-use-modifiers for
+more information. [ComposeModifierReused]
+ SomethingElse(myMod)
+ --------------------
+src/test.kt:29:Error: Modifiers should only be used once and by the root
+level layout of a Composable. This is true even if appended to or with
+other modifiers e.g. modifier.fillMaxWidth().Use Modifier (with a
+capital 'M') to construct a new Modifier that you can pass to other
+composables.See
+https://slackhq.github.io/compose-lints/rules/#dont-re-use-modifiers for
+more information. [ComposeModifierReused]
+ SomethingElse(myMod)
+ --------------------
+src/test.kt:34:Error: Modifiers should only be used once and by the root
+level layout of a Composable. This is true even if appended to or with
+other modifiers e.g. modifier.fillMaxWidth().Use Modifier (with a
+capital 'M') to construct a new Modifier that you can pass to other
+composables.See
+https://slackhq.github.io/compose-lints/rules/#dont-re-use-modifiers for
+more information. [ComposeModifierReused]
+ Box(
+ ^
+src/test.kt:40:Error: Modifiers should only be used once and by the root
+level layout of a Composable. This is true even if appended to or with
+other modifiers e.g. modifier.fillMaxWidth().Use Modifier (with a
+capital 'M') to construct a new Modifier that you can pass to other
+composables.See
+https://slackhq.github.io/compose-lints/rules/#dont-re-use-modifiers for
+more information. [ComposeModifierReused]
+ Box(
+ ^
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+
+@Composable
+fun Something(modifier: Modifier) {
+ Row(modifier) {
+ SomethingElse(modifier)
+ }
+}
+@Composable
+fun Something(modifier: Modifier): Int {
+ Column(modifier = modifier) {
+ SomethingElse(modifier = Modifier)
+ SomethingDifferent(modifier = modifier)
+ }
+}
+@Composable
+fun BoxScope.Something(modifier: Modifier) {
+ Column(modifier = modifier) {
+ SomethingDifferent()
+ }
+ SomethingElse(modifier = modifier)
+ SomethingElse(modifier = modifier.padding12())
+}
+@Composable
+fun Something(myMod: Modifier) {
+ Column {
+ SomethingElse(myMod)
+ SomethingElse(myMod)
+ }
+}
+@Composable
+fun FoundThisOneInTheWild(modifier: Modifier = Modifier) {
+ Box(
+ modifier = modifier
+ .size(AvatarSize.Default.size)
+ .clip(CircleShape)
+ .then(colorModifier)
+ ) {
+ Box(
+ modifier = modifier.padding(spacesBorderWidth)
+ )
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/ModifierReusedDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ModifierReusedDetector.errors when the modifier parameter of a Composable is used more than once by siblings or parent-children`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/compose-lints/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint.compose:compose-lint-checks:1.4.2")
+
+// build.gradle
+lintChecks 'com.slack.lint.compose:compose-lint-checks:1.4.2'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.compose.lint.checks)
+
+# libs.versions.toml
+[versions]
+compose-lint-checks = "1.4.2"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+compose-lint-checks = {
+ module = "com.slack.lint.compose:compose-lint-checks",
+ version.ref = "compose-lint-checks"
+}
+```
+
+1.4.2 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ComposeModifierReused")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ComposeModifierReused")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ComposeModifierReused
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ComposeModifierReused" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ComposeModifierReused'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ComposeModifierReused ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ComposeModifierWithoutDefault.md.html b/docs/checks/ComposeModifierWithoutDefault.md.html
new file mode 100644
index 00000000..dfadcba6
--- /dev/null
+++ b/docs/checks/ComposeModifierWithoutDefault.md.html
@@ -0,0 +1,190 @@
+
+(#) Missing Modifier default value
+
+!!! ERROR: Missing Modifier default value
+ This is an error.
+
+Id
+: `ComposeModifierWithoutDefault`
+Summary
+: Missing Modifier default value
+Severity
+: Error
+Category
+: Productivity
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: com.slack.lint.compose:compose-lints
+Feedback
+: https://github.com/slackhq/compose-lints/issues
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html)
+Since
+: 1.0.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/main/java/slack/lint/compose/ModifierWithoutDefaultDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/ModifierWithoutDefaultDetectorTest.kt)
+Copyright Year
+: 2023
+
+This @Composable function has a modifier parameter but it doesn't have a
+default value.See
+https://slackhq.github.io/compose-lints/rules/#modifiers-should-have-default-parameters
+for more information.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test.kt:5:Error: This @Composable function has a modifier parameter
+but it doesn't have a default value.See
+https://slackhq.github.io/compose-lints/rules/#modifiers-should-have-default-parameters
+for more information. [ComposeModifierWithoutDefault]
+fun Something(modifier: Modifier) { }
+ ------------------
+src/test.kt:7:Error: This @Composable function has a modifier parameter
+but it doesn't have a default value.See
+https://slackhq.github.io/compose-lints/rules/#modifiers-should-have-default-parameters
+for more information. [ComposeModifierWithoutDefault]
+fun Something(modifier: Modifier = Modifier, modifier2: Modifier) { }
+ -------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+
+@Composable
+fun Something(modifier: Modifier) { }
+@Composable
+fun Something(modifier: Modifier = Modifier, modifier2: Modifier) { }
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/ModifierWithoutDefaultDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ModifierWithoutDefaultDetector.errors when a Composable has modifiers but without default values`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/compose-lints/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint.compose:compose-lint-checks:1.4.2")
+
+// build.gradle
+lintChecks 'com.slack.lint.compose:compose-lint-checks:1.4.2'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.compose.lint.checks)
+
+# libs.versions.toml
+[versions]
+compose-lint-checks = "1.4.2"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+compose-lint-checks = {
+ module = "com.slack.lint.compose:compose-lint-checks",
+ version.ref = "compose-lint-checks"
+}
+```
+
+1.4.2 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ComposeModifierWithoutDefault")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ComposeModifierWithoutDefault")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ComposeModifierWithoutDefault
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ComposeModifierWithoutDefault" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ComposeModifierWithoutDefault'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ComposeModifierWithoutDefault ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ComposeMultipleContentEmitters.md.html b/docs/checks/ComposeMultipleContentEmitters.md.html
new file mode 100644
index 00000000..bdeb1562
--- /dev/null
+++ b/docs/checks/ComposeMultipleContentEmitters.md.html
@@ -0,0 +1,216 @@
+
+(#) Composables should only be emit from one source
+
+!!! ERROR: Composables should only be emit from one source
+ This is an error.
+
+Id
+: `ComposeMultipleContentEmitters`
+Summary
+: Composables should only be emit from one source
+Severity
+: Error
+Category
+: Productivity
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: com.slack.lint.compose:compose-lints
+Feedback
+: https://github.com/slackhq/compose-lints/issues
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html)
+Since
+: 1.0.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/main/java/slack/lint/compose/MultipleContentEmittersDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/MultipleContentEmittersDetectorTest.kt)
+Copyright Year
+: 2023
+
+Composable functions should only be emitting content into the
+composition from one source at their top level.
+
+See
+https://slackhq.github.io/compose-lints/rules/#do-not-emit-multiple-pieces-of-content
+for more information.
+
+(##) Options
+
+You can configure this lint checks using the following options:
+
+(###) content-emitters
+
+A comma-separated list of known content-emitting composables.
+This property should define a comma-separated list of known content-emitting composables.
+
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="ComposeMultipleContentEmitters">
+ <option name="content-emitters" value="some string" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test.kt:3:Error: Composable functions should only be emitting
+content into the composition from one source at their top level.
+See
+https://slackhq.github.io/compose-lints/rules/#do-not-emit-multiple-pieces-of-content
+for more information. [ComposeMultipleContentEmitters]
+@Composable
+^
+src/test.kt:8:Error: Composable functions should only be emitting
+content into the composition from one source at their top level.
+See
+https://slackhq.github.io/compose-lints/rules/#do-not-emit-multiple-pieces-of-content
+for more information. [ComposeMultipleContentEmitters]
+@Composable
+^
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+import androidx.compose.runtime.Composable
+
+@Composable
+fun Something() {
+ Text("Hi")
+ Text("Hola")
+}
+@Composable
+fun Something() {
+ Spacer16()
+ Text("Hola")
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/MultipleContentEmittersDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `MultipleContentEmittersDetector.errors when a Composable function has more than one UI emitter at the top level`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/compose-lints/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint.compose:compose-lint-checks:1.4.2")
+
+// build.gradle
+lintChecks 'com.slack.lint.compose:compose-lint-checks:1.4.2'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.compose.lint.checks)
+
+# libs.versions.toml
+[versions]
+compose-lint-checks = "1.4.2"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+compose-lint-checks = {
+ module = "com.slack.lint.compose:compose-lint-checks",
+ version.ref = "compose-lint-checks"
+}
+```
+
+1.4.2 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ComposeMultipleContentEmitters")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ComposeMultipleContentEmitters")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ComposeMultipleContentEmitters
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ComposeMultipleContentEmitters" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ComposeMultipleContentEmitters'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ComposeMultipleContentEmitters ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ComposeMutableParameters.md.html b/docs/checks/ComposeMutableParameters.md.html
new file mode 100644
index 00000000..5eddecb9
--- /dev/null
+++ b/docs/checks/ComposeMutableParameters.md.html
@@ -0,0 +1,217 @@
+
+(#) Mutable objects in Compose will break state
+
+!!! ERROR: Mutable objects in Compose will break state
+ This is an error.
+
+Id
+: `ComposeMutableParameters`
+Summary
+: Mutable objects in Compose will break state
+Severity
+: Error
+Category
+: Productivity
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: com.slack.lint.compose:compose-lints
+Feedback
+: https://github.com/slackhq/compose-lints/issues
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html)
+Since
+: 1.0.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/main/java/slack/lint/compose/MutableParametersDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/MutableParametersDetectorTest.kt)
+Copyright Year
+: 2023
+
+Using mutable objects as state in Compose will cause your users to see
+incorrect or stale data in your app.Mutable objects that are not
+observable, such as `ArrayList` or a mutable data class, cannot be
+observed by Compose to trigger recomposition when they change.See
+https://slackhq.github.io/compose-lints/rules/#do-not-use-inherently-mutable-types-as-parameters
+for more information.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test.kt:5:Error: Using mutable objects as state in Compose will
+cause your users to see incorrect or stale data in your app.Mutable
+objects that are not observable, such as ArrayList or a mutable data
+class, cannot be observed by Compose to trigger recomposition when they
+change.See
+https://slackhq.github.io/compose-lints/rules/#do-not-use-inherently-mutable-types-as-parameters
+for more information. [ComposeMutableParameters]
+fun Something(a: MutableState<String>) {}
+ --------------------
+src/test.kt:7:Error: Using mutable objects as state in Compose will
+cause your users to see incorrect or stale data in your app.Mutable
+objects that are not observable, such as ArrayList or a mutable data
+class, cannot be observed by Compose to trigger recomposition when they
+change.See
+https://slackhq.github.io/compose-lints/rules/#do-not-use-inherently-mutable-types-as-parameters
+for more information. [ComposeMutableParameters]
+fun Something(a: ArrayList<String>) {}
+ -----------------
+src/test.kt:9:Error: Using mutable objects as state in Compose will
+cause your users to see incorrect or stale data in your app.Mutable
+objects that are not observable, such as ArrayList or a mutable data
+class, cannot be observed by Compose to trigger recomposition when they
+change.See
+https://slackhq.github.io/compose-lints/rules/#do-not-use-inherently-mutable-types-as-parameters
+for more information. [ComposeMutableParameters]
+fun Something(a: HashSet<String>) {}
+ ---------------
+src/test.kt:11:Error: Using mutable objects as state in Compose will
+cause your users to see incorrect or stale data in your app.Mutable
+objects that are not observable, such as ArrayList or a mutable data
+class, cannot be observed by Compose to trigger recomposition when they
+change.See
+https://slackhq.github.io/compose-lints/rules/#do-not-use-inherently-mutable-types-as-parameters
+for more information. [ComposeMutableParameters]
+fun Something(a: MutableMap<String, String>) {}
+ --------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+import androidx.compose.runtime.MutableState
+import androidx.compose.runtime.Composable
+
+@Composable
+fun Something(a: MutableState) {}
+@Composable
+fun Something(a: ArrayList) {}
+@Composable
+fun Something(a: HashSet) {}
+@Composable
+fun Something(a: MutableMap) {}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/MutableParametersDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `MutableParametersDetector.errors when a Composable has a mutable parameter`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/compose-lints/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint.compose:compose-lint-checks:1.4.2")
+
+// build.gradle
+lintChecks 'com.slack.lint.compose:compose-lint-checks:1.4.2'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.compose.lint.checks)
+
+# libs.versions.toml
+[versions]
+compose-lint-checks = "1.4.2"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+compose-lint-checks = {
+ module = "com.slack.lint.compose:compose-lint-checks",
+ version.ref = "compose-lint-checks"
+}
+```
+
+1.4.2 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ComposeMutableParameters")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ComposeMutableParameters")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ComposeMutableParameters
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ComposeMutableParameters" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ComposeMutableParameters'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ComposeMutableParameters ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ComposeNamingLowercase.md.html b/docs/checks/ComposeNamingLowercase.md.html
new file mode 100644
index 00000000..d22bb2c3
--- /dev/null
+++ b/docs/checks/ComposeNamingLowercase.md.html
@@ -0,0 +1,198 @@
+
+(#) Value-returning Composables should be lowercase
+
+!!! ERROR: Value-returning Composables should be lowercase
+ This is an error.
+
+Id
+: `ComposeNamingLowercase`
+Summary
+: Value-returning Composables should be lowercase
+Severity
+: Error
+Category
+: Productivity
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: com.slack.lint.compose:compose-lints
+Feedback
+: https://github.com/slackhq/compose-lints/issues
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html)
+Since
+: 1.0.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/main/java/slack/lint/compose/ComposableFunctionNamingDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/ComposableFunctionNamingDetectorTest.kt)
+Copyright Year
+: 2023
+
+Composable functions that return a value should start with a lowercase
+letter.While useful and accepted outside of @Composable functions, this
+factory function convention has drawbacks that set inappropriate
+expectations for callers when used with @Composable functions.See
+https://slackhq.github.io/compose-lints/rules/#naming-composable-functions-properly
+for more information.
+
+(##) Options
+
+You can configure this lint checks using the following options:
+
+(###) allowed-composable-function-names
+
+A comma-separated list of regexes of allowed composable function names.
+This property should define comma-separated list of regexes of allowed composable function names.
+
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="ComposeNamingLowercase">
+ <option name="allowed-composable-function-names" value="some string" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test.kt:4:Error: Composable functions that return a value should
+start with a lowercase letter.While useful and accepted outside of
+@Composable functions, this factory function convention has drawbacks
+that set inappropriate expectations for callers when used with
+@Composable functions.See
+https://slackhq.github.io/compose-lints/rules/#naming-composable-functions-properly
+for more information. [ComposeNamingLowercase]
+fun MyComposable(): Something { }
+ ------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+import androidx.compose.runtime.Composable
+
+@Composable
+fun MyComposable(): Something { }
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/ComposableFunctionNamingDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint.compose:compose-lint-checks:1.4.2")
+
+// build.gradle
+lintChecks 'com.slack.lint.compose:compose-lint-checks:1.4.2'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.compose.lint.checks)
+
+# libs.versions.toml
+[versions]
+compose-lint-checks = "1.4.2"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+compose-lint-checks = {
+ module = "com.slack.lint.compose:compose-lint-checks",
+ version.ref = "compose-lint-checks"
+}
+```
+
+1.4.2 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ComposeNamingLowercase")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ComposeNamingLowercase")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ComposeNamingLowercase
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ComposeNamingLowercase" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ComposeNamingLowercase'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ComposeNamingLowercase ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ComposeNamingUppercase.md.html b/docs/checks/ComposeNamingUppercase.md.html
new file mode 100644
index 00000000..a480bcd7
--- /dev/null
+++ b/docs/checks/ComposeNamingUppercase.md.html
@@ -0,0 +1,208 @@
+
+(#) Unit Composables should be uppercase
+
+!!! ERROR: Unit Composables should be uppercase
+ This is an error.
+
+Id
+: `ComposeNamingUppercase`
+Summary
+: Unit Composables should be uppercase
+Severity
+: Error
+Category
+: Productivity
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: com.slack.lint.compose:compose-lints
+Feedback
+: https://github.com/slackhq/compose-lints/issues
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html)
+Since
+: 1.0.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/main/java/slack/lint/compose/ComposableFunctionNamingDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/ComposableFunctionNamingDetectorTest.kt)
+Copyright Year
+: 2023
+
+Composable functions that return Unit should start with an uppercase
+letter.They are considered declarative entities that can be either
+present or absent in a composition and therefore follow the naming rules
+for classes.See
+https://slackhq.github.io/compose-lints/rules/#naming-composable-functions-properly
+for more information.
+
+(##) Options
+
+You can configure this lint checks using the following options:
+
+(###) allowed-composable-function-names
+
+A comma-separated list of regexes of allowed composable function names.
+This property should define comma-separated list of regexes of allowed composable function names.
+
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="ComposeNamingUppercase">
+ <option name="allowed-composable-function-names" value="some string" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test.kt:4:Error: Composable functions that return Unit should start
+with an uppercase letter.They are considered declarative entities that
+can be either present or absent in a composition and therefore follow
+the naming rules for classes.See
+https://slackhq.github.io/compose-lints/rules/#naming-composable-functions-properly
+for more information. [ComposeNamingUppercase]
+fun myComposable() { }
+ ------------
+src/test.kt:7:Error: Composable functions that return Unit should start
+with an uppercase letter.They are considered declarative entities that
+can be either present or absent in a composition and therefore follow
+the naming rules for classes.See
+https://slackhq.github.io/compose-lints/rules/#naming-composable-functions-properly
+for more information. [ComposeNamingUppercase]
+fun myComposable(): Unit { }
+ ------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+import androidx.compose.runtime.Composable
+
+@Composable
+fun myComposable() { }
+
+@Composable
+fun myComposable(): Unit { }
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/ComposableFunctionNamingDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint.compose:compose-lint-checks:1.4.2")
+
+// build.gradle
+lintChecks 'com.slack.lint.compose:compose-lint-checks:1.4.2'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.compose.lint.checks)
+
+# libs.versions.toml
+[versions]
+compose-lint-checks = "1.4.2"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+compose-lint-checks = {
+ module = "com.slack.lint.compose:compose-lint-checks",
+ version.ref = "compose-lint-checks"
+}
+```
+
+1.4.2 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ComposeNamingUppercase")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ComposeNamingUppercase")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ComposeNamingUppercase
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ComposeNamingUppercase" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ComposeNamingUppercase'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ComposeNamingUppercase ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ComposeParameterOrder.md.html b/docs/checks/ComposeParameterOrder.md.html
new file mode 100644
index 00000000..13f0543d
--- /dev/null
+++ b/docs/checks/ComposeParameterOrder.md.html
@@ -0,0 +1,246 @@
+
+(#) Composable function parameters should be ordered
+
+!!! ERROR: Composable function parameters should be ordered
+ This is an error.
+
+Id
+: `ComposeParameterOrder`
+Summary
+: Composable function parameters should be ordered
+Severity
+: Error
+Category
+: Productivity
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: com.slack.lint.compose:compose-lints
+Feedback
+: https://github.com/slackhq/compose-lints/issues
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html)
+Since
+: 1.0.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/main/java/slack/lint/compose/ParameterOrderDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/ParameterOrderDetectorTest.kt)
+Copyright Year
+: 2023
+
+This is replaced when reported.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test.kt:5:Error: Parameters in a composable function should be
+ordered following this pattern: params without defaults, modifiers,
+params with defaults and optionally, a trailing function that might not
+have a default param.
+Current params are: [modifier: Modifier = Modifier, other: String,
+other2: String] but should be [other: String, other2: String, modifier:
+Modifier = Modifier].
+See
+https://slackhq.github.io/compose-lints/rules/#ordering-composable-parameters-properly
+for more information. [ComposeParameterOrder]
+fun MyComposable(modifier: Modifier = Modifier, other: String, other2: String) { }
+ --------------------------------------------------------------
+src/test.kt:8:Error: Parameters in a composable function should be
+ordered following this pattern: params without defaults, modifiers,
+params with defaults and optionally, a trailing function that might not
+have a default param.
+Current params are: [text: String = "deffo", modifier: Modifier =
+Modifier] but should be [modifier: Modifier = Modifier, text: String =
+"deffo"].
+See
+https://slackhq.github.io/compose-lints/rules/#ordering-composable-parameters-properly
+for more information. [ComposeParameterOrder]
+fun MyComposable(text: String = "deffo", modifier: Modifier = Modifier) { }
+ -------------------------------------------------------
+src/test.kt:11:Error: Parameters in a composable function should be
+ordered following this pattern: params without defaults, modifiers,
+params with defaults and optionally, a trailing function that might not
+have a default param.
+Current params are: [modifier: Modifier = Modifier, text: String =
+"123", modifier2: Modifier = Modifier] but should be [modifier: Modifier
+= Modifier, modifier2: Modifier = Modifier, text: String = "123"].
+See
+https://slackhq.github.io/compose-lints/rules/#ordering-composable-parameters-properly
+for more information. [ComposeParameterOrder]
+fun MyComposable(modifier: Modifier = Modifier, text: String = "123", modifier2: Modifier = Modifier) { }
+ -------------------------------------------------------------------------------------
+src/test.kt:14:Error: Parameters in a composable function should be
+ordered following this pattern: params without defaults, modifiers,
+params with defaults and optionally, a trailing function that might not
+have a default param.
+Current params are: [text: String = "123", modifier: Modifier =
+Modifier, lambda: () -> Unit] but should be [modifier: Modifier =
+Modifier, text: String = "123", lambda: () -> Unit].
+See
+https://slackhq.github.io/compose-lints/rules/#ordering-composable-parameters-properly
+for more information. [ComposeParameterOrder]
+fun MyComposable(text: String = "123", modifier: Modifier = Modifier, lambda: () -> Unit) { }
+ -------------------------------------------------------------------------
+src/test.kt:17:Error: Parameters in a composable function should be
+ordered following this pattern: params without defaults, modifiers,
+params with defaults and optionally, a trailing function that might not
+have a default param.
+Current params are: [text1: String, m2: Modifier = Modifier, modifier:
+Modifier = Modifier, trailing: () -> Unit] but should be [text1: String,
+modifier: Modifier = Modifier, m2: Modifier = Modifier, trailing: () ->
+Unit].
+See
+https://slackhq.github.io/compose-lints/rules/#ordering-composable-parameters-properly
+for more information. [ComposeParameterOrder]
+fun MyComposable(text1: String, m2: Modifier = Modifier, modifier: Modifier = Modifier, trailing: () -> Unit) { }
+ ---------------------------------------------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+
+@Composable
+fun MyComposable(modifier: Modifier = Modifier, other: String, other2: String) { }
+
+@Composable
+fun MyComposable(text: String = "deffo", modifier: Modifier = Modifier) { }
+
+@Composable
+fun MyComposable(modifier: Modifier = Modifier, text: String = "123", modifier2: Modifier = Modifier) { }
+
+@Composable
+fun MyComposable(text: String = "123", modifier: Modifier = Modifier, lambda: () -> Unit) { }
+
+@Composable
+fun MyComposable(text1: String, m2: Modifier = Modifier, modifier: Modifier = Modifier, trailing: () -> Unit) { }
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/ParameterOrderDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ParameterOrderDetector.errors found when ordering is wrong`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/compose-lints/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint.compose:compose-lint-checks:1.4.2")
+
+// build.gradle
+lintChecks 'com.slack.lint.compose:compose-lint-checks:1.4.2'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.compose.lint.checks)
+
+# libs.versions.toml
+[versions]
+compose-lint-checks = "1.4.2"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+compose-lint-checks = {
+ module = "com.slack.lint.compose:compose-lint-checks",
+ version.ref = "compose-lint-checks"
+}
+```
+
+1.4.2 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ComposeParameterOrder")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ComposeParameterOrder")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ComposeParameterOrder
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ComposeParameterOrder" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ComposeParameterOrder'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ComposeParameterOrder ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ComposePreviewNaming.md.html b/docs/checks/ComposePreviewNaming.md.html
new file mode 100644
index 00000000..ca95961b
--- /dev/null
+++ b/docs/checks/ComposePreviewNaming.md.html
@@ -0,0 +1,194 @@
+
+(#) Preview annotations require certain suffixes
+
+!!! ERROR: Preview annotations require certain suffixes
+ This is an error.
+
+Id
+: `ComposePreviewNaming`
+Summary
+: Preview annotations require certain suffixes
+Severity
+: Error
+Category
+: Productivity
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: com.slack.lint.compose:compose-lints
+Feedback
+: https://github.com/slackhq/compose-lints/issues
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html)
+Since
+: 1.0.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/main/java/slack/lint/compose/PreviewNamingDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/PreviewNamingDetectorTest.kt)
+Copyright Year
+: 2023
+
+This is replaced when reporting.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/Banana.kt:3:Error: Preview annotations with 1 preview annotations
+should end with the Preview suffix.
+See
+https://slackhq.github.io/compose-lints/rules/#naming-multipreview-annotations-properly
+for more information. [ComposePreviewNaming]
+@Preview
+^
+src/Banana.kt:5:Error: Preview annotations with 1 preview annotations
+should end with the Preview suffix.
+See
+https://slackhq.github.io/compose-lints/rules/#naming-multipreview-annotations-properly
+for more information. [ComposePreviewNaming]
+@Preview
+^
+src/Banana.kt:7:Error: Preview annotations with 1 preview annotations
+should end with the Preview suffix.
+See
+https://slackhq.github.io/compose-lints/rules/#naming-multipreview-annotations-properly
+for more information. [ComposePreviewNaming]
+@BananaPreviews
+^
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/Banana.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+import androidx.compose.ui.tooling.preview.Preview
+
+@Preview
+annotation class Banana
+@Preview
+annotation class BananaPreviews
+@BananaPreviews
+annotation class WithBananaPreviews
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/PreviewNamingDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `PreviewNamingDetector.errors when a multipreview annotation is not correctly named for 1 preview`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/compose-lints/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint.compose:compose-lint-checks:1.4.2")
+
+// build.gradle
+lintChecks 'com.slack.lint.compose:compose-lint-checks:1.4.2'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.compose.lint.checks)
+
+# libs.versions.toml
+[versions]
+compose-lint-checks = "1.4.2"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+compose-lint-checks = {
+ module = "com.slack.lint.compose:compose-lint-checks",
+ version.ref = "compose-lint-checks"
+}
+```
+
+1.4.2 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ComposePreviewNaming")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ComposePreviewNaming")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ComposePreviewNaming
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ComposePreviewNaming" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ComposePreviewNaming'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ComposePreviewNaming ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ComposePreviewPublic.md.html b/docs/checks/ComposePreviewPublic.md.html
new file mode 100644
index 00000000..652e1c9c
--- /dev/null
+++ b/docs/checks/ComposePreviewPublic.md.html
@@ -0,0 +1,199 @@
+
+(#) Preview composables should be private
+
+!!! ERROR: Preview composables should be private
+ This is an error.
+
+Id
+: `ComposePreviewPublic`
+Summary
+: Preview composables should be private
+Severity
+: Error
+Category
+: Productivity
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: com.slack.lint.compose:compose-lints
+Feedback
+: https://github.com/slackhq/compose-lints/issues
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html)
+Since
+: 1.0.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/main/java/slack/lint/compose/PreviewPublicDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/PreviewPublicDetectorTest.kt)
+Copyright Year
+: 2023
+
+Composables annotated with `@Preview` that are used only for previewing
+the UI should not be public.See
+https://slackhq.github.io/compose-lints/rules/#preview-composables-should-not-be-public
+for more information.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test.kt:4:Error: Composables annotated with @Preview that are used
+only for previewing the UI should not be public.See
+https://slackhq.github.io/compose-lints/rules/#preview-composables-should-not-be-public
+for more information. [ComposePreviewPublic]
+@Preview
+^
+src/test.kt:7:Error: Composables annotated with @Preview that are used
+only for previewing the UI should not be public.See
+https://slackhq.github.io/compose-lints/rules/#preview-composables-should-not-be-public
+for more information. [ComposePreviewPublic]
+@CombinedPreviews
+^
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/CombinedPreviews.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.tooling.preview.PreviewParameterProvider
+
+@Preview
+annotation class CombinedPreviews
+
+class User
+class UserProvider : PreviewParameterProvider
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.tooling.preview.Preview
+
+@Preview
+@Composable
+fun MyComposable() { }
+@CombinedPreviews
+@Composable
+fun MyComposable() { }
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/PreviewPublicDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint.compose:compose-lint-checks:1.4.2")
+
+// build.gradle
+lintChecks 'com.slack.lint.compose:compose-lint-checks:1.4.2'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.compose.lint.checks)
+
+# libs.versions.toml
+[versions]
+compose-lint-checks = "1.4.2"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+compose-lint-checks = {
+ module = "com.slack.lint.compose:compose-lint-checks",
+ version.ref = "compose-lint-checks"
+}
+```
+
+1.4.2 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ComposePreviewPublic")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ComposePreviewPublic")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ComposePreviewPublic
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ComposePreviewPublic" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ComposePreviewPublic'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ComposePreviewPublic ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ComposeRememberMissing.md.html b/docs/checks/ComposeRememberMissing.md.html
new file mode 100644
index 00000000..2cf0d849
--- /dev/null
+++ b/docs/checks/ComposeRememberMissing.md.html
@@ -0,0 +1,194 @@
+
+(#) State values should be remembered
+
+!!! ERROR: State values should be remembered
+ This is an error.
+
+Id
+: `ComposeRememberMissing`
+Summary
+: State values should be remembered
+Severity
+: Error
+Category
+: Productivity
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: com.slack.lint.compose:compose-lints
+Feedback
+: https://github.com/slackhq/compose-lints/issues
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html)
+Since
+: 1.0.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/main/java/slack/lint/compose/RememberMissingDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/RememberMissingDetectorTest.kt)
+Copyright Year
+: 2023
+
+This is replaced when reported.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test.kt:7:Error: Using mutableStateOf in a @Composable function
+without it being inside of a remember function.
+If you don't remember the state instance, a new state instance will be
+created when the function is recomposed.
+See
+https://slackhq.github.io/compose-lints/rules/#state-should-be-remembered-in-composables
+for more information. [ComposeRememberMissing]
+ val something = mutableStateOf("X")
+ -------------------
+src/test.kt:10:Error: Using mutableStateOf in a @Composable function
+without it being inside of a remember function.
+If you don't remember the state instance, a new state instance will be
+created when the function is recomposed.
+See
+https://slackhq.github.io/compose-lints/rules/#state-should-be-remembered-in-composables
+for more information. [ComposeRememberMissing]
+fun MyComposable(something: State<String> = mutableStateOf("X")) {
+ -------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.State
+
+@Composable
+fun MyComposable() {
+ val something = mutableStateOf("X")
+}
+@Composable
+fun MyComposable(something: State = mutableStateOf("X")) {
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/RememberMissingDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `RememberMissingDetector.errors when a non-remembered mutableStateOf is used in a Composable`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/compose-lints/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint.compose:compose-lint-checks:1.4.2")
+
+// build.gradle
+lintChecks 'com.slack.lint.compose:compose-lint-checks:1.4.2'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.compose.lint.checks)
+
+# libs.versions.toml
+[versions]
+compose-lint-checks = "1.4.2"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+compose-lint-checks = {
+ module = "com.slack.lint.compose:compose-lint-checks",
+ version.ref = "compose-lint-checks"
+}
+```
+
+1.4.2 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ComposeRememberMissing")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ComposeRememberMissing")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ComposeRememberMissing
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ComposeRememberMissing" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ComposeRememberMissing'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ComposeRememberMissing ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ComposeUnstableCollections.md.html b/docs/checks/ComposeUnstableCollections.md.html
new file mode 100644
index 00000000..53cd766b
--- /dev/null
+++ b/docs/checks/ComposeUnstableCollections.md.html
@@ -0,0 +1,219 @@
+
+(#) Immutable collections should ideally be used in Composables
+
+!!! WARNING: Immutable collections should ideally be used in Composables
+ This is a warning.
+
+Id
+: `ComposeUnstableCollections`
+Summary
+: Immutable collections should ideally be used in Composables
+Severity
+: Warning
+Category
+: Productivity
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: com.slack.lint.compose:compose-lints
+Feedback
+: https://github.com/slackhq/compose-lints/issues
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html)
+Since
+: 1.0.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/main/java/slack/lint/compose/UnstableCollectionsDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/UnstableCollectionsDetectorTest.kt)
+Copyright Year
+: 2023
+
+This is replaced when reported.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test.kt:4:Warning: The Compose Compiler cannot infer the stability
+of a parameter if a Collection is used in it, even if the item
+type is stable.
+You should use Kotlinx Immutable Collections instead: a:
+ImmutableCollection or create an @Immutable wrapper for this
+class: @Immutable data class ACollection(val items: Collection)
+See
+https://slackhq.github.io/compose-lints/rules/#avoid-using-unstable-collections
+for more information. [ComposeUnstableCollections]
+fun Something(a: Collection<String>) {}
+ ------------------
+src/test.kt:6:Warning: The Compose Compiler cannot infer the stability
+of a parameter if a List is used in it, even if the item type is
+stable.
+You should use Kotlinx Immutable Collections instead: a:
+ImmutableList or create an @Immutable wrapper for this class:
+@Immutable data class AList(val items: List)
+See
+https://slackhq.github.io/compose-lints/rules/#avoid-using-unstable-collections
+for more information. [ComposeUnstableCollections]
+fun Something(a: List<String>) {}
+ ------------
+src/test.kt:8:Warning: The Compose Compiler cannot infer the stability
+of a parameter if a Set is used in it, even if the item type is
+stable.
+You should use Kotlinx Immutable Collections instead: a:
+ImmutableSet or create an @Immutable wrapper for this class:
+@Immutable data class ASet(val items: Set)
+See
+https://slackhq.github.io/compose-lints/rules/#avoid-using-unstable-collections
+for more information. [ComposeUnstableCollections]
+fun Something(a: Set<String>) {}
+ -----------
+src/test.kt:10:Warning: The Compose Compiler cannot infer the stability
+of a parameter if a Map is used in it, even if the item
+type is stable.
+You should use Kotlinx Immutable Collections instead: a:
+ImmutableMap or create an @Immutable wrapper for this
+class: @Immutable data class AMap(val items: Map)
+See
+https://slackhq.github.io/compose-lints/rules/#avoid-using-unstable-collections
+for more information. [ComposeUnstableCollections]
+fun Something(a: Map<String, Int>) {}
+ ----------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+import androidx.compose.runtime.Composable
+
+@Composable
+fun Something(a: Collection) {}
+@Composable
+fun Something(a: List) {}
+@Composable
+fun Something(a: Set) {}
+@Composable
+fun Something(a: Map) {}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/UnstableCollectionsDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `UnstableCollectionsDetector.warnings when a Composable has a Collection List Set Map parameter`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/compose-lints/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint.compose:compose-lint-checks:1.4.2")
+
+// build.gradle
+lintChecks 'com.slack.lint.compose:compose-lint-checks:1.4.2'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.compose.lint.checks)
+
+# libs.versions.toml
+[versions]
+compose-lint-checks = "1.4.2"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+compose-lint-checks = {
+ module = "com.slack.lint.compose:compose-lint-checks",
+ version.ref = "compose-lint-checks"
+}
+```
+
+1.4.2 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ComposeUnstableCollections")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ComposeUnstableCollections")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ComposeUnstableCollections
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ComposeUnstableCollections" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ComposeUnstableCollections'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ComposeUnstableCollections ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ComposeUnstableReceiver.md.html b/docs/checks/ComposeUnstableReceiver.md.html
new file mode 100644
index 00000000..ec2ea845
--- /dev/null
+++ b/docs/checks/ComposeUnstableReceiver.md.html
@@ -0,0 +1,235 @@
+
+(#) Unstable receivers will always be recomposed
+
+!!! WARNING: Unstable receivers will always be recomposed
+ This is a warning.
+
+Id
+: `ComposeUnstableReceiver`
+Summary
+: Unstable receivers will always be recomposed
+Severity
+: Warning
+Category
+: Productivity
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: com.slack.lint.compose:compose-lints
+Feedback
+: https://github.com/slackhq/compose-lints/issues
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html)
+Since
+: 1.3.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/main/java/slack/lint/compose/UnstableReceiverDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/UnstableReceiverDetectorTest.kt)
+Copyright Year
+: 2023
+
+Instance composable functions on non-stable classes will always be
+recomposed. If possible, make the receiver type stable or refactor this
+function if that isn't possible. See
+https://slackhq.github.io/compose-lints/rules/#unstable-receivers for
+more information.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/ExampleInterface.kt:4:Warning: Instance composable functions on
+non-stable classes will always be recomposed. If possible, make the
+receiver type stable or refactor this function if that isn't possible.
+See https://slackhq.github.io/compose-lints/rules/#unstable-receivers
+for more information. [ComposeUnstableReceiver]
+ @Composable fun Content()
+ -------
+src/ExampleInterface.kt:8:Warning: Instance composable functions on
+non-stable classes will always be recomposed. If possible, make the
+receiver type stable or refactor this function if that isn't possible.
+See https://slackhq.github.io/compose-lints/rules/#unstable-receivers
+for more information. [ComposeUnstableReceiver]
+ @Composable fun Content() {}
+ -------
+src/ExampleInterface.kt:12:Warning: Instance composable functions on
+non-stable classes will always be recomposed. If possible, make the
+receiver type stable or refactor this function if that isn't possible.
+See https://slackhq.github.io/compose-lints/rules/#unstable-receivers
+for more information. [ComposeUnstableReceiver]
+fun Example.OtherContent() {}
+ -------
+src/ExampleInterface.kt:15:Warning: Instance composable functions on
+non-stable classes will always be recomposed. If possible, make the
+receiver type stable or refactor this function if that isn't possible.
+See https://slackhq.github.io/compose-lints/rules/#unstable-receivers
+for more information. [ComposeUnstableReceiver]
+val Example.OtherContentProperty get() {}
+ -------
+src/ExampleInterface.kt:19:Warning: Instance composable functions on
+non-stable classes will always be recomposed. If possible, make the
+receiver type stable or refactor this function if that isn't possible.
+See https://slackhq.github.io/compose-lints/rules/#unstable-receivers
+for more information. [ComposeUnstableReceiver]
+ @Composable fun present(): T
+ -------
+src/ExampleInterface.kt:23:Warning: Instance composable functions on
+non-stable classes will always be recomposed. If possible, make the
+receiver type stable or refactor this function if that isn't possible.
+See https://slackhq.github.io/compose-lints/rules/#unstable-receivers
+for more information. [ComposeUnstableReceiver]
+ @Composable override fun present(): String { return "hi" }
+ -------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/ExampleInterface.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+import androidx.compose.runtime.Composable
+
+interface ExampleInterface {
+ @Composable fun Content()
+}
+
+class Example {
+ @Composable fun Content() {}
+}
+
+@Composable
+fun Example.OtherContent() {}
+
+@get:Composable
+val Example.OtherContentProperty get() {}
+
+// Supertypes
+interface Presenter {
+ @Composable fun present(): T
+}
+
+class HomePresenter : Presenter {
+ @Composable override fun present(): String { return "hi" }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/UnstableReceiverDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `UnstableReceiverDetector.unstable receiver types report errors`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/compose-lints/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint.compose:compose-lint-checks:1.4.2")
+
+// build.gradle
+lintChecks 'com.slack.lint.compose:compose-lint-checks:1.4.2'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.compose.lint.checks)
+
+# libs.versions.toml
+[versions]
+compose-lint-checks = "1.4.2"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+compose-lint-checks = {
+ module = "com.slack.lint.compose:compose-lint-checks",
+ version.ref = "compose-lint-checks"
+}
+```
+
+1.4.2 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ComposeUnstableReceiver")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ComposeUnstableReceiver")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ComposeUnstableReceiver
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ComposeUnstableReceiver" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ComposeUnstableReceiver'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ComposeUnstableReceiver ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ComposeViewModelForwarding.md.html b/docs/checks/ComposeViewModelForwarding.md.html
new file mode 100644
index 00000000..0d416b33
--- /dev/null
+++ b/docs/checks/ComposeViewModelForwarding.md.html
@@ -0,0 +1,183 @@
+
+(#) Don't forward ViewModels through composables
+
+!!! ERROR: Don't forward ViewModels through composables
+ This is an error.
+
+Id
+: `ComposeViewModelForwarding`
+Summary
+: Don't forward ViewModels through composables
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: com.slack.lint.compose:compose-lints
+Feedback
+: https://github.com/slackhq/compose-lints/issues
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html)
+Since
+: 1.0.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/main/java/slack/lint/compose/ViewModelForwardingDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/ViewModelForwardingDetectorTest.kt)
+Copyright Year
+: 2023
+
+Forwarding a `ViewModel` through multiple `@Composable` functions should
+be avoided. Consider using state hoisting.See
+https://slackhq.github.io/compose-lints/rules/#hoist-all-the-things for
+more information.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/MyViewModel.kt:7:Error: Forwarding a ViewModel through multiple
+@Composable functions should be avoided. Consider using state
+hoisting.See
+https://slackhq.github.io/compose-lints/rules/#hoist-all-the-things for
+more information. [ComposeViewModelForwarding]
+ AnotherComposable(viewModel)
+ ----------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/MyViewModel.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+import androidx.compose.runtime.Composable
+
+class MyViewModel
+
+@Composable
+fun MyComposable(viewModel: MyViewModel) {
+ AnotherComposable(viewModel)
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/ViewModelForwardingDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ViewModelForwardingDetector.errors when a ViewModel is forwarded to another Composable`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/compose-lints/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint.compose:compose-lint-checks:1.4.2")
+
+// build.gradle
+lintChecks 'com.slack.lint.compose:compose-lint-checks:1.4.2'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.compose.lint.checks)
+
+# libs.versions.toml
+[versions]
+compose-lint-checks = "1.4.2"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+compose-lint-checks = {
+ module = "com.slack.lint.compose:compose-lint-checks",
+ version.ref = "compose-lint-checks"
+}
+```
+
+1.4.2 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ComposeViewModelForwarding")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ComposeViewModelForwarding")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ComposeViewModelForwarding
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ComposeViewModelForwarding" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ComposeViewModelForwarding'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ComposeViewModelForwarding ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ComposeViewModelInjection.md.html b/docs/checks/ComposeViewModelInjection.md.html
new file mode 100644
index 00000000..86b2a058
--- /dev/null
+++ b/docs/checks/ComposeViewModelInjection.md.html
@@ -0,0 +1,226 @@
+
+(#) Implicit dependencies of composables should be made explicit
+
+!!! ERROR: Implicit dependencies of composables should be made explicit
+ This is an error.
+
+Id
+: `ComposeViewModelInjection`
+Summary
+: Implicit dependencies of composables should be made explicit
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: com.slack.lint.compose:compose-lints
+Feedback
+: https://github.com/slackhq/compose-lints/issues
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html)
+Since
+: 1.0.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/main/java/slack/lint/compose/ViewModelInjectionDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/ViewModelInjectionDetectorTest.kt)
+Copyright Year
+: 2023
+
+Replaced when reporting.
+
+(##) Options
+
+You can configure this lint checks using the following options:
+
+(###) viewmodel-factories
+
+A comma-separated list of viewModel factories..
+This property should define comma-separated list of allowed viewModel factory function names.
+
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="ComposeViewModelInjection">
+ <option name="viewmodel-factories" value="some string" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test.kt:6:Error: Implicit dependencies of composables should be made
+explicit.
+Usages of to acquire a ViewModel should be done in composable default
+parameters, so that it is more testable and flexible.
+See https://slackhq.github.io/compose-lints/rules/#viewmodels for more
+information. [ComposeViewModelInjection]
+ val viewModel = <MyVM>()
+ ------------------------
+src/test.kt:11:Error: Implicit dependencies of composables should be
+made explicit.
+Usages of to acquire a ViewModel should be done in composable default
+parameters, so that it is more testable and flexible.
+See https://slackhq.github.io/compose-lints/rules/#viewmodels for more
+information. [ComposeViewModelInjection]
+ val viewModel: MyVM = ()
+ ------------------------
+src/test.kt:16:Error: Implicit dependencies of composables should be
+made explicit.
+Usages of to acquire a ViewModel should be done in composable default
+parameters, so that it is more testable and flexible.
+See https://slackhq.github.io/compose-lints/rules/#viewmodels for more
+information. [ComposeViewModelInjection]
+ val viewModel: MyVM = ()
+ ------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+
+ @Composable
+fun MyComposable(modifier: Modifier) {
+ val viewModel = ()
+}
+
+@Composable
+fun MyComposableNoParams() {
+ val viewModel: MyVM = ()
+}
+
+@Composable
+fun MyComposableTrailingLambda(block: () -> Unit) {
+ val viewModel: MyVM = ()
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/compose-lints/tree/main/compose-lint-checks/src/test/java/slack/lint/compose/ViewModelInjectionDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ViewModelInjectionDetector.errors when a weaverViewModel is used at the beginning of a Composable`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/compose-lints/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint.compose:compose-lint-checks:1.4.2")
+
+// build.gradle
+lintChecks 'com.slack.lint.compose:compose-lint-checks:1.4.2'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.compose.lint.checks)
+
+# libs.versions.toml
+[versions]
+compose-lint-checks = "1.4.2"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+compose-lint-checks = {
+ module = "com.slack.lint.compose:compose-lint-checks",
+ version.ref = "compose-lint-checks"
+}
+```
+
+1.4.2 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint.compose:compose-lint-checks](com_slack_lint_compose_compose-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ComposeViewModelInjection")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ComposeViewModelInjection")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ComposeViewModelInjection
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ComposeViewModelInjection" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ComposeViewModelInjection'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ComposeViewModelInjection ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/CompositionLocalNaming.md.html b/docs/checks/CompositionLocalNaming.md.html
new file mode 100644
index 00000000..d2b3eb17
--- /dev/null
+++ b/docs/checks/CompositionLocalNaming.md.html
@@ -0,0 +1,202 @@
+
+(#) CompositionLocal properties should be prefixed with `Local`
+
+!!! WARNING: CompositionLocal properties should be prefixed with `Local`
+ This is a warning.
+
+Id
+: `CompositionLocalNaming`
+Summary
+: CompositionLocal properties should be prefixed with `Local`
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Jetpack Compose
+Identifier
+: androidx.compose.runtime
+Feedback
+: https://issuetracker.google.com/issues/new?component=612128
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.compose.runtime:runtime-android](androidx_compose_runtime_runtime-android.md.html)
+Since
+: 1.5.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/CompositionLocalNamingDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/CompositionLocalNamingDetectorTest.kt)
+Copyright Year
+: 2020
+
+CompositionLocal properties should be prefixed with `Local`. This helps
+make it clear at their use site that these values are local to the
+current composition. Typically the full name will be `Local` + the type
+of the CompositionLocal, for example val LocalFoo = compositionLocalOf {
+Foo() }.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/androidx/compose/runtime/foo/Test.kt:6:Warning: CompositionLocal
+properties should be prefixed with Local [CompositionLocalNaming]
+ val FooCompositionLocal = compositionLocalOf { 5 }
+ -------------------
+src/androidx/compose/runtime/foo/Test.kt:9:Warning: CompositionLocal
+properties should be prefixed with Local [CompositionLocalNaming]
+ val BarCompositionLocal: CompositionLocal<String?> = staticCompositionLocalOf {
+ -------------------
+src/androidx/compose/runtime/foo/Test.kt:16:Warning: CompositionLocal
+properties should be prefixed with Local [CompositionLocalNaming]
+ val BazCompositionLocal: ProvidableCompositionLocal<Int> =
+ -------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/androidx/compose/runtime/foo/Test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package androidx.compose.runtime.foo
+
+import androidx.compose.runtime.*
+
+val FooCompositionLocal = compositionLocalOf { 5 }
+
+object Test {
+ val BarCompositionLocal: CompositionLocal = staticCompositionLocalOf {
+ null
+ }
+}
+
+class Test2 {
+ companion object {
+ val BazCompositionLocal: ProvidableCompositionLocal =
+ compositionLocalOf()
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/CompositionLocalNamingDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `CompositionLocalNamingDetector.noLocalPrefix`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=612128.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.compose.runtime:runtime-android:1.9.0-alpha01")
+
+// build.gradle
+implementation 'androidx.compose.runtime:runtime-android:1.9.0-alpha01'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.runtime.android)
+
+# libs.versions.toml
+[versions]
+runtime-android = "1.9.0-alpha01"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+runtime-android = {
+ module = "androidx.compose.runtime:runtime-android",
+ version.ref = "runtime-android"
+}
+```
+
+1.9.0-alpha01 is the version this documentation was generated from;
+there may be newer versions available.
+
+NOTE: These lint checks are **also** made available separate from the main library.
+You can also use `androidx.compose.runtime:runtime-lint:1.9.0-alpha01`.
+
+
+[Additional details about androidx.compose.runtime:runtime-android](androidx_compose_runtime_runtime-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("CompositionLocalNaming")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("CompositionLocalNaming")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection CompositionLocalNaming
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="CompositionLocalNaming" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'CompositionLocalNaming'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore CompositionLocalNaming ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ConfigurationScreenWidthHeight.md.html b/docs/checks/ConfigurationScreenWidthHeight.md.html
new file mode 100644
index 00000000..d7a81a0c
--- /dev/null
+++ b/docs/checks/ConfigurationScreenWidthHeight.md.html
@@ -0,0 +1,243 @@
+
+(#) Using Configuration.screenWidthDp/screenHeightDp instead of LocalWindowInfo.current.containerSize
+
+!!! WARNING: Using Configuration.screenWidthDp/screenHeightDp instead of LocalWindowInfo.current.containerSize
+ This is a warning.
+
+Id
+: `ConfigurationScreenWidthHeight`
+Summary
+: Using Configuration.screenWidthDp/screenHeightDp instead of LocalWindowInfo.current.containerSize
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Jetpack Compose
+Identifier
+: androidx.compose.ui
+Feedback
+: https://issuetracker.google.com/issues/new?component=612128
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.compose.ui:ui-android](androidx_compose_ui_ui-android.md.html)
+Since
+: 1.8.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/ui/ui-lint/src/main/java/androidx/compose/ui/lint/ConfigurationScreenWidthHeightDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/ConfigurationScreenWidthHeightDetectorTest.kt)
+Copyright Year
+: 2025
+
+Configuration.screenWidthDp and Configuration.screenHeightDp have
+different insets behaviour depending on target SDK version, and are
+rounded to the nearest Dp. This means that using these values in
+composition to size a layout can result in issues, as these values do
+not accurately represent the actual available window size. Instead it is
+recommended to use WindowInfo.containerSize which accurately represents
+the window size.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/test.kt:11:Warning: Using Configuration.screenWidthDp instead
+of LocalWindowInfo.current.containerSize
+[ConfigurationScreenWidthHeight]
+ LocalConfiguration.current.screenWidthDp
+ ----------------------------------------
+src/test/test.kt:12:Warning: Using Configuration.screenHeightDp instead
+of LocalWindowInfo.current.containerSize
+[ConfigurationScreenWidthHeight]
+ LocalConfiguration.current.screenHeightDp
+ -----------------------------------------
+src/test/test.kt:15:Warning: Using Configuration.screenWidthDp instead
+of LocalWindowInfo.current.containerSize
+[ConfigurationScreenWidthHeight]
+ val width = configuration.screenWidthDp.dp
+ ---------------------------
+src/test/test.kt:16:Warning: Using Configuration.screenHeightDp instead
+of LocalWindowInfo.current.containerSize
+[ConfigurationScreenWidthHeight]
+ val height = configuration.screenHeightDp.dp
+ ----------------------------
+src/test/test.kt:21:Warning: Using Configuration.screenWidthDp instead
+of LocalWindowInfo.current.containerSize
+[ConfigurationScreenWidthHeight]
+ configuration.screenWidthDp
+ ---------------------------
+src/test/test.kt:22:Warning: Using Configuration.screenHeightDp instead
+of LocalWindowInfo.current.containerSize
+[ConfigurationScreenWidthHeight]
+ configuration.screenHeightDp
+ ----------------------------
+src/test/test.kt:28:Warning: Using Configuration.screenWidthDp instead
+of LocalWindowInfo.current.containerSize
+[ConfigurationScreenWidthHeight]
+ val width = configuration.screenWidthDp.dp
+ ---------------------------
+src/test/test.kt:29:Warning: Using Configuration.screenHeightDp instead
+of LocalWindowInfo.current.containerSize
+[ConfigurationScreenWidthHeight]
+ val height = configuration.screenHeightDp.dp
+ ----------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test
+
+import android.content.res.Configuration
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.platform.LocalConfiguration
+import androidx.compose.ui.unit.dp
+
+@Composable
+fun Test() {
+ LocalConfiguration.current.screenWidthDp
+ LocalConfiguration.current.screenHeightDp
+
+ val configuration = LocalConfiguration.current
+ val width = configuration.screenWidthDp.dp
+ val height = configuration.screenHeightDp.dp
+
+ val someLambda = {
+ // Capture configuration value from composition, and use outside of
+ // composition
+ configuration.screenWidthDp
+ configuration.screenHeightDp
+ }
+}
+
+@Composable
+fun Test2(configuration: Configuration) {
+ val width = configuration.screenWidthDp.dp
+ val height = configuration.screenHeightDp.dp
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/ConfigurationScreenWidthHeightDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ConfigurationScreenWidthHeightDetector.error`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=612128.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.compose.ui:ui-android:1.9.0-alpha01")
+
+// build.gradle
+implementation 'androidx.compose.ui:ui-android:1.9.0-alpha01'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.ui.android)
+
+# libs.versions.toml
+[versions]
+ui-android = "1.9.0-alpha01"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+ui-android = {
+ module = "androidx.compose.ui:ui-android",
+ version.ref = "ui-android"
+}
+```
+
+1.9.0-alpha01 is the version this documentation was generated from;
+there may be newer versions available.
+
+NOTE: These lint checks are **also** made available separate from the main library.
+You can also use `androidx.compose.ui:ui-lint:1.9.0-alpha01`.
+
+
+[Additional details about androidx.compose.ui:ui-android](androidx_compose_ui_ui-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ConfigurationScreenWidthHeight")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ConfigurationScreenWidthHeight")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ConfigurationScreenWidthHeight
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ConfigurationScreenWidthHeight" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ConfigurationScreenWidthHeight'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ConfigurationScreenWidthHeight ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ConflictingOnColor.md.html b/docs/checks/ConflictingOnColor.md.html
new file mode 100644
index 00000000..ebd284c1
--- /dev/null
+++ b/docs/checks/ConflictingOnColor.md.html
@@ -0,0 +1,279 @@
+
+(#) Background colors with the same value should have the same 'on' color
+
+!!! ERROR: Background colors with the same value should have the same 'on' color
+ This is an error.
+
+Id
+: `ConflictingOnColor`
+Summary
+: Background colors with the same value should have the same 'on' color
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Jetpack Compose
+Identifier
+: androidx.compose.material
+Feedback
+: https://issuetracker.google.com/issues/new?component=612128
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.compose.material:material-android](androidx_compose_material_material-android.md.html)
+Since
+: 1.5.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/material/material-lint/src/main/java/androidx/compose/material/lint/ColorsDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/material/material-lint/src/test/java/androidx/compose/material/lint/ColorsDetectorTest.kt)
+Copyright Year
+: 2021
+
+In the Material color system background colors have a corresponding 'on'
+color which is used for the content color inside a component. For
+example, a button colored `primary` will have `onPrimary` text. Because
+of this, it is important that there is only one possible `onColor` for a
+given color value, otherwise there is no way to know which 'on' color
+should be used inside a component. To fix this either use the same 'on'
+color for identical background colors, or use a different background
+color for each 'on' color.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/androidx/compose/material/foo/test.kt:15:Error: Conflicting 'on'
+color for a given background [ConflictingOnColor]
+ Color.White,
+ -----------
+src/androidx/compose/material/foo/test.kt:16:Error: Conflicting 'on'
+color for a given background [ConflictingOnColor]
+ Color.White,
+ -----------
+src/androidx/compose/material/foo/test.kt:17:Error: Conflicting 'on'
+color for a given background [ConflictingOnColor]
+ Color.White,
+ -----------
+src/androidx/compose/material/foo/test.kt:18:Error: Conflicting 'on'
+color for a given background [ConflictingOnColor]
+ Color.White,
+ -----------
+src/androidx/compose/material/foo/test.kt:19:Error: Conflicting 'on'
+color for a given background [ConflictingOnColor]
+ Color.Red,
+ ---------
+src/androidx/compose/material/foo/test.kt:31:Error: Conflicting 'on'
+color for a given background [ConflictingOnColor]
+ Color.White,
+ -----------
+src/androidx/compose/material/foo/test.kt:32:Error: Conflicting 'on'
+color for a given background [ConflictingOnColor]
+ Color.Blue,
+ ----------
+src/androidx/compose/material/foo/test.kt:34:Error: Conflicting 'on'
+color for a given background [ConflictingOnColor]
+ onSurface = Color.White,
+ -----------
+src/androidx/compose/material/foo/test.kt:51:Error: Conflicting 'on'
+color for a given background [ConflictingOnColor]
+ Color.White,
+ -----------
+src/androidx/compose/material/foo/test.kt:52:Error: Conflicting 'on'
+color for a given background [ConflictingOnColor]
+ yellow400,
+ ---------
+src/androidx/compose/material/foo/test.kt:53:Error: Conflicting 'on'
+color for a given background [ConflictingOnColor]
+ Color.Blue,
+ ----------
+src/androidx/compose/material/foo/test.kt:55:Error: Conflicting 'on'
+color for a given background [ConflictingOnColor]
+ yellow500,
+ ---------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/androidx/compose/material/foo/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package androidx.compose.material.foo
+
+import androidx.compose.material.*
+import androidx.compose.ui.graphics.*
+
+val colors = Colors(
+ Color.White,
+ Color.White,
+ Color.White,
+ Color.White,
+ Color.White,
+ Color.White,
+ Color.White,
+ Color.White,
+ Color.White,
+ Color.White,
+ Color.White,
+ Color.Red,
+ false
+)
+
+val colors2 = Colors(
+ primary = Color.White,
+ Color.White,
+ Color.White,
+ Color.White,
+ background = Color.Blue,
+ Color.White,
+ Color.Green,
+ Color.White,
+ Color.Blue,
+ onBackground = Color.White,
+ onSurface = Color.White,
+ onError = Color.Red,
+ isLight = false
+)
+
+val yellow200 = Color(0xffffeb46)
+val yellow400 = Color(0xffffc000)
+val yellow500 = Color(0xffffde03)
+
+val colors3 = Colors(
+ yellow200,
+ yellow400,
+ yellow200,
+ secondaryVariant = yellow200,
+ Color.White,
+ surface = Color.Blue,
+ Color.White,
+ Color.White,
+ yellow400,
+ Color.Blue,
+ onSurface = Color(0xFFFFBBCC),
+ yellow500,
+ false
+)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/material/material-lint/src/test/java/androidx/compose/material/lint/ColorsDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ColorsDetector.constructorErrors_source`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=612128.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.compose.material:material-android:1.9.0-alpha01")
+
+// build.gradle
+implementation 'androidx.compose.material:material-android:1.9.0-alpha01'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.material.android)
+
+# libs.versions.toml
+[versions]
+material-android = "1.9.0-alpha01"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+material-android = {
+ module = "androidx.compose.material:material-android",
+ version.ref = "material-android"
+}
+```
+
+1.9.0-alpha01 is the version this documentation was generated from;
+there may be newer versions available.
+
+NOTE: These lint checks are **also** made available separate from the main library.
+You can also use `androidx.compose.material:material-lint:1.9.0-alpha01`.
+
+
+[Additional details about androidx.compose.material:material-android](androidx_compose_material_material-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ConflictingOnColor")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ConflictingOnColor")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ConflictingOnColor
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ConflictingOnColor" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ConflictingOnColor'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ConflictingOnColor ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ConstantContentStateKeyInItemsCall.md.html b/docs/checks/ConstantContentStateKeyInItemsCall.md.html
new file mode 100644
index 00000000..146ebb73
--- /dev/null
+++ b/docs/checks/ConstantContentStateKeyInItemsCall.md.html
@@ -0,0 +1,320 @@
+
+(#) Composables within an LazyList `items` call should have unique content state keys
+
+!!! ERROR: Composables within an LazyList `items` call should have unique content state keys
+ This is an error.
+
+Id
+: `ConstantContentStateKeyInItemsCall`
+Summary
+: Composables within an LazyList `items` call should have unique content state keys
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Jetpack Compose
+Identifier
+: androidx.compose.animation
+Feedback
+: https://issuetracker.google.com/issues/new?component=612128
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.compose.animation:animation-android](androidx_compose_animation_animation-android.md.html)
+Since
+: 1.8.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/animation/animation-lint/src/main/java/androidx/compose/animation/lint/SharedTransitionScopeDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/animation/animation-lint/src/test/java/androidx/compose/animation/lint/SharedTransitionScopeDetectorTest.kt)
+Copyright Year
+: 2024
+
+When using shared elements (`Modifier.sharedElement` or
+`Modifier.sharedBounds`) in a LazyList, each Composable within an
+`items` block should have its own unique key. Otherwise, only one item
+of the visible layout will be rendered, regardless if there's an ongoing
+shared element transition.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/foo/test.kt:20:Error: Each Composable within a LazyList items call
+should have unique content state keys. Make sure to either associate a
+unique key related to the item's data, or simply append the item's index
+to the key. [ConstantContentStateKeyInItemsCall]
+ state = rememberSharedContentState("Foo"),
+ ---------------------------------
+src/foo/test.kt:27:Error: Each Composable within a LazyList items call
+should have unique content state keys. Make sure to either associate a
+unique key related to the item's data, or simply append the item's index
+to the key. [ConstantContentStateKeyInItemsCall]
+ sharedContentState = rememberSharedContentState("Foo" + "Bar"),
+ -----------------------------------------
+src/foo/test.kt:34:Error: Each Composable within a LazyList items call
+should have unique content state keys. Make sure to either associate a
+unique key related to the item's data, or simply append the item's index
+to the key. [ConstantContentStateKeyInItemsCall]
+ state = rememberSharedContentState(0),
+ -----------------------------
+src/foo/test.kt:43:Error: Each Composable within a LazyList items call
+should have unique content state keys. Make sure to either associate a
+unique key related to the item's data, or simply append the item's index
+to the key. [ConstantContentStateKeyInItemsCall]
+ state = rememberSharedContentState("Foo"),
+ ---------------------------------
+src/foo/test.kt:50:Error: Each Composable within a LazyList items call
+should have unique content state keys. Make sure to either associate a
+unique key related to the item's data, or simply append the item's index
+to the key. [ConstantContentStateKeyInItemsCall]
+ sharedContentState = rememberSharedContentState("Foo" + "Bar"),
+ -----------------------------------------
+src/foo/test.kt:57:Error: Each Composable within a LazyList items call
+should have unique content state keys. Make sure to either associate a
+unique key related to the item's data, or simply append the item's index
+to the key. [ConstantContentStateKeyInItemsCall]
+ state = rememberSharedContentState(0),
+ -----------------------------
+src/foo/test.kt:66:Error: Each Composable within a LazyList items call
+should have unique content state keys. Make sure to either associate a
+unique key related to the item's data, or simply append the item's index
+to the key. [ConstantContentStateKeyInItemsCall]
+ state = rememberSharedContentState("Foo"),
+ ---------------------------------
+src/foo/test.kt:73:Error: Each Composable within a LazyList items call
+should have unique content state keys. Make sure to either associate a
+unique key related to the item's data, or simply append the item's index
+to the key. [ConstantContentStateKeyInItemsCall]
+ sharedContentState = rememberSharedContentState("Foo" + "Bar"),
+ -----------------------------------------
+src/foo/test.kt:80:Error: Each Composable within a LazyList items call
+should have unique content state keys. Make sure to either associate a
+unique key related to the item's data, or simply append the item's index
+to the key. [ConstantContentStateKeyInItemsCall]
+ state = rememberSharedContentState(0),
+ -----------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/foo/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package foo
+
+import androidx.compose.animation.*
+import androidx.compose.foundation.lazy.*
+import androidx.compose.runtime.*
+import androidx.compose.ui.*
+
+@Composable
+fun Test() {
+ SharedTransitionLayout {
+ AnimatedContent(
+ true,
+ ) { targetState ->
+ if (targetState) {
+ items(10) {
+ MyLayoutComposable(
+ modifier = Modifier
+ .sharedElement(
+ state = rememberSharedContentState("Foo"),
+ animatedVisibilityScope = this@AnimatedContent
+ )
+ )
+ MyLayoutComposable(
+ modifier = Modifier
+ .sharedBounds(
+ sharedContentState = rememberSharedContentState("Foo" + "Bar"),
+ animatedVisibilityScope = this@AnimatedContent
+ )
+ )
+ MyLayoutComposable(
+ modifier = Modifier
+ .sharedElement(
+ state = rememberSharedContentState(0),
+ animatedVisibilityScope = this@AnimatedContent
+ )
+ )
+ }
+ items(List(10) { it }) {
+ MyLayoutComposable(
+ modifier = Modifier
+ .sharedElement(
+ state = rememberSharedContentState("Foo"),
+ animatedVisibilityScope = this@AnimatedContent
+ )
+ )
+ MyLayoutComposable(
+ modifier = Modifier
+ .sharedBounds(
+ sharedContentState = rememberSharedContentState("Foo" + "Bar"),
+ animatedVisibilityScope = this@AnimatedContent
+ )
+ )
+ MyLayoutComposable(
+ modifier = Modifier
+ .sharedElement(
+ state = rememberSharedContentState(0),
+ animatedVisibilityScope = this@AnimatedContent
+ )
+ )
+ }
+ itemsIndexed(List(10) { it }) { _, _ ->
+ MyLayoutComposable(
+ modifier = Modifier
+ .sharedElement(
+ state = rememberSharedContentState("Foo"),
+ animatedVisibilityScope = this@AnimatedContent
+ )
+ )
+ MyLayoutComposable(
+ modifier = Modifier
+ .sharedBounds(
+ sharedContentState = rememberSharedContentState("Foo" + "Bar"),
+ animatedVisibilityScope = this@AnimatedContent
+ )
+ )
+ MyLayoutComposable(
+ modifier = Modifier
+ .sharedElement(
+ state = rememberSharedContentState(0),
+ animatedVisibilityScope = this@AnimatedContent
+ )
+ )
+ }
+ } else {
+ // Do Nothing
+ }
+ }
+ }
+}
+
+@Composable
+fun MyLayoutComposable(modifier: Modifier = Modifier) {
+ // Do Nothing
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/animation/animation-lint/src/test/java/androidx/compose/animation/lint/SharedTransitionScopeDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `SharedTransitionScopeDetector.constantLiteralInItemsCall_shouldWarn`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=612128.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.compose.animation:animation-android:1.9.0-alpha01")
+
+// build.gradle
+implementation 'androidx.compose.animation:animation-android:1.9.0-alpha01'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.animation.android)
+
+# libs.versions.toml
+[versions]
+animation-android = "1.9.0-alpha01"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+animation-android = {
+ module = "androidx.compose.animation:animation-android",
+ version.ref = "animation-android"
+}
+```
+
+1.9.0-alpha01 is the version this documentation was generated from;
+there may be newer versions available.
+
+NOTE: These lint checks are **also** made available separate from the main library.
+You can also use `androidx.compose.animation:animation-lint:1.9.0-alpha01`.
+
+
+[Additional details about androidx.compose.animation:animation-android](androidx_compose_animation_animation-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ConstantContentStateKeyInItemsCall")
+ fun method() {
+ SharedTransitionScope(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ConstantContentStateKeyInItemsCall")
+ void method() {
+ SharedTransitionScope(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ConstantContentStateKeyInItemsCall
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ConstantContentStateKeyInItemsCall" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ConstantContentStateKeyInItemsCall'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ConstantContentStateKeyInItemsCall ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ConstantLocale.md.html b/docs/checks/ConstantLocale.md.html
new file mode 100644
index 00000000..4a791888
--- /dev/null
+++ b/docs/checks/ConstantLocale.md.html
@@ -0,0 +1,192 @@
+
+(#) Constant Locale
+
+!!! WARNING: Constant Locale
+ This is a warning.
+
+Id
+: `ConstantLocale`
+Summary
+: Constant Locale
+Severity
+: Warning
+Category
+: Internationalization
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.2.0 (September 2018)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/LocaleDetector.kt)
+Tests
+: [Source Code](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/LocaleDetectorTest.kt)
+
+Assigning `Locale.getDefault()` to a constant is suspicious, because the
+locale can change while the app is running.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/TestLocaleJava.java:13:Warning: Assigning
+Locale.getDefault() to a final static field is suspicious; this code
+will not work correctly if the user changes locale while the app is
+running [ConstantLocale]
+ static final Locale errorLocale = Locale.getDefault();
+ -------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/test/pkg/TestLocaleJava.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import java.util.Locale;
+
+@SuppressWarnings({"ClassNameDiffersFromFileName", "MethodMayBeStatic"})
+public class TestLocaleJava {
+ public static Locale okLocale1 = Locale.getDefault();
+ public Locale okLocale2 = Locale.getDefault();
+ public final Locale okLocale3 = Locale.getDefault();
+ public void test() {
+ final Locale okLocale4 = Locale.getDefault();
+ }
+ static final Locale errorLocale = Locale.getDefault();
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/TestLocaleKotlin.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+
+import java.util.Locale
+
+@Suppress("HasPlatformType","JoinDeclarationAndAssignment")
+class TestLocaleKotlin {
+ companion object {
+ var okLocale1 = Locale.getDefault()
+ val errorLocale = Locale.getDefault()
+ }
+ var okLocale2 = Locale.getDefault()
+ val okLocale3 = Locale.getDefault()
+ fun test() {
+ val okLocale4 = Locale.getDefault()
+ }
+ val okLocale5: Locale
+ init {
+ okLocale5 = Locale.getDefault()
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MainActivity.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+
+import android.app.Activity
+import android.util.Log
+import java.text.SimpleDateFormat
+import java.util.*
+
+class MainActivity : Activity() {
+ companion object {
+ val PROBLEMATIC_DESCRIPTION_DATE_FORMAT = SimpleDateFormat("MMM dd", Locale.getDefault())
+ //same for the single parameter CTOR : SimpleDateFormat("MMM dd")
+ }
+
+ @Suppress("PropertyName")
+ val SAFE_DESCRIPTION_DATE_FORMAT = SimpleDateFormat("MMM dd", Locale.getDefault())
+
+ override fun onResume() {
+ super.onResume()
+ val today = Calendar.getInstance().time
+ Log.d("AppLog", "problematic:" + PROBLEMATIC_DESCRIPTION_DATE_FORMAT.format(today))
+ Log.d("AppLog", "safe:" + SAFE_DESCRIPTION_DATE_FORMAT.format(today))
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/LocaleDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `LocaleDetector.testFinalLocaleField`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ConstantLocale")
+ fun method() {
+ toLowerCase(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ConstantLocale")
+ void method() {
+ toLowerCase(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ConstantLocale
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ConstantLocale" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ConstantLocale'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ConstantLocale ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ConstraintLayoutToolsEditorAttribute.md.html b/docs/checks/ConstraintLayoutToolsEditorAttribute.md.html
new file mode 100644
index 00000000..f53d0059
--- /dev/null
+++ b/docs/checks/ConstraintLayoutToolsEditorAttribute.md.html
@@ -0,0 +1,152 @@
+
+(#) Flags tools:layout_editor xml properties
+
+!!! WARNING: Flags tools:layout_editor xml properties
+ This is a warning.
+
+Id
+: `ConstraintLayoutToolsEditorAttribute`
+Summary
+: Flags tools:layout_editor xml properties
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: vanniktech/lint-rules/
+Feedback
+: https://github.com/vanniktech/lint-rules/issues
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [com.vanniktech:lint-rules-android](com_vanniktech_lint-rules-android.md.html)
+Since
+: 0.6.0
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/main/kotlin/com/vanniktech/lintrules/android/ConstraintLayoutToolsEditorAttributeDetector.kt)
+Tests
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/test/kotlin/com/vanniktech/lintrules/android/ConstraintLayoutToolsEditorAttributeDetectorTest.kt)
+
+The tools:layout_editor xml properties are only used for previewing and
+won't be used in your APK hence they're unnecessary and just add
+overhead.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/layout.xml:3:Warning: Don't use tools:layout_editor_absoluteX
+[ConstraintLayoutToolsEditorAttribute]
+ tools:layout_editor_absoluteX="4dp"/>
+ -----------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/layout/layout.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<TextView
+ xmlns:tools="http://schemas.android.com/tools"
+ tools:layout_editor_absoluteX="4dp"/>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/test/kotlin/com/vanniktech/lintrules/android/ConstraintLayoutToolsEditorAttributeDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ConstraintLayoutToolsEditorAttributeDetector.toolsLayoutEditor`.
+To report a problem with this extracted sample, visit
+https://github.com/vanniktech/lint-rules/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.vanniktech:lint-rules-android:0.25.0")
+
+// build.gradle
+lintChecks 'com.vanniktech:lint-rules-android:0.25.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.lint.rules.android)
+
+# libs.versions.toml
+[versions]
+lint-rules-android = "0.25.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+lint-rules-android = {
+ module = "com.vanniktech:lint-rules-android",
+ version.ref = "lint-rules-android"
+}
+```
+
+0.25.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.vanniktech:lint-rules-android](com_vanniktech_lint-rules-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="ConstraintLayoutToolsEditorAttribute"` on the
+ problematic XML element (or one of its enclosing elements). You may
+ also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ConstraintLayoutToolsEditorAttribute" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ConstraintLayoutToolsEditorAttribute'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ConstraintLayoutToolsEditorAttribute ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ContentDescription.md.html b/docs/checks/ContentDescription.md.html
new file mode 100644
index 00000000..015c158b
--- /dev/null
+++ b/docs/checks/ContentDescription.md.html
@@ -0,0 +1,167 @@
+
+(#) Image without `contentDescription`
+
+!!! WARNING: Image without `contentDescription`
+ This is a warning.
+
+Id
+: `ContentDescription`
+Summary
+: Image without `contentDescription`
+Severity
+: Warning
+Category
+: Accessibility
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/guide/topics/ui/accessibility/apps#special-cases
+Implementation
+: [Source Code](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/AccessibilityDetector.java)
+Tests
+: [Source Code](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/AccessibilityDetectorTest.java)
+Copyright Year
+: 2011
+
+Non-textual widgets like ImageViews and ImageButtons should use the
+`contentDescription` attribute to specify a textual description of the
+widget such that screen readers and other accessibility tools can
+adequately describe the user interface.
+
+Note that elements in application screens that are purely decorative and
+do not provide any content or enable a user action should not have
+accessibility content descriptions. In this case, set their descriptions
+to `@null`. If your app's minSdkVersion is 16 or higher, you can instead
+set these graphical elements' `android:importantForAccessibility`
+attributes to `no`.
+
+Note that for text fields, you should not set both the `hint` and the
+`contentDescription` attributes since the hint will never be shown. Just
+set the `hint`.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/accessibility.xml:4:Warning: Missing `contentDescription`
+attribute on image [ContentDescription]
+ <ImageView android:id="@+id/android_logo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="http://github.com/@drawable/android_button" android:focusable="false" android:clickable="false" android:layout_weight="1.0" />
+ ---------
+res/layout/accessibility.xml:5:Warning: Missing `contentDescription`
+attribute on image [ContentDescription]
+ <ImageButton android:importantForAccessibility="yes" android:id="@+id/android_logo2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="http://github.com/@drawable/android_button" android:focusable="false" android:clickable="false" android:layout_weight="1.0" />
+ -----------
+res/layout/accessibility.xml:9:Warning: Do not set both
+`contentDescription` and `hint`: the `contentDescription` will mask the
+`hint` [ContentDescription]
+ <EditText android:hint="@string/label" android:id="@+android:id/summary" android:contentDescription="@string/label" />
+ ------------------------------------------
+res/layout/accessibility.xml:12:Warning: Empty `contentDescription`
+attribute on image [ContentDescription]
+ <ImageButton android:id="@+android:id/summary" android:contentDescription="TODO" />
+ ---------------------------------
+res/layout/accessibility.xml:13:Warning: Empty `contentDescription`
+attribute on image [ContentDescription]
+ <ImageButton android:id="@+id/summary2" android:contentDescription="" />
+ -----------------------------
+res/layout/accessibility.xml:14:Warning: Empty `contentDescription`
+attribute on image [ContentDescription]
+ <ImageButton android:id="@+id/summary3" android:contentDescription="TODO" />
+ ---------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/layout/accessibility.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/newlinear" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent">
+ <Button android:text="Button" android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
+ <ImageView android:id="@+id/android_logo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="http://github.com/@drawable/android_button" android:focusable="false" android:clickable="false" android:layout_weight="1.0" />
+ <ImageButton android:importantForAccessibility="yes" android:id="@+id/android_logo2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="http://github.com/@drawable/android_button" android:focusable="false" android:clickable="false" android:layout_weight="1.0" />
+ <Button android:text="Button" android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
+ <Button android:id="@+android:id/summary" android:contentDescription="@string/label" />
+ <ImageButton android:importantForAccessibility="no" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="http://github.com/@drawable/android_button" android:focusable="false" android:clickable="false" android:layout_weight="1.0" />
+ <EditText android:hint="@string/label" android:id="@+android:id/summary" android:contentDescription="@string/label" />
+ <EditText android:id="@+android:id/summary" android:contentDescription="@string/label" />
+ <EditText tools:ignore="ContentDescription" android:hint="@string/label" android:id="@+android:id/summary" android:contentDescription="@string/label" />
+ <ImageButton android:id="@+android:id/summary" android:contentDescription="TODO" />
+ <ImageButton android:id="@+id/summary2" android:contentDescription="" />
+ <ImageButton android:id="@+id/summary3" android:contentDescription="TODO" />
+</LinearLayout>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/AccessibilityDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `AccessibilityDetector.testAccessibility`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="ContentDescription"`
+ on the problematic XML element (or one of its enclosing elements).
+ You may also need to add the following namespace declaration on the
+ root element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <ImageButton xmlns:tools="http://schemas.android.com/tools"
+ tools:ignore="ContentDescription" ...>
+ ...
+ </ImageButton>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ContentDescription" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ContentDescription'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ContentDescription ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ContextCastToActivity.md.html b/docs/checks/ContextCastToActivity.md.html
new file mode 100644
index 00000000..523d3bdd
--- /dev/null
+++ b/docs/checks/ContextCastToActivity.md.html
@@ -0,0 +1,191 @@
+
+(#) LocalContext should not be cast to Activity, use LocalActivity instead
+
+!!! ERROR: LocalContext should not be cast to Activity, use LocalActivity instead
+ This is an error.
+
+Id
+: `ContextCastToActivity`
+Summary
+: LocalContext should not be cast to Activity, use LocalActivity instead
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Jetpack Activity Compose
+Identifier
+: androidx.activity.compose
+Feedback
+: https://issuetracker.google.com/issues/new?component=612128
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.activity:activity-compose](androidx_activity_activity-compose.md.html)
+Since
+: 1.10.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/activity/activity-compose-lint/src/main/java/androidx/activity/compose/lint/LocalContextCastIssueDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/activity/activity-compose-lint/src/test/java/androidx/activity/compose/lint/LocalContextCastIssueDetectorTest.kt)
+Copyright Year
+: 2024
+
+Casting Context to Activity is an error as Contexts are not always
+Activities. Use LocalActivity instead.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/com/example/MyActivity.kt:11:Error: LocalContext should not be cast
+to Activity, use LocalActivity instead [ContextCastToActivity]
+ val activity: Activity = LocalContext.current as Activity
+ --------------------------------
+src/com/example/MyActivity.kt:12:Error: LocalContext should not be cast
+to Activity, use LocalActivity instead [ContextCastToActivity]
+ val activity2 = LocalContext.current as? Activity
+ ---------------------------------
+src/com/example/MyActivity.kt:13:Error: LocalContext should not be cast
+to Activity, use LocalActivity instead [ContextCastToActivity]
+ val activity3 = LocalContext.current as? MyActivity
+ -----------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/com/example/MyActivity.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package com.example
+
+import android.app.Activity
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.platform.LocalContext
+
+class MyActivity: Activity()
+
+@Composable
+fun Test() {
+ val activity: Activity = LocalContext.current as Activity
+ val activity2 = LocalContext.current as? Activity
+ val activity3 = LocalContext.current as? MyActivity
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/activity/activity-compose-lint/src/test/java/androidx/activity/compose/lint/LocalContextCastIssueDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `LocalContextCastIssueDetector.errors`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=612128.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.activity:activity-compose:1.11.0-rc01")
+
+// build.gradle
+implementation 'androidx.activity:activity-compose:1.11.0-rc01'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.activity.compose)
+
+# libs.versions.toml
+[versions]
+activity-compose = "1.11.0-rc01"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+activity-compose = {
+ module = "androidx.activity:activity-compose",
+ version.ref = "activity-compose"
+}
+```
+
+1.11.0-rc01 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.activity:activity-compose](androidx_activity_activity-compose.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ContextCastToActivity")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ContextCastToActivity")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ContextCastToActivity
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ContextCastToActivity" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ContextCastToActivity'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ContextCastToActivity ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ConvertToWebp.md.html b/docs/checks/ConvertToWebp.md.html
new file mode 100644
index 00000000..d4d027e2
--- /dev/null
+++ b/docs/checks/ConvertToWebp.md.html
@@ -0,0 +1,125 @@
+
+(#) Convert to WebP
+
+!!! WARNING: Convert to WebP
+ This is a warning.
+
+Id
+: `ConvertToWebp`
+Summary
+: Convert to WebP
+Note
+: **This issue is disabled by default**; use `--enable ConvertToWebp`
+Severity
+: Warning
+Category
+: Usability: Icons
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 2.3.0 (March 2017)
+Affects
+: Kotlin and Java files, manifest files and resource files
+Editing
+: This check can *not* run live in the IDE editor
+Implementation
+: [Source Code](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/IconDetector.java)
+Tests
+: [Source Code](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/IconDetectorTest.java)
+
+The WebP format is typically more compact than PNG and JPEG. As of
+Android 4.2.1 it supports transparency and lossless conversion as well.
+Note that there is a quickfix in the IDE which lets you perform
+conversion.
+
+Previously, launcher icons were required to be in the PNG format but
+that restriction is no longer there, so lint now flags these.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ConvertToWebp")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ConvertToWebp")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ConvertToWebp
+ problematicStatement()
+ ```
+
+* Adding the suppression attribute `tools:ignore="ConvertToWebp"` on
+ the problematic XML element (or one of its enclosing elements). You
+ may also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <application tools:ignore="ConvertToWebp" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ConvertToWebp" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ConvertToWebp'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ConvertToWebp ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/CoreLibDesugaringV1.md.html b/docs/checks/CoreLibDesugaringV1.md.html
new file mode 100644
index 00000000..36d97929
--- /dev/null
+++ b/docs/checks/CoreLibDesugaringV1.md.html
@@ -0,0 +1,119 @@
+
+(#) Android 15 requires `desugar_jdk_libs` 2.+
+
+!!! ERROR: Android 15 requires `desugar_jdk_libs` 2.+
+ This is an error.
+
+Id
+: `CoreLibDesugaringV1`
+Summary
+: Android 15 requires `desugar_jdk_libs` 2.+
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 8.10.0 (May 2025)
+Affects
+: Gradle build files and TOML files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/GradleDetector.kt)
+Tests
+: [Source Code](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/GradleDetectorTest.kt)
+
+Core library desugaring with `compileSdk` 35 or later (Android 15)
+requires using version 2.+ of the core library desugaring libraries. The
+code may compile successfully, but can crash at runtime.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+build.gradle.kts:9:Error: Core library desugaring runtime library
+version 1.2.3 does not support compileSdk=35 or later; please upgrade to
+version 2.1.4 [CoreLibDesugaringV1]
+ coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.2.3") // ERROR
+ ------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`build.gradle.kts`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+android {
+ compileSdk = 35
+ compileOptions {
+ isCoreLibraryDesugaringEnabled = true
+ }
+}
+dependencies {
+ coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.4") // OK
+ coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.2.3") // ERROR
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/GradleDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `GradleDetector.testCoreLibV1`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection CoreLibDesugaringV1
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="CoreLibDesugaringV1" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'CoreLibDesugaringV1'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore CoreLibDesugaringV1 ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/CoroutineCreationDuringComposition.md.html b/docs/checks/CoroutineCreationDuringComposition.md.html
new file mode 100644
index 00000000..79349e41
--- /dev/null
+++ b/docs/checks/CoroutineCreationDuringComposition.md.html
@@ -0,0 +1,335 @@
+
+(#) Calls to `async` or `launch` should happen inside a LaunchedEffect and not composition
+
+!!! ERROR: Calls to `async` or `launch` should happen inside a LaunchedEffect and not composition
+ This is an error.
+
+Id
+: `CoroutineCreationDuringComposition`
+Summary
+: Calls to `async` or `launch` should happen inside a LaunchedEffect and not composition
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Jetpack Compose
+Identifier
+: androidx.compose.runtime
+Feedback
+: https://issuetracker.google.com/issues/new?component=612128
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.compose.runtime:runtime-android](androidx_compose_runtime_runtime-android.md.html)
+Since
+: 1.5.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/ComposableCoroutineCreationDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/ComposableCoroutineCreationDetectorTest.kt)
+Copyright Year
+: 2021
+
+Creating a coroutine with `async` or `launch` during composition is
+often incorrect - this means that a coroutine will be created even if
+the composition fails / is rolled back, and it also means that multiple
+coroutines could end up mutating the same state, causing inconsistent
+results. Instead, use `LaunchedEffect` and create coroutines inside the
+suspending block. The block will only run after a successful
+composition, and will cancel existing coroutines when `key` changes,
+allowing correct cleanup.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/androidx/compose/runtime/foo/test.kt:10:Error: Calls to async should
+happen inside a LaunchedEffect and not composition
+[CoroutineCreationDuringComposition]
+ CoroutineScope.async {}
+ -----
+src/androidx/compose/runtime/foo/test.kt:11:Error: Calls to launch
+should happen inside a LaunchedEffect and not composition
+[CoroutineCreationDuringComposition]
+ CoroutineScope.launch {}
+ ------
+src/androidx/compose/runtime/foo/test.kt:12:Error: Calls to launchIn
+should happen inside a LaunchedEffect and not composition
+[CoroutineCreationDuringComposition]
+ flowOf(Unit).launchIn(CoroutineScope)
+ --------
+src/androidx/compose/runtime/foo/test.kt:16:Error: Calls to async should
+happen inside a LaunchedEffect and not composition
+[CoroutineCreationDuringComposition]
+ CoroutineScope.async {}
+ -----
+src/androidx/compose/runtime/foo/test.kt:17:Error: Calls to launch
+should happen inside a LaunchedEffect and not composition
+[CoroutineCreationDuringComposition]
+ CoroutineScope.launch {}
+ ------
+src/androidx/compose/runtime/foo/test.kt:18:Error: Calls to launchIn
+should happen inside a LaunchedEffect and not composition
+[CoroutineCreationDuringComposition]
+ flowOf(Unit).launchIn(CoroutineScope)
+ --------
+src/androidx/compose/runtime/foo/test.kt:22:Error: Calls to async should
+happen inside a LaunchedEffect and not composition
+[CoroutineCreationDuringComposition]
+ CoroutineScope.async {}
+ -----
+src/androidx/compose/runtime/foo/test.kt:23:Error: Calls to launch
+should happen inside a LaunchedEffect and not composition
+[CoroutineCreationDuringComposition]
+ CoroutineScope.launch {}
+ ------
+src/androidx/compose/runtime/foo/test.kt:24:Error: Calls to launchIn
+should happen inside a LaunchedEffect and not composition
+[CoroutineCreationDuringComposition]
+ flowOf(Unit).launchIn(CoroutineScope)
+ --------
+src/androidx/compose/runtime/foo/test.kt:33:Error: Calls to async should
+happen inside a LaunchedEffect and not composition
+[CoroutineCreationDuringComposition]
+ CoroutineScope.async {}
+ -----
+src/androidx/compose/runtime/foo/test.kt:34:Error: Calls to launch
+should happen inside a LaunchedEffect and not composition
+[CoroutineCreationDuringComposition]
+ CoroutineScope.launch {}
+ ------
+src/androidx/compose/runtime/foo/test.kt:35:Error: Calls to launchIn
+should happen inside a LaunchedEffect and not composition
+[CoroutineCreationDuringComposition]
+ flowOf(Unit).launchIn(CoroutineScope)
+ --------
+src/androidx/compose/runtime/foo/test.kt:38:Error: Calls to async should
+happen inside a LaunchedEffect and not composition
+[CoroutineCreationDuringComposition]
+ CoroutineScope.async {}
+ -----
+src/androidx/compose/runtime/foo/test.kt:39:Error: Calls to launch
+should happen inside a LaunchedEffect and not composition
+[CoroutineCreationDuringComposition]
+ CoroutineScope.launch {}
+ ------
+src/androidx/compose/runtime/foo/test.kt:40:Error: Calls to launchIn
+should happen inside a LaunchedEffect and not composition
+[CoroutineCreationDuringComposition]
+ flowOf(Unit).launchIn(CoroutineScope)
+ --------
+src/androidx/compose/runtime/foo/test.kt:46:Error: Calls to async should
+happen inside a LaunchedEffect and not composition
+[CoroutineCreationDuringComposition]
+ CoroutineScope.async {}
+ -----
+src/androidx/compose/runtime/foo/test.kt:47:Error: Calls to launch
+should happen inside a LaunchedEffect and not composition
+[CoroutineCreationDuringComposition]
+ CoroutineScope.launch {}
+ ------
+src/androidx/compose/runtime/foo/test.kt:48:Error: Calls to launchIn
+should happen inside a LaunchedEffect and not composition
+[CoroutineCreationDuringComposition]
+ flowOf(Unit).launchIn(CoroutineScope)
+ --------
+src/androidx/compose/runtime/foo/test.kt:52:Error: Calls to async should
+happen inside a LaunchedEffect and not composition
+[CoroutineCreationDuringComposition]
+ CoroutineScope.async {}
+ -----
+src/androidx/compose/runtime/foo/test.kt:53:Error: Calls to launch
+should happen inside a LaunchedEffect and not composition
+[CoroutineCreationDuringComposition]
+ CoroutineScope.launch {}
+ ------
+src/androidx/compose/runtime/foo/test.kt:54:Error: Calls to launchIn
+should happen inside a LaunchedEffect and not composition
+[CoroutineCreationDuringComposition]
+ flowOf(Unit).launchIn(CoroutineScope)
+ --------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/androidx/compose/runtime/foo/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package androidx.compose.runtime.foo
+
+import androidx.compose.runtime.Composable
+import kotlinx.coroutines.*
+import kotlinx.coroutines.flow.*
+
+@Composable
+fun Test() {
+ CoroutineScope.async {}
+ CoroutineScope.launch {}
+ flowOf(Unit).launchIn(CoroutineScope)
+}
+
+val lambda = @Composable {
+ CoroutineScope.async {}
+ CoroutineScope.launch {}
+ flowOf(Unit).launchIn(CoroutineScope)
+}
+
+val lambda2: @Composable () -> Unit = {
+ CoroutineScope.async {}
+ CoroutineScope.launch {}
+ flowOf(Unit).launchIn(CoroutineScope)
+}
+
+@Composable
+fun LambdaParameter(content: @Composable () -> Unit) {}
+
+@Composable
+fun Test2() {
+ LambdaParameter(content = {
+ CoroutineScope.async {}
+ CoroutineScope.launch {}
+ flowOf(Unit).launchIn(CoroutineScope)
+ })
+ LambdaParameter {
+ CoroutineScope.async {}
+ CoroutineScope.launch {}
+ flowOf(Unit).launchIn(CoroutineScope)
+ }
+}
+
+fun test3() {
+ val localLambda1 = @Composable {
+ CoroutineScope.async {}
+ CoroutineScope.launch {}
+ flowOf(Unit).launchIn(CoroutineScope)
+ }
+
+ val localLambda2: @Composable () -> Unit = {
+ CoroutineScope.async {}
+ CoroutineScope.launch {}
+ flowOf(Unit).launchIn(CoroutineScope)
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/ComposableCoroutineCreationDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ComposableCoroutineCreationDetector.errors`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=612128.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.compose.runtime:runtime-android:1.9.0-alpha01")
+
+// build.gradle
+implementation 'androidx.compose.runtime:runtime-android:1.9.0-alpha01'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.runtime.android)
+
+# libs.versions.toml
+[versions]
+runtime-android = "1.9.0-alpha01"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+runtime-android = {
+ module = "androidx.compose.runtime:runtime-android",
+ version.ref = "runtime-android"
+}
+```
+
+1.9.0-alpha01 is the version this documentation was generated from;
+there may be newer versions available.
+
+NOTE: These lint checks are **also** made available separate from the main library.
+You can also use `androidx.compose.runtime:runtime-lint:1.9.0-alpha01`.
+
+
+[Additional details about androidx.compose.runtime:runtime-android](androidx_compose_runtime_runtime-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("CoroutineCreationDuringComposition")
+ fun method() {
+ async(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("CoroutineCreationDuringComposition")
+ void method() {
+ async(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection CoroutineCreationDuringComposition
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="CoroutineCreationDuringComposition" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'CoroutineCreationDuringComposition'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore CoroutineCreationDuringComposition ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/CredManMissingDal.md.html b/docs/checks/CredManMissingDal.md.html
new file mode 100644
index 00000000..0563b165
--- /dev/null
+++ b/docs/checks/CredManMissingDal.md.html
@@ -0,0 +1,118 @@
+
+(#) Missing Digital Asset Link for Credential Manager
+
+!!! ERROR: Missing Digital Asset Link for Credential Manager
+ This is an error.
+
+Id
+: `CredManMissingDal`
+Summary
+: Missing Digital Asset Link for Credential Manager
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 8.7.0 (October 2024)
+Affects
+: Kotlin and Java files
+Editing
+: This check can *not* run live in the IDE editor
+See
+: https://developer.android.com/identity/sign-in/credential-manager#add-support-dal
+Implementation
+: [Source Code](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/CredentialManagerDigitalAssetLinkDetector.kt)
+Tests
+: [Source Code](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/CredentialManagerDigitalAssetLinkDetectorTest.kt)
+
+When using password sign-in through Credential Manager, an asset
+statements string resource file that includes the `assetlinks.json`
+files to load must be declared in the manifest using a ``
+element.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:3:Error: Missing tag for asset
+statements for Credential Manager [CredManMissingDal]
+ <application>
+ -----------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest package="com.example.app" xmlns:android="http://schemas.android.com/apk/res/android">
+ <uses-sdk android:minSdkVersion="33" android:targetSdkVersion="34" />
+ <application>
+ <activity android:name=".MainActivity" android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/com/example/app/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package com.example.app
+
+import androidx.credentials.CreatePasswordRequest
+
+fun foo() {
+ val createPasswordRequest = CreatePasswordRequest("user", "pass")
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/CredentialManagerDigitalAssetLinkDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="CredManMissingDal" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'CredManMissingDal'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore CredManMissingDal ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/CredentialDependency.md.html b/docs/checks/CredentialDependency.md.html
new file mode 100644
index 00000000..b14224c3
--- /dev/null
+++ b/docs/checks/CredentialDependency.md.html
@@ -0,0 +1,104 @@
+
+(#) `credentials-play-services-auth` is Required
+
+!!! WARNING: `credentials-play-services-auth` is Required
+ This is a warning.
+
+Id
+: `CredentialDependency`
+Summary
+: `credentials-play-services-auth` is Required
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 8.6.0 (August 2024)
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/jetpack/androidx/releases/credentials
+Implementation
+: [Source Code](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/CredentialManagerDependencyDetector.kt)
+Tests
+: [Source Code](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/CredentialManagerDependencyDetectorTest.kt)
+
+The dependency `androidx.credentials:credentials-play-services-auth` is
+required for Android 13 and below to get support from Play services for
+the Credential Manager API (`androidx.credentials:credentials`) to work.
+For Android 14 and above, this is optional. Please check release notes
+for the latest version.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`build.gradle`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~groovy linenumbers
+dependencies {
+ implementation 'androidx.credentials:credentials:+'
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/CredentialManagerDependencyDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="CredentialDependency"` on the problematic XML element
+ (or one of its enclosing elements). You may also need to add the
+ following namespace declaration on the root element in the XML file
+ if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="CredentialDependency" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'CredentialDependency'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore CredentialDependency ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/CredentialManagerMisuse.md.html b/docs/checks/CredentialManagerMisuse.md.html
new file mode 100644
index 00000000..f74af78c
--- /dev/null
+++ b/docs/checks/CredentialManagerMisuse.md.html
@@ -0,0 +1,149 @@
+
+(#) Misuse of Credential Manager API
+
+!!! WARNING: Misuse of Credential Manager API
+ This is a warning.
+
+Id
+: `CredentialManagerMisuse`
+Summary
+: Misuse of Credential Manager API
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 8.8.0 (January 2025)
+Affects
+: Kotlin and Java files
+Editing
+: This check can *not* run live in the IDE editor
+See
+: https://developer.android.com/identity/sign-in/credential-manager#handle-exceptions
+Implementation
+: [Source Code](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/CredentialManagerMisuseDetector.kt)
+Tests
+: [Source Code](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/CredentialManagerMisuseDetectorTest.kt)
+
+When calling `CredentialManager.getCredential` or
+`CredentialManager.getCredentialAsync`, you should handle
+`NoCredentialException` somewhere in your project.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/com/example/app/Foo.kt:26:Warning: Call to
+CredentialManager.getCredential without use of NoCredentialException
+[CredentialManagerMisuse]
+ credentialManager.getCredential(context, request)
+ -------------------------------------------------
+src/com/example/app/Foo.kt:27:Warning: Call to
+CredentialManager.getCredential without use of NoCredentialException
+[CredentialManagerMisuse]
+ credentialManager.getCredential(context, prepareGetCredentialResponse.pendingGetCredentialHandle!!)
+ ---------------------------------------------------------------------------------------------------
+src/com/example/app/Foo.kt:28:Warning: Call to
+CredentialManager.getCredential without use of NoCredentialException
+[CredentialManagerMisuse]
+ credentialManager.getCredentialAsync(context, request, cancellationSignal, executor, callback)
+ ----------------------------------------------------------------------------------------------
+src/com/example/app/Foo.kt:29:Warning: Call to
+CredentialManager.getCredential without use of NoCredentialException
+[CredentialManagerMisuse]
+ credentialManager.getCredentialAsync(context, prepareGetCredentialResponse.pendingGetCredentialHandle!!, cancellationSignal, executor, callback)
+ ------------------------------------------------------------------------------------------------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/com/example/app/Foo.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package com.example.app
+
+import android.content.Context
+import android.os.Build
+import android.os.CancellationSignal
+import androidx.credentials.CredentialManager
+import androidx.credentials.CredentialManagerCallback
+import androidx.credentials.GetCredentialRequest
+import androidx.credentials.GetCredentialResponse
+import androidx.credentials.PrepareGetCredentialResponse
+import androidx.credentials.PrepareGetCredentialResponse.PendingGetCredentialHandle
+import androidx.credentials.exceptions.GetCredentialException
+import androidx.credentials.exceptions.NoCredentialException
+import java.util.concurrent.Executor
+
+class Foo {
+ suspend fun foo(
+ credentialManager: CredentialManager,
+ context: Context,
+ request: GetCredentialRequest,
+ cancellationSignal: CancellationSignal,
+ executor: Executor,
+ callback: CredentialManagerCallback) {
+ try {
+ val prepareGetCredentialResponse = credentialManager.prepareGetCredential(request)
+ credentialManager.getCredential(context, request)
+ credentialManager.getCredential(context, prepareGetCredentialResponse.pendingGetCredentialHandle!!)
+ credentialManager.getCredentialAsync(context, request, cancellationSignal, executor, callback)
+ credentialManager.getCredentialAsync(context, prepareGetCredentialResponse.pendingGetCredentialHandle!!, cancellationSignal, executor, callback)
+ } catch (e: GetCredentialException) {
+ bar(e)
+ }
+ }
+
+ fun bar(e: GetCredentialException) {
+ TODO()
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/CredentialManagerMisuseDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="CredentialManagerMisuse" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'CredentialManagerMisuse'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore CredentialManagerMisuse ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/CredentialManagerSignInWithGoogle.md.html b/docs/checks/CredentialManagerSignInWithGoogle.md.html
new file mode 100644
index 00000000..3fd01180
--- /dev/null
+++ b/docs/checks/CredentialManagerSignInWithGoogle.md.html
@@ -0,0 +1,121 @@
+
+(#) Misuse of Sign in with Google API
+
+!!! WARNING: Misuse of Sign in with Google API
+ This is a warning.
+
+Id
+: `CredentialManagerSignInWithGoogle`
+Summary
+: Misuse of Sign in with Google API
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 8.7.0 (October 2024)
+Affects
+: Kotlin and Java files
+Editing
+: This check can *not* run live in the IDE editor
+See
+: https://developer.android.com/identity/sign-in/credential-manager-siwg#create-sign
+Implementation
+: [Source Code](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/CredentialManagerSignInWithGoogleDetector.kt)
+Tests
+: [Source Code](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/CredentialManagerSignInWithGoogleDetectorTest.kt)
+
+When using `:googleid` classes like `GetGoogleIdOption` and
+`GetSignInWithGoogleOption`, you must handle the response using
+`GoogleIdTokenCredential.createFrom`.
+
+This check reports all uses of these `:googleid` classes if there are no
+references to `GoogleIdTokenCredential[.Companion].createFrom`.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/com/example/app/Foo.kt:9:Warning: Use of :googleid classes without
+use of GoogleIdTokenCredential.createFrom
+[CredentialManagerSignInWithGoogle]
+ val googleIdOption = GetGoogleIdOption.Builder().build()
+ -----------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/com/example/app/Foo.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package com.example.app
+
+import androidx.credentials.GetCredentialResponse
+import androidx.credentials.PublicKeyCredential
+import com.google.android.libraries.identity.googleid.GetGoogleIdOption
+
+class Foo {
+ fun foo() {
+ val googleIdOption = GetGoogleIdOption.Builder().build()
+ }
+
+ fun handleSignIn(result: GetCredentialResponse) {
+ when (val credential = result.credential) {
+ is PublicKeyCredential -> {
+ bar()
+ }
+ else -> {}
+ }
+ }
+
+ fun bar() { TODO() }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/CredentialManagerSignInWithGoogleDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="CredentialManagerSignInWithGoogle" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'CredentialManagerSignInWithGoogle'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore CredentialManagerSignInWithGoogle ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/CustomPermissionTypo.md.html b/docs/checks/CustomPermissionTypo.md.html
new file mode 100644
index 00000000..a9f1dff2
--- /dev/null
+++ b/docs/checks/CustomPermissionTypo.md.html
@@ -0,0 +1,134 @@
+
+(#) Permission appears to be a custom permission with a typo
+
+!!! WARNING: Permission appears to be a custom permission with a typo
+ This is a warning.
+
+Id
+: `CustomPermissionTypo`
+Summary
+: Permission appears to be a custom permission with a typo
+Severity
+: Warning
+Category
+: Security
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 7.4.0 (January 2023)
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://goo.gle/CustomPermissionTypo
+Implementation
+: [Source Code](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/PermissionErrorDetector.kt)
+Tests
+: [Source Code](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/PermissionErrorDetectorTest.kt)
+
+This check looks for required permissions that *look* like custom
+permissions defined in the same manifest, but aren't, and may be typos.
+
+Please double check the permission value you have supplied.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:9:Warning: Did you mean my.custom.permission.FOOBAR?
+[CustomPermissionTypo]
+ <service android:permission="my.custom.permission.FOOBOB" />
+ ------------------------------------------------------------
+AndroidManifest.xml:11:Warning: Did you mean
+my.custom.permission.BAZQUXX? [CustomPermissionTypo]
+ <activity android:permission="my.custom.permission.BAZQXX" />
+ -------------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="com.example.helloworld">
+ <permission android:name="my.custom.permission.FOOBAR" />
+ <permission android:name="my.custom.permission.FOOBAB" />
+ <permission android:name="my.custom.permission.BAZQUXX" />
+ <permission android:name="my.custom.permission.BAZQUZZ" />
+ <application>
+ <service android:permission="my.custom.permission.FOOBOB" />
+ <service android:permission="my.custom.permission.FOOBAB" />
+ <activity android:permission="my.custom.permission.BAZQXX" />
+ <activity android:permission="my.custom.permission.BAZQUZZ" />
+ <activity android:permission="my.custom.permission.WAKE_LOCK" />
+ </application>
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/PermissionErrorDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="CustomPermissionTypo"` on the problematic XML element
+ (or one of its enclosing elements). You may also need to add the
+ following namespace declaration on the root element in the XML file
+ if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <permission tools:ignore="CustomPermissionTypo" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="CustomPermissionTypo" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'CustomPermissionTypo'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore CustomPermissionTypo ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/CustomSplashScreen.md.html b/docs/checks/CustomSplashScreen.md.html
new file mode 100644
index 00000000..ec284d4d
--- /dev/null
+++ b/docs/checks/CustomSplashScreen.md.html
@@ -0,0 +1,133 @@
+
+(#) Application-defined Launch Screen
+
+!!! WARNING: Application-defined Launch Screen
+ This is a warning.
+
+Id
+: `CustomSplashScreen`
+Summary
+: Application-defined Launch Screen
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 7.0.0 (July 2021)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/guide/topics/ui/splash-screen
+Implementation
+: [Source Code](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/SplashScreenDetector.kt)
+Tests
+: [Source Code](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/SplashScreenDetectorTest.kt)
+
+Starting in Android 12 (API 31+), the application's Launch Screen is
+provided by the system and the application should not create its own,
+otherwise the user will see two splashscreens. Please check the
+`SplashScreen` class to check how the Splash Screen can be controlled
+and customized.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/SplashActivity.kt:6:Warning: The application should not
+provide its own launch screen [CustomSplashScreen]
+class SplashActivity : AppCompatActivity() {
+ --------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/SplashActivity.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+
+import androidx.appcompat.app.AppCompatActivity
+import android.os.Bundle
+
+class SplashActivity : AppCompatActivity() {
+ override fun onCreate(savedState: Bundle?) { }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/SplashScreenDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("CustomSplashScreen")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("CustomSplashScreen")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection CustomSplashScreen
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="CustomSplashScreen" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'CustomSplashScreen'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore CustomSplashScreen ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/CustomViewStyleable.md.html b/docs/checks/CustomViewStyleable.md.html
new file mode 100644
index 00000000..4d1fc2b5
--- /dev/null
+++ b/docs/checks/CustomViewStyleable.md.html
@@ -0,0 +1,214 @@
+
+(#) Mismatched Styleable/Custom View Name
+
+!!! WARNING: Mismatched Styleable/Custom View Name
+ This is a warning.
+
+Id
+: `CustomViewStyleable`
+Summary
+: Mismatched Styleable/Custom View Name
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 0.1.0 (September 2014)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/CustomViewDetector.java)
+Tests
+: [Source Code](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/CustomViewDetectorTest.java)
+
+The convention for custom views is to use a `declare-styleable` whose
+name matches the custom view class name. The IDE relies on this
+convention such that for example code completion can be offered for
+attributes in a custom view in layout XML resource files.
+
+(Similarly, layout parameter classes should use the suffix `_Layout`.)
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/CustomView1.java:18:Warning: By convention, the custom view
+(CustomView1) and the declare-styleable (MyDeclareStyleable) should have
+the same name (various editor features rely on this convention)
+[CustomViewStyleable]
+ context.obtainStyledAttributes(R.styleable.MyDeclareStyleable);
+ ------------------------------
+src/test/pkg/CustomView1.java:19:Warning: By convention, the custom view
+(CustomView1) and the declare-styleable (MyDeclareStyleable) should have
+the same name (various editor features rely on this convention)
+[CustomViewStyleable]
+ context.obtainStyledAttributes(defStyleRes, R.styleable.MyDeclareStyleable);
+ ------------------------------
+src/test/pkg/CustomView1.java:20:Warning: By convention, the custom view
+(CustomView1) and the declare-styleable (MyDeclareStyleable) should have
+the same name (various editor features rely on this convention)
+[CustomViewStyleable]
+ context.obtainStyledAttributes(attrs, R.styleable.MyDeclareStyleable);
+ ------------------------------
+src/test/pkg/CustomView1.java:21:Warning: By convention, the custom view
+(CustomView1) and the declare-styleable (MyDeclareStyleable) should have
+the same name (various editor features rely on this convention)
+[CustomViewStyleable]
+ context.obtainStyledAttributes(attrs, R.styleable.MyDeclareStyleable, defStyleAttr,
+ ------------------------------
+src/test/pkg/CustomView1.java:46:Warning: By convention, the
+declare-styleable (MyLayout) for a layout parameter class
+(MyLayoutParams) is expected to be the surrounding class (MyLayout) plus
+"_Layout", e.g. MyLayout_Layout. (Various editor features rely on this
+convention.) [CustomViewStyleable]
+ context.obtainStyledAttributes(R.styleable.MyLayout); // Wrong
+ --------------------
+src/test/pkg/CustomView1.java:47:Warning: By convention, the
+declare-styleable (MyDeclareStyleable) for a layout parameter class
+(MyLayoutParams) is expected to be the surrounding class (MyLayout) plus
+"_Layout", e.g. MyLayout_Layout. (Various editor features rely on this
+convention.) [CustomViewStyleable]
+ context.obtainStyledAttributes(R.styleable.MyDeclareStyleable); // Wrong
+ ------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/CustomView1.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.Button;
+import android.widget.LinearLayout;
+
+public class CustomView1 extends Button {
+ public CustomView1(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr);
+ // OK
+ context.obtainStyledAttributes(R.styleable.CustomView1);
+ context.obtainStyledAttributes(defStyleRes, R.styleable.CustomView1);
+ context.obtainStyledAttributes(attrs, R.styleable.CustomView1);
+ context.obtainStyledAttributes(attrs, R.styleable.CustomView1, defStyleAttr, defStyleRes);
+
+ // Wrong:
+ context.obtainStyledAttributes(R.styleable.MyDeclareStyleable);
+ context.obtainStyledAttributes(defStyleRes, R.styleable.MyDeclareStyleable);
+ context.obtainStyledAttributes(attrs, R.styleable.MyDeclareStyleable);
+ context.obtainStyledAttributes(attrs, R.styleable.MyDeclareStyleable, defStyleAttr,
+ defStyleRes);
+
+ // Unknown: Not flagged
+ int[] dynamic = getStyleable();
+ context.obtainStyledAttributes(dynamic);
+ context.obtainStyledAttributes(defStyleRes, dynamic);
+ context.obtainStyledAttributes(attrs, dynamic);
+ context.obtainStyledAttributes(attrs, dynamic, defStyleAttr, defStyleRes);
+ }
+
+ private int[] getStyleable() {
+ return new int[0];
+ }
+
+ public static class MyLayout extends LinearLayout {
+ public MyLayout(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ context.obtainStyledAttributes(R.styleable.MyLayout);
+ }
+
+ public static class MyLayoutParams extends LinearLayout.LayoutParams {
+ public MyLayoutParams(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ context.obtainStyledAttributes(R.styleable.MyLayout_Layout); // OK
+ context.obtainStyledAttributes(R.styleable.MyLayout); // Wrong
+ context.obtainStyledAttributes(R.styleable.MyDeclareStyleable); // Wrong
+ }
+ }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/CustomViewDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `CustomViewDetector.test`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("CustomViewStyleable")
+ fun method() {
+ obtainStyledAttributes(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("CustomViewStyleable")
+ void method() {
+ obtainStyledAttributes(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection CustomViewStyleable
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="CustomViewStyleable" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'CustomViewStyleable'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore CustomViewStyleable ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/CustomX509TrustManager.md.html b/docs/checks/CustomX509TrustManager.md.html
new file mode 100644
index 00000000..805461b5
--- /dev/null
+++ b/docs/checks/CustomX509TrustManager.md.html
@@ -0,0 +1,173 @@
+
+(#) Implements custom TLS trust manager
+
+!!! WARNING: Implements custom TLS trust manager
+ This is a warning.
+
+Id
+: `CustomX509TrustManager`
+Summary
+: Implements custom TLS trust manager
+Severity
+: Warning
+Category
+: Security
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 7.0.0 (July 2021)
+Affects
+: Kotlin and Java files and library bytecode
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://goo.gle/CustomX509TrustManager
+Implementation
+: [Source Code](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/X509TrustManagerDetector.java)
+Tests
+: [Source Code](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/X509TrustManagerDetectorTest.kt)
+
+This check looks for custom `X509TrustManager` implementations.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/InsecureTLSIntentService.java:15:Warning: Implementing a
+custom X509TrustManager is error-prone and likely to be insecure. It is
+likely to disable certificate validation altogether, and is non-trivial
+to implement correctly without calling Android's default implementation.
+[CustomX509TrustManager]
+ TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() {
+ ----------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/InsecureTLSIntentService.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.app.IntentService;
+import android.content.Intent;
+
+import java.security.GeneralSecurityException;
+import java.security.cert.CertificateException;
+
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+public class InsecureTLSIntentService extends IntentService {
+ TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() {
+ @Override
+ public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+
+ @Override
+ public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
+ }
+
+ @Override
+ public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) throws CertificateException {
+ }
+ }};
+
+ public InsecureTLSIntentService() {
+ super("InsecureTLSIntentService");
+ }
+
+ @Override
+ protected void onHandleIntent(Intent intent) {
+ try {
+ SSLContext sc = SSLContext.getInstance("TLSv1.2");
+ sc.init(null, trustAllCerts, new java.security.SecureRandom());
+ HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
+ } catch (GeneralSecurityException e) {
+ System.out.println(e.getStackTrace());
+ }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/X509TrustManagerDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `X509TrustManagerDetector.testTrustsAll`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("CustomX509TrustManager")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("CustomX509TrustManager")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection CustomX509TrustManager
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="CustomX509TrustManager" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'CustomX509TrustManager'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore CustomX509TrustManager ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/CutPasteId.md.html b/docs/checks/CutPasteId.md.html
new file mode 100644
index 00000000..cc0547a8
--- /dev/null
+++ b/docs/checks/CutPasteId.md.html
@@ -0,0 +1,145 @@
+
+(#) Likely cut & paste mistakes
+
+!!! WARNING: Likely cut & paste mistakes
+ This is a warning.
+
+Id
+: `CutPasteId`
+Summary
+: Likely cut & paste mistakes
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/CutPasteDetector.java)
+Tests
+: [Source Code](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/CutPasteDetectorTest.java)
+Copyright Year
+: 2012
+
+This lint check looks for cases where you have cut & pasted calls to
+`findViewById` but have forgotten to update the R.id field. It's
+possible that your code is simply (redundantly) looking up the field
+repeatedly, but lint cannot distinguish that from a case where you for
+example want to initialize fields `prev` and `next` and you cut & pasted
+`findViewById(R.id.prev)` and forgot to update the second initialization
+to `R.id.next`.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/PasteError.java:10:Warning: The id R.id.previous has
+already been looked up in this method; possible cut & paste error?
+[CutPasteId]
+ next = (Button) findViewById(R.id.previous); // TYPO, meant R.id.next
+ ---------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/test/pkg/PasteError.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+import android.app.Activity;
+import android.widget.Button;
+
+public class PasteError extends Activity {
+ private Button next;
+ private Button previous;
+ protected void onCreate() {
+ previous = (Button) findViewById(R.id.previous);
+ next = (Button) findViewById(R.id.previous); // TYPO, meant R.id.next
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`test.pkg`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text linenumbers
+@id/next
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/CutPasteDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("CutPasteId")
+ fun method() {
+ findViewById(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("CutPasteId")
+ void method() {
+ findViewById(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection CutPasteId
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="CutPasteId" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'CutPasteId'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore CutPasteId ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DalvikOverride.md.html b/docs/checks/DalvikOverride.md.html
new file mode 100644
index 00000000..035014cd
--- /dev/null
+++ b/docs/checks/DalvikOverride.md.html
@@ -0,0 +1,177 @@
+
+(#) Method considered overridden by Dalvik
+
+!!! ERROR: Method considered overridden by Dalvik
+ This is an error.
+
+Id
+: `DalvikOverride`
+Summary
+: Method considered overridden by Dalvik
+Note
+: **This issue is disabled by default**; use `--enable DalvikOverride`
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Class files
+Editing
+: This check can *not* run live in the IDE editor
+Implementation
+: [Source Code](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/OverrideDetector.java)
+Tests
+: [Source Code](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/OverrideDetectorTest.kt)
+Copyright Year
+: 2012
+
+The Dalvik virtual machine will treat a package private method in one
+class as overriding a package private method in its super class, even if
+they are in separate packages.
+
+If you really did intend for this method to override the other, make the
+method `protected` instead.
+
+If you did **not** intend the override, consider making the method
+private, or changing its name or signature.
+
+Note that this check is disabled be default, because ART (the successor
+to Dalvik) no longer has this behavior.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/pkg2/Class2.java:7:Error: This package private method may be
+unintentionally overriding method in pkg1.Class1 [DalvikOverride]
+ void method() { // Flag this as an accidental override
+ ------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/pkg1/Class1.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package pkg1;
+
+public class Class1 {
+ void method() {
+ }
+
+ void method2(int foo) {
+ }
+
+ void method3() {
+ }
+
+ void method4() {
+ }
+
+ void method5() {
+ }
+
+ void method6() {
+ }
+
+ void method7() {
+ }
+
+ public static class Class4 extends Class1 {
+ void method() { // Not an error: same package
+ }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/pkg2/Class2.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package pkg2;
+
+import android.annotation.SuppressLint;
+import pkg1.Class1;
+
+public class Class2 extends Class1 {
+ void method() { // Flag this as an accidental override
+ }
+
+ void method2(String foo) { // not an override: different signature
+ }
+
+ static void method4() { // not an override: static
+ }
+
+ private void method3() { // not an override: private
+ }
+
+ protected void method5() { // not an override: protected
+ }
+
+ public void method6() { // not an override: public
+ }
+
+ @SuppressLint("DalvikOverride")
+ public void method7() { // suppressed: no warning
+ }
+
+ public class Class3 extends Object {
+ void method() { // Not an override: not a subclass
+ }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/OverrideDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `OverrideDetector.test`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DalvikOverride" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DalvikOverride'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DalvikOverride ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DataBindingWithoutKapt.md.html b/docs/checks/DataBindingWithoutKapt.md.html
new file mode 100644
index 00000000..452e0dec
--- /dev/null
+++ b/docs/checks/DataBindingWithoutKapt.md.html
@@ -0,0 +1,115 @@
+
+(#) Data Binding without Annotation Processing
+
+!!! WARNING: Data Binding without Annotation Processing
+ This is a warning.
+
+Id
+: `DataBindingWithoutKapt`
+Summary
+: Data Binding without Annotation Processing
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.5.0 (August 2019)
+Affects
+: Gradle build files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://kotlinlang.org/docs/reference/kapt.html
+Implementation
+: [Source Code](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/GradleDetector.kt)
+Tests
+: [Source Code](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/GradleDetectorTest.kt)
+
+Apps that use Kotlin and data binding should also apply the kotlin-kapt
+plugin.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+build.gradle:6:Warning: If you plan to use data binding in a Kotlin
+project, you should apply the kotlin-kapt plugin.
+[DataBindingWithoutKapt]
+ enabled true
+ ------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`build.gradle`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~groovy linenumbers
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+
+android {
+ dataBinding {
+ enabled true
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/GradleDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `GradleDetector.testDataBindingWithoutKaptUsingApplyPluginSyntax`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection DataBindingWithoutKapt
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DataBindingWithoutKapt" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DataBindingWithoutKapt'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DataBindingWithoutKapt ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DataExtractionRules.md.html b/docs/checks/DataExtractionRules.md.html
new file mode 100644
index 00000000..0fa0ab95
--- /dev/null
+++ b/docs/checks/DataExtractionRules.md.html
@@ -0,0 +1,179 @@
+
+(#) Missing data extraction rules
+
+!!! WARNING: Missing data extraction rules
+ This is a warning.
+
+Id
+: `DataExtractionRules`
+Summary
+: Missing data extraction rules
+Severity
+: Warning
+Category
+: Security
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 7.1.0 (January 2022)
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/about/versions/12/backup-restore#xml-changes
+See
+: https://goo.gle/DataExtractionRules
+Implementation
+: [Source Code](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/ManifestDetector.kt)
+Tests
+: [Source Code](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/ManifestDetectorTest.kt)
+
+Before Android 12, the attributes `android:allowBackup` and
+`android:fullBackupContent` were used to configure all forms of backup,
+including cloud backups, device-to-device transfers and adb backup.
+
+In Android 12 and higher, these attributes have been deprecated and will
+only apply to cloud backups. You should instead use the attribute
+`android:dataExtractionRules`, specifying an `@xml` resource that
+configures which files to back up, for cloud backups and for
+device-to-device transfers, separately. If your `minSdkVersion` supports
+older versions, you'll still want to specify an
+`android:fullBackupContent` resource if the default behavior is not
+right for your app.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:11:Warning: The attribute android:allowBackup is
+deprecated from Android 12 and the default allows backup
+[DataExtractionRules]
+ android:allowBackup="true" >
+ ----
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="foo.bar2"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk android:minSdkVersion="31" />
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:allowBackup="true" >
+ </application>
+
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <!-- Home -->
+ <string name="home_title">Home Sample</string>
+ <string name="show_all_apps">All</string>
+
+ <!-- Home Menus -->
+ <string name="menu_wallpaper">Wallpaper</string>
+ <string name="menu_search">Search</string>
+ <string name="menu_settings">Settings</string>
+ <string name="sample" translatable="false">Ignore Me</string>
+
+ <!-- Wallpaper -->
+ <string name="wallpaper_instructions">Tap picture to set portrait wallpaper</string>
+</resources>
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ManifestDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ManifestDetector.testAllowBackupUnnecessary`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="DataExtractionRules"` on the problematic XML element
+ (or one of its enclosing elements). You may also need to add the
+ following namespace declaration on the root element in the XML file
+ if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <application tools:ignore="DataExtractionRules" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DataExtractionRules" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DataExtractionRules'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DataExtractionRules ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DeepLinkInActivityDestination.md.html b/docs/checks/DeepLinkInActivityDestination.md.html
new file mode 100644
index 00000000..dd797ed4
--- /dev/null
+++ b/docs/checks/DeepLinkInActivityDestination.md.html
@@ -0,0 +1,183 @@
+
+(#) A should not be attached to an destination
+
+!!! WARNING: A should not be attached to an destination
+ This is a warning.
+
+Id
+: `DeepLinkInActivityDestination`
+Summary
+: A should not be attached to an destination
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Identifier
+: androidx.navigation.runtime
+Feedback
+: https://issuetracker.google.com/issues/new?component=409828
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.navigation:navigation-runtime](androidx_navigation_navigation-runtime.md.html)
+Since
+: 2.5.0
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/navigation/navigation-runtime-lint/src/main/java/androidx/navigation/runtime/lint/DeepLinkInActivityDestinationDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/navigation/navigation-runtime-lint/src/test/java/androidx/navigation/runtime/lint/DeepLinkInActivityDestinationDetectorTest.kt)
+Copyright Year
+: 2022
+
+Attaching a to an destination will never give
+ the right behavior when using an implicit deep link on
+another app's task (where the system back should
+immediately take the user back to the app that triggered
+the deep link). Instead, attach the deep link directly to
+ the second activity (either by manually writing the appropriate
+ or by adding the to the start
+destination of a nav host in that second activity).
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/navigation/nav_main.xml:17:Warning: Do not attach a to an
+ destination. Attach the deeplink directly to the second
+activity or the start destination of a nav host in the second activity
+instead. [DeepLinkInActivityDestination]
+ <deepLink app:uri="www.example.com" />
+ --------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/navigation/nav_main.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<navigation xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/nav_main"
+ app:startDestination="@id/fragment_main"
+ >
+
+ <fragment
+ android:id="@+id/fragment_main"
+ android:name="com.example.deeplink.MainFragment"
+ />
+
+ <activity
+ android:id="@+id/activity_deep_link"
+ android:name="com.example.deeplink.DeepLinkActivity"
+ >
+ <deepLink app:uri="www.example.com" />
+ </activity>
+
+</navigation>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/navigation/navigation-runtime-lint/src/test/java/androidx/navigation/runtime/lint/DeepLinkInActivityDestinationDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `DeepLinkInActivityDestinationDetector.expectFail`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=409828.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.navigation:navigation-runtime:2.9.0-rc01")
+
+// build.gradle
+implementation 'androidx.navigation:navigation-runtime:2.9.0-rc01'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.navigation.runtime)
+
+# libs.versions.toml
+[versions]
+navigation-runtime = "2.9.0-rc01"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+navigation-runtime = {
+ module = "androidx.navigation:navigation-runtime",
+ version.ref = "navigation-runtime"
+}
+```
+
+2.9.0-rc01 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.navigation:navigation-runtime](androidx_navigation_navigation-runtime.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="DeepLinkInActivityDestination"` on the problematic
+ XML element (or one of its enclosing elements). You may also need to
+ add the following namespace declaration on the root element in the
+ XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <deepLink xmlns:tools="http://schemas.android.com/tools"
+ tools:ignore="DeepLinkInActivityDestination" ...>
+ ...
+ </deepLink>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DeepLinkInActivityDestination" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DeepLinkInActivityDestination'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DeepLinkInActivityDestination ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DefaultCleartextTraffic.md.html b/docs/checks/DefaultCleartextTraffic.md.html
new file mode 100644
index 00000000..87c7c87b
--- /dev/null
+++ b/docs/checks/DefaultCleartextTraffic.md.html
@@ -0,0 +1,168 @@
+
+(#) Application by default permits cleartext traffic
+
+!!! WARNING: Application by default permits cleartext traffic
+ This is a warning.
+
+Id
+: `DefaultCleartextTraffic`
+Summary
+: Application by default permits cleartext traffic
+Severity
+: Warning
+Category
+: Security
+Platform
+: Android
+Vendor
+: Google - Android 3P Vulnerability Research
+Contact
+: https://github.com/google/android-security-lints
+Feedback
+: https://github.com/google/android-security-lints/issues
+Min
+: Lint 4.1
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [com.android.security.lint:lint](com_android_security_lint_lint.md.html)
+Since
+: 1.0.1
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://goo.gle/DefaultCleartextTraffic
+Implementation
+: [Source Code](https://github.com/google/android-security-lints/tree/main/checks/src/main/java/com/example/lint/checks/MissingNetworkSecurityConfigDetector.kt)
+Tests
+: [Source Code](https://github.com/google/android-security-lints/tree/main/checks/src/test/java/com/example/lint/checks/MissingNetworkSecurityConfigDetectorTest.kt)
+Copyright Year
+: 2023
+
+Apps targeting SDK versions earlier than 28 trust cleartext traffic by
+default. The application must explicitly opt out of this in order to
+only use secure connections.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:3:Warning: On SDK versions below 28, the application
+by default trusts cleartext traffic. Add a Network Security Config file
+to opt out of these insecure connections. [DefaultCleartextTraffic]
+<application>
+ -----------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest xmlns:android='http://schemas.android.com/apk/res/android' package='test.pkg'>
+<uses-sdk android:targetSdkVersion='27'/>
+<application>
+ <activity android:name='com.example.MainActivity'></activity>
+</application>
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/google/android-security-lints/tree/main/checks/src/test/java/com/example/lint/checks/MissingNetworkSecurityConfigDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `MissingNetworkSecurityConfigDetector.testWhenNoNetworkSecurityConfig_defaultCleartextTrafficSdkLevel_showsWarning`.
+To report a problem with this extracted sample, visit
+https://github.com/google/android-security-lints/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.android.security.lint:lint:1.0.3")
+
+// build.gradle
+lintChecks 'com.android.security.lint:lint:1.0.3'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.com.android.security.lint.lint)
+
+# libs.versions.toml
+[versions]
+com-android-security-lint-lint = "1.0.3"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+com-android-security-lint-lint = {
+ module = "com.android.security.lint:lint",
+ version.ref = "com-android-security-lint-lint"
+}
+```
+
+1.0.3 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.android.security.lint:lint](com_android_security_lint_lint.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="DefaultCleartextTraffic"` on the problematic XML
+ element (or one of its enclosing elements). You may also need to add
+ the following namespace declaration on the root element in the XML
+ file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <application tools:ignore="DefaultCleartextTraffic" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DefaultCleartextTraffic" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DefaultCleartextTraffic'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DefaultCleartextTraffic ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DefaultEncoding.md.html b/docs/checks/DefaultEncoding.md.html
new file mode 100644
index 00000000..aef44ccd
--- /dev/null
+++ b/docs/checks/DefaultEncoding.md.html
@@ -0,0 +1,224 @@
+
+(#) Using Default Character Encoding
+
+!!! ERROR: Using Default Character Encoding
+ This is an error.
+
+Id
+: `DefaultEncoding`
+Summary
+: Using Default Character Encoding
+Note
+: **This issue is disabled by default**; use `--enable DefaultEncoding`
+Severity
+: Error
+Category
+: Correctness
+Platform
+: JDK
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 7.3.0 (September 2022)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/DefaultEncodingDetector.kt)
+Tests
+: [Source Code](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/DefaultEncodingDetectorTest.kt)
+
+Some APIs will implicitly use the default system character encoding
+instead of UTF-8 when converting to or from bytes, such as when creating
+a default `FileReader`.
+
+This is *usually* not correct; you only want to do this if you need to
+read files created by other programs where they have deliberately
+written in the same encoding. The default encoding varies from platform
+to platform and can vary from locale to locale, so this makes it
+difficult to interpret files containing non-ASCII characters.
+
+We recommend using UTF-8 everywhere.
+
+Note that on Android, the default file encoding is always UTF-8 (see
+https://developer.android.com/reference/java/nio/charset/Charset#defaultCharset()
+for more), so this lint check deliberately does not flag any problems in
+Android code, since it is always safe to rely on the default character
+encoding there.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/Test.java:14:Error: This file will be written with the
+default system encoding instead of a specific charset which is usually a
+mistake; add StandardCharsets.UTF_8? [DefaultEncoding]
+ new FileWriter("/path"); // ERROR 1
+ -----------------------
+src/test/pkg/Test.java:15:Error: This file will be written with the
+default system encoding instead of a specific charset which is usually a
+mistake; add charset argument, FileWriter(..., UTF_8)?
+[DefaultEncoding]
+ new FileWriter(file); // ERROR 2
+ --------------------
+src/test/pkg/Test.java:16:Error: This file will be written with the
+default system encoding instead of a specific charset which is usually a
+mistake; add charset argument, FileWriter(..., UTF_8)?
+[DefaultEncoding]
+ new FileWriter(file, true); // ERROR 3
+ --------------------------
+src/test/pkg/Test.java:17:Error: This file will be written with the
+default system encoding instead of a specific charset which is usually a
+mistake; add charset argument, FileWriter(..., UTF_8)?
+[DefaultEncoding]
+ new PrintWriter(new BufferedWriter(new FileWriter(file))); // ERROR 4
+ --------------------
+src/test/pkg/Test.java:24:Error: This PrintWriter will use the default
+system encoding instead of a specific charset which is usually a
+mistake; add charset argument, PrintWriter(..., UTF_8)?
+[DefaultEncoding]
+ new PrintWriter(System.out, true); // ERROR 5
+ ---------------------------------
+src/test/pkg/Test.java:25:Error: This PrintWriter will use the default
+system encoding instead of a specific charset which is usually a
+mistake; add charset argument, PrintWriter(..., UTF_8)?
+[DefaultEncoding]
+ new PrintWriter("/path"); // ERROR 6
+ ------------------------
+src/test/pkg/Test.java:26:Error: This PrintWriter will use the default
+system encoding instead of a specific charset which is usually a
+mistake; add charset argument, PrintWriter(..., UTF_8)?
+[DefaultEncoding]
+ new PrintWriter(file); // ERROR 7
+ ---------------------
+src/test/pkg/Test.java:36:Error: This string will be interpreted with
+the default system encoding instead of a specific charset which is
+usually a mistake; add charset argument, String(..., UTF_8)?
+[DefaultEncoding]
+ new String(bytes); // ERROR 8
+ -----------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/Test.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+
+@SuppressWarnings({"Since15", "unused", "CharsetObjectCanBeUsed"})
+public class Test {
+ public void testFileWriter(File file, FileDescriptor fd) throws IOException {
+ new FileWriter("/path"); // ERROR 1
+ new FileWriter(file); // ERROR 2
+ new FileWriter(file, true); // ERROR 3
+ new PrintWriter(new BufferedWriter(new FileWriter(file))); // ERROR 4
+
+ new FileWriter(fd); // OK 1
+ new FileWriter(file, StandardCharsets.UTF_8); // OK 2
+ }
+
+ public void testPrintWriter(File file) throws IOException {
+ new PrintWriter(System.out, true); // ERROR 5
+ new PrintWriter("/path"); // ERROR 6
+ new PrintWriter(file); // ERROR 7
+
+ new PrintWriter("/path", "utf-8"); // OK 3
+ new PrintWriter("/path", StandardCharsets.UTF_8); // OK 4
+ new PrintWriter(System.out, true, StandardCharsets.UTF_8); // OK 5
+ new PrintWriter(file, "utf-8"); // OK 6
+ new PrintWriter(file, Charset.defaultCharset()); // OK 7
+ }
+
+ public void test(byte[] bytes) throws IOException {
+ new String(bytes); // ERROR 8
+ new String(bytes, StandardCharsets.UTF_8); // OK 9
+ new String(bytes, "UTF-8"); // OK 10
+ new String(bytes, 0, 5, "UTF-8"); // OK 11
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/DefaultEncodingDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("DefaultEncoding")
+ fun method() {
+ getBytes(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("DefaultEncoding")
+ void method() {
+ getBytes(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection DefaultEncoding
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DefaultEncoding" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DefaultEncoding'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DefaultEncoding ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DefaultLayoutAttribute.md.html b/docs/checks/DefaultLayoutAttribute.md.html
new file mode 100644
index 00000000..4631f903
--- /dev/null
+++ b/docs/checks/DefaultLayoutAttribute.md.html
@@ -0,0 +1,153 @@
+
+(#) Flags default layout values
+
+!!! WARNING: Flags default layout values
+ This is a warning.
+
+Id
+: `DefaultLayoutAttribute`
+Summary
+: Flags default layout values
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: vanniktech/lint-rules/
+Feedback
+: https://github.com/vanniktech/lint-rules/issues
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [com.vanniktech:lint-rules-android](com_vanniktech_lint-rules-android.md.html)
+Since
+: 0.6.0
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/main/kotlin/com/vanniktech/lintrules/android/DefaultLayoutAttributeDetector.kt)
+Tests
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/test/kotlin/com/vanniktech/lintrules/android/DefaultLayoutAttributeDetectorTest.kt)
+
+Flags default layout values that are not needed. One for instance is the
+textStyle="normal" that can be just removed.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/ids.xml:5:Warning: This is the default and hence you don't
+need to specify it [DefaultLayoutAttribute]
+ android:textStyle="normal"/>
+ ------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/layout/ids.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<TextView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textStyle="normal"/>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/test/kotlin/com/vanniktech/lintrules/android/DefaultLayoutAttributeDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `DefaultLayoutAttributeDetector.textStyleNormal`.
+To report a problem with this extracted sample, visit
+https://github.com/vanniktech/lint-rules/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.vanniktech:lint-rules-android:0.25.0")
+
+// build.gradle
+lintChecks 'com.vanniktech:lint-rules-android:0.25.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.lint.rules.android)
+
+# libs.versions.toml
+[versions]
+lint-rules-android = "0.25.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+lint-rules-android = {
+ module = "com.vanniktech:lint-rules-android",
+ version.ref = "lint-rules-android"
+}
+```
+
+0.25.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.vanniktech:lint-rules-android](com_vanniktech_lint-rules-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="DefaultLayoutAttribute"` on the problematic XML
+ element (or one of its enclosing elements). You may also need to add
+ the following namespace declaration on the root element in the XML
+ file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DefaultLayoutAttribute" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DefaultLayoutAttribute'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DefaultLayoutAttribute ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DefaultLocale.md.html b/docs/checks/DefaultLocale.md.html
new file mode 100644
index 00000000..4420b36b
--- /dev/null
+++ b/docs/checks/DefaultLocale.md.html
@@ -0,0 +1,221 @@
+
+(#) Implied default locale in case conversion
+
+!!! WARNING: Implied default locale in case conversion
+ This is a warning.
+
+Id
+: `DefaultLocale`
+Summary
+: Implied default locale in case conversion
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/reference/java/util/Locale.html#default_locale
+Implementation
+: [Source Code](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/LocaleDetector.kt)
+Tests
+: [Source Code](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/LocaleDetectorTest.kt)
+Copyright Year
+: 2012
+
+Calling `String#toLowerCase()` or `#toUpperCase()` **without specifying
+an explicit locale** is a common source of bugs. The reason for that is
+that those methods will use the current locale on the user's device, and
+even though the code appears to work correctly when you are developing
+the app, it will fail in some locales. For example, in the Turkish
+locale, the uppercase replacement for `i` is **not** `I`.
+
+If you want the methods to just perform ASCII replacement, for example
+to convert an enum name, call `String#toUpperCase(Locale.ROOT)` instead.
+If you really want to use the current locale, call
+`String#toUpperCase(Locale.getDefault())` instead.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/LocaleTest.java:11:Warning: Implicitly using the default
+locale is a common source of bugs: Use toUpperCase(Locale) instead. For
+strings meant to be internal use Locale.ROOT, otherwise
+Locale.getDefault(). [DefaultLocale]
+ System.out.println("WRONG".toUpperCase());
+ -----------
+src/test/pkg/LocaleTest.java:16:Warning: Implicitly using the default
+locale is a common source of bugs: Use toLowerCase(Locale) instead. For
+strings meant to be internal use Locale.ROOT, otherwise
+Locale.getDefault(). [DefaultLocale]
+ System.out.println("WRONG".toLowerCase());
+ -----------
+src/test/pkg/LocaleTest.java:20:Warning: Implicitly using the default
+locale is a common source of bugs: Use String.format(Locale, ...)
+instead [DefaultLocale]
+ String.format("WRONG: %f", 1.0f); // Implies locale
+ --------------------------------
+src/test/pkg/LocaleTest.java:21:Warning: Implicitly using the default
+locale is a common source of bugs: Use String.format(Locale, ...)
+instead [DefaultLocale]
+ String.format("WRONG: %1$f", 1.0f);
+ ----------------------------------
+src/test/pkg/LocaleTest.java:22:Warning: Implicitly using the default
+locale is a common source of bugs: Use String.format(Locale, ...)
+instead [DefaultLocale]
+ String.format("WRONG: %e", 1.0f);
+ --------------------------------
+src/test/pkg/LocaleTest.java:23:Warning: Implicitly using the default
+locale is a common source of bugs: Use String.format(Locale, ...)
+instead [DefaultLocale]
+ String.format("WRONG: %d", 1.0f);
+ --------------------------------
+src/test/pkg/LocaleTest.java:24:Warning: Implicitly using the default
+locale is a common source of bugs: Use String.format(Locale, ...)
+instead [DefaultLocale]
+ String.format("WRONG: %g", 1.0f);
+ --------------------------------
+src/test/pkg/LocaleTest.java:25:Warning: Implicitly using the default
+locale is a common source of bugs: Use String.format(Locale, ...)
+instead [DefaultLocale]
+ String.format("WRONG: %g", 1.0f);
+ --------------------------------
+src/test/pkg/LocaleTest.java:26:Warning: Implicitly using the default
+locale is a common source of bugs: Use String.format(Locale, ...)
+instead [DefaultLocale]
+ String.format("WRONG: %1$tm %1$te,%1$tY",
+ ^
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/LocaleTest.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import java.text.*;
+import java.util.*;
+@SuppressWarnings({"ResultOfMethodCallIgnored", "MalformedFormatString", "MethodMayBeStatic", "ResultOfObjectAllocationIgnored", "SimpleDateFormatWithoutLocale", "StringToUpperCaseOrToLowerCaseWithoutLocale", "ClassNameDiffersFromFileName"})
+public class LocaleTest {
+ public void testStrings() {
+ System.out.println("OK".toUpperCase(Locale.getDefault()));
+ System.out.println("OK".toUpperCase(Locale.US));
+ System.out.println("OK".toUpperCase(Locale.CHINA));
+ System.out.println("WRONG".toUpperCase());
+
+ System.out.println("OK".toLowerCase(Locale.getDefault()));
+ System.out.println("OK".toLowerCase(Locale.US));
+ System.out.println("OK".toLowerCase(Locale.CHINA));
+ System.out.println("WRONG".toLowerCase());
+
+ String.format(Locale.getDefault(), "OK: %f", 1.0f);
+ String.format("OK: %x %A %c %b %B %h %n %%", 1, 2, 'c', true, false, 5);
+ String.format("WRONG: %f", 1.0f); // Implies locale
+ String.format("WRONG: %1$f", 1.0f);
+ String.format("WRONG: %e", 1.0f);
+ String.format("WRONG: %d", 1.0f);
+ String.format("WRONG: %g", 1.0f);
+ String.format("WRONG: %g", 1.0f);
+ String.format("WRONG: %1$tm %1$te,%1$tY",
+ new GregorianCalendar(2012, GregorianCalendar.AUGUST, 27));
+ }
+
+ @android.annotation.SuppressLint("NewApi") // DateFormatSymbols requires API 9
+ public void testSimpleDateFormat() {
+ new SimpleDateFormat(); // WRONG
+ new SimpleDateFormat("yyyy-MM-dd"); // WRONG
+ new SimpleDateFormat("yyyy-MM-dd", DateFormatSymbols.getInstance()); // WRONG
+ new SimpleDateFormat("yyyy-MM-dd", Locale.US); // OK
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/LocaleDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `LocaleDetector.testBasic`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("DefaultLocale")
+ fun method() {
+ toLowerCase(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("DefaultLocale")
+ void method() {
+ toLowerCase(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection DefaultLocale
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DefaultLocale" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DefaultLocale'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DefaultLocale ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DefaultTrustedUserCerts.md.html b/docs/checks/DefaultTrustedUserCerts.md.html
new file mode 100644
index 00000000..ab0551b7
--- /dev/null
+++ b/docs/checks/DefaultTrustedUserCerts.md.html
@@ -0,0 +1,170 @@
+
+(#) Application by default trusts user-added CA certificates
+
+!!! WARNING: Application by default trusts user-added CA certificates
+ This is a warning.
+
+Id
+: `DefaultTrustedUserCerts`
+Summary
+: Application by default trusts user-added CA certificates
+Severity
+: Warning
+Category
+: Security
+Platform
+: Android
+Vendor
+: Google - Android 3P Vulnerability Research
+Contact
+: https://github.com/google/android-security-lints
+Feedback
+: https://github.com/google/android-security-lints/issues
+Min
+: Lint 4.1
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [com.android.security.lint:lint](com_android_security_lint_lint.md.html)
+Since
+: 1.0.1
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://goo.gle/DefaultTrustedUserCerts
+Implementation
+: [Source Code](https://github.com/google/android-security-lints/tree/main/checks/src/main/java/com/example/lint/checks/MissingNetworkSecurityConfigDetector.kt)
+Tests
+: [Source Code](https://github.com/google/android-security-lints/tree/main/checks/src/test/java/com/example/lint/checks/MissingNetworkSecurityConfigDetectorTest.kt)
+Copyright Year
+: 2023
+
+Apps targeting SDK versions earlier than 24 trust user-added CA
+certificates by default. In practice, it is better to limit the set of
+trusted CAs so only trusted CAs are used for an app's secure
+connections.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:3:Warning: On SDK versions below 24, the application
+by default trusts user-added CA certificates. Add a Network Security
+Config file to opt out of this insecure behavior.
+[DefaultTrustedUserCerts]
+<application>
+ -----------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest xmlns:android='http://schemas.android.com/apk/res/android' package='test.pkg'>
+<uses-sdk android:targetSdkVersion='23'/>
+<application>
+ <activity android:name='com.example.MainActivity'></activity>
+</application>
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/google/android-security-lints/tree/main/checks/src/test/java/com/example/lint/checks/MissingNetworkSecurityConfigDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `MissingNetworkSecurityConfigDetector.testWhenNoNetworkSecurityConfig_defaultUserCerts_showsWarning`.
+To report a problem with this extracted sample, visit
+https://github.com/google/android-security-lints/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.android.security.lint:lint:1.0.3")
+
+// build.gradle
+lintChecks 'com.android.security.lint:lint:1.0.3'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.com.android.security.lint.lint)
+
+# libs.versions.toml
+[versions]
+com-android-security-lint-lint = "1.0.3"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+com-android-security-lint-lint = {
+ module = "com.android.security.lint:lint",
+ version.ref = "com-android-security-lint-lint"
+}
+```
+
+1.0.3 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.android.security.lint:lint](com_android_security_lint_lint.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="DefaultTrustedUserCerts"` on the problematic XML
+ element (or one of its enclosing elements). You may also need to add
+ the following namespace declaration on the root element in the XML
+ file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <application tools:ignore="DefaultTrustedUserCerts" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DefaultTrustedUserCerts" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DefaultTrustedUserCerts'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DefaultTrustedUserCerts ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DefaultUncaughtExceptionDelegation.md.html b/docs/checks/DefaultUncaughtExceptionDelegation.md.html
new file mode 100644
index 00000000..00846ee0
--- /dev/null
+++ b/docs/checks/DefaultUncaughtExceptionDelegation.md.html
@@ -0,0 +1,111 @@
+
+(#) Missing default uncaught exception handler delegation
+
+!!! WARNING: Missing default uncaught exception handler delegation
+ This is a warning.
+
+Id
+: `DefaultUncaughtExceptionDelegation`
+Summary
+: Missing default uncaught exception handler delegation
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 8.11.0-alpha07 (April 2025)
+Affects
+: Kotlin and Java files
+Editing
+: This check can *not* run live in the IDE editor
+Implementation
+: [Source Code](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/UncaughtExceptionHandlerDetector.kt)
+Tests
+: [Source Code](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/UncaughtExceptionHandlerDetectorTest.kt)
+
+A default uncaught exception handler should usually call the existing
+(previously set) default uncaught exception handler. This is especially
+true on Android, which uses a default uncaught exception handler to
+handle crashes. This lint check reports calls to
+`setDefaultUncaughtExceptionHandler` unless we can also see a call to
+`getDefaultUncaughtExceptionHandler` (to get the existing handler) in
+the same module. Make sure you also call
+`existingHandler.uncaughtException(thread, throwable)` from your new
+handler.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/com/example/app/test.kt:7:Warning: Must call
+getDefaultUncaughtExceptionHandler() to get the existing handler, and
+call existingHandler.uncaughtException(thread, throwable) from your new
+handler [DefaultUncaughtExceptionDelegation]
+ setDefaultUncaughtExceptionHandler { thread, throwable ->
+ ^
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/com/example/app/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package com.example.app
+
+import android.util.Log
+import java.lang.Thread.setDefaultUncaughtExceptionHandler
+
+fun foo() {
+ setDefaultUncaughtExceptionHandler { thread, throwable ->
+ Log.e("foo", "Uncaught exception")
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/UncaughtExceptionHandlerDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DefaultUncaughtExceptionDelegation" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DefaultUncaughtExceptionDelegation'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DefaultUncaughtExceptionDelegation ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DeletedProvider.md.html b/docs/checks/DeletedProvider.md.html
new file mode 100644
index 00000000..0eee685b
--- /dev/null
+++ b/docs/checks/DeletedProvider.md.html
@@ -0,0 +1,170 @@
+
+(#) Using Deleted Provider
+
+!!! ERROR: Using Deleted Provider
+ This is an error.
+
+Id
+: `DeletedProvider`
+Summary
+: Using Deleted Provider
+Severity
+: Error
+Category
+: Security
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.2.0 (September 2018)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://android-developers.googleblog.com/2018/03/cryptography-changes-in-android-p.html
+See
+: https://goo.gle/DeletedProvider
+Implementation
+: [Source Code](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/DeletedProviderDetector.kt)
+Tests
+: [Source Code](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/DeletedProviderDetectorTest.kt)
+
+The `Crypto` provider has been completely removed in Android P (and was
+deprecated in an earlier release). This means that the code will throw a
+`NoSuchProviderException` and the app will crash. Even if the code
+catches that exception at a higher level, this is not secure and should
+not be used.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/RemovedGeneratorTest.java:24:Error: The Crypto provider has
+been deleted in Android P (and was deprecated in Android N), so the code
+will crash [DeletedProvider]
+ SecureRandom instance2 = SecureRandom.getInstance("SHA1PRNG", "Crypto");
+ --------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/RemovedGeneratorTest.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.IvParameterSpec;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.SecureRandom;
+
+@SuppressWarnings({"FieldCanBeLocal", "EmptyCatchBlock", "ClassNameDiffersFromFileName", "TryWithIdenticalCatches"})
+public class RemovedGeneratorTest {
+ private static byte[] f3341b;
+ private static byte[] f3340a;
+ private static SecretKey f3342c;
+ private static IvParameterSpec f3343d;
+ private static Cipher f3344e;
+ static {
+ System.loadLibrary("NewSecretJNI");
+ if (f3340a != null && f3341b != null) {
+ try {
+ KeyGenerator instance = KeyGenerator.getInstance("AES");
+ SecureRandom instance2 = SecureRandom.getInstance("SHA1PRNG", "Crypto");
+ instance2.setSeed(f3340a);
+ instance.init(128, instance2);
+ f3342c = instance.generateKey();
+ f3343d = new IvParameterSpec(f3341b);
+ f3344e = Cipher.getInstance("AES/CBC/PKCS5Padding");
+ } catch (NoSuchAlgorithmException e) {
+ } catch (NoSuchPaddingException e2) {
+ } catch (NoSuchProviderException e3) {
+ e3.printStackTrace();
+ }
+ }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/DeletedProviderDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `DeletedProviderDetector.testScenario`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("DeletedProvider")
+ fun method() {
+ getInstance(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("DeletedProvider")
+ void method() {
+ getInstance(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection DeletedProvider
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DeletedProvider" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DeletedProvider'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DeletedProvider ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DenyListedApi.md.html b/docs/checks/DenyListedApi.md.html
new file mode 100644
index 00000000..4e4406e8
--- /dev/null
+++ b/docs/checks/DenyListedApi.md.html
@@ -0,0 +1,197 @@
+
+(#) Deny-listed API
+
+!!! ERROR: Deny-listed API
+ This is an error.
+
+Id
+: `DenyListedApi`
+Summary
+: Deny-listed API
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.1.0
+Affects
+: Kotlin and Java files, resource files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/denylistedapis/DenyListedApiDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/denylistedapis/DenyListedApiDetectorTest.kt)
+Copyright Year
+: 2022
+
+This lint check flags usages of APIs in external libraries that we
+prefer not to use.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/foo/SomeView.kt:9:Error: Use Context#getDrawableCompat() instead
+[DenyListedApi]
+ ContextCompat.getDrawable(context, 42)
+ -----------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/foo/SomeView.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package foo
+
+import android.content.Context
+import android.graphics.drawable.Drawable
+import androidx.core.content.ContextCompat
+
+class SomeView(context: Context) {
+ init {
+ ContextCompat.getDrawable(context, 42)
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/denylistedapis/DenyListedApiDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `DenyListedApiDetector.flag function with params in deny list`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/slack-lints.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("DenyListedApi")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("DenyListedApi")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection DenyListedApi
+ problematicStatement()
+ ```
+
+* Adding the suppression attribute `tools:ignore="DenyListedApi"` on
+ the problematic XML element (or one of its enclosing elements). You
+ may also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <java.util.LinkedList xmlns:tools="http://schemas.android.com/tools"
+ tools:ignore="DenyListedApi" ...>
+ ...
+ </java.util.LinkedList>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DenyListedApi" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DenyListedApi'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DenyListedApi ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DenyListedBlockingApi.md.html b/docs/checks/DenyListedBlockingApi.md.html
new file mode 100644
index 00000000..8be1224f
--- /dev/null
+++ b/docs/checks/DenyListedBlockingApi.md.html
@@ -0,0 +1,197 @@
+
+(#) Deny-listed API
+
+!!! ERROR: Deny-listed API
+ This is an error.
+
+Id
+: `DenyListedBlockingApi`
+Summary
+: Deny-listed API
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.7.0
+Affects
+: Kotlin and Java files, resource files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/denylistedapis/DenyListedApiDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/denylistedapis/DenyListedApiDetectorTest.kt)
+Copyright Year
+: 2022
+
+This lint check flags usages of APIs in external libraries that we
+prefer not to use.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/foo/SomeClass.kt:6:Error: Blocking calls in coroutines can cause
+deadlocks and application jank. Prefer making the enclosing function a
+suspend function or refactoring this in a way to use non-blocking calls.
+If running in a test, use runTest {} or Turbine to test synchronous
+values. [DenyListedBlockingApi]
+ val result = runBlocking {}
+ -----------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/foo/SomeClass.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package foo
+
+import kotlinx.coroutines.runBlocking
+
+class SomeClass {
+ val result = runBlocking {}
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/denylistedapis/DenyListedApiDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `DenyListedApiDetector.coroutineRunBlocking`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/slack-lints.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("DenyListedBlockingApi")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("DenyListedBlockingApi")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection DenyListedBlockingApi
+ problematicStatement()
+ ```
+
+* Adding the suppression attribute
+ `tools:ignore="DenyListedBlockingApi"` on the problematic XML
+ element (or one of its enclosing elements). You may also need to add
+ the following namespace declaration on the root element in the XML
+ file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <java.util.LinkedList xmlns:tools="http://schemas.android.com/tools"
+ tools:ignore="DenyListedBlockingApi" ...>
+ ...
+ </java.util.LinkedList>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DenyListedBlockingApi" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DenyListedBlockingApi'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DenyListedBlockingApi ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/Deprecated.md.html b/docs/checks/Deprecated.md.html
new file mode 100644
index 00000000..fe9555ad
--- /dev/null
+++ b/docs/checks/Deprecated.md.html
@@ -0,0 +1,209 @@
+
+(#) Using deprecated resources
+
+!!! WARNING: Using deprecated resources
+ This is a warning.
+
+Id
+: `Deprecated`
+Summary
+: Using deprecated resources
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Kotlin and Java files, manifest files and resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/DeprecationDetector.kt)
+Tests
+: [Source Code](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/DeprecationDetectorTest.kt)
+Copyright Year
+: 2011
+
+Deprecated views, attributes and so on are deprecated because there is a
+better way to do something. Do it that new way. You've been warned.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/deprecation.xml:1:Warning: AbsoluteLayout is deprecated
+[Deprecated]
+<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ --------------
+res/layout/deprecation.xml:15:Warning: android:autoText is deprecated:
+Use inputType instead [Deprecated]
+ android:autoText="true"
+ -----------------------
+res/layout/deprecation.xml:16:Warning: android:capitalize is deprecated:
+Use inputType instead [Deprecated]
+ android:capitalize="true"
+ -------------------------
+res/layout/deprecation.xml:17:Warning: android:editable is deprecated:
+Use an to make it editable [Deprecated]
+ android:editable="true"
+ -----------------------
+res/layout/deprecation.xml:19:Warning: android:inputMethod is
+deprecated: Use inputType instead [Deprecated]
+ android:inputMethod="@+id/foo"
+ ------------------------------
+res/layout/deprecation.xml:20:Warning: android:numeric is deprecated:
+Use inputType instead [Deprecated]
+ android:numeric="true"
+ ----------------------
+res/layout/deprecation.xml:21:Warning: android:password is deprecated:
+Use inputType instead [Deprecated]
+ android:password="true"
+ -----------------------
+res/layout/deprecation.xml:22:Warning: android:phoneNumber is
+deprecated: Use inputType instead [Deprecated]
+ android:phoneNumber="true"
+ --------------------------
+res/layout/deprecation.xml:25:Warning: android:editable is deprecated:
+ is already editable [Deprecated]
+ <EditText android:editable="true" />
+ -----------------------
+res/layout/deprecation.xml:26:Warning: android:editable is deprecated:
+Use inputType instead [Deprecated]
+ <EditText android:editable="false" />
+ ------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/layout/deprecation.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <Button
+ android:id="@+id/button1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_x="5dp"
+ android:layout_y="100dp"
+ android:text="Button" />
+
+ <!-- Deprecated attributes -->
+ <TextView
+ android:autoText="true"
+ android:capitalize="true"
+ android:editable="true"
+ android:enabled="true"
+ android:inputMethod="@+id/foo"
+ android:numeric="true"
+ android:password="true"
+ android:phoneNumber="true"
+ android:singleLine="true" />
+
+ <EditText android:editable="true" />
+ <EditText android:editable="false" />
+
+</AbsoluteLayout>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/DeprecationDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `DeprecationDetector.testApi4`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="Deprecated"` on the
+ problematic XML element (or one of its enclosing elements). You may
+ also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <AbsoluteLayout sharedUserId="..." tools:ignore="Deprecated" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("Deprecated")
+ fun method() {
+ getInstance(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("Deprecated")
+ void method() {
+ getInstance(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection Deprecated
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="Deprecated" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'Deprecated'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore Deprecated ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DeprecatedCall.md.html b/docs/checks/DeprecatedCall.md.html
new file mode 100644
index 00000000..060e135a
--- /dev/null
+++ b/docs/checks/DeprecatedCall.md.html
@@ -0,0 +1,192 @@
+
+(#) This class or method is deprecated; consider using an alternative
+
+!!! WARNING: This class or method is deprecated; consider using an alternative
+ This is a warning.
+
+Id
+: `DeprecatedCall`
+Summary
+: This class or method is deprecated; consider using an alternative
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.1.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/DeprecatedAnnotationDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/DeprecatedAnnotationDetectorTest.kt)
+Copyright Year
+: 2021
+
+Using deprecated classes is not advised; please consider using an
+alternative.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/slack/test/TestClass.java:8:Warning: This class or method is
+deprecated; consider using an alternative. [DeprecatedCall]
+ new ThisIsDeprecated();
+ ----------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/slack/test/ThisIsDeprecated.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package slack.test;
+
+@Deprecated()
+class ThisIsDeprecated {
+
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/slack/test/TestClass.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package slack.test;
+
+import slack.test.ThisIsDeprecated;
+
+public class TestClass {
+
+ public void doStuff() {
+ new ThisIsDeprecated();
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/DeprecatedAnnotationDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `DeprecatedAnnotationDetector.deprecated class has a warning`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/slack-lints.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("DeprecatedCall")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("DeprecatedCall")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection DeprecatedCall
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DeprecatedCall" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DeprecatedCall'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DeprecatedCall ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DeprecatedProvider.md.html b/docs/checks/DeprecatedProvider.md.html
new file mode 100644
index 00000000..8ba987bf
--- /dev/null
+++ b/docs/checks/DeprecatedProvider.md.html
@@ -0,0 +1,171 @@
+
+(#) Using BC Provider
+
+!!! WARNING: Using BC Provider
+ This is a warning.
+
+Id
+: `DeprecatedProvider`
+Summary
+: Using BC Provider
+Severity
+: Warning
+Category
+: Security
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.2.0 (September 2018)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://android-developers.googleblog.com/2018/03/cryptography-changes-in-android-p.html
+See
+: https://goo.gle/DeprecatedProvider
+Implementation
+: [Source Code](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/CipherGetInstanceDetector.kt)
+Tests
+: [Source Code](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/CipherGetInstanceDetectorTest.kt)
+
+The `BC` provider has been deprecated and will not be provided when
+`targetSdkVersion` is P or higher.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/BCProviderTest.java:16:Warning: The BC provider is
+deprecated and when targetSdkVersion is moved to P this method will
+throw a NoSuchAlgorithmException. To fix this you should stop specifying
+a provider and use the default implementation [DeprecatedProvider]
+ Cipher.getInstance("AES/CBC/PKCS7PADDING", "BC"); // Error
+ ----
+src/test/pkg/BCProviderTest.java:17:Warning: The BC provider is
+deprecated and when targetSdkVersion is moved to P this method will
+throw a NoSuchAlgorithmException. To fix this you should stop specifying
+a provider and use the default implementation [DeprecatedProvider]
+ Cipher.getInstance("AES/CBC/PKCS7PADDING", BC_PROVIDER); // Error
+ -----------
+src/test/pkg/BCProviderTest.java:19:Warning: The BC provider is
+deprecated and when targetSdkVersion is moved to P this method will
+throw a NoSuchAlgorithmException. To fix this you should stop specifying
+a provider and use the default implementation [DeprecatedProvider]
+ Cipher.getInstance("AES/CBC/PKCS7PADDING", Security.getProvider("BC")); // Error
+ --------------------------
+src/test/pkg/BCProviderTest.java:20:Warning: The BC provider is
+deprecated and when targetSdkVersion is moved to P this method will
+throw a NoSuchAlgorithmException. To fix this you should stop specifying
+a provider and use the default implementation [DeprecatedProvider]
+ Cipher.getInstance("AES/CBC/PKCS7PADDING", Security.getProvider(BC_PROVIDER)); // Error
+ ---------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/BCProviderTest.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import javax.crypto.Cipher;
+import javax.crypto.NoSuchPaddingException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Security;
+
+@SuppressWarnings({"ClassNameDiffersFromFileName", "MethodMayBeStatic"})
+public class BCProviderTest {
+ public static final String BC_PROVIDER = "BC";
+
+ void test() throws NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException {
+ Cipher.getInstance("AES/CBC/PKCS7PADDING"); // OK
+ Cipher.getInstance("AES/CBC/PKCS7PADDING", "bar"); // OK
+ Cipher.getInstance("AES/CBC/PKCS7PADDING", "BC"); // Error
+ Cipher.getInstance("AES/CBC/PKCS7PADDING", BC_PROVIDER); // Error
+ Cipher.getInstance("AES/CBC/PKCS7PADDING", Security.getProvider("bar")); // OK
+ Cipher.getInstance("AES/CBC/PKCS7PADDING", Security.getProvider("BC")); // Error
+ Cipher.getInstance("AES/CBC/PKCS7PADDING", Security.getProvider(BC_PROVIDER)); // Error
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/CipherGetInstanceDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `CipherGetInstanceDetector.testDeprecatedProvider`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("DeprecatedProvider")
+ fun method() {
+ getInstance(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("DeprecatedProvider")
+ void method() {
+ getInstance(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection DeprecatedProvider
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DeprecatedProvider" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DeprecatedProvider'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DeprecatedProvider ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DeprecatedSinceApi.md.html b/docs/checks/DeprecatedSinceApi.md.html
new file mode 100644
index 00000000..8feb3e94
--- /dev/null
+++ b/docs/checks/DeprecatedSinceApi.md.html
@@ -0,0 +1,191 @@
+
+(#) Using a method deprecated in earlier SDK
+
+!!! WARNING: Using a method deprecated in earlier SDK
+ This is a warning.
+
+Id
+: `DeprecatedSinceApi`
+Summary
+: Using a method deprecated in earlier SDK
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 7.3.0 (September 2022)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/DeprecatedSinceApiDetector.kt)
+Tests
+: [Source Code](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/DeprecatedSinceApiDetectorTest.kt)
+
+Some backport methods are only necessary until a specific version of
+Android. These have been annotated with `@DeprecatedSinceApi`,
+specifying the relevant API level and replacement suggestions. Calling
+these methods when the `minSdkVersion` is already at the deprecated API
+level or above is unnecessary.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/Test.kt:9:Warning: This method is deprecated as of API
+level 21 [DeprecatedSinceApi]
+ api.noLongerNecessary1(0) // WARN 1
+ -------------------------
+src/test/pkg/Test.kt:10:Warning: This method is deprecated as of API
+level 23; Use AlarmManager.notify instead [DeprecatedSinceApi]
+ api.noLongerNecessary2(0) // WARN 2
+ -------------------------
+src/test/pkg/Test.kt:11:Warning: This method is deprecated as of API
+level 24 [DeprecatedSinceApi]
+ api.noLongerNecessary3(0) // WARN 3
+ -------------------------
+src/test/pkg/Test.kt:18:Warning: This class is deprecated as of API
+level 19 [DeprecatedSinceApi]
+ val clz = Api2::class.java // WARN 4
+ -----------
+src/test/pkg/Test.kt:19:Warning: This method is deprecated as of API
+level 23 [DeprecatedSinceApi]
+ val method1 = api2::someMethod1 // WARN 5
+ -----------------
+src/test/pkg/Test.kt:20:Warning: This method is deprecated as of API
+level 21 [DeprecatedSinceApi]
+ val method2 = api2::someMethod2 // WARN 6
+ -----------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/Test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+@file:Suppress("UNUSED_PARAMETER", "UNUSED_VARIABLE", "unused")
+package test.pkg
+import androidx.annotation.DeprecatedSinceApi
+
+class Test {
+ fun test(api: Api, api2: Api2) {
+ // minSdkVersion = 24:
+
+ api.noLongerNecessary1(0) // WARN 1
+ api.noLongerNecessary2(0) // WARN 2
+ api.noLongerNecessary3(0) // WARN 3
+
+ api.unnecessaryInTheFuture1(0) // OK 1
+ api.unnecessaryInTheFuture2(0) // OK 2
+
+ // The above enforced calls (the most common scenario); check
+ // some other reference types.
+ val clz = Api2::class.java // WARN 4
+ val method1 = api2::someMethod1 // WARN 5
+ val method2 = api2::someMethod2 // WARN 6
+ }
+}
+
+class Api {
+ @DeprecatedSinceApi(api = 21)
+ fun noLongerNecessary1(arg: Int) { }
+
+ @DeprecatedSinceApi(api = 23, message = "Use AlarmManager.notify instead")
+ fun noLongerNecessary2(arg: Int) { }
+
+ @DeprecatedSinceApi(api = 24)
+ fun noLongerNecessary3(arg: Int) { }
+
+ @DeprecatedSinceApi(api = 25)
+ fun unnecessaryInTheFuture1(arg: Int) { }
+
+ @DeprecatedSinceApi(api = 33)
+ fun unnecessaryInTheFuture2(arg: Int) { }
+}
+
+@DeprecatedSinceApi(api = 19)
+class Api2 {
+ @DeprecatedSinceApi(api = 23)
+ fun someMethod1(arg: Int) { }
+ @DeprecatedSinceApi(api = 21)
+ fun someMethod2(arg: Int) { }
+}
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/DeprecatedSinceApiDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("DeprecatedSinceApi")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("DeprecatedSinceApi")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection DeprecatedSinceApi
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DeprecatedSinceApi" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DeprecatedSinceApi'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DeprecatedSinceApi ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DeprecatedSqlUsage.md.html b/docs/checks/DeprecatedSqlUsage.md.html
new file mode 100644
index 00000000..460a4236
--- /dev/null
+++ b/docs/checks/DeprecatedSqlUsage.md.html
@@ -0,0 +1,180 @@
+
+(#) Use SqlDelight
+
+!!! WARNING: Use SqlDelight
+ This is a warning.
+
+Id
+: `DeprecatedSqlUsage`
+Summary
+: Use SqlDelight
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.1.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/DeprecatedSqlUsageDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/DeprecatedSqlUsageDetectorTest.kt)
+Copyright Year
+: 2021
+
+Safer, faster, etc.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/foo/SqlUsageTestFailure.java:7:Warning: All SQL querying should be
+performed using SqlDelight [DeprecatedSqlUsage]
+ db.execSQL("DROP TABLE IF EXISTS foo");
+ --------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/foo/SqlUsageTestFailure.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package foo;
+
+import android.database.sqlite.SQLiteDatabase;
+
+public static class SqlUsageTestFailure {
+ public static void delete(SQLiteDatabase db) {
+ db.execSQL("DROP TABLE IF EXISTS foo");
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/DeprecatedSqlUsageDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `DeprecatedSqlUsageDetector.testJavaInspection`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/slack-lints.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("DeprecatedSqlUsage")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("DeprecatedSqlUsage")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection DeprecatedSqlUsage
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DeprecatedSqlUsage" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DeprecatedSqlUsage'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DeprecatedSqlUsage ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DetachAndAttachSameFragment.md.html b/docs/checks/DetachAndAttachSameFragment.md.html
new file mode 100644
index 00000000..dc9a0348
--- /dev/null
+++ b/docs/checks/DetachAndAttachSameFragment.md.html
@@ -0,0 +1,150 @@
+
+(#) Separate attach() and detach() into separate FragmentTransactions
+
+!!! WARNING: Separate attach() and detach() into separate FragmentTransactions
+ This is a warning.
+
+Id
+: `DetachAndAttachSameFragment`
+Summary
+: Separate attach() and detach() into separate FragmentTransactions
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Identifier
+: androidx.fragment
+Feedback
+: https://issuetracker.google.com/issues/new?component=460964
+Min
+: Lint 7.0
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [androidx.fragment:fragment](androidx_fragment_fragment.md.html)
+Since
+: 1.4.0
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/fragment/fragment-lint/src/main/java/androidx/fragment/lint/AttachAndDetachInSameTransactionDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/fragment/fragment-lint/src/test/java/androidx/fragment/lint/AttachAndDetachInSameTransactionDetectorTest.kt)
+Copyright Year
+: 2019
+
+When doing a FragmentTransaction that includes both attach()
+ and detach() operations being committed on the same fragment
+instance, it is a no-op. The reason for this is that the
+FragmentManager optimizes all operations within a single
+transaction so the attach() and detach() cancel each other out
+ and neither is actually executed. To get the desired behavior, you
+should separate the attach() and detach() calls into
+separate FragmentTransactions.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.fragment:fragment:1.8.6")
+
+// build.gradle
+implementation 'androidx.fragment:fragment:1.8.6'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.fragment)
+
+# libs.versions.toml
+[versions]
+fragment = "1.8.6"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+fragment = {
+ module = "androidx.fragment:fragment",
+ version.ref = "fragment"
+}
+```
+
+1.8.6 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.fragment:fragment](androidx_fragment_fragment.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("DetachAndAttachSameFragment")
+ fun method() {
+ beginTransaction(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("DetachAndAttachSameFragment")
+ void method() {
+ beginTransaction(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection DetachAndAttachSameFragment
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DetachAndAttachSameFragment" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DetachAndAttachSameFragment'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DetachAndAttachSameFragment ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DevModeObsolete.md.html b/docs/checks/DevModeObsolete.md.html
new file mode 100644
index 00000000..d2df2794
--- /dev/null
+++ b/docs/checks/DevModeObsolete.md.html
@@ -0,0 +1,136 @@
+
+(#) Dev Mode Obsolete
+
+!!! WARNING: Dev Mode Obsolete
+ This is a warning.
+
+Id
+: `DevModeObsolete`
+Summary
+: Dev Mode Obsolete
+Severity
+: Warning
+Category
+: Performance
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.0.0 (October 2017)
+Affects
+: Gradle build files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/GradleDetector.kt)
+Tests
+: [Source Code](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/GradleDetectorTest.kt)
+
+In the past, our documentation recommended creating a `dev` product
+flavor with has a minSdkVersion of 21, in order to enable multidexing to
+speed up builds significantly during development.
+
+That workaround is no longer necessary, and it has some serious
+downsides, such as breaking API access checking (since the true
+`minSdkVersion` is no longer known).
+
+In recent versions of the IDE and the Gradle plugin, the IDE
+automatically passes the API level of the connected device used for
+deployment, and if that device is at least API 21, then multidexing is
+automatically turned on, meaning that you get the same speed benefits as
+the `dev` product flavor but without the downsides.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+build.gradle:9:Warning: You no longer need a dev mode to enable
+multi-dexing during development, and this can break API version checks
+[DevModeObsolete]
+ minSdkVersion 21
+ ----------------
+build.gradle:10:Warning: You no longer need a dev mode to enable
+multi-dexing during development, and this can break API version checks
+[DevModeObsolete]
+ minSdk = 21
+ -----------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`build.gradle`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~groovy linenumbers
+apply plugin: 'com.android.application'
+
+android {
+ productFlavors {
+ // When building a variant that uses this flavor, the following configurations
+ // override those in the defaultConfig block.
+ dev {
+ // To avoid using legacy multidex, set minSdkVersion to 21 or higher.
+ minSdkVersion 21
+ minSdk = 21
+ versionNameSuffix "-dev"
+ applicationIdSuffix '.dev'
+ }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/GradleDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `GradleDetector.testDevVariantNotNeeded`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection DevModeObsolete
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DevModeObsolete" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DevModeObsolete'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DevModeObsolete ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DeviceAdmin.md.html b/docs/checks/DeviceAdmin.md.html
new file mode 100644
index 00000000..66c08305
--- /dev/null
+++ b/docs/checks/DeviceAdmin.md.html
@@ -0,0 +1,206 @@
+
+(#) Malformed Device Admin
+
+!!! WARNING: Malformed Device Admin
+ This is a warning.
+
+Id
+: `DeviceAdmin`
+Summary
+: Malformed Device Admin
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/ManifestDetector.kt)
+Tests
+: [Source Code](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/ManifestDetectorTest.kt)
+Copyright Year
+: 2011
+
+If you register a broadcast receiver which acts as a device admin, you
+must also register an `` for the action
+`android.app.action.DEVICE_ADMIN_ENABLED`, without any ``, such
+that the device admin can be activated/deactivated.
+
+To do this, add
+```xml
+``
+ ` `
+` `
+```
+to your ``.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:30:Warning: You must have an intent filter for
+action android.app.action.DEVICE_ADMIN_ENABLED [DeviceAdmin]
+ <meta-data android:name="android.app.device_admin"
+ ---------------------------------------
+AndroidManifest.xml:43:Warning: You must have an intent filter for
+action android.app.action.DEVICE_ADMIN_ENABLED [DeviceAdmin]
+ <meta-data android:name="android.app.device_admin"
+ ---------------------------------------
+AndroidManifest.xml:55:Warning: You must have an intent filter for
+action android.app.action.DEVICE_ADMIN_ENABLED [DeviceAdmin]
+ <meta-data android:name="android.app.device_admin"
+ ---------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="foo.bar2"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk android:minSdkVersion="14"/>
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name">
+
+ <!-- OK -->
+ <receiver android:name=".DeviceAdminTestReceiver"
+ android:label="@string/app_name"
+ android:description="@string/app_name"
+ android:permission="android.permission.BIND_DEVICE_ADMIN">
+ <meta-data android:name="android.app.device_admin"
+ android:resource="@xml/device_admin"/>
+ <intent-filter>
+ <action android:name="android.app.action.DEVICE_ADMIN_ENABLED"/>
+ </intent-filter>
+ </receiver>
+
+ <!-- Specifies data -->
+ <receiver android:name=".DeviceAdminTestReceiver"
+ android:label="@string/app_name"
+ android:description="@string/app_name"
+ android:permission="android.permission.BIND_DEVICE_ADMIN">
+ <meta-data android:name="android.app.device_admin"
+ android:resource="@xml/device_admin"/>
+ <intent-filter>
+ <action android:name="android.app.action.DEVICE_ADMIN_ENABLED"/>
+ <data android:scheme="content" />
+ </intent-filter>
+ </receiver>
+
+ <!-- Missing right intent-filter -->
+ <receiver android:name=".DeviceAdminTestReceiver"
+ android:label="@string/app_name"
+ android:description="@string/app_name"
+ android:permission="android.permission.BIND_DEVICE_ADMIN">
+ <meta-data android:name="android.app.device_admin"
+ android:resource="@xml/device_admin"/>
+ <intent-filter>
+ <action android:name="com.test.foo.DEVICE_ADMIN_ENABLED"/>
+ </intent-filter>
+ </receiver>
+
+ <!-- Missing intent-filter -->
+ <receiver android:name=".DeviceAdminTestReceiver"
+ android:label="@string/app_name"
+ android:description="@string/app_name"
+ android:permission="android.permission.BIND_DEVICE_ADMIN">
+ <meta-data android:name="android.app.device_admin"
+ android:resource="@xml/device_admin"/>
+ </receiver>
+
+ <!-- Suppressed -->
+ <receiver android:name=".DeviceAdminTestReceiver"
+ android:label="@string/app_name"
+ android:description="@string/app_name"
+ android:permission="android.permission.BIND_DEVICE_ADMIN"
+ tools:ignore="DeviceAdmin">
+ <meta-data android:name="android.app.device_admin"
+ android:resource="@xml/device_admin"/>
+ <intent-filter>
+ <action android:name="com.test.foo.DEVICE_ADMIN_ENABLED"/>
+ </intent-filter>
+ </receiver>
+
+ </application>
+
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ManifestDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ManifestDetector.testDeviceAdmin`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="DeviceAdmin"` on the
+ problematic XML element (or one of its enclosing elements). You may
+ also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <application tools:ignore="DeviceAdmin" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DeviceAdmin" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DeviceAdmin'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DeviceAdmin ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DialogFragmentCallbacksDetector.md.html b/docs/checks/DialogFragmentCallbacksDetector.md.html
new file mode 100644
index 00000000..c7499c4c
--- /dev/null
+++ b/docs/checks/DialogFragmentCallbacksDetector.md.html
@@ -0,0 +1,188 @@
+
+(#) Use onCancel() and onDismiss() instead of calling setOnCancelListener() and setOnDismissListener() from onCreateDialog()
+
+!!! WARNING: Use onCancel() and onDismiss() instead of calling setOnCancelListener() and setOnDismissListener() from onCreateDialog()
+ This is a warning.
+
+Id
+: `DialogFragmentCallbacksDetector`
+Summary
+: Use onCancel() and onDismiss() instead of calling setOnCancelListener() and setOnDismissListener() from onCreateDialog()
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Identifier
+: androidx.fragment
+Feedback
+: https://issuetracker.google.com/issues/new?component=460964
+Min
+: Lint 7.0
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [androidx.fragment:fragment](androidx_fragment_fragment.md.html)
+Since
+: 1.4.0
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/fragment/fragment-lint/src/main/java/androidx/fragment/lint/OnCreateDialogIncorrectCallbackDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/fragment/fragment-lint/src/test/java/androidx/fragment/lint/OnCreateDialogIncorrectCallbackDetectorTest.kt)
+Copyright Year
+: 2021
+
+When using a `DialogFragment`, the `setOnCancelListener` and
+ `setOnDismissListener` callback functions within the
+`onCreateDialog` function __must not be used__ because
+the `DialogFragment` owns these callbacks. Instead the
+respective `onCancel` and `onDismiss` functions can be used to
+ achieve the desired effect.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/foo/TestFragment.java:11:Warning: Use onCancel() instead of calling
+setOnCancelListener() from onCreateDialog()
+[DialogFragmentCallbacksDetector]
+ dialog.setOnCancelListener({ });
+ -------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/foo/TestFragment.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package foo;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.DialogFragment;
+public class TestFragment extends DialogFragment {
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ Dialog dialog = AlertDialog.Builder(requireActivity());
+ dialog.setOnCancelListener({ });
+ return dialog.create();
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/fragment/fragment-lint/src/test/java/androidx/fragment/lint/OnCreateDialogIncorrectCallbackDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `OnCreateDialogIncorrectCallbackDetector.java expect fail dialog fragment with cancel listener`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=460964.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.fragment:fragment:1.8.6")
+
+// build.gradle
+implementation 'androidx.fragment:fragment:1.8.6'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.fragment)
+
+# libs.versions.toml
+[versions]
+fragment = "1.8.6"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+fragment = {
+ module = "androidx.fragment:fragment",
+ version.ref = "fragment"
+}
+```
+
+1.8.6 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.fragment:fragment](androidx_fragment_fragment.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("DialogFragmentCallbacksDetector")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("DialogFragmentCallbacksDetector")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection DialogFragmentCallbacksDetector
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DialogFragmentCallbacksDetector" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DialogFragmentCallbacksDetector'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DialogFragmentCallbacksDetector ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DiffUtilEquals.md.html b/docs/checks/DiffUtilEquals.md.html
new file mode 100644
index 00000000..78db3853
--- /dev/null
+++ b/docs/checks/DiffUtilEquals.md.html
@@ -0,0 +1,168 @@
+
+(#) Suspicious DiffUtil Equality
+
+!!! ERROR: Suspicious DiffUtil Equality
+ This is an error.
+
+Id
+: `DiffUtilEquals`
+Summary
+: Suspicious DiffUtil Equality
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.4.0 (April 2019)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://issuetracker.google.com/116789824
+Implementation
+: [Source Code](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/DiffUtilDetector.kt)
+Tests
+: [Source Code](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/DiffUtilDetectorTest.kt)
+
+`areContentsTheSame` is used by `DiffUtil` to produce diffs. If the
+method is implemented incorrectly, such as using identity equals instead
+of equals, or calling equals on a class that has not implemented it,
+weird visual artifacts can occur.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/test.kt:10:Error: Suspicious equality check: Did you mean
+== instead of === ? [DiffUtilEquals]
+ oldItem === newItem // ERROR
+ ---
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/test/pkg/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+
+import androidx.recyclerview.widget.DiffUtil
+
+private val diffCallback = object : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(oldItem: Cheese, newItem: Cheese): Boolean =
+ oldItem.id === newItem.id
+
+ override fun areContentsTheSame(oldItem: Cheese, newItem: Cheese): Boolean =
+ oldItem === newItem // ERROR
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyCallback.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import androidx.recyclerview.widget.DiffUtil;
+
+public class MyCallback extends DiffUtil.ItemCallback {
+ @Override
+ public boolean areItemsTheSame(Cheese oldItem, Cheese newItem) {
+ return oldItem.getId() == newItem.getId();
+ }
+
+ @Override
+ public boolean areContentsTheSame(Cheese oldItem, Cheese newItem) {
+ return oldItem == newItem;
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/Cheese.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+public class Cheese {
+ public String id;
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/DiffUtilDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `DiffUtilDetector.testIdentityOperator`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("DiffUtilEquals")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("DiffUtilEquals")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection DiffUtilEquals
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DiffUtilEquals" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DiffUtilEquals'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DiffUtilEquals ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DisableBaselineAlignment.md.html b/docs/checks/DisableBaselineAlignment.md.html
new file mode 100644
index 00000000..1d7c1d91
--- /dev/null
+++ b/docs/checks/DisableBaselineAlignment.md.html
@@ -0,0 +1,160 @@
+
+(#) Missing `baselineAligned` attribute
+
+!!! WARNING: Missing `baselineAligned` attribute
+ This is a warning.
+
+Id
+: `DisableBaselineAlignment`
+Summary
+: Missing `baselineAligned` attribute
+Severity
+: Warning
+Category
+: Performance
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/InefficientWeightDetector.java)
+Tests
+: [Source Code](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/InefficientWeightDetectorTest.java)
+Copyright Year
+: 2011
+
+When a `LinearLayout` is used to distribute the space proportionally
+between nested layouts, the baseline alignment property should be turned
+off to make the layout computation faster.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/baseline_weights.xml:2:Warning: Set
+android:baselineAligned="false" on this element for better performance
+[DisableBaselineAlignment]
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ ------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/layout/baseline_weights.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal" >
+
+ <LinearLayout
+ android:id="@+id/linearLayout1"
+ android:layout_weight="0.3"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+
+ <Button
+ android:id="@+id/button1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Button" />
+
+ <Button
+ android:id="@+id/button2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Button" />
+
+ <Button
+ android:id="@+id/button3"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Button" />
+ </LinearLayout>
+
+ <FrameLayout
+ android:id="@+id/frameLayout1"
+ android:layout_weight="0.7"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+ </FrameLayout>
+
+</LinearLayout>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/InefficientWeightDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `InefficientWeightDetector.testWeights3`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="DisableBaselineAlignment"` on the problematic XML
+ element (or one of its enclosing elements). You may also need to add
+ the following namespace declaration on the root element in the XML
+ file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <LinearLayout xmlns:tools="http://schemas.android.com/tools"
+ tools:ignore="DisableBaselineAlignment" ...>
+ ...
+ </LinearLayout>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DisableBaselineAlignment" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DisableBaselineAlignment'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DisableBaselineAlignment ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DisabledAllSafeBrowsing.md.html b/docs/checks/DisabledAllSafeBrowsing.md.html
new file mode 100644
index 00000000..9b41cfe4
--- /dev/null
+++ b/docs/checks/DisabledAllSafeBrowsing.md.html
@@ -0,0 +1,172 @@
+
+(#) Application has disabled safe browsing for all WebView objects
+
+!!! WARNING: Application has disabled safe browsing for all WebView objects
+ This is a warning.
+
+Id
+: `DisabledAllSafeBrowsing`
+Summary
+: Application has disabled safe browsing for all WebView objects
+Severity
+: Warning
+Category
+: Security
+Platform
+: Android
+Vendor
+: Google - Android 3P Vulnerability Research
+Contact
+: https://github.com/google/android-security-lints
+Feedback
+: https://github.com/google/android-security-lints/issues
+Min
+: Lint 4.1
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [com.android.security.lint:lint](com_android_security_lint_lint.md.html)
+Since
+: 1.0.1
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://goo.gle/DisabledAllSafeBrowsing
+Implementation
+: [Source Code](https://github.com/google/android-security-lints/tree/main/checks/src/main/java/com/example/lint/checks/SafeBrowsingDetector.kt)
+Tests
+: [Source Code](https://github.com/google/android-security-lints/tree/main/checks/src/test/java/com/example/lint/checks/SafeBrowsingDetectorTest.kt)
+Copyright Year
+: 2024
+
+Safe Browsing is a service to help applications check URLs against a
+known list of unsafe web resources. We recommend keeping Safe Browsing
+enabled at all times and designing your app around any constraints this
+causes.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:3:Warning: Safe Browsing should be kept enabled at
+all times, as it aims to keep users from unsafe URLs
+[DisabledAllSafeBrowsing]
+ <meta-data android:name='android.webkit.WebView.EnableSafeBrowsing' android:value='false'/>
+ -------------------------------------------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest xmlns:android='http://schemas.android.com/apk/res/android' package='test.pkg'>
+<application android:debuggable='false'>
+ <meta-data android:name='android.webkit.WebView.EnableSafeBrowsing' android:value='false'/>
+ <activity android:name='com.example.MainActivity'></activity>
+</application>
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/google/android-security-lints/tree/main/checks/src/test/java/com/example/lint/checks/SafeBrowsingDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `SafeBrowsingDetector.testWhenSafeBrowsingDisabledInManifest_showsWarning`.
+To report a problem with this extracted sample, visit
+https://github.com/google/android-security-lints/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.android.security.lint:lint:1.0.3")
+
+// build.gradle
+lintChecks 'com.android.security.lint:lint:1.0.3'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.com.android.security.lint.lint)
+
+# libs.versions.toml
+[versions]
+com-android-security-lint-lint = "1.0.3"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+com-android-security-lint-lint = {
+ module = "com.android.security.lint:lint",
+ version.ref = "com-android-security-lint-lint"
+}
+```
+
+1.0.3 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.android.security.lint:lint](com_android_security_lint_lint.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="DisabledAllSafeBrowsing"` on the problematic XML
+ element (or one of its enclosing elements). You may also need to add
+ the following namespace declaration on the root element in the XML
+ file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <meta-data tools:ignore="DisabledAllSafeBrowsing" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DisabledAllSafeBrowsing" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DisabledAllSafeBrowsing'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DisabledAllSafeBrowsing ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DiscouragedApi.md.html b/docs/checks/DiscouragedApi.md.html
new file mode 100644
index 00000000..a2454763
--- /dev/null
+++ b/docs/checks/DiscouragedApi.md.html
@@ -0,0 +1,143 @@
+
+(#) Using discouraged APIs
+
+!!! WARNING: Using discouraged APIs
+ This is a warning.
+
+Id
+: `DiscouragedApi`
+Summary
+: Using discouraged APIs
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 7.1.0 (January 2022)
+Affects
+: Kotlin and Java files, manifest files and resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/DiscouragedDetector.kt)
+Tests
+: [Source Code](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/DiscouragedDetectorTest.kt)
+
+Discouraged APIs are allowed and are not deprecated, but they may be
+unfit for common use (e.g. due to slow performance or subtle behavior).
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/Test1.java:9:Warning: Use of this function is discouraged.
+It is more efficient to retrieve resources by identifier than by name.
+See getValue(int id, TypedValue outValue, boolean resolveRefs).
+[DiscouragedApi]
+ Resources.getValue("name", testValue, false);
+ --------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/Test1.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.content.res.Resources;
+import android.util.TypedValue;
+
+public class Test1 {
+ public void setValue() {
+ TypedValue testValue;
+ Resources.getValue("name", testValue, false);
+ Resources.getValue(0, testValue, false);
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/DiscouragedDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("DiscouragedApi")
+ fun method() {
+ scheduleAtFixedRate(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("DiscouragedApi")
+ void method() {
+ scheduleAtFixedRate(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection DiscouragedApi
+ problematicStatement()
+ ```
+
+* Adding the suppression attribute `tools:ignore="DiscouragedApi"` on
+ the problematic XML element (or one of its enclosing elements). You
+ may also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DiscouragedApi" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DiscouragedApi'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DiscouragedApi ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DiscouragedPrivateApi.md.html b/docs/checks/DiscouragedPrivateApi.md.html
new file mode 100644
index 00000000..7526711d
--- /dev/null
+++ b/docs/checks/DiscouragedPrivateApi.md.html
@@ -0,0 +1,186 @@
+
+(#) Using Discouraged Private API
+
+!!! WARNING: Using Discouraged Private API
+ This is a warning.
+
+Id
+: `DiscouragedPrivateApi`
+Summary
+: Using Discouraged Private API
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.5.0 (August 2019)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/preview/restrictions-non-sdk-interfaces
+Implementation
+: [Source Code](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/PrivateApiDetector.kt)
+Tests
+: [Source Code](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/PrivateApiDetectorTest.kt)
+
+Usage of restricted non-SDK interface may throw an exception at runtime.
+Accessing non-SDK methods or fields through reflection has a high
+likelihood to break your app between versions, and is being restricted
+to facilitate future app compatibility.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/application/ReflectionTestJava.java:11:Warning: Reflective
+access to addAssetPath, which is not part of the public SDK and
+therefore likely to change in future Android releases
+[DiscouragedPrivateApi]
+ Method m1 = AssetManager.class.getDeclaredMethod("addAssetPath", String.class);
+ ------------------------------------------------------------------
+src/test/pkg/application/ReflectionTestJava.java:12:Warning: Reflective
+access to addAssetPath, which is not part of the public SDK and
+therefore likely to change in future Android releases
+[DiscouragedPrivateApi]
+ Method m2 = assetManager.getClass().getDeclaredMethod("addAssetPath", String.class);
+ -----------------------------------------------------------------------
+src/test/pkg/application/ReflectionTestJava.java:13:Warning: Reflective
+access to addAssetPath, which is not part of the public SDK and
+therefore likely to change in future Android releases
+[DiscouragedPrivateApi]
+ Method m3 = AssetManager.class.getDeclaredMethod("addAssetPath", path.getClass());
+ ---------------------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/test/pkg/application/ReflectionTestJava.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg.application;
+
+import android.content.res.AssetManager;
+
+import java.lang.reflect.Method;
+
+public class ReflectionTestJava {
+ private static void addAssetPath(AssetManager assetManager) throws Exception {
+ String path = "foo/bar";
+ Method m1 = AssetManager.class.getDeclaredMethod("addAssetPath", String.class);
+ Method m2 = assetManager.getClass().getDeclaredMethod("addAssetPath", String.class);
+ Method m3 = AssetManager.class.getDeclaredMethod("addAssetPath", path.getClass());
+ Method m4 = AssetManager.class.getDeclaredMethod("invalidateCachesLocked", int.class);
+ Method m5 = AssetManager.class.getDeclaredMethod("invalidateCachesLocked", Integer.TYPE);
+ Method m6 = AssetManager.class.getDeclaredMethod("invalidateCachesLocked", Integer.class); // OK, doesn't exist
+
+ Class> activityClass = Class.forName("android.app.Activity");
+ Class> bundleClass = Class.forName("android.os.Bundle");
+ Method m7 = activityClass.getDeclaredMethod("dispatchActivityPostCreated", bundleClass);
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/application/ReflectionTestKotlin.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg.application;
+
+import android.content.res.AssetManager
+
+class ReflectionTestKotlin {
+ private fun addAssetPath(assetManager: AssetManager) {
+ val path = "foo/bar"
+ val m1 = AssetManager::class.java.getDeclaredMethod("addAssetPath", String::class.java)
+ val m2 = assetManager.javaClass.getDeclaredMethod("invalidateCachesLocked", Int::class.javaPrimitiveType)
+ val m3 = assetManager.javaClass.getDeclaredMethod("invalidateCachesLocked", Int::class.java) // OK, doesn't exist
+ val m4 = AssetManager::class.java.getDeclaredMethod("addAssetPath", path.javaClass)
+
+ val activityClass = Class.forName("android.app.Activity")
+ val bundleClass = Class.forName("android.os.Bundle")
+ val m5 = activityClass.getDeclaredMethod("dispatchActivityPostCreated", bundleClass)
+
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/PrivateApiDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `PrivateApiDetector.testJavaReflection`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("DiscouragedPrivateApi")
+ fun method() {
+ forName(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("DiscouragedPrivateApi")
+ void method() {
+ forName(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection DiscouragedPrivateApi
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DiscouragedPrivateApi" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DiscouragedPrivateApi'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DiscouragedPrivateApi ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DoNotCallProviders.md.html b/docs/checks/DoNotCallProviders.md.html
new file mode 100644
index 00000000..5f5a0bc3
--- /dev/null
+++ b/docs/checks/DoNotCallProviders.md.html
@@ -0,0 +1,227 @@
+
+(#) Dagger provider methods should not be called directly by user code
+
+!!! ERROR: Dagger provider methods should not be called directly by user code
+ This is an error.
+
+Id
+: `DoNotCallProviders`
+Summary
+: Dagger provider methods should not be called directly by user code
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.1.0
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/DoNotCallProvidersDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/DoNotCallProvidersDetectorTest.kt)
+Copyright Year
+: 2021
+
+Dagger provider methods should not be called directly by user code.
+These are intended solely for use by Dagger-generated code and it is
+programmer error to call them from user code.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/foo/MyModule.kt:15:Error: Dagger provider methods should not be
+called directly by user code. [DoNotCallProviders]
+ binds1("this is bad")
+ ---------------------
+src/foo/MyModule.kt:16:Error: Dagger provider methods should not be
+called directly by user code. [DoNotCallProviders]
+ "this is bad".binds2()
+ ---------------------
+src/foo/MyModule.kt:17:Error: Dagger provider methods should not be
+called directly by user code. [DoNotCallProviders]
+ provider()
+ ----------
+src/foo/MyModule.kt:18:Error: Dagger provider methods should not be
+called directly by user code. [DoNotCallProviders]
+ producer()
+ ----------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/foo/MyModule.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package foo
+import dagger.Binds
+import dagger.Module
+import dagger.Provides
+import dagger.producers.Produces
+import javax.annotation.Generated
+
+@Module
+abstract class MyModule {
+
+ @Binds fun binds1(input: String): Comparable
+ @Binds fun String.binds2(): Comparable
+
+ fun badCode() {
+ binds1("this is bad")
+ "this is bad".binds2()
+ provider()
+ producer()
+ }
+
+ companion object {
+ @Provides
+ fun provider(): String {
+ return ""
+ }
+ @Produces
+ fun producer(): String {
+ return ""
+ }
+ }
+}
+
+@Generated("Totes generated code")
+abstract class GeneratedCode {
+ fun doStuff() {
+ moduleInstance().binds1("this is technically fine but would never happen in dagger")
+ MyModule.provider()
+ MyModule.producer()
+ }
+
+ abstract fun moduleInstance(): MyModule
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/DoNotCallProvidersDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `DoNotCallProvidersDetector.kotlin`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/slack-lints.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("DoNotCallProviders")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("DoNotCallProviders")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection DoNotCallProviders
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DoNotCallProviders" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DoNotCallProviders'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DoNotCallProviders ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DoNotCallViewToString.md.html b/docs/checks/DoNotCallViewToString.md.html
new file mode 100644
index 00000000..b07fc067
--- /dev/null
+++ b/docs/checks/DoNotCallViewToString.md.html
@@ -0,0 +1,146 @@
+
+(#) Do not use `View.toString()`
+
+!!! ERROR: Do not use `View.toString()`
+ This is an error.
+
+Id
+: `DoNotCallViewToString`
+Summary
+: Do not use `View.toString()`
+Severity
+: Error
+Category
+: Security
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.8.1
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/ui/DoNotCallViewToString.kt)
+Copyright Year
+: 2024
+
+`View.toString()` and its overrides can often print surprisingly
+detailed information about the current view state, and has led to PII
+logging issues in the past.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("DoNotCallViewToString")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("DoNotCallViewToString")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection DoNotCallViewToString
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DoNotCallViewToString" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DoNotCallViewToString'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DoNotCallViewToString ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DoNotExposeEitherNetInRepositories.md.html b/docs/checks/DoNotExposeEitherNetInRepositories.md.html
new file mode 100644
index 00000000..b56515df
--- /dev/null
+++ b/docs/checks/DoNotExposeEitherNetInRepositories.md.html
@@ -0,0 +1,216 @@
+
+(#) Repository APIs should not expose EitherNet types directly
+
+!!! ERROR: Repository APIs should not expose EitherNet types directly
+ This is an error.
+
+Id
+: `DoNotExposeEitherNetInRepositories`
+Summary
+: Repository APIs should not expose EitherNet types directly
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.1.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/eithernet/DoNotExposeEitherNetInRepositoriesDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/eithernet/DoNotExposeEitherNetInRepositoriesDetectorTest.kt)
+Copyright Year
+: 2022
+
+EitherNet (and networking in general) should be an implementation detail
+of the repository layer.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/MyRepository.java:8:Error: Repository APIs should not expose
+EitherNet types directly. [DoNotExposeEitherNetInRepositories]
+ ApiResult<String, Exception> getResult();
+ ----------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/com/slack/eithernet/ApiResult.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package com.slack.eithernet
+
+interface ApiResult
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/MyRepository.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test;
+
+import com.slack.eithernet.ApiResult;
+
+interface MyRepository {
+ // Bad
+
+ ApiResult getResult();
+
+ // Good
+
+ String getString();
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/MyClassRepository.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test;
+
+import com.slack.eithernet.ApiResult;
+
+abstract class MyClassRepository {
+ // Bad
+
+ public abstract ApiResult getResultPublic();
+ public ApiResult resultField = null;
+
+ // Good
+
+ ApiResult resultFieldPackagePrivate = null;
+ private final ApiResult resultFieldPrivate = null;
+ protected ApiResult resultFieldProtected = null;
+ abstract ApiResult getResultPackagePrivate();
+ private ApiResult getResultPrivate();
+ private ApiResult getResultProtected();
+ public abstract String getString();
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/eithernet/DoNotExposeEitherNetInRepositoriesDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `DoNotExposeEitherNetInRepositoriesDetector.javaTests`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/slack-lints.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("DoNotExposeEitherNetInRepositories")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("DoNotExposeEitherNetInRepositories")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection DoNotExposeEitherNetInRepositories
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DoNotExposeEitherNetInRepositories" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DoNotExposeEitherNetInRepositories'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DoNotExposeEitherNetInRepositories ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DoNotMock.md.html b/docs/checks/DoNotMock.md.html
new file mode 100644
index 00000000..4278f74d
--- /dev/null
+++ b/docs/checks/DoNotMock.md.html
@@ -0,0 +1,276 @@
+
+(#)
+
+!!! ERROR:
+ This is an error.
+
+Id
+: `DoNotMock`
+Summary
+:
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.1.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/mocking/MockDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/mocking/DoNotMockMockDetectorTest.kt)
+Copyright Year
+: 2021
+
+Do not mock classes annotated with `@DoNotMock`, as they are explicitly
+asking not to be mocked in favor of better options (test fakes, etc).
+These types should define explanations/alternatives in their
+annotation.
+
+(##) Options
+
+You can configure this lint checks using the following options:
+
+(###) mock-annotations
+
+A comma-separated list of mock annotations..
+This property should define comma-separated list of mock annotation class names (FQCN). Set this for all issues using this option.
+
+Default is "org.mockito.Mock,org.mockito.Spy".
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="DoNotMock">
+ <option name="mock-annotations" value=""org.mockito.Mock,org.mockito.Spy"" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(###) mock-factories
+
+A comma-separated list of mock factories (org.mockito.Mockito#methodName)..
+A comma-separated list of mock factories (org.mockito.Mockito#methodName). Set this for all issues using this option.
+
+Default is "org.mockito.Mockito#mock,org.mockito.Mockito#spy,slack.test.mockito.MockitoHelpers#mock,slack.test.mockito.MockitoHelpersKt#mock,org.mockito.kotlin.MockingKt#mock,org.mockito.kotlin.SpyingKt#spy".
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="DoNotMock">
+ <option name="mock-factories" value=""org.mockito.Mockito#mock,org.mockito.Mockito#spy,slack.test.mockito.MockitoHelpers#mock,slack.test.mockito.MockitoHelpersKt#mock,org.mockito.kotlin.MockingKt#mock,org.mockito.kotlin.SpyingKt#spy"" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(###) mock-report
+
+If enabled, writes a mock report to /build/reports/mockdetector/mock-report.csv..
+If enabled, writes a mock report to /build/reports/mockdetector/mock-report.csv. The format of the file is a csv of (type,isError) of mocked classes. Set this for all issues using this option.
+
+Default is "none".
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="DoNotMock">
+ <option name="mock-report" value=""none"" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+test/test/slack/test/TestClass.kt:6:Error: Do not mock TestClass: Use
+fake() [DoNotMock]
+ @Mock lateinit var mock1: TestClass
+ -----------------------------------
+test/test/slack/test/TestClass.kt:7:Error: Do not mock TestClass2: Use
+fake() [DoNotMock]
+ @Mock lateinit var mock2: TestClass2
+ ------------------------------------
+test/test/slack/test/TestClass.kt:8:Error: Do not mock TestClass3:
+BECAUSE REASONS [DoNotMock]
+ @Mock lateinit var mock3: TestClass3
+ ------------------------------------
+test/test/slack/test/TestClass.kt:9:Error: Do not mock TestClass4:
+BECAUSE REASONS [DoNotMock]
+ @Mock lateinit var mock4: TestClass4
+ ------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`test/test/slack/test/TestClass.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package slack.test
+
+@slack.lint.annotations.DoNotMock("Use fake()")
+interface TestClass {
+ fun fake(): TestClass? = null
+}
+
+@com.google.errorprone.annotations.DoNotMock("Use fake()")
+interface TestClass2 {
+ fun fake(): TestClass2? = null
+}
+
+@slack.lint.annotations.DoNotMock
+interface TestClass3 {
+ fun fake(): TestClass3? = null
+}
+
+@com.google.errorprone.annotations.DoNotMock
+interface TestClass4 {
+ fun fake(): TestClass4? = null
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`test/test/slack/test/TestClass.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package slack.test
+
+import org.mockito.Mock
+
+class MyTests {
+ @Mock lateinit var mock1: TestClass
+ @Mock lateinit var mock2: TestClass2
+ @Mock lateinit var mock3: TestClass3
+ @Mock lateinit var mock4: TestClass4
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/mocking/DoNotMockMockDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `MockDetector.kotlinTests`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/slack-lints.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("DoNotMock")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("DoNotMock")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection DoNotMock
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DoNotMock" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DoNotMock'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DoNotMock ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DoNotMockAnything.md.html b/docs/checks/DoNotMockAnything.md.html
new file mode 100644
index 00000000..17e0d171
--- /dev/null
+++ b/docs/checks/DoNotMockAnything.md.html
@@ -0,0 +1,206 @@
+
+(#) Do not add new mocks
+
+!!! ERROR: Do not add new mocks
+ This is an error.
+
+Id
+: `DoNotMockAnything`
+Summary
+: Do not add new mocks
+Note
+: **This issue is disabled by default**; use `--enable DoNotMockAnything`
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.7.2
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/mocking/MockDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/mocking/DoNotMockMockDetectorTest.kt)
+Copyright Year
+: 2021
+
+Mocking is almost always unnecessary and will make your tests more
+brittle. Use real instances (if appropriate) or test fakes instead. This
+lint is a catch-all for mocking, and has been enabled in this project to
+help prevent new mocking from being added.
+
+(##) Options
+
+You can configure this lint checks using the following options:
+
+(###) mock-annotations
+
+A comma-separated list of mock annotations..
+This property should define comma-separated list of mock annotation class names (FQCN). Set this for all issues using this option.
+
+Default is "org.mockito.Mock,org.mockito.Spy".
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="DoNotMockAnything">
+ <option name="mock-annotations" value=""org.mockito.Mock,org.mockito.Spy"" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(###) mock-factories
+
+A comma-separated list of mock factories (org.mockito.Mockito#methodName)..
+A comma-separated list of mock factories (org.mockito.Mockito#methodName). Set this for all issues using this option.
+
+Default is "org.mockito.Mockito#mock,org.mockito.Mockito#spy,slack.test.mockito.MockitoHelpers#mock,slack.test.mockito.MockitoHelpersKt#mock,org.mockito.kotlin.MockingKt#mock,org.mockito.kotlin.SpyingKt#spy".
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="DoNotMockAnything">
+ <option name="mock-factories" value=""org.mockito.Mockito#mock,org.mockito.Mockito#spy,slack.test.mockito.MockitoHelpers#mock,slack.test.mockito.MockitoHelpersKt#mock,org.mockito.kotlin.MockingKt#mock,org.mockito.kotlin.SpyingKt#spy"" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(###) mock-report
+
+If enabled, writes a mock report to /build/reports/mockdetector/mock-report.csv..
+If enabled, writes a mock report to /build/reports/mockdetector/mock-report.csv. The format of the file is a csv of (type,isError) of mocked classes. Set this for all issues using this option.
+
+Default is "none".
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="DoNotMockAnything">
+ <option name="mock-report" value=""none"" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("DoNotMockAnything")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("DoNotMockAnything")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection DoNotMockAnything
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DoNotMockAnything" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DoNotMockAnything'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DoNotMockAnything ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DoNotMockAutoValue.md.html b/docs/checks/DoNotMockAutoValue.md.html
new file mode 100644
index 00000000..31e97a83
--- /dev/null
+++ b/docs/checks/DoNotMockAutoValue.md.html
@@ -0,0 +1,202 @@
+
+(#) AutoValue classes represent pure data classes, so mocking them should not be necessary
+
+!!! ERROR: AutoValue classes represent pure data classes, so mocking them should not be necessary
+ This is an error.
+
+Id
+: `DoNotMockAutoValue`
+Summary
+: AutoValue classes represent pure data classes, so mocking them should not be necessary
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.1.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/mocking/MockDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/mocking/DoNotMockMockDetectorTest.kt)
+Copyright Year
+: 2021
+
+`AutoValue` classes represent pure data classes, so mocking them should
+not be necessary. Construct a real instance of the class instead.
+
+(##) Options
+
+You can configure this lint checks using the following options:
+
+(###) mock-annotations
+
+A comma-separated list of mock annotations..
+This property should define comma-separated list of mock annotation class names (FQCN). Set this for all issues using this option.
+
+Default is "org.mockito.Mock,org.mockito.Spy".
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="DoNotMockAutoValue">
+ <option name="mock-annotations" value=""org.mockito.Mock,org.mockito.Spy"" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(###) mock-factories
+
+A comma-separated list of mock factories (org.mockito.Mockito#methodName)..
+A comma-separated list of mock factories (org.mockito.Mockito#methodName). Set this for all issues using this option.
+
+Default is "org.mockito.Mockito#mock,org.mockito.Mockito#spy,slack.test.mockito.MockitoHelpers#mock,slack.test.mockito.MockitoHelpersKt#mock,org.mockito.kotlin.MockingKt#mock,org.mockito.kotlin.SpyingKt#spy".
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="DoNotMockAutoValue">
+ <option name="mock-factories" value=""org.mockito.Mockito#mock,org.mockito.Mockito#spy,slack.test.mockito.MockitoHelpers#mock,slack.test.mockito.MockitoHelpersKt#mock,org.mockito.kotlin.MockingKt#mock,org.mockito.kotlin.SpyingKt#spy"" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(###) mock-report
+
+If enabled, writes a mock report to /build/reports/mockdetector/mock-report.csv..
+If enabled, writes a mock report to /build/reports/mockdetector/mock-report.csv. The format of the file is a csv of (type,isError) of mocked classes. Set this for all issues using this option.
+
+Default is "none".
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="DoNotMockAutoValue">
+ <option name="mock-report" value=""none"" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("DoNotMockAutoValue")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("DoNotMockAutoValue")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection DoNotMockAutoValue
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DoNotMockAutoValue" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DoNotMockAutoValue'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DoNotMockAutoValue ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DoNotMockDataClass.md.html b/docs/checks/DoNotMockDataClass.md.html
new file mode 100644
index 00000000..61017640
--- /dev/null
+++ b/docs/checks/DoNotMockDataClass.md.html
@@ -0,0 +1,202 @@
+
+(#) data classes represent pure data classes, so mocking them should not be necessary
+
+!!! ERROR: data classes represent pure data classes, so mocking them should not be necessary
+ This is an error.
+
+Id
+: `DoNotMockDataClass`
+Summary
+: data classes represent pure data classes, so mocking them should not be necessary
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.1.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/mocking/MockDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/mocking/DoNotMockMockDetectorTest.kt)
+Copyright Year
+: 2021
+
+data classes represent pure data classes, so mocking them should not be
+necessary. Construct a real instance of the class instead.
+
+(##) Options
+
+You can configure this lint checks using the following options:
+
+(###) mock-annotations
+
+A comma-separated list of mock annotations..
+This property should define comma-separated list of mock annotation class names (FQCN). Set this for all issues using this option.
+
+Default is "org.mockito.Mock,org.mockito.Spy".
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="DoNotMockDataClass">
+ <option name="mock-annotations" value=""org.mockito.Mock,org.mockito.Spy"" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(###) mock-factories
+
+A comma-separated list of mock factories (org.mockito.Mockito#methodName)..
+A comma-separated list of mock factories (org.mockito.Mockito#methodName). Set this for all issues using this option.
+
+Default is "org.mockito.Mockito#mock,org.mockito.Mockito#spy,slack.test.mockito.MockitoHelpers#mock,slack.test.mockito.MockitoHelpersKt#mock,org.mockito.kotlin.MockingKt#mock,org.mockito.kotlin.SpyingKt#spy".
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="DoNotMockDataClass">
+ <option name="mock-factories" value=""org.mockito.Mockito#mock,org.mockito.Mockito#spy,slack.test.mockito.MockitoHelpers#mock,slack.test.mockito.MockitoHelpersKt#mock,org.mockito.kotlin.MockingKt#mock,org.mockito.kotlin.SpyingKt#spy"" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(###) mock-report
+
+If enabled, writes a mock report to /build/reports/mockdetector/mock-report.csv..
+If enabled, writes a mock report to /build/reports/mockdetector/mock-report.csv. The format of the file is a csv of (type,isError) of mocked classes. Set this for all issues using this option.
+
+Default is "none".
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="DoNotMockDataClass">
+ <option name="mock-report" value=""none"" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("DoNotMockDataClass")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("DoNotMockDataClass")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection DoNotMockDataClass
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DoNotMockDataClass" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DoNotMockDataClass'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DoNotMockDataClass ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DoNotMockObjectClass.md.html b/docs/checks/DoNotMockObjectClass.md.html
new file mode 100644
index 00000000..2bac1692
--- /dev/null
+++ b/docs/checks/DoNotMockObjectClass.md.html
@@ -0,0 +1,202 @@
+
+(#) object classes are singletons, so mocking them should not be necessary
+
+!!! ERROR: object classes are singletons, so mocking them should not be necessary
+ This is an error.
+
+Id
+: `DoNotMockObjectClass`
+Summary
+: object classes are singletons, so mocking them should not be necessary
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.3.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/mocking/MockDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/mocking/DoNotMockMockDetectorTest.kt)
+Copyright Year
+: 2021
+
+object classes are global singletons, so mocking them should not be
+necessary. Use the object instance instead.
+
+(##) Options
+
+You can configure this lint checks using the following options:
+
+(###) mock-annotations
+
+A comma-separated list of mock annotations..
+This property should define comma-separated list of mock annotation class names (FQCN). Set this for all issues using this option.
+
+Default is "org.mockito.Mock,org.mockito.Spy".
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="DoNotMockObjectClass">
+ <option name="mock-annotations" value=""org.mockito.Mock,org.mockito.Spy"" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(###) mock-factories
+
+A comma-separated list of mock factories (org.mockito.Mockito#methodName)..
+A comma-separated list of mock factories (org.mockito.Mockito#methodName). Set this for all issues using this option.
+
+Default is "org.mockito.Mockito#mock,org.mockito.Mockito#spy,slack.test.mockito.MockitoHelpers#mock,slack.test.mockito.MockitoHelpersKt#mock,org.mockito.kotlin.MockingKt#mock,org.mockito.kotlin.SpyingKt#spy".
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="DoNotMockObjectClass">
+ <option name="mock-factories" value=""org.mockito.Mockito#mock,org.mockito.Mockito#spy,slack.test.mockito.MockitoHelpers#mock,slack.test.mockito.MockitoHelpersKt#mock,org.mockito.kotlin.MockingKt#mock,org.mockito.kotlin.SpyingKt#spy"" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(###) mock-report
+
+If enabled, writes a mock report to /build/reports/mockdetector/mock-report.csv..
+If enabled, writes a mock report to /build/reports/mockdetector/mock-report.csv. The format of the file is a csv of (type,isError) of mocked classes. Set this for all issues using this option.
+
+Default is "none".
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="DoNotMockObjectClass">
+ <option name="mock-report" value=""none"" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("DoNotMockObjectClass")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("DoNotMockObjectClass")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection DoNotMockObjectClass
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DoNotMockObjectClass" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DoNotMockObjectClass'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DoNotMockObjectClass ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DoNotMockPlatformTypes.md.html b/docs/checks/DoNotMockPlatformTypes.md.html
new file mode 100644
index 00000000..8120480b
--- /dev/null
+++ b/docs/checks/DoNotMockPlatformTypes.md.html
@@ -0,0 +1,206 @@
+
+(#) platform types should not be mocked
+
+!!! ERROR: platform types should not be mocked
+ This is an error.
+
+Id
+: `DoNotMockPlatformTypes`
+Summary
+: platform types should not be mocked
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.4.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/mocking/MockDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/mocking/DoNotMockMockDetectorTest.kt)
+Copyright Year
+: 2021
+
+Platform types (i.e. classes in java.*, android.*, etc) should not be
+mocked. Use a real instance or fake instead. Mocking platform types like
+these can lead to surprising test failures due to mocks that actually
+behave differently than real instances, especially when passed into real
+implementations that use them and expect them to behave in a certain
+way. If using Robolectric, consider using its shadow APIs.
+
+(##) Options
+
+You can configure this lint checks using the following options:
+
+(###) mock-annotations
+
+A comma-separated list of mock annotations..
+This property should define comma-separated list of mock annotation class names (FQCN). Set this for all issues using this option.
+
+Default is "org.mockito.Mock,org.mockito.Spy".
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="DoNotMockPlatformTypes">
+ <option name="mock-annotations" value=""org.mockito.Mock,org.mockito.Spy"" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(###) mock-factories
+
+A comma-separated list of mock factories (org.mockito.Mockito#methodName)..
+A comma-separated list of mock factories (org.mockito.Mockito#methodName). Set this for all issues using this option.
+
+Default is "org.mockito.Mockito#mock,org.mockito.Mockito#spy,slack.test.mockito.MockitoHelpers#mock,slack.test.mockito.MockitoHelpersKt#mock,org.mockito.kotlin.MockingKt#mock,org.mockito.kotlin.SpyingKt#spy".
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="DoNotMockPlatformTypes">
+ <option name="mock-factories" value=""org.mockito.Mockito#mock,org.mockito.Mockito#spy,slack.test.mockito.MockitoHelpers#mock,slack.test.mockito.MockitoHelpersKt#mock,org.mockito.kotlin.MockingKt#mock,org.mockito.kotlin.SpyingKt#spy"" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(###) mock-report
+
+If enabled, writes a mock report to /build/reports/mockdetector/mock-report.csv..
+If enabled, writes a mock report to /build/reports/mockdetector/mock-report.csv. The format of the file is a csv of (type,isError) of mocked classes. Set this for all issues using this option.
+
+Default is "none".
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="DoNotMockPlatformTypes">
+ <option name="mock-report" value=""none"" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("DoNotMockPlatformTypes")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("DoNotMockPlatformTypes")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection DoNotMockPlatformTypes
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DoNotMockPlatformTypes" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DoNotMockPlatformTypes'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DoNotMockPlatformTypes ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DoNotMockRecordClass.md.html b/docs/checks/DoNotMockRecordClass.md.html
new file mode 100644
index 00000000..dd681f34
--- /dev/null
+++ b/docs/checks/DoNotMockRecordClass.md.html
@@ -0,0 +1,202 @@
+
+(#) record classes represent pure data classes, so mocking them should not be necessary
+
+!!! ERROR: record classes represent pure data classes, so mocking them should not be necessary
+ This is an error.
+
+Id
+: `DoNotMockRecordClass`
+Summary
+: record classes represent pure data classes, so mocking them should not be necessary
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.3.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/mocking/MockDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/mocking/DoNotMockMockDetectorTest.kt)
+Copyright Year
+: 2021
+
+record classes represent pure data classes, so mocking them should not
+be necessary. Construct a real instance of the class instead.
+
+(##) Options
+
+You can configure this lint checks using the following options:
+
+(###) mock-annotations
+
+A comma-separated list of mock annotations..
+This property should define comma-separated list of mock annotation class names (FQCN). Set this for all issues using this option.
+
+Default is "org.mockito.Mock,org.mockito.Spy".
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="DoNotMockRecordClass">
+ <option name="mock-annotations" value=""org.mockito.Mock,org.mockito.Spy"" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(###) mock-factories
+
+A comma-separated list of mock factories (org.mockito.Mockito#methodName)..
+A comma-separated list of mock factories (org.mockito.Mockito#methodName). Set this for all issues using this option.
+
+Default is "org.mockito.Mockito#mock,org.mockito.Mockito#spy,slack.test.mockito.MockitoHelpers#mock,slack.test.mockito.MockitoHelpersKt#mock,org.mockito.kotlin.MockingKt#mock,org.mockito.kotlin.SpyingKt#spy".
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="DoNotMockRecordClass">
+ <option name="mock-factories" value=""org.mockito.Mockito#mock,org.mockito.Mockito#spy,slack.test.mockito.MockitoHelpers#mock,slack.test.mockito.MockitoHelpersKt#mock,org.mockito.kotlin.MockingKt#mock,org.mockito.kotlin.SpyingKt#spy"" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(###) mock-report
+
+If enabled, writes a mock report to /build/reports/mockdetector/mock-report.csv..
+If enabled, writes a mock report to /build/reports/mockdetector/mock-report.csv. The format of the file is a csv of (type,isError) of mocked classes. Set this for all issues using this option.
+
+Default is "none".
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="DoNotMockRecordClass">
+ <option name="mock-report" value=""none"" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("DoNotMockRecordClass")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("DoNotMockRecordClass")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection DoNotMockRecordClass
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DoNotMockRecordClass" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DoNotMockRecordClass'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DoNotMockRecordClass ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DoNotMockSealedClass.md.html b/docs/checks/DoNotMockSealedClass.md.html
new file mode 100644
index 00000000..606113c4
--- /dev/null
+++ b/docs/checks/DoNotMockSealedClass.md.html
@@ -0,0 +1,203 @@
+
+(#) sealed classes have a restricted type hierarchy, use a subtype instead
+
+!!! ERROR: sealed classes have a restricted type hierarchy, use a subtype instead
+ This is an error.
+
+Id
+: `DoNotMockSealedClass`
+Summary
+: sealed classes have a restricted type hierarchy, use a subtype instead
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.3.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/mocking/MockDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/mocking/DoNotMockMockDetectorTest.kt)
+Copyright Year
+: 2021
+
+sealed classes have a restricted type hierarchy, so creating new
+unrestricted mocks will break runtime expectations. Mockito also cannot
+mock sealed classes in Java 17+. Use a subtype instead.
+
+(##) Options
+
+You can configure this lint checks using the following options:
+
+(###) mock-annotations
+
+A comma-separated list of mock annotations..
+This property should define comma-separated list of mock annotation class names (FQCN). Set this for all issues using this option.
+
+Default is "org.mockito.Mock,org.mockito.Spy".
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="DoNotMockSealedClass">
+ <option name="mock-annotations" value=""org.mockito.Mock,org.mockito.Spy"" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(###) mock-factories
+
+A comma-separated list of mock factories (org.mockito.Mockito#methodName)..
+A comma-separated list of mock factories (org.mockito.Mockito#methodName). Set this for all issues using this option.
+
+Default is "org.mockito.Mockito#mock,org.mockito.Mockito#spy,slack.test.mockito.MockitoHelpers#mock,slack.test.mockito.MockitoHelpersKt#mock,org.mockito.kotlin.MockingKt#mock,org.mockito.kotlin.SpyingKt#spy".
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="DoNotMockSealedClass">
+ <option name="mock-factories" value=""org.mockito.Mockito#mock,org.mockito.Mockito#spy,slack.test.mockito.MockitoHelpers#mock,slack.test.mockito.MockitoHelpersKt#mock,org.mockito.kotlin.MockingKt#mock,org.mockito.kotlin.SpyingKt#spy"" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(###) mock-report
+
+If enabled, writes a mock report to /build/reports/mockdetector/mock-report.csv..
+If enabled, writes a mock report to /build/reports/mockdetector/mock-report.csv. The format of the file is a csv of (type,isError) of mocked classes. Set this for all issues using this option.
+
+Default is "none".
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="DoNotMockSealedClass">
+ <option name="mock-report" value=""none"" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("DoNotMockSealedClass")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("DoNotMockSealedClass")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection DoNotMockSealedClass
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DoNotMockSealedClass" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DoNotMockSealedClass'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DoNotMockSealedClass ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DrawAllocation.md.html b/docs/checks/DrawAllocation.md.html
new file mode 100644
index 00000000..b93f25b3
--- /dev/null
+++ b/docs/checks/DrawAllocation.md.html
@@ -0,0 +1,152 @@
+
+(#) Memory allocations within drawing code
+
+!!! WARNING: Memory allocations within drawing code
+ This is a warning.
+
+Id
+: `DrawAllocation`
+Summary
+: Memory allocations within drawing code
+Severity
+: Warning
+Category
+: Performance
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/JavaPerformanceDetector.java)
+Tests
+: [Source Code](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/JavaPerformanceDetectorTest.java)
+Copyright Year
+: 2012
+
+You should avoid allocating objects during a drawing or layout
+operation. These are called frequently, so a smooth UI can be
+interrupted by garbage collection pauses caused by the object
+allocations.
+
+The way this is generally handled is to allocate the needed objects up
+front and to reuse them for each drawing operation.
+
+Some methods allocate memory on your behalf (such as `Bitmap.create`),
+and these should be handled in the same way.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/MyView.java:18:Warning: Avoid object allocations during
+draw/layout operations (preallocate and reuse instead) [DrawAllocation]
+ bitmap = Bitmap.createBitmap(100, 100, null);
+ -----------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/MyView.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.util.AttributeSet;
+import android.view.View;
+
+public abstract class MyView extends View {
+ public MyView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ bitmap = Bitmap.createBitmap(100, 100, null);
+ }
+
+ private Bitmap bitmap;
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/JavaPerformanceDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("DrawAllocation")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("DrawAllocation")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection DrawAllocation
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DrawAllocation" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DrawAllocation'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DrawAllocation ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DuplicateActivity.md.html b/docs/checks/DuplicateActivity.md.html
new file mode 100644
index 00000000..fda7075c
--- /dev/null
+++ b/docs/checks/DuplicateActivity.md.html
@@ -0,0 +1,173 @@
+
+(#) Activity registered more than once
+
+!!! ERROR: Activity registered more than once
+ This is an error, and is also enforced at build time when
+ supported by the build system. For Android this means it will
+ run during release builds.
+
+Id
+: `DuplicateActivity`
+Summary
+: Activity registered more than once
+Severity
+: Fatal
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/ManifestDetector.kt)
+Tests
+: [Source Code](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/ManifestDetectorTest.kt)
+Copyright Year
+: 2011
+
+An activity should only be registered once in the manifest. If it is
+accidentally registered more than once, then subtle errors can occur,
+since attribute declarations from the two elements are not merged, so
+you may accidentally remove previous declarations.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:15:Error: Duplicate registration for activity
+com.example.helloworld.HelloWorld [DuplicateActivity]
+ <activity android:name="com.example.helloworld.HelloWorld"
+ ------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.helloworld"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <uses-sdk android:minSdkVersion="14" />
+ <application android:icon="@drawable/icon" android:label="@string/app_name">
+ <activity android:name=".HelloWorld"
+ android:label="@string/app_name">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name="com.example.helloworld.HelloWorld"
+ android:label="@string/app_name">
+ </activity>
+
+ </application>
+
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <!-- Home -->
+ <string name="home_title">Home Sample</string>
+ <string name="show_all_apps">All</string>
+
+ <!-- Home Menus -->
+ <string name="menu_wallpaper">Wallpaper</string>
+ <string name="menu_search">Search</string>
+ <string name="menu_settings">Settings</string>
+ <string name="sample" translatable="false">Ignore Me</string>
+
+ <!-- Wallpaper -->
+ <string name="wallpaper_instructions">Tap picture to set portrait wallpaper</string>
+</resources>
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ManifestDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ManifestDetector.testDuplicateActivity`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="DuplicateActivity"`
+ on the problematic XML element (or one of its enclosing elements).
+ You may also need to add the following namespace declaration on the
+ root element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <application tools:ignore="DuplicateActivity" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DuplicateActivity" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DuplicateActivity'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DuplicateActivity ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DuplicateDefinition.md.html b/docs/checks/DuplicateDefinition.md.html
new file mode 100644
index 00000000..b58c3f0e
--- /dev/null
+++ b/docs/checks/DuplicateDefinition.md.html
@@ -0,0 +1,193 @@
+
+(#) Duplicate definitions of resources
+
+!!! ERROR: Duplicate definitions of resources
+ This is an error.
+
+Id
+: `DuplicateDefinition`
+Summary
+: Duplicate definitions of resources
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/DuplicateResourceDetector.java)
+Tests
+: [Source Code](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/DuplicateResourceDetectorTest.java)
+Copyright Year
+: 2012
+
+You can define a resource multiple times in different resource folders;
+that's how string translations are done, for example. However, defining
+the same resource more than once in the same resource folder is likely
+an error, for example attempting to add a new resource without realizing
+that the name is already used, and so on.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/values/strings2.xml:19:Error: wallpaper_instructions has already
+been defined in this folder [DuplicateDefinition]
+ <string name="wallpaper_instructions">Tap image to set landscape wallpaper</string>
+ -----------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`res/values/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <!-- Home -->
+ <string name="home_title">Home Sample</string>
+ <string name="show_all_apps">All</string>
+
+ <!-- Home Menus -->
+ <string name="menu_wallpaper">Wallpaper</string>
+ <string name="menu_search">Search</string>
+ <string name="menu_settings">Settings</string>
+ <string name="sample" translatable="false">Ignore Me</string>
+
+ <!-- Wallpaper -->
+ <string name="wallpaper_instructions">Tap picture to set portrait wallpaper</string>
+</resources>
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values/strings2.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <!-- Wallpaper -->
+ <string name="wallpaper_instructions">Tap image to set landscape wallpaper</string>
+</resources>
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values-cs/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="home_title">"Domů"</string>
+ <string name="show_all_apps">"Vše"</string>
+ <string name="menu_wallpaper">"Tapeta"</string>
+ <string name="menu_search">"Hledat"</string>
+ <!-- no translation found for menu_settings (1769059051084007158) -->
+ <skip />
+ <string name="wallpaper_instructions">"Klepnutím na obrázek nastavíte tapetu portrétu"</string>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values/customattr.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<resources>
+ <declare-styleable name="ContentFrame">
+ <attr name="content" format="reference" />
+ <attr name="contentId" format="reference" />
+ </declare-styleable>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values/customattr2.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<resources>
+ <declare-styleable name="ContentFrame">
+ <attr name="content" format="reference" />
+ <attr name="contentId" format="reference" />
+ </declare-styleable>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/DuplicateResourceDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `DuplicateResourceDetector.test`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DuplicateDefinition" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DuplicateDefinition'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DuplicateDefinition ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DuplicateDivider.md.html b/docs/checks/DuplicateDivider.md.html
new file mode 100644
index 00000000..948738b0
--- /dev/null
+++ b/docs/checks/DuplicateDivider.md.html
@@ -0,0 +1,155 @@
+
+(#) Unnecessary Divider Copy
+
+!!! WARNING: Unnecessary Divider Copy
+ This is a warning.
+
+Id
+: `DuplicateDivider`
+Summary
+: Unnecessary Divider Copy
+Severity
+: Warning
+Category
+: Performance
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 2.3.0 (March 2017)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/ItemDecoratorDetector.java)
+Tests
+: [Source Code](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/ItemDecoratorDetectorTest.kt)
+
+Older versions of the RecyclerView library did not include a divider
+decorator, but one was provided as a sample in the support demos. This
+divider class has been widely copy/pasted into various projects.
+
+In recent versions of the support library, the divider decorator is now
+included, so you can replace custom copies with the "built-in" version,
+`android.support.v7.widget.DividerItemDecoration`.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/com/example/android/supportv7/widget/decorator/DividerItemDecoration.java:11:Warning:
+Replace with android.support.v7.widget.DividerItemDecoration?
+[DuplicateDivider]
+public abstract class DividerItemDecoration extends RecyclerView.ItemDecoration {
+ ---------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/com/example/android/supportv7/widget/decorator/DividerItemDecoration.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package com.example.android.supportv7.widget.decorator;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.support.v7.widget.RecyclerView;
+import android.view.View;
+
+public abstract class DividerItemDecoration extends RecyclerView.ItemDecoration {
+
+ private static final int[] ATTRS = new int[]{
+ android.R.attr.listDivider
+ };
+
+ public static int HORIZONTAL_LIST;
+
+ public static int VERTICAL_LIST;
+
+ private Drawable mDivider;
+
+ private int mOrientation;
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ItemDecoratorDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ItemDecoratorDetector.test`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("DuplicateDivider")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("DuplicateDivider")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection DuplicateDivider
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DuplicateDivider" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DuplicateDivider'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DuplicateDivider ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DuplicateIds.md.html b/docs/checks/DuplicateIds.md.html
new file mode 100644
index 00000000..9bf2d504
--- /dev/null
+++ b/docs/checks/DuplicateIds.md.html
@@ -0,0 +1,122 @@
+
+(#) Duplicate ids within a single layout
+
+!!! ERROR: Duplicate ids within a single layout
+ This is an error, and is also enforced at build time when
+ supported by the build system. For Android this means it will
+ run during release builds.
+
+Id
+: `DuplicateIds`
+Summary
+: Duplicate ids within a single layout
+Severity
+: Fatal
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/DuplicateIdDetector.java)
+Tests
+: [Source Code](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/DuplicateIdDetectorTest.kt)
+Copyright Year
+: 2011
+
+Within a layout, id's should be unique since otherwise `findViewById()`
+can return an unexpected view.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/duplicate.xml:5:Error: Duplicate id @+id/android_logo,
+already defined earlier in this layout [DuplicateIds]
+ <ImageButton android:id="@+id/android_logo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="http://github.com/@drawable/android_button" android:focusable="false" android:clickable="false" android:layout_weight="1.0" />
+ ------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/layout/duplicate.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/newlinear" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent">
+ <Button android:text="Button" android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
+ <ImageView android:id="@+id/android_logo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="http://github.com/@drawable/android_button" android:focusable="false" android:clickable="false" android:layout_weight="1.0" />
+ <ImageButton android:id="@+id/android_logo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="http://github.com/@drawable/android_button" android:focusable="false" android:clickable="false" android:layout_weight="1.0" />
+ <Button android:text="Button" android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
+</LinearLayout>
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/DuplicateIdDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `DuplicateIdDetector.testDuplicate`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="DuplicateIds"` on
+ the problematic XML element (or one of its enclosing elements). You
+ may also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <include xmlns:tools="http://schemas.android.com/tools"
+ tools:ignore="DuplicateIds" ...>
+ ...
+ </include>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DuplicateIds" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DuplicateIds'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DuplicateIds ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DuplicateIncludedIds.md.html b/docs/checks/DuplicateIncludedIds.md.html
new file mode 100644
index 00000000..347edfac
--- /dev/null
+++ b/docs/checks/DuplicateIncludedIds.md.html
@@ -0,0 +1,212 @@
+
+(#) Duplicate ids across layouts combined with include tags
+
+!!! WARNING: Duplicate ids across layouts combined with include tags
+ This is a warning.
+
+Id
+: `DuplicateIncludedIds`
+Summary
+: Duplicate ids across layouts combined with include tags
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/DuplicateIdDetector.java)
+Tests
+: [Source Code](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/DuplicateIdDetectorTest.kt)
+Copyright Year
+: 2011
+
+It's okay for two independent layouts to use the same ids. However, if
+layouts are combined with include tags, then the id's need to be unique
+within any chain of included layouts, or `Activity#findViewById()` can
+return an unexpected view.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/layout1.xml:7:Warning: Duplicate id @+id/button2, defined or
+included multiple times in layout/layout1.xml: [layout/layout1.xml
+defines @+id/button2, layout/layout1.xml => layout/layout2.xml =>
+layout/layout4.xml defines @+id/button2] [DuplicateIncludedIds]
+ <include
+ ^
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`res/layout/layout1.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <include
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ layout="@layout/layout2" />
+
+ <Button
+ android:id="@+id/button1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Button" />
+
+ <Button
+ android:id="@+id/button2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Button" />
+
+</LinearLayout>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/layout/layout2.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <RadioButton
+ android:id="@+id/radioButton1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="RadioButton" />
+
+ <include
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ layout="@layout/layout3" />
+
+ <include
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ layout="@layout/layout4" />
+
+</LinearLayout>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/layout/layout3.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <Button
+ android:id="@+id/button1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Button" />
+
+ <CheckBox
+ android:id="@+id/checkBox1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="CheckBox" />
+
+</LinearLayout>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/layout/layout4.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <Button
+ android:id="@+id/button1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Button" />
+
+ <Button
+ android:id="@+id/button2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Button" />
+
+</LinearLayout>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/DuplicateIdDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `DuplicateIdDetector.testDuplicateChains`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="DuplicateIncludedIds"` on the problematic XML element
+ (or one of its enclosing elements). You may also need to add the
+ following namespace declaration on the root element in the XML file
+ if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <include xmlns:tools="http://schemas.android.com/tools"
+ tools:ignore="DuplicateIncludedIds" ...>
+ ...
+ </include>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DuplicateIncludedIds" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DuplicateIncludedIds'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DuplicateIncludedIds ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DuplicatePlatformClasses.md.html b/docs/checks/DuplicatePlatformClasses.md.html
new file mode 100644
index 00000000..50748cbd
--- /dev/null
+++ b/docs/checks/DuplicatePlatformClasses.md.html
@@ -0,0 +1,178 @@
+
+(#) Duplicate Platform Classes
+
+!!! ERROR: Duplicate Platform Classes
+ This is an error, and is also enforced at build time when
+ supported by the build system. For Android this means it will
+ run during release builds.
+
+Id
+: `DuplicatePlatformClasses`
+Summary
+: Duplicate Platform Classes
+Severity
+: Fatal
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.0.0 (October 2017)
+Affects
+: Gradle build files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/GradleDetector.kt)
+Tests
+: [Source Code](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/GradleDetectorTest.kt)
+
+There are a number of libraries that duplicate not just functionality of
+the Android platform but using the exact same class names as the ones
+provided in Android -- for example the apache http classes. This can
+lead to unexpected crashes.
+
+To solve this, you need to either find a newer version of the library
+which no longer has this problem, or to repackage the library (and all
+of its dependencies) using something like the `jarjar` tool, or finally,
+rewriting the code to use different APIs (for example, for http code,
+consider using `HttpUrlConnection` or a library like `okhttp`).
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+build.gradle:3:Error: xpp3 defines classes that conflict with classes
+now provided by Android. Solutions include finding newer versions or
+alternative libraries that don't have the same problem (for example, for
+httpclient use HttpUrlConnection or okhttp instead), or repackaging the
+library using something like jarjar. [DuplicatePlatformClasses]
+ implementation 'xpp3:xpp3:1.1.4c'
+ ---------------------------------
+build.gradle:4:Error: commons-logging defines classes that conflict with
+classes now provided by Android. Solutions include finding newer
+versions or alternative libraries that don't have the same problem (for
+example, for httpclient use HttpUrlConnection or okhttp instead), or
+repackaging the library using something like jarjar.
+[DuplicatePlatformClasses]
+ implementation 'commons-logging:commons-logging:1.2'
+ ----------------------------------------------------
+build.gradle:5:Error: xmlParserAPIs defines classes that conflict with
+classes now provided by Android. Solutions include finding newer
+versions or alternative libraries that don't have the same problem (for
+example, for httpclient use HttpUrlConnection or okhttp instead), or
+repackaging the library using something like jarjar.
+[DuplicatePlatformClasses]
+ implementation 'xerces:xmlParserAPIs:2.6.2'
+ -------------------------------------------
+build.gradle:6:Error: json defines classes that conflict with classes
+now provided by Android. Solutions include finding newer versions or
+alternative libraries that don't have the same problem (for example, for
+httpclient use HttpUrlConnection or okhttp instead), or repackaging the
+library using something like jarjar. [DuplicatePlatformClasses]
+ implementation 'org.json:json:20170516'
+ ---------------------------------------
+build.gradle:7:Error: opengl-api defines classes that conflict with
+classes now provided by Android. Solutions include finding newer
+versions or alternative libraries that don't have the same problem (for
+example, for httpclient use HttpUrlConnection or okhttp instead), or
+repackaging the library using something like jarjar.
+[DuplicatePlatformClasses]
+ implementation 'org.khronos:opengl-api:gl1.1-android-2.1_r1'
+ ------------------------------------------------------------
+build.gradle:8:Error: android defines classes that conflict with classes
+now provided by Android. Solutions include finding newer versions or
+alternative libraries that don't have the same problem (for example, for
+httpclient use HttpUrlConnection or okhttp instead), or repackaging the
+library using something like jarjar. [DuplicatePlatformClasses]
+ implementation 'com.google.android:android:4.1.1.4'
+ ---------------------------------------------------
+build.gradle:9:Error: httpclient defines classes that conflict with
+classes now provided by Android. Solutions include finding newer
+versions or alternative libraries that don't have the same problem (for
+example, for httpclient use HttpUrlConnection or okhttp instead), or
+repackaging the library using something like jarjar.
+[DuplicatePlatformClasses]
+ compile group: 'org.apache.httpcomponents',
+ ^
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`build.gradle`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~groovy linenumbers
+dependencies {
+ implementation 'my.indirect.dependency:myname:1.2.3'
+ implementation 'xpp3:xpp3:1.1.4c'
+ implementation 'commons-logging:commons-logging:1.2'
+ implementation 'xerces:xmlParserAPIs:2.6.2'
+ implementation 'org.json:json:20170516'
+ implementation 'org.khronos:opengl-api:gl1.1-android-2.1_r1'
+ implementation 'com.google.android:android:4.1.1.4'
+ compile group: 'org.apache.httpcomponents',
+ name: 'httpclient',
+ version: '4.5.3'
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/GradleDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `GradleDetector.testDuplicateWarnings`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection DuplicatePlatformClasses
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DuplicatePlatformClasses" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DuplicatePlatformClasses'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DuplicatePlatformClasses ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DuplicateStrings.md.html b/docs/checks/DuplicateStrings.md.html
new file mode 100644
index 00000000..65b6a302
--- /dev/null
+++ b/docs/checks/DuplicateStrings.md.html
@@ -0,0 +1,119 @@
+
+(#) Duplicate Strings
+
+!!! WARNING: Duplicate Strings
+ This is a warning.
+
+Id
+: `DuplicateStrings`
+Summary
+: Duplicate Strings
+Note
+: **This issue is disabled by default**; use `--enable DuplicateStrings`
+Severity
+: Warning
+Category
+: Performance: Application Size
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.3.0 (January 2019)
+Affects
+: Resource files
+Editing
+: This check can *not* run live in the IDE editor
+See
+: https://developer.android.com/reference/android/widget/TextView.html#attr_android:inputType
+Implementation
+: [Source Code](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/StringCasingDetector.kt)
+Tests
+: [Source Code](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/StringCasingDetectorTest.kt)
+
+Duplicate strings can make applications larger unnecessarily.
+
+This lint check looks for duplicate strings, including differences for
+strings where the only difference is in capitalization. Title casing and
+all uppercase can all be adjusted in the layout or in code.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/values/duplicate_strings.xml:3:Warning: Duplicate string value
+HELLO, used in hello_caps and hello. Use android:inputType or
+android:capitalize to treat these as the same and avoid string
+duplication. [DuplicateStrings]
+ <string name="hello">hello</string>
+ -----------------------------------
+res/values/duplicate_strings.xml:5:Warning: Duplicate string value Hello
+World, used in hello_world and title_casing_hello_world. Use
+android:inputType or android:capitalize to treat these as the same and
+avoid string duplication. [DuplicateStrings]
+ <string name="hello_world">hello world</string>
+ -----------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/values/duplicate_strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+ <resources>
+ <string name="hello">hello</string>
+ <string name="hello_caps">HELLO</string>
+ <string name="hello_world">hello world</string>
+ <string name="title_casing_hello_world">Hello World</string>
+ </resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/StringCasingDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `StringCasingDetector.testDuplicateStrings`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DuplicateStrings" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DuplicateStrings'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DuplicateStrings ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/DuplicateUsesFeature.md.html b/docs/checks/DuplicateUsesFeature.md.html
new file mode 100644
index 00000000..f9e0be48
--- /dev/null
+++ b/docs/checks/DuplicateUsesFeature.md.html
@@ -0,0 +1,164 @@
+
+(#) Feature declared more than once
+
+!!! WARNING: Feature declared more than once
+ This is a warning.
+
+Id
+: `DuplicateUsesFeature`
+Summary
+: Feature declared more than once
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/ManifestDetector.kt)
+Tests
+: [Source Code](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/ManifestDetectorTest.kt)
+Copyright Year
+: 2011
+
+A given feature should only be declared once in the manifest.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:9:Warning: Duplicate declaration of uses-feature
+android.hardware.camera [DuplicateUsesFeature]
+ <uses-feature android:name="android.hardware.camera"/>
+ --------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="foo.bar2"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk android:minSdkVersion="14" />
+
+ <uses-feature android:name="android.hardware.camera"/>
+ <uses-feature android:name="android.hardware.camera"/>
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name" >
+ </application>
+
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <!-- Home -->
+ <string name="home_title">Home Sample</string>
+ <string name="show_all_apps">All</string>
+
+ <!-- Home Menus -->
+ <string name="menu_wallpaper">Wallpaper</string>
+ <string name="menu_search">Search</string>
+ <string name="menu_settings">Settings</string>
+ <string name="sample" translatable="false">Ignore Me</string>
+
+ <!-- Wallpaper -->
+ <string name="wallpaper_instructions">Tap picture to set portrait wallpaper</string>
+</resources>
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ManifestDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ManifestDetector.testDuplicateUsesFeature`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="DuplicateUsesFeature"` on the problematic XML element
+ (or one of its enclosing elements). You may also need to add the
+ following namespace declaration on the root element in the XML file
+ if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <application tools:ignore="DuplicateUsesFeature" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="DuplicateUsesFeature" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'DuplicateUsesFeature'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore DuplicateUsesFeature ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/EagerGradleConfiguration.md.html b/docs/checks/EagerGradleConfiguration.md.html
new file mode 100644
index 00000000..da544e11
--- /dev/null
+++ b/docs/checks/EagerGradleConfiguration.md.html
@@ -0,0 +1,147 @@
+
+(#) Avoid using eager task APIs
+
+!!! ERROR: Avoid using eager task APIs
+ This is an error.
+
+Id
+: `EagerGradleConfiguration`
+Summary
+: Avoid using eager task APIs
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Identifier
+: androidx.lint:lint-gradle
+Feedback
+: https://issuetracker.google.com/issues/new?component=1147525
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.lint:lint-gradle](androidx_lint_lint-gradle.md.html)
+Since
+: 1.0.0-alpha02
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/lint/lint-gradle/src/main/java/androidx/lint/gradle/DiscouragedGradleMethodDetector.kt)
+Copyright Year
+: 2024
+
+Lazy APIs defer creating and configuring objects until they are needed
+instead of
+doing unnecessary work in the configuration phase.
+See
+https://docs.gradle.org/current/userguide/task_configuration_avoidance.html
+for
+more details.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.lint:lint-gradle:1.0.0-alpha04")
+
+// build.gradle
+implementation 'androidx.lint:lint-gradle:1.0.0-alpha04'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.lint.gradle)
+
+# libs.versions.toml
+[versions]
+lint-gradle = "1.0.0-alpha04"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+lint-gradle = {
+ module = "androidx.lint:lint-gradle",
+ version.ref = "lint-gradle"
+}
+```
+
+1.0.0-alpha04 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.lint:lint-gradle](androidx_lint_lint-gradle.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("EagerGradleConfiguration")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("EagerGradleConfiguration")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection EagerGradleConfiguration
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="EagerGradleConfiguration" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'EagerGradleConfiguration'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore EagerGradleConfiguration ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/EasterEgg.md.html b/docs/checks/EasterEgg.md.html
new file mode 100644
index 00000000..f8de6ffd
--- /dev/null
+++ b/docs/checks/EasterEgg.md.html
@@ -0,0 +1,156 @@
+
+(#) Code contains easter egg
+
+!!! WARNING: Code contains easter egg
+ This is a warning.
+
+Id
+: `EasterEgg`
+Summary
+: Code contains easter egg
+Note
+: **This issue is disabled by default**; use `--enable EasterEgg`
+Severity
+: Warning
+Category
+: Security
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Gradle build files, Kotlin and Java files, manifest files, property files and resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/CommentDetector.java)
+Tests
+: [Source Code](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/CommentDetectorTest.java)
+Copyright Year
+: 2012
+
+An "easter egg" is code deliberately hidden in the code, both from
+potential users and even from other developers. This lint check looks
+for code which looks like it may be hidden from sight.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/Hidden.java:5:Warning: Code might be hidden here; found
+unicode escape sequence which is interpreted as comment end, compiled
+code follows [EasterEgg]
+ /* \u002a\u002f static { System.out.println("I'm executed on class load"); } \u002f\u002a */
+ ------------
+src/test/pkg/Hidden.java:6:Warning: Code might be hidden here; found
+unicode escape sequence which is interpreted as comment end, compiled
+code follows [EasterEgg]
+ /* \u002A\U002F static { System.out.println("I'm executed on class load"); } \u002f\u002a */
+ ------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/Hidden.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+public class Hidden {
+ // Innocent comment...?
+ /* \u002a\u002f static { System.out.println("I'm executed on class load"); } \u002f\u002a */
+ /* \u002A\U002F static { System.out.println("I'm executed on class load"); } \u002f\u002a */
+ /* Normal \\u002A\U002F */ // OK
+ static {
+ String s = "\u002a\u002f"; // OK
+ }
+ // STOPSHIP
+ /* We must STOPSHIP! */
+ String x = "STOPSHIP"; // OK
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/CommentDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `CommentDetector.testJava`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("EasterEgg")
+ fun method() {
+ TODO(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("EasterEgg")
+ void method() {
+ TODO(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection EasterEgg
+ problematicStatement()
+ ```
+
+* Adding the suppression attribute `tools:ignore="EasterEgg"` on the
+ problematic XML element (or one of its enclosing elements). You may
+ also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="EasterEgg" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'EasterEgg'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore EasterEgg ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/EditedTargetSdkVersion.md.html b/docs/checks/EditedTargetSdkVersion.md.html
new file mode 100644
index 00000000..494578e4
--- /dev/null
+++ b/docs/checks/EditedTargetSdkVersion.md.html
@@ -0,0 +1,101 @@
+
+(#) Manually Edited TargetSdkVersion
+
+!!! ERROR: Manually Edited TargetSdkVersion
+ This is an error.
+
+Id
+: `EditedTargetSdkVersion`
+Summary
+: Manually Edited TargetSdkVersion
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 8.1.0 (July 2023)
+Affects
+: Gradle build files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/GradleDetector.kt)
+Tests
+: [Source Code](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/GradleDetectorTest.kt)
+
+Updating the `targetSdkVersion` of an app is seemingly easy: just
+increment the `targetSdkVersion` number in the manifest file!
+
+But that's not actually safe. The `targetSdkVersion` controls a wide
+range of behaviors that change from release to release, and to update,
+you should carefully consult the documentation to see what has changed,
+how your app may need to adjust, and then of course, carefully test
+everything.
+
+In new versions of Android Studio, there is a special migration
+assistant, available from the tools menu (and as a quickfix from this
+lint warning) which analyzes your specific app and filters the set of
+applicable migration steps to those needed for your app.
+
+This lint check does something very simple: it just detects whether it
+looks like you've manually edited the targetSdkVersion field in a
+build.gradle file. Obviously, as part of doing the above careful steps,
+you may end up editing the value, which would trigger the check -- and
+it's safe to ignore it; this lint check *only* runs in the IDE, not from
+the command line; it's sole purpose to bring *awareness* to the (many)
+developers who haven't been aware of this issue and have just bumped the
+targetSdkVersion, recompiled, and uploaded their updated app to the
+Google Play Store, sometimes leading to crashes or other problems on
+newer devices.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection EditedTargetSdkVersion
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="EditedTargetSdkVersion" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'EditedTargetSdkVersion'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore EditedTargetSdkVersion ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/EllipsizeMaxLines.md.html b/docs/checks/EllipsizeMaxLines.md.html
new file mode 100644
index 00000000..6de85fd2
--- /dev/null
+++ b/docs/checks/EllipsizeMaxLines.md.html
@@ -0,0 +1,140 @@
+
+(#) Combining Ellipsize and Maxlines
+
+!!! ERROR: Combining Ellipsize and Maxlines
+ This is an error.
+
+Id
+: `EllipsizeMaxLines`
+Summary
+: Combining Ellipsize and Maxlines
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.0.0 (October 2017)
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://issuetracker.google.com/issues/36950033
+Implementation
+: [Source Code](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/EllipsizeMaxLinesDetector.java)
+Tests
+: [Source Code](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/EllipsizeMaxLinesDetectorTest.java)
+
+Combining `ellipsize` and `maxLines=1` can lead to crashes on some
+devices. Earlier versions of lint recommended replacing
+`singleLine=true` with `maxLines=1` but that should not be done when
+using `ellipsize`.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/sample.xml:9:Error: Combining ellipsize=start and lines=1 can
+lead to crashes. Use singleLine=true instead. [EllipsizeMaxLines]
+ android:lines="1"
+ -----------------
+res/layout/sample.xml:16:Error: Combining ellipsize=start and maxLines=1
+can lead to crashes. Use singleLine=true instead. [EllipsizeMaxLines]
+ android:maxLines="1"
+ --------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/layout/sample.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" >
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:ellipsize="start"
+ android:lines="1"
+ android:text="Really long text that needs to be ellipsized here - 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:ellipsize="start"
+ android:maxLines="1"
+ android:text="long text" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:ellipsize="end"
+ android:lines="1"
+ android:text="long text" />
+
+</RelativeLayout>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/EllipsizeMaxLinesDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `EllipsizeMaxLinesDetector.testSimple`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="EllipsizeMaxLines"`
+ on the problematic XML element (or one of its enclosing elements).
+ You may also need to add the following namespace declaration on the
+ root element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="EllipsizeMaxLines" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'EllipsizeMaxLines'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore EllipsizeMaxLines ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/EmptyNavDeepLink.md.html b/docs/checks/EmptyNavDeepLink.md.html
new file mode 100644
index 00000000..542850ce
--- /dev/null
+++ b/docs/checks/EmptyNavDeepLink.md.html
@@ -0,0 +1,184 @@
+
+(#) NavDeepLink must define an uri, action, and/or mimetype to be valid
+
+!!! ERROR: NavDeepLink must define an uri, action, and/or mimetype to be valid
+ This is an error.
+
+Id
+: `EmptyNavDeepLink`
+Summary
+: NavDeepLink must define an uri, action, and/or mimetype to be valid
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Identifier
+: androidx.navigation.common
+Feedback
+: https://issuetracker.google.com/issues/new?component=409828
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.navigation:navigation-common](androidx_navigation_navigation-common.md.html)
+Since
+: 2.6.0
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/navigation/navigation-common-lint/src/main/java/androidx/navigation/common/lint/EmptyNavDeepLinkDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/navigation/navigation-common-lint/src/test/java/androidx/navigation/common/lint/EmptyNavDeepLinkDetectorTest.kt)
+Copyright Year
+: 2022
+
+Attempting to create an empty NavDeepLink will result in an
+IllegalStateException at runtime. You may set these arguments within the
+lambda of the call to navDeepLink.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/com/example/test.kt:6:Error: Creation of empty NavDeepLink
+[EmptyNavDeepLink]
+ navDeepLink { }
+ -----------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/com/example/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package com.example
+
+import androidx.navigation.navDeepLink
+
+fun createDeepLink() {
+ navDeepLink { }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/androidx/navigation/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package androidx.navigation
+
+public fun navDeepLink(deepLinkBuilder: NavDeepLinkDslBuilder.() -> Unit): NavDeepLink {}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/navigation/navigation-common-lint/src/test/java/androidx/navigation/common/lint/EmptyNavDeepLinkDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `EmptyNavDeepLinkDetector.testErrors`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=409828.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.navigation:navigation-common:2.9.0-rc01")
+
+// build.gradle
+implementation 'androidx.navigation:navigation-common:2.9.0-rc01'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.navigation.common)
+
+# libs.versions.toml
+[versions]
+navigation-common = "2.9.0-rc01"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+navigation-common = {
+ module = "androidx.navigation:navigation-common",
+ version.ref = "navigation-common"
+}
+```
+
+2.9.0-rc01 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.navigation:navigation-common](androidx_navigation_navigation-common.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("EmptyNavDeepLink")
+ fun method() {
+ navDeepLink(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("EmptyNavDeepLink")
+ void method() {
+ navDeepLink(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection EmptyNavDeepLink
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="EmptyNavDeepLink" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'EmptyNavDeepLink'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore EmptyNavDeepLink ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/EmptySuperCall.md.html b/docs/checks/EmptySuperCall.md.html
new file mode 100644
index 00000000..3dabc18d
--- /dev/null
+++ b/docs/checks/EmptySuperCall.md.html
@@ -0,0 +1,146 @@
+
+(#) Calling an empty super method
+
+!!! WARNING: Calling an empty super method
+ This is a warning.
+
+Id
+: `EmptySuperCall`
+Summary
+: Calling an empty super method
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 7.3.0 (September 2022)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/EmptySuperDetector.kt)
+Tests
+: [Source Code](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/EmptySuperDetectorTest.kt)
+
+For methods annotated with `@EmptySuper`, overriding methods should not
+also call the super implementation, either because it is empty, or
+perhaps it contains code not intended to be run when the method is
+overridden.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/ParentClass.kt:22:Warning: No need to call super.someOtherMethod;
+the super method is defined to be empty [EmptySuperCall]
+ super.someOtherMethod(arg) // ERROR
+ ---------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/ParentClass.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+import androidx.annotation.EmptySuper
+
+open class ParentClass {
+ @EmptySuper
+ open fun someMethod(arg: Int) {
+ // ...
+ }
+
+ @EmptySuper
+ open fun someOtherMethod(arg: Int) {
+ // ...
+ }
+}
+
+class MyClass : ParentClass() {
+ override fun someMethod(arg: Int) {
+ // Not calling the overridden (@EmptySuper) method.
+ println(super.toString()) // but invoking other super methods is fine
+ }
+
+ override fun someOtherMethod(arg: Int) {
+ super.someOtherMethod(arg) // ERROR
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/EmptySuperDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("EmptySuperCall")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("EmptySuperCall")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection EmptySuperCall
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="EmptySuperCall" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'EmptySuperCall'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore EmptySuperCall ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/EnforceUTF8.md.html b/docs/checks/EnforceUTF8.md.html
new file mode 100644
index 00000000..552311db
--- /dev/null
+++ b/docs/checks/EnforceUTF8.md.html
@@ -0,0 +1,123 @@
+
+(#) Encoding used in resource files is not UTF-8
+
+!!! ERROR: Encoding used in resource files is not UTF-8
+ This is an error, and is also enforced at build time when
+ supported by the build system. For Android this means it will
+ run during release builds.
+
+Id
+: `EnforceUTF8`
+Summary
+: Encoding used in resource files is not UTF-8
+Severity
+: Fatal
+Category
+: Internationalization
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/Utf8Detector.java)
+Tests
+: [Source Code](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/Utf8DetectorTest.java)
+Copyright Year
+: 2012
+
+XML supports encoding in a wide variety of character sets. However, not
+all tools handle the XML encoding attribute correctly, and nearly all
+Android apps use UTF-8, so by using UTF-8 you can protect yourself
+against subtle bugs when using non-ASCII characters.
+
+In particular, the Android Gradle build system will merge resource XML
+files assuming the resource files are using UTF-8 encoding.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/encoding.xml:1:Error: iso-latin-1: Not using UTF-8 as the
+file encoding. This can lead to subtle bugs with non-ascii characters
+[EnforceUTF8]
+<?xml version="1.0" encoding="iso-latin-1"?>
+ -----------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/layout/encoding.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="iso-latin-1"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+</LinearLayout>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/Utf8DetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `Utf8Detector.testIsoLatin`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="EnforceUTF8"` on the
+ problematic XML element (or one of its enclosing elements). You may
+ also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="EnforceUTF8" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'EnforceUTF8'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore EnforceUTF8 ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/EnqueueWork.md.html b/docs/checks/EnqueueWork.md.html
new file mode 100644
index 00000000..5c21c3fc
--- /dev/null
+++ b/docs/checks/EnqueueWork.md.html
@@ -0,0 +1,255 @@
+
+(#) WorkManager Enqueue
+
+!!! WARNING: WorkManager Enqueue
+ This is a warning.
+
+Id
+: `EnqueueWork`
+Summary
+: WorkManager Enqueue
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.2.0 (September 2018)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/WorkManagerDetector.kt)
+Tests
+: [Source Code](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/WorkManagerDetectorTest.kt)
+
+`WorkContinuations` cannot be enqueued automatically. You must call
+`enqueue()` on a `WorkContinuation` to have it and its parent
+continuations enqueued inside `WorkManager`.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/WorkManagerTest.java:15:Warning: WorkContinuation cont not
+enqueued: did you forget to call enqueue()? [EnqueueWork]
+ WorkContinuation cont = workManager.beginWith(workRequest1, workRequest2); // ERROR
+ -------------------------------------------------
+src/test/pkg/WorkManagerTest.java:22:Warning: WorkContinuation not
+enqueued: did you forget to call enqueue()? [EnqueueWork]
+ workManager.beginWith(workRequest1, workRequest2); // ERROR
+ -------------------------------------------------
+src/test/pkg/WorkManagerTest.java:46:Warning: WorkContinuation cont2 not
+enqueued: did you forget to call enqueue()? [EnqueueWork]
+ WorkContinuation cont2 = cont1.then(workRequest3).then(workRequest4); // ERROR
+ -------------------------------------------
+src/test/pkg/WorkManagerTest.java:47:Warning: WorkContinuation cont3 not
+enqueued: did you forget to call enqueue()? [EnqueueWork]
+ WorkContinuation cont3 = cont1.then(workRequest5); // ERROR
+ ------------------------
+src/test/pkg/WorkManagerTest.java:59:Warning: WorkContinuation cont4 not
+enqueued: did you forget to call enqueue()? [EnqueueWork]
+ WorkContinuation cont4 = WorkContinuation.combine(workRequest6, cont2, cont3); // ERROR
+ ----------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/WorkManagerTest.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import androidx.work.WorkManager;
+import androidx.work.WorkContinuation;
+import androidx.work.OneTimeWorkRequest;import java.util.Arrays;
+
+@SuppressWarnings({"ClassNameDiffersFromFileName", "unused"})
+public abstract class WorkManagerTest {
+ void someWork(OneTimeWorkRequest workRequest1, OneTimeWorkRequest workRequest2) {
+ WorkManager workManager = WorkManager.getInstance();
+ WorkContinuation cont = workManager.beginWith(workRequest1, workRequest2); // ERROR
+ doSomeOtherStuff();
+ // cont needs to be enqueued before it goes out of scope
+ }
+
+ void someWork2(OneTimeWorkRequest workRequest1, OneTimeWorkRequest workRequest2) {
+ WorkManager workManager = WorkManager.getInstance();
+ workManager.beginWith(workRequest1, workRequest2); // ERROR
+ doSomeOtherStuff();
+ }
+
+ void someWork3(OneTimeWorkRequest workRequest1, OneTimeWorkRequest workRequest2) {
+ WorkManager workManager = WorkManager.getInstance();
+ WorkContinuation cont = workManager.beginWith(workRequest1, workRequest2); // OK
+ doSomeOtherStuff();
+ cont.enqueue();
+ }
+
+ void someWork4(OneTimeWorkRequest workRequest1, OneTimeWorkRequest workRequest2) {
+ WorkManager workManager = WorkManager.getInstance();
+ WorkContinuation cont = workManager.beginWith(workRequest1, workRequest2).enqueue(); // OK
+ doSomeOtherStuff();
+ cont.enqueue();
+ }
+
+ void someHarderWork(
+ OneTimeWorkRequest workRequest1, OneTimeWorkRequest workRequest2,
+ OneTimeWorkRequest workRequest3, OneTimeWorkRequest workRequest4,
+ OneTimeWorkRequest workRequest5) {
+ WorkManager workManager = WorkManager.getInstance();
+ WorkContinuation cont1 = workManager.beginWith(workRequest1, workRequest2); // OK
+ WorkContinuation cont2 = cont1.then(workRequest3).then(workRequest4); // ERROR
+ WorkContinuation cont3 = cont1.then(workRequest5); // ERROR
+ // cont2 and cont3 need to be enqueued before they go out of scope; cont1 does not
+ }
+
+ void someEvenHarderWork(
+ OneTimeWorkRequest workRequest1, OneTimeWorkRequest workRequest2,
+ OneTimeWorkRequest workRequest3, OneTimeWorkRequest workRequest4,
+ OneTimeWorkRequest workRequest5, OneTimeWorkRequest workRequest6) {
+ WorkManager workManager = WorkManager.getInstance();
+ WorkContinuation cont1 = workManager.beginWith(workRequest1, workRequest2); // OK
+ WorkContinuation cont2 = cont1.then(workRequest3).then(workRequest4); // OK
+ WorkContinuation cont3 = cont1.then(workRequest5); // OK
+ WorkContinuation cont4 = WorkContinuation.combine(workRequest6, cont2, cont3); // ERROR
+ // Only cont4 needs to be enqueued
+ }
+
+ void someEvenHarderWorkDoneProperly(
+ OneTimeWorkRequest workRequest1, OneTimeWorkRequest workRequest2,
+ OneTimeWorkRequest workRequest3, OneTimeWorkRequest workRequest4,
+ OneTimeWorkRequest workRequest5, OneTimeWorkRequest workRequest6) {
+ WorkManager workManager = WorkManager.getInstance();
+ WorkContinuation cont1 = workManager.beginWith(workRequest1, workRequest2); // OK
+ WorkContinuation cont2 = cont1.then(workRequest3).then(workRequest4); // OK
+ WorkContinuation cont3 = cont1.then(workRequest5); // OK
+ WorkContinuation cont4 = WorkContinuation.combine(workRequest6, cont2, cont3); // OK
+ cont4.enqueue();
+ }
+
+ void someEvenHarderWorkWithLists1(
+ OneTimeWorkRequest workRequest1, OneTimeWorkRequest workRequest2,
+ OneTimeWorkRequest workRequest3, OneTimeWorkRequest workRequest4,
+ OneTimeWorkRequest workRequest5, OneTimeWorkRequest workRequest6) {
+ WorkManager workManager = WorkManager.getInstance();
+ WorkContinuation cont1 = workManager.beginWith(workRequest1, workRequest2); // OK
+ WorkContinuation cont2 = cont1.then(workRequest3).then(workRequest4); // OK
+ WorkContinuation cont3 = cont1.then(workRequest5); // OK
+ List continuations = new ArrayList<>();
+ continuations.add(cont2);
+ continuations.add(cont3);
+ WorkContinuation cont4 = WorkContinuation.combine(workRequest6, continuations); // OK
+ cont4.enqueue();
+ }
+
+ void someEvenHarderWorkWithLists2(
+ OneTimeWorkRequest workRequest1, OneTimeWorkRequest workRequest2,
+ OneTimeWorkRequest workRequest3, OneTimeWorkRequest workRequest4,
+ OneTimeWorkRequest workRequest5, OneTimeWorkRequest workRequest6) {
+ WorkManager workManager = WorkManager.getInstance();
+ WorkContinuation cont1 = workManager.beginWith(workRequest1, workRequest2); // OK
+ WorkContinuation cont2 = cont1.then(workRequest3).then(workRequest4); // OK
+ WorkContinuation cont3 = cont1.then(workRequest5); // OK
+ List continuations = Arrays.asList(cont2, cont3);
+ WorkContinuation cont4 = WorkContinuation.combine(workRequest6, continuations); // OK
+ cont4.enqueue();
+ }
+
+ WorkContinuation someWorkThatIsReturned(
+ OneTimeWorkRequest workRequest1,
+ OneTimeWorkRequest workRequest2) {
+ WorkManager workManager = WorkManager.getInstance();
+ WorkContinuation cont1 = workManager.beginWith(workRequest1, workRequest2); // OK
+ return cont1;
+ }
+
+ private void doSomeOtherStuff() {
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/WorkManagerDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `WorkManagerDetector.testJava`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("EnqueueWork")
+ fun method() {
+ beginWith(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("EnqueueWork")
+ void method() {
+ beginWith(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection EnqueueWork
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="EnqueueWork" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'EnqueueWork'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore EnqueueWork ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/EnsureInitializerMetadata.md.html b/docs/checks/EnsureInitializerMetadata.md.html
new file mode 100644
index 00000000..7b1f527f
--- /dev/null
+++ b/docs/checks/EnsureInitializerMetadata.md.html
@@ -0,0 +1,162 @@
+
+(#) Every Initializer needs to be accompanied by a corresponding entry in the AndroidManifest.xml file
+
+!!! ERROR: Every Initializer needs to be accompanied by a corresponding entry in the AndroidManifest.xml file
+ This is an error, and is also enforced at build time when
+ supported by the build system. For Android this means it will
+ run during release builds.
+
+Id
+: `EnsureInitializerMetadata`
+Summary
+: Every Initializer needs to be accompanied by a corresponding entry in the AndroidManifest.xml file
+Severity
+: Fatal
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Identifier
+: androidx.startup
+Feedback
+: https://issuetracker.google.com/issues/new?component=823348
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [androidx.startup:startup-runtime](androidx_startup_startup-runtime.md.html)
+Since
+: 1.0.0
+Affects
+: Kotlin and Java files and manifest files
+Editing
+: This check can *not* run live in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/startup/startup-runtime-lint/src/main/java/androidx/startup/lint/EnsureInitializerMetadataDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/startup/startup-runtime-lint/src/test/java/androidx/startup/lint/EnsureInitializerMetadataTest.kt)
+Copyright Year
+: 2020
+
+When a library defines a Initializer, it needs to be accompanied by a
+corresponding entry in the AndroidManifest.xml file.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.startup:startup-runtime:1.2.0")
+
+// build.gradle
+implementation 'androidx.startup:startup-runtime:1.2.0'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.startup.runtime)
+
+# libs.versions.toml
+[versions]
+startup-runtime = "1.2.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+startup-runtime = {
+ module = "androidx.startup:startup-runtime",
+ version.ref = "startup-runtime"
+}
+```
+
+1.2.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.startup:startup-runtime](androidx_startup_startup-runtime.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("EnsureInitializerMetadata")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("EnsureInitializerMetadata")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection EnsureInitializerMetadata
+ problematicStatement()
+ ```
+
+* Adding the suppression attribute
+ `tools:ignore="EnsureInitializerMetadata"` on the problematic XML
+ element (or one of its enclosing elements). You may also need to add
+ the following namespace declaration on the root element in the XML
+ file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <meta-data tools:ignore="EnsureInitializerMetadata" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="EnsureInitializerMetadata" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'EnsureInitializerMetadata'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore EnsureInitializerMetadata ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/EnsureInitializerNoArgConstr.md.html b/docs/checks/EnsureInitializerNoArgConstr.md.html
new file mode 100644
index 00000000..6ee46b41
--- /dev/null
+++ b/docs/checks/EnsureInitializerNoArgConstr.md.html
@@ -0,0 +1,177 @@
+
+(#) Missing Initializer no-arg constructor
+
+!!! ERROR: Missing Initializer no-arg constructor
+ This is an error, and is also enforced at build time when
+ supported by the build system. For Android this means it will
+ run during release builds.
+
+Id
+: `EnsureInitializerNoArgConstr`
+Summary
+: Missing Initializer no-arg constructor
+Severity
+: Fatal
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Identifier
+: androidx.startup
+Feedback
+: https://issuetracker.google.com/issues/new?component=823348
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [androidx.startup:startup-runtime](androidx_startup_startup-runtime.md.html)
+Since
+: 1.0.0
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/startup/startup-runtime-lint/src/main/java/androidx/startup/lint/InitializerConstructorDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/startup/startup-runtime-lint/src/test/java/androidx/startup/lint/InitializerConstructorTest.kt)
+Copyright Year
+: 2020
+
+Every `Initializer` must have a no argument constructor.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+com/example/TestInitializer.kt:5:Error: Missing Initializer no-arg
+constructor [EnsureInitializerNoArgConstr]
+class TestInitializer(val int: Int): Initializer<Unit> {
+^
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`com/example/TestInitializer.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package com.example
+
+import androidx.startup.Initializer
+
+class TestInitializer(val int: Int): Initializer {
+
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/startup/startup-runtime-lint/src/test/java/androidx/startup/lint/InitializerConstructorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `InitializerConstructorDetector.testFailureWhenZeroNoArgumentConstructorsArePresent`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=823348.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.startup:startup-runtime:1.2.0")
+
+// build.gradle
+implementation 'androidx.startup:startup-runtime:1.2.0'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.startup.runtime)
+
+# libs.versions.toml
+[versions]
+startup-runtime = "1.2.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+startup-runtime = {
+ module = "androidx.startup:startup-runtime",
+ version.ref = "startup-runtime"
+}
+```
+
+1.2.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.startup:startup-runtime](androidx_startup_startup-runtime.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("EnsureInitializerNoArgConstr")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("EnsureInitializerNoArgConstr")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection EnsureInitializerNoArgConstr
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="EnsureInitializerNoArgConstr" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'EnsureInitializerNoArgConstr'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore EnsureInitializerNoArgConstr ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ErroneousLayoutAttribute.md.html b/docs/checks/ErroneousLayoutAttribute.md.html
new file mode 100644
index 00000000..81d27d1d
--- /dev/null
+++ b/docs/checks/ErroneousLayoutAttribute.md.html
@@ -0,0 +1,153 @@
+
+(#) Layout attribute that's not applicable to a particular view
+
+!!! WARNING: Layout attribute that's not applicable to a particular view
+ This is a warning.
+
+Id
+: `ErroneousLayoutAttribute`
+Summary
+: Layout attribute that's not applicable to a particular view
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: vanniktech/lint-rules/
+Feedback
+: https://github.com/vanniktech/lint-rules/issues
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [com.vanniktech:lint-rules-android](com_vanniktech_lint-rules-android.md.html)
+Since
+: 0.24.0
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/main/kotlin/com/vanniktech/lintrules/android/ErroneousLayoutAttributeDetector.kt)
+Tests
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/test/kotlin/com/vanniktech/lintrules/android/ErroneousLayoutAttributeDetectorTest.kt)
+
+Flags if a layout attribute is not applicable to a particular view.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/ids.xml:5:Warning: Attribute is erroneous on FrameLayout
+[ErroneousLayoutAttribute]
+ android:orientation="horizontal"
+ --------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/layout/ids.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ />
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/test/kotlin/com/vanniktech/lintrules/android/ErroneousLayoutAttributeDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ErroneousLayoutAttributeDetector.erroneousFrameLayoutOrientation`.
+To report a problem with this extracted sample, visit
+https://github.com/vanniktech/lint-rules/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.vanniktech:lint-rules-android:0.25.0")
+
+// build.gradle
+lintChecks 'com.vanniktech:lint-rules-android:0.25.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.lint.rules.android)
+
+# libs.versions.toml
+[versions]
+lint-rules-android = "0.25.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+lint-rules-android = {
+ module = "com.vanniktech:lint-rules-android",
+ version.ref = "lint-rules-android"
+}
+```
+
+0.25.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.vanniktech:lint-rules-android](com_vanniktech_lint-rules-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="ErroneousLayoutAttribute"` on the problematic XML
+ element (or one of its enclosing elements). You may also need to add
+ the following namespace declaration on the root element in the XML
+ file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ErroneousLayoutAttribute" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ErroneousLayoutAttribute'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ErroneousLayoutAttribute ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ErrorProneDoNotMockUsage.md.html b/docs/checks/ErrorProneDoNotMockUsage.md.html
new file mode 100644
index 00000000..37772d7c
--- /dev/null
+++ b/docs/checks/ErrorProneDoNotMockUsage.md.html
@@ -0,0 +1,203 @@
+
+(#) Use Slack's internal `@DoNotMock` annotation
+
+!!! ERROR: Use Slack's internal `@DoNotMock` annotation
+ This is an error.
+
+Id
+: `ErrorProneDoNotMockUsage`
+Summary
+: Use Slack's internal `@DoNotMock` annotation
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.1.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/mocking/ErrorProneDoNotMockDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/mocking/DoNotMockUsageDetectorTest.kt)
+Copyright Year
+: 2021
+
+While error-prone has a `@DoNotMock` annotation, prefer to use Slack's
+internal one as it's not specific to error-prone and won't go away in a
+Java-less world.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/slack/test/TestClass.kt:10:Error: Use Slack's internal @DoNotMock
+annotation. [ErrorProneDoNotMockUsage]
+@com.google.errorprone.annotations.DoNotMock("Use fake()")
+----------------------------------------------------------
+src/slack/test/TestClass.kt:20:Error: Use Slack's internal @DoNotMock
+annotation. [ErrorProneDoNotMockUsage]
+@DoNotMock
+----------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/slack/test/TestClass.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package slack.test
+
+import com.google.errorprone.annotations.DoNotMock
+
+@slack.lint.annotations.DoNotMock("Use fake()")
+interface TestClass {
+ fun fake(): TestClass? = null
+}
+
+@com.google.errorprone.annotations.DoNotMock("Use fake()")
+interface TestClass2 {
+ fun fake(): TestClass2? = null
+}
+
+@slack.lint.annotations.DoNotMock
+interface TestClass3 {
+ fun fake(): TestClass3? = null
+}
+
+@DoNotMock
+interface TestClass4 {
+ fun fake(): TestClass4? = null
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/mocking/DoNotMockUsageDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ErrorProneDoNotMockDetector.kotlinTests`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/slack-lints.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ErrorProneDoNotMockUsage")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ErrorProneDoNotMockUsage")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ErrorProneDoNotMockUsage
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ErrorProneDoNotMockUsage" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ErrorProneDoNotMockUsage'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ErrorProneDoNotMockUsage ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ExactAlarm.md.html b/docs/checks/ExactAlarm.md.html
new file mode 100644
index 00000000..08e37cdf
--- /dev/null
+++ b/docs/checks/ExactAlarm.md.html
@@ -0,0 +1,148 @@
+
+(#) Invalid Usage of Exact Alarms
+
+!!! ERROR: Invalid Usage of Exact Alarms
+ This is an error.
+
+Id
+: `ExactAlarm`
+Summary
+: Invalid Usage of Exact Alarms
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 8.1.0 (July 2023)
+Affects
+: Kotlin and Java files and manifest files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/training/scheduling/alarms
+Implementation
+: [Source Code](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/AlarmDetector.kt)
+Tests
+: [Source Code](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/AlarmDetectorTest.kt)
+
+The `USE_EXACT_ALARM` permission is only available when targeting API
+level 33 and above. Also, note that this permission is only permitted
+for apps whose core functionality requires precisely-timed actions for
+user facing features.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:2:Error: USE_EXACT_ALARM can only be used when
+targeting API level 33 or higher [ExactAlarm]
+ <uses-permission android:name="android.permission.USE_EXACT_ALARM" />
+ ----------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+ <uses-permission android:name="android.permission.USE_EXACT_ALARM" />
+ <uses-sdk android:targetSdkVersion="32" />
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/AlarmDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `AlarmDetector.testExactAlarmPermissions`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="ExactAlarm"` on the
+ problematic XML element (or one of its enclosing elements). You may
+ also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <uses-permission tools:ignore="ExactAlarm" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ExactAlarm")
+ fun method() {
+ setRepeating(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ExactAlarm")
+ void method() {
+ setRepeating(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ExactAlarm
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ExactAlarm" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ExactAlarm'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ExactAlarm ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ExceptionMessage.md.html b/docs/checks/ExceptionMessage.md.html
new file mode 100644
index 00000000..57435080
--- /dev/null
+++ b/docs/checks/ExceptionMessage.md.html
@@ -0,0 +1,184 @@
+
+(#) Please provide a string for the `lazyMessage` parameter
+
+!!! ERROR: Please provide a string for the `lazyMessage` parameter
+ This is an error.
+
+Id
+: `ExceptionMessage`
+Summary
+: Please provide a string for the `lazyMessage` parameter
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.6.0
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/ExceptionMessageDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/ExceptionMessageDetectorTest.kt)
+Copyright Year
+: 2023
+
+Calls to `check()`, `checkNotNull()`, `require()` and `requireNotNull()`
+should include a message string that can be used to debug issues
+experienced by users.
+
+When we read user-supplied logs, the line numbers are sometimes
+notsufficient to determine the cause of a bug. Inline functions
+cansometimes make it hard to determine which file threw an
+exception.Consider supplying a `lazyMessage` parameter to identify the
+`check()`or `require()` call.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/test.kt:5:Error: Please specify a lazyMessage param for check
+[ExceptionMessage]
+ check(true)
+ -----
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test
+
+fun content() {
+ check(true)
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/ExceptionMessageDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ExceptionMessageDetector.checkWithoutMessage`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/slack-lints.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ExceptionMessage")
+ fun method() {
+ check(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ExceptionMessage")
+ void method() {
+ check(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ExceptionMessage
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ExceptionMessage" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ExceptionMessage'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ExceptionMessage ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ExifInterface.md.html b/docs/checks/ExifInterface.md.html
new file mode 100644
index 00000000..ac63734a
--- /dev/null
+++ b/docs/checks/ExifInterface.md.html
@@ -0,0 +1,153 @@
+
+(#) Using `android.media.ExifInterface`
+
+!!! WARNING: Using `android.media.ExifInterface`
+ This is a warning.
+
+Id
+: `ExifInterface`
+Summary
+: Using `android.media.ExifInterface`
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.0.0 (October 2017)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/ExifInterfaceDetector.java)
+Tests
+: [Source Code](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/ExifInterfaceDetectorTest.java)
+
+The `android.media.ExifInterface` implementation has some known security
+bugs in older versions of Android. There is a new implementation
+available of this library in the support library, which is preferable.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/ExifUsage.java:3:Warning: Avoid using
+android.media.ExifInterface; use
+androidx.exifinterface.media.ExifInterface instead [ExifInterface]
+import android.media.ExifInterface;
+ ---------------------------
+src/test/pkg/ExifUsage.java:13:Warning: Avoid using
+android.media.ExifInterface; use
+androidx.exifinterface.media.ExifInterface instead [ExifInterface]
+ android.media.ExifInterface exif2 =
+ ---------------------------
+src/test/pkg/ExifUsage.java:14:Warning: Avoid using
+android.media.ExifInterface; use
+androidx.exifinterface.media.ExifInterface instead [ExifInterface]
+ new android.media.ExifInterface(path);
+ ---------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/ExifUsage.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.media.ExifInterface;
+
+@SuppressWarnings("unused")
+public class ExifUsage {
+ // platform usage
+ private void setExifLatLong(String path, String lat, String lon) throws Exception {
+ ExifInterface exif = new ExifInterface(path);
+ exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE, lat);
+ exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE, lon);
+ exif.saveAttributes();
+ android.media.ExifInterface exif2 =
+ new android.media.ExifInterface(path);
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ExifInterfaceDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ExifInterfaceDetector.testAndroidX`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ExifInterface")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ExifInterface")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ExifInterface
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ExifInterface" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ExifInterface'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ExifInterface ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ExpensiveAssertion.md.html b/docs/checks/ExpensiveAssertion.md.html
new file mode 100644
index 00000000..de35e96c
--- /dev/null
+++ b/docs/checks/ExpensiveAssertion.md.html
@@ -0,0 +1,242 @@
+
+(#) Expensive Assertions
+
+!!! WARNING: Expensive Assertions
+ This is a warning.
+
+Id
+: `ExpensiveAssertion`
+Summary
+: Expensive Assertions
+Note
+: **This issue is disabled by default**; use `--enable ExpensiveAssertion`
+Severity
+: Warning
+Category
+: Performance
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 4.0.0 (May 2020)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/AssertDetector.kt)
+Tests
+: [Source Code](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/AssertDetectorTest.kt)
+
+In Kotlin, assertions are not handled the same way as from the Java
+programming language. In particular, they're just implemented as a
+library call, and inside the library call the error is only thrown if
+assertions are enabled.
+
+This means that the arguments to the `assert` call will **always** be
+evaluated. If you're doing any computation in the expression being
+asserted, that computation will unconditionally be performed whether or
+not assertions are turned on. This typically turns into wasted work in
+release builds.
+
+This check looks for cases where the assertion condition is nontrivial,
+e.g. it is performing method calls or doing more work than simple
+comparisons on local variables or fields.
+
+You can work around this by writing your own inline assert method
+instead:
+
+```kotlin
+@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
+inline fun assert(condition: () -> Boolean) {
+ if (_Assertions.ENABLED && !condition()) {
+ throw AssertionError()
+ }
+}
+```
+
+In Android, because assertions are not enforced at runtime, instead use
+this:
+
+```kotlin
+inline fun assert(condition: () -> Boolean) {
+ if (BuildConfig.DEBUG && !condition()) {
+ throw AssertionError()
+ }
+}
+```
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/AssertTest.kt:18:Warning: Kotlin assertion arguments are
+always evaluated, even when assertions are off. Consider surrounding
+assertion with if (javaClass.desiredAssertionStatus()) { assert(...) }
+[ExpensiveAssertion]
+ assert(expensive()) // WARN
+ -----------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/test/pkg/AssertTest.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+
+class AssertTest {
+ fun test() {
+ assert(true) // Error on Android, not elsewhere
+ assert(false) // Error on Android, not elsewhere
+ assert(true, { "My lazy message" }) // Error on Android, not elsewhere
+ assert(true) { "My lazy message" } // Error on Android, not elsewhere
+ }
+
+ fun testNotExpensive(int: Int, bool1: Boolean, bool2: Boolean) {
+ assert(int < 5)
+ assert(!bool1 || bool2 == bool1)
+ assert(int != bool1) { "This is $int and x2=$bool2" } // ERROR
+ }
+
+ fun testExpensive() {
+ assert(expensive()) // WARN
+ }
+
+ fun testOk() {
+ if (AssertTest::class.java.desiredAssertionStatus()) {
+ assert(expensive()) // Error on Android, ok elsewhere
+ }
+ if (javaClass.desiredAssertionStatus()) {
+ assert(expensive()) // Error on Android, ok elsewhere
+ }
+ }
+
+ private fun expensive(): Boolean {
+ Thread.sleep(500)
+ return (System.currentTimeMillis().rem(1L)) == 0L
+ }
+
+ fun foo(x1: Boolean, x2: Boolean, x3: Number?) {
+ assert(x1 == x2) // ERROR
+ assert(x3 != null) // ERROR
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+fun testExpensive() {
+ assert(expensive()) // no suggestion to surround with javaClass from toplevel
+ assert(cheap())
+ assert(cheap2(0))
+ assert(cheap3())
+}
+private fun expensive(): Boolean {
+ Thread.sleep(500)
+ return true
+}
+
+const val DEBUGGING = false
+private fun cheap(): Boolean {
+ return DEBUGGING
+}
+private fun cheap2(x: Int): Boolean = x < 10
+private fun cheap3() = test.pkg.Utils.isDiagnosing()
+
+fun castOkay(foo: Any) {
+ assert(foo is String) // OK
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/Utils.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+public class Utils {
+ public static final boolean DIAGNOSE = false;
+ public static boolean isDiagnosing() {
+ return DIAGNOSE;
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/AssertDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `AssertDetector.testExpensiveKotlinCalls`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ExpensiveAssertion")
+ fun method() {
+ assert(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ExpensiveAssertion")
+ void method() {
+ assert(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ExpensiveAssertion
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ExpensiveAssertion" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ExpensiveAssertion'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ExpensiveAssertion ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ExperimentalAnnotationRetention.md.html b/docs/checks/ExperimentalAnnotationRetention.md.html
new file mode 100644
index 00000000..c3b2097e
--- /dev/null
+++ b/docs/checks/ExperimentalAnnotationRetention.md.html
@@ -0,0 +1,145 @@
+
+(#) Experimental annotation with incorrect retention
+
+!!! ERROR: Experimental annotation with incorrect retention
+ This is an error.
+
+Id
+: `ExperimentalAnnotationRetention`
+Summary
+: Experimental annotation with incorrect retention
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Identifier
+: androidx.annotation.experimental
+Feedback
+: https://issuetracker.google.com/issues/new?component=459778
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.annotation:annotation-experimental](androidx_annotation_annotation-experimental.md.html)
+Since
+: 1.2.0
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/annotation/annotation-experimental-lint/src/main/java/androidx/annotation/experimental/lint/AnnotationRetentionDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/annotation/annotation-experimental-lint/src/test/kotlin/androidx/annotation/experimental/lint/AnnotationRetentionDetectorTest.kt)
+Copyright Year
+: 2021
+
+Experimental annotations defined in Java source should use default
+(`CLASS`) retention, while Kotlin-sourced annotations should use
+`BINARY` retention.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.annotation:annotation-experimental:1.5.0-rc01")
+
+// build.gradle
+implementation 'androidx.annotation:annotation-experimental:1.5.0-rc01'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.annotation.experimental)
+
+# libs.versions.toml
+[versions]
+annotation-experimental = "1.5.0-rc01"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+annotation-experimental = {
+ module = "androidx.annotation:annotation-experimental",
+ version.ref = "annotation-experimental"
+}
+```
+
+1.5.0-rc01 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.annotation:annotation-experimental](androidx_annotation_annotation-experimental.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ExperimentalAnnotationRetention")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ExperimentalAnnotationRetention")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ExperimentalAnnotationRetention
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ExperimentalAnnotationRetention" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ExperimentalAnnotationRetention'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ExperimentalAnnotationRetention ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ExpiredTargetSdkVersion.md.html b/docs/checks/ExpiredTargetSdkVersion.md.html
new file mode 100644
index 00000000..9d37833d
--- /dev/null
+++ b/docs/checks/ExpiredTargetSdkVersion.md.html
@@ -0,0 +1,139 @@
+
+(#) TargetSdkVersion No Longer Supported
+
+!!! ERROR: TargetSdkVersion No Longer Supported
+ This is an error, and is also enforced at build time when
+ supported by the build system. For Android this means it will
+ run during release builds.
+
+Id
+: `ExpiredTargetSdkVersion`
+Summary
+: TargetSdkVersion No Longer Supported
+Severity
+: Fatal
+Category
+: Compliance
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.2.0 (September 2018)
+Affects
+: Gradle build files, TOML files and manifest files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://support.google.com/googleplay/android-developer/answer/113469#targetsdk
+See
+: https://developer.android.com/distribute/best-practices/develop/target-sdk.html
+Implementation
+: [Source Code](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/GradleDetector.kt)
+Tests
+: [Source Code](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/GradleDetectorTest.kt)
+
+Configuring your app or sdk to target a recent API level ensures that
+users benefit from significant security and performance improvements,
+while still allowing your app to run on older Android versions (down to
+the `minSdkVersion`).
+
+To update your `targetSdkVersion`, follow the steps from "Meeting Google
+Play requirements for target API level",
+https://developer.android.com/distribute/best-practices/develop/target-sdk.html.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+../gradle/libs.versions.toml:2:Error: Google Play requires that apps
+target API level 33 or higher. [ExpiredTargetSdkVersion]
+targetSdk = "30" # ERROR 1
+ ----
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`settings.gradle.kts`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+android {
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`../gradle/libs.versions.toml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~toml linenumbers
+[versions]
+targetSdk = "30" # ERROR 1
+
+#noinspection ExpiredTargetSdkVersion
+targetSdkVersion = "30" # OK 1
+#noinspection ExpiringTargetSdkVersion
+target_sdk_version = "30" # OK 2
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/GradleDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `GradleDetector.testTargetExpiringViaToml`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ExpiredTargetSdkVersion
+ problematicStatement()
+ ```
+
+* Adding the suppression attribute
+ `tools:ignore="ExpiredTargetSdkVersion"` on the problematic XML
+ element (or one of its enclosing elements). You may also need to add
+ the following namespace declaration on the root element in the XML
+ file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ExpiredTargetSdkVersion" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ExpiredTargetSdkVersion'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ExpiredTargetSdkVersion ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ExpiringTargetSdkVersion.md.html b/docs/checks/ExpiringTargetSdkVersion.md.html
new file mode 100644
index 00000000..74bbbe9d
--- /dev/null
+++ b/docs/checks/ExpiringTargetSdkVersion.md.html
@@ -0,0 +1,135 @@
+
+(#) TargetSdkVersion Soon Expiring
+
+!!! WARNING: TargetSdkVersion Soon Expiring
+ This is a warning.
+
+Id
+: `ExpiringTargetSdkVersion`
+Summary
+: TargetSdkVersion Soon Expiring
+Severity
+: Warning
+Category
+: Compliance
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.2.0 (September 2018)
+Affects
+: Gradle build files, TOML files and manifest files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://support.google.com/googleplay/android-developer/answer/113469#targetsdk
+See
+: https://developer.android.com/distribute/best-practices/develop/target-sdk.html
+Implementation
+: [Source Code](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/GradleDetector.kt)
+Tests
+: [Source Code](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/GradleDetectorTest.kt)
+
+Configuring your app or sdk to target a recent API level ensures that
+users benefit from significant security and performance improvements,
+while still allowing your app or sdk to run on older Android versions
+(down to the `minSdkVersion`).
+
+To update your `targetSdkVersion`, follow the steps from "Meeting Google
+Play requirements for target API level",
+https://developer.android.com/distribute/best-practices/develop/target-sdk.html.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+build.gradle:6:Warning: Google Play will soon require that apps target
+API level 33 or higher. This will be required for new apps and updates
+starting on August 31, 2023. [ExpiringTargetSdkVersion]
+ targetSdkVersion 31
+ -------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`build.gradle`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~groovy linenumbers
+apply plugin: 'com.android.application'
+
+android {
+ defaultConfig {
+ // Already meeting last year's requirement but not this year's requirement
+ targetSdkVersion 31
+ targetSdkVersion 2023 // OK
+ targetSdkVersion 2024 // OK
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/GradleDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `GradleDetector.testExpiring2`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ExpiringTargetSdkVersion
+ problematicStatement()
+ ```
+
+* Adding the suppression attribute
+ `tools:ignore="ExpiringTargetSdkVersion"` on the problematic XML
+ element (or one of its enclosing elements). You may also need to add
+ the following namespace declaration on the root element in the XML
+ file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ExpiringTargetSdkVersion" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ExpiringTargetSdkVersion'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ExpiringTargetSdkVersion ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ExportedContentProvider.md.html b/docs/checks/ExportedContentProvider.md.html
new file mode 100644
index 00000000..85398661
--- /dev/null
+++ b/docs/checks/ExportedContentProvider.md.html
@@ -0,0 +1,195 @@
+
+(#) Content provider does not require permission
+
+!!! WARNING: Content provider does not require permission
+ This is a warning.
+
+Id
+: `ExportedContentProvider`
+Summary
+: Content provider does not require permission
+Severity
+: Warning
+Category
+: Security
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://goo.gle/ExportedContentProvider
+Implementation
+: [Source Code](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/SecurityDetector.java)
+Tests
+: [Source Code](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/SecurityDetectorTest.java)
+Copyright Year
+: 2011
+
+Content providers are exported by default and any application on the
+system can potentially use them to read and write data. If the content
+provider provides access to sensitive data, it should be protected by
+specifying `export=false` in the manifest or by protecting it with a
+permission that can be granted to other applications.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:14:Warning: Exported content providers can provide
+access to potentially sensitive data [ExportedContentProvider]
+ <provider
+ --------
+AndroidManifest.xml:20:Warning: Exported content providers can provide
+access to potentially sensitive data [ExportedContentProvider]
+ <provider
+ --------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="foo.bar2"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk android:minSdkVersion="14" />
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name" >
+
+ <!-- exported implicitly, fail -->
+ <provider
+ android:name="com.sample.provider.providerClass1"
+ android:authorities="com.sample.provider.providerData">
+ </provider>
+
+ <!-- exported explicitly, fail -->
+ <provider
+ android:exported="true"
+ android:name="com.sample.provider.providerClass2"
+ android:authorities="com.sample.provider.providerData">
+ </provider>
+
+ <!-- not exported, win -->
+ <provider
+ android:exported="false"
+ android:name="com.sample.provider.providerClass3"
+ android:authorities="com.sample.provider.providerData">
+ </provider>
+ </application>
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <!-- Home -->
+ <string name="home_title">Home Sample</string>
+ <string name="show_all_apps">All</string>
+
+ <!-- Home Menus -->
+ <string name="menu_wallpaper">Wallpaper</string>
+ <string name="menu_search">Search</string>
+ <string name="menu_settings">Settings</string>
+ <string name="sample" translatable="false">Ignore Me</string>
+
+ <!-- Wallpaper -->
+ <string name="wallpaper_instructions">Tap picture to set portrait wallpaper</string>
+</resources>
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/SecurityDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `SecurityDetector.testContentProvider1`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="ExportedContentProvider"` on the problematic XML
+ element (or one of its enclosing elements). You may also need to add
+ the following namespace declaration on the root element in the XML
+ file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <service tools:ignore="ExportedContentProvider" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ExportedContentProvider" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ExportedContentProvider'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ExportedContentProvider ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ExportedPreferenceActivity.md.html b/docs/checks/ExportedPreferenceActivity.md.html
new file mode 100644
index 00000000..a0d127ae
--- /dev/null
+++ b/docs/checks/ExportedPreferenceActivity.md.html
@@ -0,0 +1,186 @@
+
+(#) PreferenceActivity should not be exported
+
+!!! WARNING: PreferenceActivity should not be exported
+ This is a warning.
+
+Id
+: `ExportedPreferenceActivity`
+Summary
+: PreferenceActivity should not be exported
+Severity
+: Warning
+Category
+: Security
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Kotlin and Java files and manifest files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: http://securityintelligence.com/new-vulnerability-android-framework-fragment-injection
+See
+: https://goo.gle/ExportedPreferenceActivity
+Implementation
+: [Source Code](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/PreferenceActivityDetector.kt)
+Tests
+: [Source Code](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/PreferenceActivityDetectorTest.java)
+Copyright Year
+: 2014
+
+Fragment injection gives anyone who can send your `PreferenceActivity`
+an intent the ability to load any fragment, with any arguments, in your
+process.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:28:Warning: PreferenceActivity should not be
+exported [ExportedPreferenceActivity]
+ <activity
+ ^
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2014 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="test.bytecode"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk android:minSdkVersion="10" />
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name" >
+ <activity
+ android:name="android.preference.PreferenceActivity"
+ android:label="@string/app_name" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/PreferenceActivityDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `PreferenceActivityDetector.testWarningWhenImplicitlyExportingPreferenceActivity`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="ExportedPreferenceActivity"` on the problematic XML
+ element (or one of its enclosing elements). You may also need to add
+ the following namespace declaration on the root element in the XML
+ file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <activity tools:ignore="ExportedPreferenceActivity" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ExportedPreferenceActivity")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ExportedPreferenceActivity")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ExportedPreferenceActivity
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ExportedPreferenceActivity" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ExportedPreferenceActivity'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ExportedPreferenceActivity ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ExportedReceiver.md.html b/docs/checks/ExportedReceiver.md.html
new file mode 100644
index 00000000..84fa79a8
--- /dev/null
+++ b/docs/checks/ExportedReceiver.md.html
@@ -0,0 +1,180 @@
+
+(#) Receiver does not require permission
+
+!!! WARNING: Receiver does not require permission
+ This is a warning.
+
+Id
+: `ExportedReceiver`
+Summary
+: Receiver does not require permission
+Severity
+: Warning
+Category
+: Security
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://goo.gle/ExportedReceiver
+Implementation
+: [Source Code](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/SecurityDetector.java)
+Tests
+: [Source Code](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/SecurityDetectorTest.java)
+Copyright Year
+: 2011
+
+Exported receivers (receivers which either set `exported=true` or
+contain an intent-filter and do not specify `exported=false`) should
+define a permission that an entity must have in order to launch the
+receiver or bind to it. Without this, any application can use this
+receiver.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:12:Warning: Exported receiver does not require
+permission [ExportedReceiver]
+ <receiver
+ --------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="foo.bar2"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk android:minSdkVersion="14" />
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name" >
+ <receiver
+ android:label="@string/app_name"
+ android:name="com.sample.service.serviceClass" >
+ <intent-filter >
+ <action android:name="com.sample.service.serviceClass" >
+ </action>
+ </intent-filter>
+ </receiver>
+ </application>
+
+</manifest>
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <!-- Home -->
+ <string name="home_title">Home Sample</string>
+ <string name="show_all_apps">All</string>
+
+ <!-- Home Menus -->
+ <string name="menu_wallpaper">Wallpaper</string>
+ <string name="menu_search">Search</string>
+ <string name="menu_settings">Settings</string>
+ <string name="sample" translatable="false">Ignore Me</string>
+
+ <!-- Wallpaper -->
+ <string name="wallpaper_instructions">Tap picture to set portrait wallpaper</string>
+</resources>
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/SecurityDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `SecurityDetector.testReceiver1`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="ExportedReceiver"`
+ on the problematic XML element (or one of its enclosing elements).
+ You may also need to add the following namespace declaration on the
+ root element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <service tools:ignore="ExportedReceiver" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ExportedReceiver" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ExportedReceiver'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ExportedReceiver ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ExportedService.md.html b/docs/checks/ExportedService.md.html
new file mode 100644
index 00000000..ab9b62d6
--- /dev/null
+++ b/docs/checks/ExportedService.md.html
@@ -0,0 +1,181 @@
+
+(#) Exported service does not require permission
+
+!!! WARNING: Exported service does not require permission
+ This is a warning.
+
+Id
+: `ExportedService`
+Summary
+: Exported service does not require permission
+Severity
+: Warning
+Category
+: Security
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://goo.gle/ExportedService
+Implementation
+: [Source Code](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/SecurityDetector.java)
+Tests
+: [Source Code](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/SecurityDetectorTest.java)
+Copyright Year
+: 2011
+
+Exported services (services which either set `exported=true` or contain
+an intent-filter and do not specify `exported=false`) should define a
+permission that an entity must have in order to launch the service or
+bind to it. Without this, any application can use this service.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:12:Warning: Exported service does not require
+permission [ExportedService]
+ <service
+ -------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="foo.bar2"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk android:minSdkVersion="14" />
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name" >
+ <service
+ android:exported="true"
+ android:label="@string/app_name"
+ android:name="com.sample.service.serviceClass"
+ android:process=":remote" >
+ <intent-filter >
+ <action android:name="com.sample.service.serviceClass" >
+ </action>
+ </intent-filter>
+ </service>
+ </application>
+
+</manifest>
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <!-- Home -->
+ <string name="home_title">Home Sample</string>
+ <string name="show_all_apps">All</string>
+
+ <!-- Home Menus -->
+ <string name="menu_wallpaper">Wallpaper</string>
+ <string name="menu_search">Search</string>
+ <string name="menu_settings">Settings</string>
+ <string name="sample" translatable="false">Ignore Me</string>
+
+ <!-- Wallpaper -->
+ <string name="wallpaper_instructions">Tap picture to set portrait wallpaper</string>
+</resources>
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/SecurityDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `SecurityDetector.testBroken`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="ExportedService"` on
+ the problematic XML element (or one of its enclosing elements). You
+ may also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <service tools:ignore="ExportedService" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ExportedService" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ExportedService'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ExportedService ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ExposedRootPath.md.html b/docs/checks/ExposedRootPath.md.html
new file mode 100644
index 00000000..265fef08
--- /dev/null
+++ b/docs/checks/ExposedRootPath.md.html
@@ -0,0 +1,160 @@
+
+(#) Application specifies the device root directory
+
+!!! WARNING: Application specifies the device root directory
+ This is a warning.
+
+Id
+: `ExposedRootPath`
+Summary
+: Application specifies the device root directory
+Severity
+: Warning
+Category
+: Security
+Platform
+: Android
+Vendor
+: Google - Android 3P Vulnerability Research
+Contact
+: https://github.com/google/android-security-lints
+Feedback
+: https://github.com/google/android-security-lints/issues
+Min
+: Lint 4.1
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [com.android.security.lint:lint](com_android_security_lint_lint.md.html)
+Since
+: 1.0.1
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://goo.gle/ExposedRootPath
+Implementation
+: [Source Code](https://github.com/google/android-security-lints/tree/main/checks/src/main/java/com/example/lint/checks/MisconfiguredFileProviderDetector.kt)
+Tests
+: [Source Code](https://github.com/google/android-security-lints/tree/main/checks/src/test/java/com/example/lint/checks/MisconfiguredFileProviderDetectorTest.kt)
+Copyright Year
+: 2023
+
+Allowing the device root directory in the `FileProvider` configuration
+provides arbitrary access to files and folders for attackers, thereby
+increasing the attack surface.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/xml/file_paths.xml:5:Warning: Do not use as it provides
+arbitrary access to device files and folders [ExposedRootPath]
+ <root-path name="root" path="/"/>
+ ---------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/xml/file_paths.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+ <paths xmlns:android="http://schemas.android.com/apk/res/android">
+ <files-path name="my_images" path="images/"/>
+ <files-path name="my_docs" path="docs/"/>
+ <root-path name="root" path="/"/>
+ </paths>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/google/android-security-lints/tree/main/checks/src/test/java/com/example/lint/checks/MisconfiguredFileProviderDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `MisconfiguredFileProviderDetector.testWhenRootPathUsedInConfig_showsWarningAndQuickFix`.
+To report a problem with this extracted sample, visit
+https://github.com/google/android-security-lints/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.android.security.lint:lint:1.0.3")
+
+// build.gradle
+lintChecks 'com.android.security.lint:lint:1.0.3'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.com.android.security.lint.lint)
+
+# libs.versions.toml
+[versions]
+com-android-security-lint-lint = "1.0.3"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+com-android-security-lint-lint = {
+ module = "com.android.security.lint:lint",
+ version.ref = "com-android-security-lint-lint"
+}
+```
+
+1.0.3 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.android.security.lint:lint](com_android_security_lint_lint.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="ExposedRootPath"` on
+ the problematic XML element (or one of its enclosing elements). You
+ may also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ExposedRootPath" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ExposedRootPath'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ExposedRootPath ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ExtraText.md.html b/docs/checks/ExtraText.md.html
new file mode 100644
index 00000000..522bba73
--- /dev/null
+++ b/docs/checks/ExtraText.md.html
@@ -0,0 +1,140 @@
+
+(#) Extraneous text in resource files
+
+!!! ERROR: Extraneous text in resource files
+ This is an error.
+
+Id
+: `ExtraText`
+Summary
+: Extraneous text in resource files
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Manifest files and resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/ExtraTextDetector.kt)
+Tests
+: [Source Code](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/ExtraTextDetectorTest.kt)
+Copyright Year
+: 2011
+
+Non-value resource files should only contain elements and attributes.
+Any XML text content found in the file is likely accidental (and
+potentially dangerous if the text resembles XML and the developer
+believes the text to be functional).
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:7:Error: Unexpected text found in manifest file:
+"android:label="Android AdServices" android:forceQueryable="true"
+android:directBootAware="true">" [ExtraText]
+ android:label="Android AdServices"
+ ^
+res/drawable/icon.xml:1:Warning: Unexpected text found in drawable file:
+">" [ExtraText]
+<shape>>
+ -
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.adservices.api">
+
+ <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
+ <application>
+ android:label="Android AdServices"
+ android:forceQueryable="true"
+ android:directBootAware="true">
+ </application>
+ `
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/drawable/icon.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<shape>>
+ <item></item>>
+</shape>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<resources>
+ <string name="test">Test</string> <!-- Text is allowed in value resource files -->
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/xml/myfile.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<foo>
+ Test <!-- Text is allowed in xml and raw folder files -->
+</foo>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ExtraTextDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="ExtraText"` on the
+ problematic XML element (or one of its enclosing elements). You may
+ also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ExtraText" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ExtraText'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ExtraText ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ExtraTranslation.md.html b/docs/checks/ExtraTranslation.md.html
new file mode 100644
index 00000000..2eb9515d
--- /dev/null
+++ b/docs/checks/ExtraTranslation.md.html
@@ -0,0 +1,288 @@
+
+(#) Extra translation
+
+!!! ERROR: Extra translation
+ This is an error, and is also enforced at build time when
+ supported by the build system. For Android this means it will
+ run during release builds.
+
+Id
+: `ExtraTranslation`
+Summary
+: Extra translation
+Severity
+: Fatal
+Category
+: Correctness: Messages
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Binary resource files, resource files and resource folders
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/TranslationDetector.kt)
+Tests
+: [Source Code](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/TranslationDetectorTest.kt)
+Copyright Year
+: 2018
+
+If a string appears in a specific language translation file, but there
+is no corresponding string in the default locale, then this string is
+probably unused. (It's technically possible that your application is
+only intended to run in a specific locale, but it's still a good idea to
+provide a fallback.)
+
+Note that these strings can lead to crashes if the string is looked up
+on any locale not providing a translation, so it's important to clean
+them up.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/values-de-rDE/strings.xml:11:Error: "continue_skip_label" is
+translated here but not found in default locale [ExtraTranslation]
+ <string name="continue_skip_label">"Weiter"</string>
+ --------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`res/values/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <!-- Home -->
+ <string name="home_title">Home Sample</string>
+ <string name="show_all_apps">All</string>
+
+ <!-- Home Menus -->
+ <string name="menu_wallpaper">Wallpaper</string>
+ <string name="menu_search">Search</string>
+ <string name="menu_settings">Settings</string>
+ <string name="sample" translatable="false">Ignore Me</string>
+
+ <!-- Wallpaper -->
+ <string name="wallpaper_instructions">Tap picture to set portrait wallpaper</string>
+</resources>
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values-cs/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="home_title">"Domů"</string>
+ <string name="show_all_apps">"Vše"</string>
+ <string name="menu_wallpaper">"Tapeta"</string>
+ <string name="menu_search">"Hledat"</string>
+ <!-- no translation found for menu_settings (1769059051084007158) -->
+ <skip />
+ <string name="wallpaper_instructions">"Klepnutím na obrázek nastavíte tapetu portrétu"</string>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values-de-rDE/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="home_title">"Startseite"</string>
+ <string name="show_all_apps">"Alle"</string>
+ <string name="menu_wallpaper">"Bildschirmhintergrund"</string>
+ <string name="menu_search">"Suchen"</string>
+ <!-- no translation found for menu_settings (1769059051084007158) -->
+ <skip />
+ <string name="wallpaper_instructions">"Tippen Sie auf Bild, um Porträt-Bildschirmhintergrund einzustellen"</string>
+ <string name="continue_skip_label">"Weiter"</string>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values-es/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="home_title">"Casa"</string>
+ <string name="show_all_apps">"Todo"</string>
+ <string name="menu_wallpaper">"Papel tapiz"</string>
+ <string name="menu_search">"Búsqueda"</string>
+ <!-- no translation found for menu_settings (1769059051084007158) -->
+ <skip />
+ <string name="wallpaper_instructions">"Puntee en la imagen para establecer papel tapiz vertical"</string>
+
+ <string-array name="security_questions">
+ <item>"Comida favorita"</item>
+ <item>"Ciudad de nacimiento"</item>
+ <item>"Nombre de tu mejor amigo/a de la infancia"</item>
+ <item>"Nombre de tu colegio"</item>
+ </string-array>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values-es-rUS/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="menu_search">"Búsqueda"</string>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values-land/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <!-- Wallpaper -->
+ <string name="wallpaper_instructions">Tap image to set landscape wallpaper</string>
+</resources>
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values-cs/arrays.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="security_questions">
+ <item>"Oblíbené jídlo?"</item>
+ <item>"Město narození."</item>
+ <item>"Jméno nejlepšího kamaráda z dětství?"</item>
+ <item>"Název střední školy"</item>
+ </string-array>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values-es/donottranslate.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="full_wday_month_day_no_year">EEEE, d MMMM</string>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values-nl-rNL/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="home_title">"Start"</string>
+ <!-- Commented out in the unit test to generate extra warnings:
+ <string name="show_all_apps">"Alles"</string>
+ <string name="menu_wallpaper">"Achtergrond"</string>
+ -->
+ <string name="menu_search">"Zoeken"</string>
+ <!-- no translation found for menu_settings (1769059051084007158) -->
+ <skip />
+ <string name="wallpaper_instructions">"Tik op afbeelding om portretachtergrond in te stellen"</string>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values/public.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<resources><public /></resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/layout/foo.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<LinearLayout/>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/layout-ja/foo.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<LinearLayout/>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/TranslationDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `TranslationDetector.testTranslation`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="ExtraTranslation"`
+ on the problematic XML element (or one of its enclosing elements).
+ You may also need to add the following namespace declaration on the
+ root element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ExtraTranslation" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ExtraTranslation'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ExtraTranslation ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/FieldGetter.md.html b/docs/checks/FieldGetter.md.html
new file mode 100644
index 00000000..7c71500c
--- /dev/null
+++ b/docs/checks/FieldGetter.md.html
@@ -0,0 +1,8 @@
+
+(#) FieldGetter
+
+The issue for this id has been deleted or marked obsolete and can now be
+ignored.
+
+(Additional metadata not available.)
+
\ No newline at end of file
diff --git a/docs/checks/FieldSiteTargetOnQualifierAnnotation.md.html b/docs/checks/FieldSiteTargetOnQualifierAnnotation.md.html
new file mode 100644
index 00000000..8fc95bda
--- /dev/null
+++ b/docs/checks/FieldSiteTargetOnQualifierAnnotation.md.html
@@ -0,0 +1,279 @@
+
+(#) Redundant 'field:' used for Dagger qualifier annotation
+
+!!! WARNING: Redundant 'field:' used for Dagger qualifier annotation
+ This is a warning.
+
+Id
+: `FieldSiteTargetOnQualifierAnnotation`
+Summary
+: Redundant 'field:' used for Dagger qualifier annotation
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Google
+Identifier
+: com.google.dagger:dagger-lint
+Contact
+: https://github.com/google/dagger
+Feedback
+: https://github.com/google/dagger/issues
+Min
+: Lint 7.3 and 7.4
+Compiled
+: Lint 7.1
+Artifact
+: [com.google.dagger:dagger-lint](com_google_dagger_dagger-lint.md.html)
+Since
+: 2.40.2
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/google/dagger/tree/master/java/dagger/lint/DaggerKotlinIssueDetector.kt)
+Tests
+: [Source Code](https://github.com/google/dagger/tree/master/javatests/dagger/lint/DaggerKotlinIssueDetectorTest.kt)
+Copyright Year
+: 2020
+
+It's redundant to use 'field:' site-targets for qualifier annotations.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/foo/MyQualifier.kt:14:Warning: Redundant 'field:' used for Dagger
+qualifier annotation. [FieldSiteTargetOnQualifierAnnotation]
+ @field:MyQualifier
+ ------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/foo/MyQualifier.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package foo
+import javax.inject.Inject
+import javax.inject.Qualifier
+import kotlin.jvm.JvmStatic
+import dagger.Provides
+import dagger.Module
+
+@Qualifier
+annotation class MyQualifier
+
+class InjectedTest {
+ // This should fail because of `:field`
+ @Inject
+ @field:MyQualifier
+ lateinit var prop: String
+
+ // This is fine!
+ @Inject
+ @MyQualifier
+ lateinit var prop2: String
+}
+
+@Module
+object ObjectModule {
+ // This should fail because it uses `@JvmStatic`
+ @JvmStatic
+ @Provides
+ fun provideFoo(): String {
+
+ }
+
+ // This is fine!
+ @Provides
+ fun provideBar(): String {
+
+ }
+}
+
+@Module
+class ClassModule {
+ companion object {
+ // This should fail because the companion object is part of ClassModule, so this is unnecessary.
+ @JvmStatic
+ @Provides
+ fun provideBaz(): String {
+
+ }
+ }
+}
+
+@Module
+class ClassModuleQualified {
+ companion object {
+ // This should fail because the companion object is part of ClassModule, so this is unnecessary.
+ // This specifically tests a fully qualified annotation
+ @kotlin.jvm.JvmStatic
+ @Provides
+ fun provideBaz(): String {
+
+ }
+ }
+}
+
+@Module
+class ClassModule2 {
+ // This should fail because the companion object is part of ClassModule
+ @Module
+ companion object {
+ @Provides
+ fun provideBaz(): String {
+
+ }
+ }
+}
+
+@Module
+class ClassModule2Qualified {
+ // This should fail because the companion object is part of ClassModule
+ // This specifically tests a fully qualified annotation
+ @dagger.Module
+ companion object {
+ @Provides
+ fun provideBaz(): String {
+
+ }
+ }
+}
+
+// This is correct as of Dagger 2.26!
+@Module
+class ClassModule3 {
+ companion object {
+ @Provides
+ fun provideBaz(): String {
+
+ }
+ }
+}
+
+class ClassModule4 {
+ // This is should fail because this should be extracted to a standalone object.
+ @Module
+ companion object {
+ @Provides
+ fun provideBaz(): String {
+
+ }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/google/dagger/tree/master/javatests/dagger/lint/DaggerKotlinIssueDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `DaggerKotlinIssueDetector.simpleSmokeTestForQualifiersAndProviders`.
+To report a problem with this extracted sample, visit
+https://github.com/google/dagger/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("com.google.dagger:dagger-lint:2.56.2")
+
+// build.gradle
+implementation 'com.google.dagger:dagger-lint:2.56.2'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.dagger.lint)
+
+# libs.versions.toml
+[versions]
+dagger-lint = "2.56.2"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+dagger-lint = {
+ module = "com.google.dagger:dagger-lint",
+ version.ref = "dagger-lint"
+}
+```
+
+2.56.2 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.google.dagger:dagger-lint](com_google_dagger_dagger-lint.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("FieldSiteTargetOnQualifierAnnotation")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("FieldSiteTargetOnQualifierAnnotation")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection FieldSiteTargetOnQualifierAnnotation
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="FieldSiteTargetOnQualifierAnnotation" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'FieldSiteTargetOnQualifierAnnotation'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore FieldSiteTargetOnQualifierAnnotation ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/FileEndsWithExt.md.html b/docs/checks/FileEndsWithExt.md.html
new file mode 100644
index 00000000..ea48d515
--- /dev/null
+++ b/docs/checks/FileEndsWithExt.md.html
@@ -0,0 +1,142 @@
+
+(#) File endsWith on file extensions
+
+!!! WARNING: File endsWith on file extensions
+ This is a warning.
+
+Id
+: `FileEndsWithExt`
+Summary
+: File endsWith on file extensions
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 7.1.0 (January 2022)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/FileEndsWithDetector.kt)
+Tests
+: [Source Code](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/FileEndsWithDetectorTest.kt)
+
+The Kotlin extension method `File.endsWith(suffix)` checks whole path
+components, not just string suffixes. This means that
+`File("foo.txt").endsWith(".txt")` will return false. Instead you might
+have intended `file.path.endsWith` or `file.extension.equals`.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test.kt:4:Warning: File.endsWith compares whole filenames, not just
+file extensions; did you mean file.path.endsWith(".xml") ?
+[FileEndsWithExt]
+fun File.isXml() = endsWith(".xml")
+ ----------------
+src/test.kt:7:Warning: File.extension does not include the leading dot;
+did you mean "json" ? [FileEndsWithExt]
+fun File.isJson() = extension == ".json"
+ -------
+src/test.kt:8:Warning: File.extension does not include the leading dot;
+did you mean "webp" ? [FileEndsWithExt]
+fun isWebp(path: File) = path.extension.startsWith(".webp")
+ -------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+import java.io.File
+
+// This does not work -- it will return false for "foo/bar.xml", but true for "foo/.xml"
+fun File.isXml() = endsWith(".xml")
+
+// This does not work -- the extension property does not include the leading dot
+fun File.isJson() = extension == ".json"
+fun isWebp(path: File) = path.extension.startsWith(".webp")
+
+fun File.isText() = path.endsWith(".txt") // OK
+fun File.isPng() = extension == "png" // OK
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/FileEndsWithDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("FileEndsWithExt")
+ fun method() {
+ endsWith(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("FileEndsWithExt")
+ void method() {
+ endsWith(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection FileEndsWithExt
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="FileEndsWithExt" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'FileEndsWithExt'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore FileEndsWithExt ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/FilePropertyDetector.md.html b/docs/checks/FilePropertyDetector.md.html
new file mode 100644
index 00000000..ddcbeeac
--- /dev/null
+++ b/docs/checks/FilePropertyDetector.md.html
@@ -0,0 +1,144 @@
+
+(#) Avoid using Property
+
+!!! ERROR: Avoid using Property
+ This is an error.
+
+Id
+: `FilePropertyDetector`
+Summary
+: Avoid using Property
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Identifier
+: androidx.lint:lint-gradle
+Feedback
+: https://issuetracker.google.com/issues/new?component=1147525
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.lint:lint-gradle](androidx_lint_lint-gradle.md.html)
+Since
+: 1.0.0-alpha03
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/lint/lint-gradle/src/main/java/androidx/lint/gradle/FilePropertyDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/lint/lint-gradle/src/test/java/androidx/lint/gradle/FilePropertyDetectorTest.kt)
+Copyright Year
+: 2024
+
+`Property` is discouraged. Use `RegularFileProperty` for files or
+`DirectoryProperty` for directories to enforce better type safety.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.lint:lint-gradle:1.0.0-alpha04")
+
+// build.gradle
+implementation 'androidx.lint:lint-gradle:1.0.0-alpha04'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.lint.gradle)
+
+# libs.versions.toml
+[versions]
+lint-gradle = "1.0.0-alpha04"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+lint-gradle = {
+ module = "androidx.lint:lint-gradle",
+ version.ref = "lint-gradle"
+}
+```
+
+1.0.0-alpha04 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.lint:lint-gradle](androidx_lint_lint-gradle.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("FilePropertyDetector")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("FilePropertyDetector")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection FilePropertyDetector
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="FilePropertyDetector" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'FilePropertyDetector'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore FilePropertyDetector ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/FindViewByIdCast.md.html b/docs/checks/FindViewByIdCast.md.html
new file mode 100644
index 00000000..cb9bde6b
--- /dev/null
+++ b/docs/checks/FindViewByIdCast.md.html
@@ -0,0 +1,193 @@
+
+(#) Add Explicit Cast
+
+!!! WARNING: Add Explicit Cast
+ This is a warning.
+
+Id
+: `FindViewByIdCast`
+Summary
+: Add Explicit Cast
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.0.0 (October 2017)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/ViewTypeDetector.kt)
+Tests
+: [Source Code](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/ViewTypeDetectorTest.kt)
+
+In Android O, the `findViewById` signature switched to using generics,
+which means that most of the time you can leave out explicit casts and
+just assign the result of the `findViewById` call to variables of
+specific view classes.
+
+However, due to language changes between Java 7 and 8, this change may
+cause code to not compile without explicit casts. This lint check looks
+for these scenarios and suggests casts to be added now such that the
+code will continue to compile if the language level is updated to 1.8.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/main/java/test/pkg/ImplicitCastTest2.java:9:Warning: Add explicit
+cast here; won't compile with Java language level 1.8 without it
+[FindViewByIdCast]
+ checkNotNull1(findViewById(R.id.textView)).setAlpha(0.5f); // WARN
+ ---------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/main/java/test/pkg/ImplicitCastTest2.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.view.View;
+
+import test.pkg.R;
+
+public class ImplicitCastTest2 extends MyActivityStub {
+ public void test() {
+ checkNotNull1(findViewById(R.id.textView)).setAlpha(0.5f); // WARN
+ checkNotNull2(findViewById(R.id.textView)).setAlpha(0.5f); // OK 1
+ checkNotNull3(findViewById(R.id.textView)).setAlpha(0.5f); // OK 2
+ checkNotNull1(findViewById(R.id.textView)); // OK 3
+ checkNotNull2(findViewById(R.id.textView)); // OK 4
+ checkNotNull3(findViewById(R.id.textView)); // OK 5
+ checkNotNull1((View)findViewById(R.id.textView)); // OK 6
+ checkNotNull2((View)findViewById(R.id.textView)); // OK 7
+ checkNotNull3((View)findViewById(R.id.textView)); // OK 8
+ View view1 = checkNotNull1(findViewById(R.id.textView)); // OK 9
+ View view2 = checkNotNull2(findViewById(R.id.textView)); // OK 10
+ View view3 = checkNotNull3(findViewById(R.id.textView)); // OK 11
+ findViewById(R.id.textView); // OK 12
+ }
+
+ public static T checkNotNull1(T reference) {
+ if(reference == null) {
+ throw new NullPointerException();
+ } else {
+ return reference;
+ }
+ }
+
+ public static T checkNotNull2(T reference) {
+ if(reference == null) {
+ throw new NullPointerException();
+ } else {
+ return reference;
+ }
+ }
+
+ public static View checkNotNull3(View reference) {
+ if(reference == null) {
+ throw new NullPointerException();
+ } else {
+ return reference;
+ }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`build.gradle`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~groovy linenumbers
+android {
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ViewTypeDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ViewTypeDetector.testCastNeeded`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("FindViewByIdCast")
+ fun method() {
+ findViewById(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("FindViewByIdCast")
+ void method() {
+ findViewById(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection FindViewByIdCast
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="FindViewByIdCast" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'FindViewByIdCast'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore FindViewByIdCast ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/FlowOperatorInvokedInComposition.md.html b/docs/checks/FlowOperatorInvokedInComposition.md.html
new file mode 100644
index 00000000..330e385e
--- /dev/null
+++ b/docs/checks/FlowOperatorInvokedInComposition.md.html
@@ -0,0 +1,337 @@
+
+(#) Flow operator functions should not be invoked within composition
+
+!!! ERROR: Flow operator functions should not be invoked within composition
+ This is an error.
+
+Id
+: `FlowOperatorInvokedInComposition`
+Summary
+: Flow operator functions should not be invoked within composition
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Jetpack Compose
+Identifier
+: androidx.compose.runtime
+Feedback
+: https://issuetracker.google.com/issues/new?component=612128
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.compose.runtime:runtime-android](androidx_compose_runtime_runtime-android.md.html)
+Since
+: 1.5.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/ComposableFlowOperatorDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/ComposableFlowOperatorDetectorTest.kt)
+Copyright Year
+: 2021
+
+Calling a Flow operator function within composition will result in a new
+Flow being created every recomposition, which will reset
+collectAsState() and cause other related problems. Instead Flow
+operators should be called inside `remember`, or a side effect such as
+LaunchedEffect.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/androidx/compose/runtime/foo/test.kt:15:Error: Flow operator
+functions should not be invoked within composition
+[FlowOperatorInvokedInComposition]
+ .customOperator(true)
+ --------------
+src/androidx/compose/runtime/foo/test.kt:16:Error: Flow operator
+functions should not be invoked within composition
+[FlowOperatorInvokedInComposition]
+ .drop(0)
+ ----
+src/androidx/compose/runtime/foo/test.kt:21:Error: Flow operator
+functions should not be invoked within composition
+[FlowOperatorInvokedInComposition]
+ .map { true }
+ ---
+src/androidx/compose/runtime/foo/test.kt:22:Error: Flow operator
+functions should not be invoked within composition
+[FlowOperatorInvokedInComposition]
+ .customOperator(true)
+ --------------
+src/androidx/compose/runtime/foo/test.kt:23:Error: Flow operator
+functions should not be invoked within composition
+[FlowOperatorInvokedInComposition]
+ .drop(0)
+ ----
+src/androidx/compose/runtime/foo/test.kt:28:Error: Flow operator
+functions should not be invoked within composition
+[FlowOperatorInvokedInComposition]
+ .map { true }
+ ---
+src/androidx/compose/runtime/foo/test.kt:29:Error: Flow operator
+functions should not be invoked within composition
+[FlowOperatorInvokedInComposition]
+ .customOperator(true)
+ --------------
+src/androidx/compose/runtime/foo/test.kt:30:Error: Flow operator
+functions should not be invoked within composition
+[FlowOperatorInvokedInComposition]
+ .drop(0)
+ ----
+src/androidx/compose/runtime/foo/test.kt:40:Error: Flow operator
+functions should not be invoked within composition
+[FlowOperatorInvokedInComposition]
+ .map { true }
+ ---
+src/androidx/compose/runtime/foo/test.kt:41:Error: Flow operator
+functions should not be invoked within composition
+[FlowOperatorInvokedInComposition]
+ .customOperator(true)
+ --------------
+src/androidx/compose/runtime/foo/test.kt:42:Error: Flow operator
+functions should not be invoked within composition
+[FlowOperatorInvokedInComposition]
+ .drop(0)
+ ----
+src/androidx/compose/runtime/foo/test.kt:46:Error: Flow operator
+functions should not be invoked within composition
+[FlowOperatorInvokedInComposition]
+ .map { true }
+ ---
+src/androidx/compose/runtime/foo/test.kt:47:Error: Flow operator
+functions should not be invoked within composition
+[FlowOperatorInvokedInComposition]
+ .customOperator(true)
+ --------------
+src/androidx/compose/runtime/foo/test.kt:48:Error: Flow operator
+functions should not be invoked within composition
+[FlowOperatorInvokedInComposition]
+ .drop(0)
+ ----
+src/androidx/compose/runtime/foo/test.kt:55:Error: Flow operator
+functions should not be invoked within composition
+[FlowOperatorInvokedInComposition]
+ .map { true }
+ ---
+src/androidx/compose/runtime/foo/test.kt:56:Error: Flow operator
+functions should not be invoked within composition
+[FlowOperatorInvokedInComposition]
+ .customOperator(true)
+ --------------
+src/androidx/compose/runtime/foo/test.kt:57:Error: Flow operator
+functions should not be invoked within composition
+[FlowOperatorInvokedInComposition]
+ .drop(0)
+ ----
+src/androidx/compose/runtime/foo/test.kt:62:Error: Flow operator
+functions should not be invoked within composition
+[FlowOperatorInvokedInComposition]
+ .map { true }
+ ---
+src/androidx/compose/runtime/foo/test.kt:63:Error: Flow operator
+functions should not be invoked within composition
+[FlowOperatorInvokedInComposition]
+ .customOperator(true)
+ --------------
+src/androidx/compose/runtime/foo/test.kt:64:Error: Flow operator
+functions should not be invoked within composition
+[FlowOperatorInvokedInComposition]
+ .drop(0)
+ ----
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/androidx/compose/runtime/foo/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package androidx.compose.runtime.foo
+
+import androidx.compose.runtime.Composable
+import kotlinx.coroutines.flow.*
+
+val emptyFlow: Flow = object : Flow {}
+
+fun Flow.customOperator(param: Boolean): Flow = this
+
+@Composable
+fun Test() {
+ emptyFlow
+ .map { true }
+ .customOperator(true)
+ .drop(0)
+}
+
+val lambda = @Composable {
+ emptyFlow
+ .map { true }
+ .customOperator(true)
+ .drop(0)
+}
+
+val lambda2: @Composable () -> Unit = {
+ emptyFlow
+ .map { true }
+ .customOperator(true)
+ .drop(0)
+}
+
+@Composable
+fun LambdaParameter(content: @Composable () -> Unit) {}
+
+@Composable
+fun Test2() {
+ LambdaParameter(content = {
+ emptyFlow
+ .map { true }
+ .customOperator(true)
+ .drop(0)
+ })
+ LambdaParameter {
+ emptyFlow
+ .map { true }
+ .customOperator(true)
+ .drop(0)
+ }
+}
+
+fun test3() {
+ val localLambda1 = @Composable {
+ emptyFlow
+ .map { true }
+ .customOperator(true)
+ .drop(0)
+ }
+
+ val localLambda2: @Composable () -> Unit = {
+ emptyFlow
+ .map { true }
+ .customOperator(true)
+ .drop(0)
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/ComposableFlowOperatorDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ComposableFlowOperatorDetector.errors`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=612128.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.compose.runtime:runtime-android:1.9.0-alpha01")
+
+// build.gradle
+implementation 'androidx.compose.runtime:runtime-android:1.9.0-alpha01'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.runtime.android)
+
+# libs.versions.toml
+[versions]
+runtime-android = "1.9.0-alpha01"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+runtime-android = {
+ module = "androidx.compose.runtime:runtime-android",
+ version.ref = "runtime-android"
+}
+```
+
+1.9.0-alpha01 is the version this documentation was generated from;
+there may be newer versions available.
+
+NOTE: These lint checks are **also** made available separate from the main library.
+You can also use `androidx.compose.runtime:runtime-lint:1.9.0-alpha01`.
+
+
+[Additional details about androidx.compose.runtime:runtime-android](androidx_compose_runtime_runtime-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("FlowOperatorInvokedInComposition")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("FlowOperatorInvokedInComposition")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection FlowOperatorInvokedInComposition
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="FlowOperatorInvokedInComposition" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'FlowOperatorInvokedInComposition'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore FlowOperatorInvokedInComposition ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/FontValidation.md.html b/docs/checks/FontValidation.md.html
new file mode 100644
index 00000000..d93e4daa
--- /dev/null
+++ b/docs/checks/FontValidation.md.html
@@ -0,0 +1,123 @@
+
+(#) Validation of font files
+
+!!! ERROR: Validation of font files
+ This is an error.
+
+Id
+: `FontValidation`
+Summary
+: Validation of font files
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 7.0.0 (July 2021)
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/guide/topics/text/downloadable-fonts.html
+Implementation
+: [Source Code](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/FontDetector.java)
+Tests
+: [Source Code](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/FontDetectorTest.java)
+
+Look for problems in various font files.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/font/font1.xml:4:Error: A downloadable font cannot have a sub
+tag [FontValidation]
+ <font
+ ----
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/font/font1.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<font-family xmlns:android="http://schemas.android.com/apk/res/android"
+ android:fontProviderQuery="Monserrat">
+ <font
+ android:fontStyle="normal"
+ android:fontWeight="400"
+ android:font="@font/monserrat" />
+</font-family>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/FontDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `FontDetector.testBothDownloadableAndFontFamilyPresent`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="FontValidation"` on
+ the problematic XML element (or one of its enclosing elements). You
+ may also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <font-family xmlns:tools="http://schemas.android.com/tools"
+ tools:ignore="FontValidation" ...>
+ ...
+ </font-family>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="FontValidation" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'FontValidation'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore FontValidation ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/FontValidationError.md.html b/docs/checks/FontValidationError.md.html
new file mode 100644
index 00000000..b3254330
--- /dev/null
+++ b/docs/checks/FontValidationError.md.html
@@ -0,0 +1,7 @@
+
+(#) FontValidationError
+
+This issue id is an alias for [FontValidation](FontValidation.md.html).
+
+(Additional metadata not available.)
+
\ No newline at end of file
diff --git a/docs/checks/FontValidationWarning.md.html b/docs/checks/FontValidationWarning.md.html
new file mode 100644
index 00000000..b8a5489d
--- /dev/null
+++ b/docs/checks/FontValidationWarning.md.html
@@ -0,0 +1,7 @@
+
+(#) FontValidationWarning
+
+This issue id is an alias for [FontValidation](FontValidation.md.html).
+
+(Additional metadata not available.)
+
\ No newline at end of file
diff --git a/docs/checks/ForegroundServicePermission.md.html b/docs/checks/ForegroundServicePermission.md.html
new file mode 100644
index 00000000..6398827f
--- /dev/null
+++ b/docs/checks/ForegroundServicePermission.md.html
@@ -0,0 +1,203 @@
+
+(#) Missing permissions required by foregroundServiceType
+
+!!! ERROR: Missing permissions required by foregroundServiceType
+ This is an error.
+
+Id
+: `ForegroundServicePermission`
+Summary
+: Missing permissions required by foregroundServiceType
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 8.2.0 (November 2023)
+Affects
+: Kotlin and Java files and manifest files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/ForegroundServicePermissionDetector.kt)
+Tests
+: [Source Code](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/ForegroundServicePermissionDetectorTest.kt)
+
+For targetSdkVersion >= 34, each `foregroundServiceType` listed in the
+`` element requires specific sets of permissions to be declared
+in the manifest. If permissions are missing, then when the foreground
+service is started with a `foregroundServiceType` that has missing
+permissions, a `SecurityException` will be thrown.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:13:Error: foregroundServiceType:camera requires
+permission:[android.permission.FOREGROUND_SERVICE_CAMERA] AND any
+permission in list:[android.permission.CAMERA,
+android.permission.SYSTEM_CAMERA] [ForegroundServicePermission]
+ <service
+ ^
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="foo.bar2"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk android:targetSdkVersion="34" />
+ <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name" >
+ <service
+ android:exported="true"
+ android:label="@string/app_name"
+ android:name="com.sample.service.serviceClass"
+ android:foregroundServiceType="camera"
+ android:process=":remote" >
+ <intent-filter >
+ <action android:name="com.sample.service.serviceClass" >
+ </action>
+ </intent-filter>
+ </service>
+ </application>
+
+</manifest>
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <!-- Home -->
+ <string name="home_title">Home Sample</string>
+ <string name="show_all_apps">All</string>
+
+ <!-- Home Menus -->
+ <string name="menu_wallpaper">Wallpaper</string>
+ <string name="menu_search">Search</string>
+ <string name="menu_settings">Settings</string>
+ <string name="sample" translatable="false">Ignore Me</string>
+
+ <!-- Wallpaper -->
+ <string name="wallpaper_instructions">Tap picture to set portrait wallpaper</string>
+</resources>
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ForegroundServicePermissionDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="ForegroundServicePermission"` on the problematic XML
+ element (or one of its enclosing elements). You may also need to add
+ the following namespace declaration on the root element in the XML
+ file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <service tools:ignore="ForegroundServicePermission" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ForegroundServicePermission")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ForegroundServicePermission")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ForegroundServicePermission
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ForegroundServicePermission" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ForegroundServicePermission'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ForegroundServicePermission ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ForegroundServiceType.md.html b/docs/checks/ForegroundServiceType.md.html
new file mode 100644
index 00000000..3eac4fb1
--- /dev/null
+++ b/docs/checks/ForegroundServiceType.md.html
@@ -0,0 +1,161 @@
+
+(#) Missing `foregroundServiceType` attribute in manifest
+
+!!! ERROR: Missing `foregroundServiceType` attribute in manifest
+ This is an error.
+
+Id
+: `ForegroundServiceType`
+Summary
+: Missing `foregroundServiceType` attribute in manifest
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 8.2.0 (November 2023)
+Affects
+: Kotlin and Java files and manifest files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/ForegroundServiceTypesDetector.kt)
+Tests
+: [Source Code](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/ForegroundServiceTypesDetectorTest.kt)
+
+For `targetSdkVersion` >= 34, to call `Service.startForeground()`, the
+ element in the manifest file must have the
+`foregroundServiceType` attribute specified.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/MyService.java:8:Error: To call Service.startForeground(),
+the element of manifest file must have the
+foregroundServiceType attribute specified [ForegroundServiceType]
+ startForeground(1, null);
+ ---------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="test.pkg">
+ <uses-sdk android:targetSdkVersion="34" />
+ <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
+ <application>
+ <service
+ android:exported="true"
+ android:name="test.pkg.MyService">
+ </service>
+ </application>
+</manifest>
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyService.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+public class MyService extends Service {
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ startForeground(1, null);
+ return START_NOT_STICKY;
+ }
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ForegroundServiceTypesDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="ForegroundServiceType"` on the problematic XML
+ element (or one of its enclosing elements). You may also need to add
+ the following namespace declaration on the root element in the XML
+ file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ForegroundServiceType")
+ fun method() {
+ startForeground(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ForegroundServiceType")
+ void method() {
+ startForeground(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ForegroundServiceType
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ForegroundServiceType" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ForegroundServiceType'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ForegroundServiceType ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/FormalGerman.md.html b/docs/checks/FormalGerman.md.html
new file mode 100644
index 00000000..d140bebe
--- /dev/null
+++ b/docs/checks/FormalGerman.md.html
@@ -0,0 +1,175 @@
+
+(#) Marks strings which contain formal German words
+
+!!! WARNING: Marks strings which contain formal German words
+ This is a warning.
+
+Id
+: `FormalGerman`
+Summary
+: Marks strings which contain formal German words
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: vanniktech/lint-rules/
+Feedback
+: https://github.com/vanniktech/lint-rules/issues
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [com.vanniktech:lint-rules-android](com_vanniktech_lint-rules-android.md.html)
+Since
+: 0.24.0
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/main/kotlin/com/vanniktech/lintrules/android/FormalGermanDetector.kt)
+Tests
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/test/kotlin/com/vanniktech/lintrules/android/FormalGermanDetectorTest.kt)
+
+Informal language should be used at all times.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/values/config.xml:2:Warning: Formal language "Ihr" detected
+[FormalGerman]
+ <string name="my_string_1">Wie lautet Ihr Name?</string>
+ ^
+res/values/config.xml:3:Warning: Formal language "Sie?" detected
+[FormalGerman]
+ <string name="my_string_2">Wie heissen Sie?</string>
+ ^
+res/values/config.xml:4:Warning: Formal language "Ihrem" detected
+[FormalGerman]
+ <string name="my_string_3">Frag nach Ihrem Namen.</string>
+ ^
+res/values/config.xml:5:Warning: Formal language "Sie" detected
+[FormalGerman]
+ <string name="my_string_4">Wie Sie möchten</string>
+ ^
+res/values/config.xml:6:Warning: Formal language "Ihre" detected
+[FormalGerman]
+ <string name="my_string_5">Ihre Historie</string>
+ ^
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/values/config.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<resources>
+ <string name="my_string_1">Wie lautet Ihr Name?</string>
+ <string name="my_string_2">Wie heissen Sie?</string>
+ <string name="my_string_3">Frag nach Ihrem Namen.</string>
+ <string name="my_string_4">Wie Sie möchten</string>
+ <string name="my_string_5">Ihre Historie</string>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/test/kotlin/com/vanniktech/lintrules/android/FormalGermanDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `FormalGermanDetector.formal`.
+To report a problem with this extracted sample, visit
+https://github.com/vanniktech/lint-rules/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.vanniktech:lint-rules-android:0.25.0")
+
+// build.gradle
+lintChecks 'com.vanniktech:lint-rules-android:0.25.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.lint.rules.android)
+
+# libs.versions.toml
+[versions]
+lint-rules-android = "0.25.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+lint-rules-android = {
+ module = "com.vanniktech:lint-rules-android",
+ version.ref = "lint-rules-android"
+}
+```
+
+0.25.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.vanniktech:lint-rules-android](com_vanniktech_lint-rules-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="FormalGerman"` on
+ the problematic XML element (or one of its enclosing elements). You
+ may also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <resources xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <string tools:ignore="FormalGerman" .../>
+ ...
+ </resources>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="FormalGerman" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'FormalGerman'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore FormalGerman ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/FragmentAddMenuProvider.md.html b/docs/checks/FragmentAddMenuProvider.md.html
new file mode 100644
index 00000000..835a0cd0
--- /dev/null
+++ b/docs/checks/FragmentAddMenuProvider.md.html
@@ -0,0 +1,150 @@
+
+(#) Use getViewLifecycleOwner() as the LifecycleOwner instead of a Fragment instance
+
+!!! ERROR: Use getViewLifecycleOwner() as the LifecycleOwner instead of a Fragment instance
+ This is an error.
+
+Id
+: `FragmentAddMenuProvider`
+Summary
+: Use getViewLifecycleOwner() as the LifecycleOwner instead of a Fragment instance
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Identifier
+: androidx.fragment
+Feedback
+: https://issuetracker.google.com/issues/new?component=460964
+Min
+: Lint 7.0
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [androidx.fragment:fragment](androidx_fragment_fragment.md.html)
+Since
+: 1.4.0
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/fragment/fragment-lint/src/main/java/androidx/fragment/lint/UnsafeFragmentLifecycleObserverDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/fragment/fragment-lint/src/test/java/androidx/fragment/lint/AddMenuProviderDetectorTest.kt)
+Copyright Year
+: 2019
+
+The Fragment lifecycle can result in a Fragment being active
+ longer than its view. This can lead to unexpected behavior from
+lifecycle aware objects remaining active longer than the
+Fragment's view. To solve this issue,
+getViewLifecycleOwner() should be used as a LifecycleOwner rather than
+the Fragment instance once it is safe to access the view
+lifecycle in a Fragment's onCreateView, onViewCreated,
+onActivityCreated, or onViewStateRestored methods.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.fragment:fragment:1.8.6")
+
+// build.gradle
+implementation 'androidx.fragment:fragment:1.8.6'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.fragment)
+
+# libs.versions.toml
+[versions]
+fragment = "1.8.6"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+fragment = {
+ module = "androidx.fragment:fragment",
+ version.ref = "fragment"
+}
+```
+
+1.8.6 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.fragment:fragment](androidx_fragment_fragment.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("FragmentAddMenuProvider")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("FragmentAddMenuProvider")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection FragmentAddMenuProvider
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="FragmentAddMenuProvider" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'FragmentAddMenuProvider'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore FragmentAddMenuProvider ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/FragmentBackPressedCallback.md.html b/docs/checks/FragmentBackPressedCallback.md.html
new file mode 100644
index 00000000..3360c695
--- /dev/null
+++ b/docs/checks/FragmentBackPressedCallback.md.html
@@ -0,0 +1,150 @@
+
+(#) Use getViewLifecycleOwner() as the LifecycleOwner instead of a Fragment instance
+
+!!! ERROR: Use getViewLifecycleOwner() as the LifecycleOwner instead of a Fragment instance
+ This is an error.
+
+Id
+: `FragmentBackPressedCallback`
+Summary
+: Use getViewLifecycleOwner() as the LifecycleOwner instead of a Fragment instance
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Identifier
+: androidx.fragment
+Feedback
+: https://issuetracker.google.com/issues/new?component=460964
+Min
+: Lint 7.0
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [androidx.fragment:fragment](androidx_fragment_fragment.md.html)
+Since
+: 1.2.2
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/fragment/fragment-lint/src/main/java/androidx/fragment/lint/UnsafeFragmentLifecycleObserverDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/fragment/fragment-lint/src/test/java/androidx/fragment/lint/BackPressedDispatcherCallbackDetectorTest.kt)
+Copyright Year
+: 2019
+
+The Fragment lifecycle can result in a Fragment being active
+ longer than its view. This can lead to unexpected behavior from
+lifecycle aware objects remaining active longer than the
+Fragment's view. To solve this issue,
+getViewLifecycleOwner() should be used as a LifecycleOwner rather than
+the Fragment instance once it is safe to access the view
+lifecycle in a Fragment's onCreateView, onViewCreated,
+onActivityCreated, or onViewStateRestored methods.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.fragment:fragment:1.8.6")
+
+// build.gradle
+implementation 'androidx.fragment:fragment:1.8.6'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.fragment)
+
+# libs.versions.toml
+[versions]
+fragment = "1.8.6"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+fragment = {
+ module = "androidx.fragment:fragment",
+ version.ref = "fragment"
+}
+```
+
+1.8.6 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.fragment:fragment](androidx_fragment_fragment.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("FragmentBackPressedCallback")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("FragmentBackPressedCallback")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection FragmentBackPressedCallback
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="FragmentBackPressedCallback" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'FragmentBackPressedCallback'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore FragmentBackPressedCallback ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/FragmentConstructorInjection.md.html b/docs/checks/FragmentConstructorInjection.md.html
new file mode 100644
index 00000000..fa7c557d
--- /dev/null
+++ b/docs/checks/FragmentConstructorInjection.md.html
@@ -0,0 +1,224 @@
+
+(#) Fragment dependencies should be injected using constructor injections only
+
+!!! ERROR: Fragment dependencies should be injected using constructor injections only
+ This is an error.
+
+Id
+: `FragmentConstructorInjection`
+Summary
+: Fragment dependencies should be injected using constructor injections only
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.1.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/FragmentDaggerFieldInjectionDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/FragmentDaggerFieldInjectionDetectorTest.kt)
+Copyright Year
+: 2021
+
+This Fragment has been set up to inject its dependencies through the
+constructor. This dependency should be declared in the constructor where
+dagger will handle the injection at runtime.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/foo/MyFragment.kt:14:Error: Fragment dependencies should be injected
+using constructor injections only. [FragmentConstructorInjection]
+ @Inject
+ ^
+src/foo/MyFragment.kt:16:Error: Fragment dependencies should be injected
+using constructor injections only. [FragmentConstructorInjection]
+ @Inject
+ ^
+src/foo/MyFragment.kt:31:Error: Fragment dependencies should be injected
+using constructor injections only. [FragmentConstructorInjection]
+ @Inject
+ ^
+src/foo/MyFragment.kt:33:Error: Fragment dependencies should be injected
+using constructor injections only. [FragmentConstructorInjection]
+ @Inject
+ ^
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/foo/MyFragment.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package foo
+
+import javax.inject.Inject
+import dagger.assisted.AssistedInject
+import slack.coreui.fragment.ViewBindingFragment
+
+class MyFragment @Inject constructor(
+ private val flag: Boolean
+): ViewBindingFragment() {
+
+ private lateinit var notAnnotated: String
+ private val defaulted: String = "defaulted"
+
+ @Inject
+ private lateinit var stringValue1: String
+ @Inject
+ private lateinit var intValue1: Int
+
+ fun onCreate() {
+ notAnnotated = "fast"
+ }
+}
+
+class MyFragmentAssistedInject @AssistedInject constructor(
+ private val flag: Boolean
+): ViewBindingFragment() {
+
+ private lateinit var notAnnotated: String
+ private val defaulted: String = "defaulted"
+
+ @Inject
+ private lateinit var stringValue1: String
+ @Inject
+ private lateinit var intValue1: Int
+
+ fun onCreate() {
+ notAnnotated = "fast"
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/FragmentDaggerFieldInjectionDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `FragmentDaggerFieldInjectionDetector.Kotlin - fragment has field injection errors when constructor injection exists`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/slack-lints.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("FragmentConstructorInjection")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("FragmentConstructorInjection")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection FragmentConstructorInjection
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="FragmentConstructorInjection" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'FragmentConstructorInjection'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore FragmentConstructorInjection ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/FragmentFieldInjection.md.html b/docs/checks/FragmentFieldInjection.md.html
new file mode 100644
index 00000000..20dedecf
--- /dev/null
+++ b/docs/checks/FragmentFieldInjection.md.html
@@ -0,0 +1,201 @@
+
+(#) Fragment dependencies should be injected using the Fragment's constructor
+
+!!! ERROR: Fragment dependencies should be injected using the Fragment's constructor
+ This is an error.
+
+Id
+: `FragmentFieldInjection`
+Summary
+: Fragment dependencies should be injected using the Fragment's constructor
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.1.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/FragmentDaggerFieldInjectionDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/FragmentDaggerFieldInjectionDetectorTest.kt)
+Copyright Year
+: 2021
+
+This dependency should be injected by dagger via the constructor. Add
+this field's type into the parameter list of the Fragment's constructor.
+This constructor should be annotated with either `@AssistedInject` or
+`@Inject`. Annotate with `@AssistedInject` if this Fragment requires
+runtime arguments via a `Bundle`. Annotate with `@Inject` if this
+Fragment does not require any runtime arguments. If this is an abstract
+class, the constructor does not need to be annotated with `@Inject` or
+`@AssistedInject`.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/foo/MyFragment.kt:11:Error: Fragment dependencies should be injected
+using the Fragment's constructor. [FragmentFieldInjection]
+ @Inject
+ ^
+src/foo/MyFragment.kt:13:Error: Fragment dependencies should be injected
+using the Fragment's constructor. [FragmentFieldInjection]
+ @Inject
+ ^
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/foo/MyFragment.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package foo
+
+import javax.inject.Inject
+import slack.coreui.fragment.ViewBindingFragment
+
+class MyFragment : ViewBindingFragment() {
+
+ private lateinit var notAnnotated: String
+ private val defaulted: String = "defaulted"
+
+ @Inject
+ private lateinit var stringValue1: String
+ @Inject
+ private lateinit var intValue1: Int
+
+ fun onCreate() {
+ notAnnotated = "fast"
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/FragmentDaggerFieldInjectionDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `FragmentDaggerFieldInjectionDetector.Kotlin - fragment has field injection warnings`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/slack-lints.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("FragmentFieldInjection")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("FragmentFieldInjection")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection FragmentFieldInjection
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="FragmentFieldInjection" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'FragmentFieldInjection'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore FragmentFieldInjection ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/FragmentGradleConfiguration-2.md.html b/docs/checks/FragmentGradleConfiguration-2.md.html
new file mode 100644
index 00000000..d48efc07
--- /dev/null
+++ b/docs/checks/FragmentGradleConfiguration-2.md.html
@@ -0,0 +1,155 @@
+
+(#) Include the fragment-testing-manifest library using the debugImplementation configuration
+
+!!! ERROR: Include the fragment-testing-manifest library using the debugImplementation configuration
+ This is an error.
+
+Id
+: `FragmentGradleConfiguration`
+Summary
+: Include the fragment-testing-manifest library using the debugImplementation configuration
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Identifier
+: androidx.fragment.testing.manifest
+Feedback
+: https://issuetracker.google.com/issues/new?component=460964
+Min
+: Lint 7.0
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [androidx.fragment:fragment-testing-manifest](androidx_fragment_fragment-testing-manifest.md.html)
+Since
+: 1.6.0
+Affects
+: Gradle build files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://d.android.com/training/basics/fragments/testing#configure
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/fragment/fragment-testing-manifest-lint/src/main/java/androidx/fragment/testing/manifest/lint/GradleConfigurationDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/fragment/fragment-testing-manifest-lint/src/test/java/androidx/fragment/testing/manifest/lint/GradleConfigurationDetectorTest.kt)
+Copyright Year
+: 2019
+
+The fragment-testing-manifest library defines an EmptyActivity
+ used when using FragmentScenario. Howver, it only needs to be
+present in testing configurations therefore use this
+dependency with the debugImplementation configuration.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+build.gradle:2:Error: Replace with debugImplementation.
+[FragmentGradleConfiguration]
+ androidTestImplementation("androidx.fragment:fragment-testing-manifest:1.2.0-beta02")
+ -------------------------------------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`build.gradle`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~groovy linenumbers
+dependencies {
+ androidTestImplementation("androidx.fragment:fragment-testing-manifest:1.2.0-beta02")
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/fragment/fragment-testing-manifest-lint/src/test/java/androidx/fragment/testing/manifest/lint/GradleConfigurationDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `GradleConfigurationDetector.expectFail`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=460964.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.fragment:fragment-testing-manifest:1.8.6")
+
+// build.gradle
+implementation 'androidx.fragment:fragment-testing-manifest:1.8.6'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.fragment.testing.manifest)
+
+# libs.versions.toml
+[versions]
+fragment-testing-manifest = "1.8.6"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+fragment-testing-manifest = {
+ module = "androidx.fragment:fragment-testing-manifest",
+ version.ref = "fragment-testing-manifest"
+}
+```
+
+1.8.6 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.fragment:fragment-testing-manifest](androidx_fragment_fragment-testing-manifest.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection FragmentGradleConfiguration
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="FragmentGradleConfiguration" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'FragmentGradleConfiguration'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore FragmentGradleConfiguration ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/FragmentGradleConfiguration.md.html b/docs/checks/FragmentGradleConfiguration.md.html
new file mode 100644
index 00000000..8f95f0f3
--- /dev/null
+++ b/docs/checks/FragmentGradleConfiguration.md.html
@@ -0,0 +1,156 @@
+
+(#) Include the fragment-testing library using the debugImplementation configuration
+
+!!! ERROR: Include the fragment-testing library using the debugImplementation configuration
+ This is an error.
+
+Id
+: `FragmentGradleConfiguration`
+Summary
+: Include the fragment-testing library using the debugImplementation configuration
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Identifier
+: androidx.fragment.testing
+Feedback
+: https://issuetracker.google.com/issues/new?component=460964
+Min
+: Lint 7.0
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [androidx.fragment:fragment-testing](androidx_fragment_fragment-testing.md.html)
+Since
+: 1.6.0
+Affects
+: Gradle build files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://d.android.com/training/basics/fragments/testing#configure
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/fragment/fragment-testing-manifest-lint/src/main/java/androidx/fragment/testing/manifest/lint/GradleConfigurationDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/fragment/fragment-testing-manifest-lint/src/test/java/androidx/fragment/testing/manifest/lint/GradleConfigurationDetectorTest.kt)
+Copyright Year
+: 2019
+
+The fragment-testing library contains a FragmentScenario class that
+ creates an Activity that must exist in the runtime APK. To
+include the fragment-testing library in the runtime APK
+it must be added using the debugImplementation
+configuration.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+build.gradle:2:Error: Replace with debugImplementation.
+[FragmentGradleConfiguration]
+ androidTestImplementation("androidx.fragment:fragment-testing-manifest:1.2.0-beta02")
+ -------------------------------------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`build.gradle`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~groovy linenumbers
+dependencies {
+ androidTestImplementation("androidx.fragment:fragment-testing-manifest:1.2.0-beta02")
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/fragment/fragment-testing-manifest-lint/src/test/java/androidx/fragment/testing/manifest/lint/GradleConfigurationDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `GradleConfigurationDetector.expectFail`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=460964.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.fragment:fragment-testing:1.8.6")
+
+// build.gradle
+implementation 'androidx.fragment:fragment-testing:1.8.6'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.fragment.testing)
+
+# libs.versions.toml
+[versions]
+fragment-testing = "1.8.6"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+fragment-testing = {
+ module = "androidx.fragment:fragment-testing",
+ version.ref = "fragment-testing"
+}
+```
+
+1.8.6 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.fragment:fragment-testing](androidx_fragment_fragment-testing.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection FragmentGradleConfiguration
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="FragmentGradleConfiguration" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'FragmentGradleConfiguration'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore FragmentGradleConfiguration ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/FragmentLiveDataObserve.md.html b/docs/checks/FragmentLiveDataObserve.md.html
new file mode 100644
index 00000000..f7fa7979
--- /dev/null
+++ b/docs/checks/FragmentLiveDataObserve.md.html
@@ -0,0 +1,150 @@
+
+(#) Use getViewLifecycleOwner() as the LifecycleOwner instead of a Fragment instance when observing a LiveData object
+
+!!! ERROR: Use getViewLifecycleOwner() as the LifecycleOwner instead of a Fragment instance when observing a LiveData object
+ This is an error.
+
+Id
+: `FragmentLiveDataObserve`
+Summary
+: Use getViewLifecycleOwner() as the LifecycleOwner instead of a Fragment instance when observing a LiveData object
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Identifier
+: androidx.fragment
+Feedback
+: https://issuetracker.google.com/issues/new?component=460964
+Min
+: Lint 7.0
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [androidx.fragment:fragment](androidx_fragment_fragment.md.html)
+Since
+: 1.2.0
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/fragment/fragment-lint/src/main/java/androidx/fragment/lint/UnsafeFragmentLifecycleObserverDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/fragment/fragment-lint/src/test/java/androidx/fragment/lint/FragmentLiveDataObserveDetectorTest.kt)
+Copyright Year
+: 2019
+
+When observing a LiveData object from a fragment's onCreateView,
+ onViewCreated, onActivityCreated, or onViewStateRestored method
+ getViewLifecycleOwner() should be used as the
+LifecycleOwner rather than the Fragment instance. The
+Fragment lifecycle can result in the Fragment being
+active longer than its view. This can lead to unexpected behavior from
+ LiveData objects being observed longer than the Fragment's
+view is active.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.fragment:fragment:1.8.6")
+
+// build.gradle
+implementation 'androidx.fragment:fragment:1.8.6'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.fragment)
+
+# libs.versions.toml
+[versions]
+fragment = "1.8.6"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+fragment = {
+ module = "androidx.fragment:fragment",
+ version.ref = "fragment"
+}
+```
+
+1.8.6 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.fragment:fragment](androidx_fragment_fragment.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("FragmentLiveDataObserve")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("FragmentLiveDataObserve")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection FragmentLiveDataObserve
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="FragmentLiveDataObserve" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'FragmentLiveDataObserve'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore FragmentLiveDataObserve ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/FragmentTagUsage.md.html b/docs/checks/FragmentTagUsage.md.html
new file mode 100644
index 00000000..16e9a4c7
--- /dev/null
+++ b/docs/checks/FragmentTagUsage.md.html
@@ -0,0 +1,170 @@
+
+(#) Use FragmentContainerView instead of the tag
+
+!!! WARNING: Use FragmentContainerView instead of the tag
+ This is a warning.
+
+Id
+: `FragmentTagUsage`
+Summary
+: Use FragmentContainerView instead of the tag
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Identifier
+: androidx.fragment
+Feedback
+: https://issuetracker.google.com/issues/new?component=460964
+Min
+: Lint 7.0
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [androidx.fragment:fragment](androidx_fragment_fragment.md.html)
+Since
+: 1.2.0
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/reference/androidx/fragment/app/FragmentContainerView.html
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/fragment/fragment-lint/src/main/java/androidx/fragment/lint/FragmentTagDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/fragment/fragment-lint/src/test/java/androidx/fragment/lint/FragmentTagDetectorTest.kt)
+Copyright Year
+: 2019
+
+FragmentContainerView replaces the tag as the preferred
+ way of adding fragments via XML. Unlike the tag,
+FragmentContainerView uses a normal
+`FragmentTransaction` under the hood to add the initial fragment,
+ allowing further FragmentTransaction operations on the
+FragmentContainerView and providing a consistent timing
+for lifecycle events.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/layout.xml:5:Warning: Replace the tag with
+FragmentContainerView. [FragmentTagUsage]
+ <fragment android:name="androidx.fragment.app.Test'$'InflatedFragment"
+ --------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/layout/layout.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <fragment android:name="androidx.fragment.app.Test'$'InflatedFragment"
+ android:id="@+id/child_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+</FrameLayout>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/fragment/fragment-lint/src/test/java/androidx/fragment/lint/FragmentTagDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `FragmentTagDetector.expectFail`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=460964.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.fragment:fragment:1.8.6")
+
+// build.gradle
+implementation 'androidx.fragment:fragment:1.8.6'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.fragment)
+
+# libs.versions.toml
+[versions]
+fragment = "1.8.6"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+fragment = {
+ module = "androidx.fragment:fragment",
+ version.ref = "fragment"
+}
+```
+
+1.8.6 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.fragment:fragment](androidx_fragment_fragment.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="FragmentTagUsage"`
+ on the problematic XML element (or one of its enclosing elements).
+ You may also need to add the following namespace declaration on the
+ root element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <fragment xmlns:tools="http://schemas.android.com/tools"
+ tools:ignore="FragmentTagUsage" ...>
+ ...
+ </fragment>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="FragmentTagUsage" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'FragmentTagUsage'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore FragmentTagUsage ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/FrequentlyChangedStateReadInComposition.md.html b/docs/checks/FrequentlyChangedStateReadInComposition.md.html
new file mode 100644
index 00000000..6fc6a490
--- /dev/null
+++ b/docs/checks/FrequentlyChangedStateReadInComposition.md.html
@@ -0,0 +1,8 @@
+
+(#) FrequentlyChangedStateReadInComposition
+
+The issue for this id has been deleted or marked obsolete and can now be
+ignored.
+
+(Additional metadata not available.)
+
\ No newline at end of file
diff --git a/docs/checks/FrequentlyChangingValue.md.html b/docs/checks/FrequentlyChangingValue.md.html
new file mode 100644
index 00000000..ed77dc9d
--- /dev/null
+++ b/docs/checks/FrequentlyChangingValue.md.html
@@ -0,0 +1,508 @@
+
+(#) Reading a value annotated with @FrequentlyChangingValue inside composition
+
+!!! WARNING: Reading a value annotated with @FrequentlyChangingValue inside composition
+ This is a warning.
+
+Id
+: `FrequentlyChangingValue`
+Summary
+: Reading a value annotated with @FrequentlyChangingValue inside composition
+Severity
+: Warning
+Category
+: Performance
+Platform
+: Any
+Vendor
+: Jetpack Compose
+Identifier
+: androidx.compose.runtime
+Feedback
+: https://issuetracker.google.com/issues/new?component=612128
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.compose.runtime:runtime-android](androidx_compose_runtime_runtime-android.md.html)
+Since
+: 1.9.0-alpha01
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/FrequentlyChangingValueDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/FrequentlyChangingValueDetectorTest.kt)
+Copyright Year
+: 2025
+
+Reading a value annotated with @FrequentlyChangingValue inside
+composition can cause performance issues due to frequent recompositions.
+To avoid frequent recompositions, instead consider:
+
+- Using derivedStateOf to filter state changes based on a provided
+ calculation. For example, rather than recomposing on every scroll
+ position change, only recomposing if the scroll position changes
+ from 0 (at the top of the list) to greater than 0 (not at the top of
+ the list), and vice versa.
+- Using snapshotFlow to create a flow of changes from a provided state.
+ This can then be collected inside a LaunchedEffect, and used to make
+ changes without needing to recompose.
+- If using Compose UI, read this value inside measure / layout / draw,
+ depending on where it is needed. This will cause invalidation of the
+ corresponding phase, instead of a recomposition. See
+ developer.android.com for more information on Jetpack Compose
+ phases.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/androidx/compose/runtime/foo/{.kt:8:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ test()
+ ----
+src/androidx/compose/runtime/foo/{.kt:10:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ val fooValue = foo.value
+ -----
+src/androidx/compose/runtime/foo/{.kt:11:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ bar.calculateValue()
+ --------------
+src/androidx/compose/runtime/foo/{.kt:12:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ val barValue = bar.value
+ -----
+src/androidx/compose/runtime/foo/{.kt:14:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ barImpl.calculateValue()
+ --------------
+src/androidx/compose/runtime/foo/{.kt:15:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ val barImplValue = barImpl.value
+ -----
+src/androidx/compose/runtime/foo/{.kt:19:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ test()
+ ----
+src/androidx/compose/runtime/foo/{.kt:21:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ val fooValue = foo.value
+ -----
+src/androidx/compose/runtime/foo/{.kt:22:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ bar.calculateValue()
+ --------------
+src/androidx/compose/runtime/foo/{.kt:23:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ val barValue = bar.value
+ -----
+src/androidx/compose/runtime/foo/{.kt:25:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ barImpl.calculateValue()
+ --------------
+src/androidx/compose/runtime/foo/{.kt:26:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ val barImplValue = barImpl.value
+ -----
+src/androidx/compose/runtime/foo/{.kt:30:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ test()
+ ----
+src/androidx/compose/runtime/foo/{.kt:32:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ val fooValue = foo.value
+ -----
+src/androidx/compose/runtime/foo/{.kt:33:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ bar.calculateValue()
+ --------------
+src/androidx/compose/runtime/foo/{.kt:34:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ val barValue = bar.value
+ -----
+src/androidx/compose/runtime/foo/{.kt:36:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ barImpl.calculateValue()
+ --------------
+src/androidx/compose/runtime/foo/{.kt:37:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ val barImplValue = barImpl.value
+ -----
+src/androidx/compose/runtime/foo/{.kt:46:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ test()
+ ----
+src/androidx/compose/runtime/foo/{.kt:48:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ val fooValue = foo.value
+ -----
+src/androidx/compose/runtime/foo/{.kt:49:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ bar.calculateValue()
+ --------------
+src/androidx/compose/runtime/foo/{.kt:50:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ val barValue = bar.value
+ -----
+src/androidx/compose/runtime/foo/{.kt:52:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ barImpl.calculateValue()
+ --------------
+src/androidx/compose/runtime/foo/{.kt:53:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ val barImplValue = barImpl.value
+ -----
+src/androidx/compose/runtime/foo/{.kt:56:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ test()
+ ----
+src/androidx/compose/runtime/foo/{.kt:58:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ val fooValue = foo.value
+ -----
+src/androidx/compose/runtime/foo/{.kt:59:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ bar.calculateValue()
+ --------------
+src/androidx/compose/runtime/foo/{.kt:60:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ val barValue = bar.value
+ -----
+src/androidx/compose/runtime/foo/{.kt:62:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ barImpl.calculateValue()
+ --------------
+src/androidx/compose/runtime/foo/{.kt:63:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ val barImplValue = barImpl.value
+ -----
+src/androidx/compose/runtime/foo/{.kt:69:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ test()
+ ----
+src/androidx/compose/runtime/foo/{.kt:71:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ val fooValue = foo.value
+ -----
+src/androidx/compose/runtime/foo/{.kt:72:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ bar.calculateValue()
+ --------------
+src/androidx/compose/runtime/foo/{.kt:73:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ val barValue = bar.value
+ -----
+src/androidx/compose/runtime/foo/{.kt:75:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ barImpl.calculateValue()
+ --------------
+src/androidx/compose/runtime/foo/{.kt:76:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ val barImplValue = barImpl.value
+ -----
+src/androidx/compose/runtime/foo/{.kt:80:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ test()
+ ----
+src/androidx/compose/runtime/foo/{.kt:82:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ val fooValue = foo.value
+ -----
+src/androidx/compose/runtime/foo/{.kt:83:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ bar.calculateValue()
+ --------------
+src/androidx/compose/runtime/foo/{.kt:84:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ val barValue = bar.value
+ -----
+src/androidx/compose/runtime/foo/{.kt:86:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ barImpl.calculateValue()
+ --------------
+src/androidx/compose/runtime/foo/{.kt:87:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ val barImplValue = barImpl.value
+ -----
+src/androidx/compose/runtime/foo/{.kt:95:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ val fooValue = foo.value
+ -----
+src/androidx/compose/runtime/foo/{.kt:96:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ val barValue = bar.value
+ -----
+src/androidx/compose/runtime/foo/{.kt:98:Warning: Reading a value
+annotated with @FrequentlyChangingValue inside composition
+[FrequentlyChangingValue]
+ val barImplValue = barImpl.value
+ -----
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/androidx/compose/runtime/foo/{.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package androidx.compose.runtime.foo
+
+import androidx.compose.runtime.*
+
+@Composable
+fun Test(bar: Bar) {
+ test()
+ val foo = Foo()
+ val fooValue = foo.value
+ bar.calculateValue()
+ val barValue = bar.value
+ val barImpl = BarImpl()
+ barImpl.calculateValue()
+ val barImplValue = barImpl.value
+}
+
+val lambda = @Composable { bar: Bar ->
+ test()
+ val foo = Foo()
+ val fooValue = foo.value
+ bar.calculateValue()
+ val barValue = bar.value
+ val barImpl = BarImpl()
+ barImpl.calculateValue()
+ val barImplValue = barImpl.value
+}
+
+val lambda2: @Composable (bar: Bar) -> Unit = { bar ->
+ test()
+ val foo = Foo()
+ val fooValue = foo.value
+ bar.calculateValue()
+ val barValue = bar.value
+ val barImpl = BarImpl()
+ barImpl.calculateValue()
+ val barImplValue = barImpl.value
+}
+
+@Composable
+fun LambdaParameter(content: @Composable () -> Unit) {}
+
+@Composable
+fun Test2(bar: Bar) {
+ LambdaParameter(content = {
+ test()
+ val foo = Foo()
+ val fooValue = foo.value
+ bar.calculateValue()
+ val barValue = bar.value
+ val barImpl = BarImpl()
+ barImpl.calculateValue()
+ val barImplValue = barImpl.value
+ })
+ LambdaParameter {
+ test()
+ val foo = Foo()
+ val fooValue = foo.value
+ bar.calculateValue()
+ val barValue = bar.value
+ val barImpl = BarImpl()
+ barImpl.calculateValue()
+ val barImplValue = barImpl.value
+ }
+}
+
+fun test3(bar: Bar) {
+ val localLambda1 = @Composable {
+ test()
+ val foo = Foo()
+ val fooValue = foo.value
+ bar.calculateValue()
+ val barValue = bar.value
+ val barImpl = BarImpl()
+ barImpl.calculateValue()
+ val barImplValue = barImpl.value
+ }
+
+ val localLambda2: @Composable () -> Unit = {
+ test()
+ val foo = Foo()
+ val fooValue = foo.value
+ bar.calculateValue()
+ val barValue = bar.value
+ val barImpl = BarImpl()
+ barImpl.calculateValue()
+ val barImplValue = barImpl.value
+ }
+}
+
+@Composable
+fun Test4(bar: Bar) {
+ val localObject = object {
+ val foo = Foo()
+ val fooValue = foo.value
+ val barValue = bar.value
+ val barImpl = BarImpl()
+ val barImplValue = barImpl.value
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/FrequentlyChangingValueDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `FrequentlyChangingValueDetector.errors`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=612128.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.compose.runtime:runtime-android:1.9.0-alpha01")
+
+// build.gradle
+implementation 'androidx.compose.runtime:runtime-android:1.9.0-alpha01'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.runtime.android)
+
+# libs.versions.toml
+[versions]
+runtime-android = "1.9.0-alpha01"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+runtime-android = {
+ module = "androidx.compose.runtime:runtime-android",
+ version.ref = "runtime-android"
+}
+```
+
+1.9.0-alpha01 is the version this documentation was generated from;
+there may be newer versions available.
+
+NOTE: These lint checks are **also** made available separate from the main library.
+You can also use `androidx.compose.runtime:runtime-lint:1.9.0-alpha01`.
+
+
+[Additional details about androidx.compose.runtime:runtime-android](androidx_compose_runtime_runtime-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("FrequentlyChangingValue")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("FrequentlyChangingValue")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection FrequentlyChangingValue
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="FrequentlyChangingValue" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'FrequentlyChangingValue'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore FrequentlyChangingValue ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/FullBackupContent.md.html b/docs/checks/FullBackupContent.md.html
new file mode 100644
index 00000000..328003d4
--- /dev/null
+++ b/docs/checks/FullBackupContent.md.html
@@ -0,0 +1,141 @@
+
+(#) Valid Full Backup Content File
+
+!!! ERROR: Valid Full Backup Content File
+ This is an error, and is also enforced at build time when
+ supported by the build system. For Android this means it will
+ run during release builds.
+
+Id
+: `FullBackupContent`
+Summary
+: Valid Full Backup Content File
+Severity
+: Fatal
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 1.3.0 (July 2015)
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://android-developers.googleblog.com/2015/07/auto-backup-for-apps-made-simple.html
+Implementation
+: [Source Code](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/FullBackupContentDetector.kt)
+Tests
+: [Source Code](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/FullBackupContentDetectorTest.kt)
+
+Ensures that ` and ``
+files, which configure backup options, are valid.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/xml/data_extraction_rules.xml:6:Error: foo.xml is not in an included
+path [FullBackupContent]
+ <exclude domain="sharedpref" path="foo.xml"/>
+ -------
+res/xml/full_backup_content.xml:5:Error: foo.xml is not in an included
+path [FullBackupContent]
+ <exclude domain="sharedpref" path="foo.xml"/>
+ -------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="my.pkg" >
+ <application
+ android:fullBackupContent="@xml/full_backup_content">
+ android:dataExtractionRules="@xml/data_extraction_rules"
+ android:label="@string/app_name">
+ ...
+ </application>
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/xml/data_extraction_rules.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<data-extraction-rules>
+ <cloud-backup>
+ <include domain="file" path="dd"/>
+ <exclude domain="file" path="dd/fo3o.txt"/>
+ <exclude domain="file" path="dd/ss/foo.txt"/>
+ <exclude domain="sharedpref" path="foo.xml"/>
+ </cloud-backup>
+ <device-transfer>
+ <include domain="file"/>
+ <exclude domain="file" path="dd/fo3o.txt"/>
+ <include domain="sharedpref" path="something"/>
+ </device-transfer>
+</data-extraction-rules>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/xml/full_backup_content.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<full-backup-content>
+ <include domain="file" path="dd"/>
+ <exclude domain="file" path="dd/fo3o.txt"/>
+ <exclude domain="file" path="dd/ss/foo.txt"/>
+ <exclude domain="sharedpref" path="foo.xml"/>
+</full-backup-content>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/FullBackupContentDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="FullBackupContent"`
+ on the problematic XML element (or one of its enclosing elements).
+ You may also need to add the following namespace declaration on the
+ root element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="FullBackupContent" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'FullBackupContent'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore FullBackupContent ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/FullyQualifiedResource.md.html b/docs/checks/FullyQualifiedResource.md.html
new file mode 100644
index 00000000..a5de0f0d
--- /dev/null
+++ b/docs/checks/FullyQualifiedResource.md.html
@@ -0,0 +1,207 @@
+
+(#) Resources should use an import alias instead of being fully qualified
+
+!!! ERROR: Resources should use an import alias instead of being fully qualified
+ This is an error.
+
+Id
+: `FullyQualifiedResource`
+Summary
+: Resources should use an import alias instead of being fully qualified
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.1.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/resources/FullyQualifiedResourceDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/resources/FullyQualifiedResourceDetectorTest.kt)
+Copyright Year
+: 2022
+
+Resources should use an import alias instead of being fully qualified.
+For example:
+import slack.l10n.R as L10nR
+...
+...getString(L10nR.string.app_name)
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Options
+
+You can configure this lint checks using the following options:
+
+(###) import-aliases
+
+A comma-separated list of package name and their import aliases..
+This property should define a comma-separated list of package name and their import aliases in the format: packageName as importAlias
+
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="FullyQualifiedResource">
+ <option name="import-aliases" value="some string" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/slack/pkg/subpackage/MyClass.kt:6:Error: Use L10nR as an import
+alias instead [FullyQualifiedResource]
+ val appName = getString(slack.l10n.R.string.app_name)
+ ------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/slack/pkg/subpackage/MyClass.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package slack.pkg.subpackage
+
+class MyClass {
+
+ init {
+ val appName = getString(slack.l10n.R.string.app_name)
+ }
+
+ }
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/resources/FullyQualifiedResourceDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `FullyQualifiedResourceDetector.test failure no imports`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/slack-lints.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("FullyQualifiedResource")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("FullyQualifiedResource")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection FullyQualifiedResource
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="FullyQualifiedResource" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'FullyQualifiedResource'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore FullyQualifiedResource ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/GestureBackNavigation.md.html b/docs/checks/GestureBackNavigation.md.html
new file mode 100644
index 00000000..775d3a0d
--- /dev/null
+++ b/docs/checks/GestureBackNavigation.md.html
@@ -0,0 +1,177 @@
+
+(#) Usage of KeyEvent.KEYCODE_BACK
+
+!!! WARNING: Usage of KeyEvent.KEYCODE_BACK
+ This is a warning.
+
+Id
+: `GestureBackNavigation`
+Summary
+: Usage of KeyEvent.KEYCODE_BACK
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 7.4.0 (January 2023)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/guide/navigation/custom-back/predictive-back-gesture
+Implementation
+: [Source Code](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/GestureBackNavDetector.kt)
+Tests
+: [Source Code](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/GestureBackNavDetectorTest.kt)
+
+For apps targeting and running on Android 16+ (API 36+), predictive back
+animations are enabled by default. A back gesture does not trigger
+`{Activity,Dialog}.onBackPressed`, and does not dispatch
+`KeyEvent.KEYCODE_BACK`.
+
+Apps should migrate to AndroidX's backward compatible
+`OnBackPressedDispatcher`.
+
+This lint check does not consider per-activity opt-in/opt-out, so you
+may need to suppress or baseline reported incidents if migrating
+per-activity.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/KeyEventKeyCodeBackTest.java:17:Warning: onBackPressed is
+no longer called for back gestures; migrate to AndroidX's backward
+compatible OnBackPressedDispatcher [GestureBackNavigation]
+ public void onBackPressed() {
+ -------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="test.pkg">
+
+ <uses-sdk android:minSdkVersion="24" android:targetSdkVersion="35" />
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:enableOnBackInvokedCallback="true" >
+ <activity
+ android:name=".KeyEventKeyCodeBackTest"
+ android:label="@string/app_name"
+ android:exported="true" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/KeyEventKeyCodeBackTest.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.app.Activity;
+import android.content.Context;
+import android.view.KeyEvent;
+
+@SuppressWarnings("unused")
+public class KeyEventKeyCodeBackTest extends Activity {
+
+ public boolean onKeyUp(int keyCode, KeyEvent event) {
+ if (KeyEvent.KEYCODE_BACK == keyCode) {
+ return true;
+ }
+ }
+
+ @Override
+ public void onBackPressed() {
+ // handle back
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/GestureBackNavDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("GestureBackNavigation")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("GestureBackNavigation")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection GestureBackNavigation
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="GestureBackNavigation" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'GestureBackNavigation'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore GestureBackNavigation ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/GetContentDescriptionOverride.md.html b/docs/checks/GetContentDescriptionOverride.md.html
new file mode 100644
index 00000000..51630a32
--- /dev/null
+++ b/docs/checks/GetContentDescriptionOverride.md.html
@@ -0,0 +1,138 @@
+
+(#) Overriding `getContentDescription()` on a View
+
+!!! ERROR: Overriding `getContentDescription()` on a View
+ This is an error.
+
+Id
+: `GetContentDescriptionOverride`
+Summary
+: Overriding `getContentDescription()` on a View
+Severity
+: Error
+Category
+: Accessibility
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.0.0 (October 2017)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/GetContentDescriptionOverrideDetector.java)
+Tests
+: [Source Code](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/GetContentDescriptionOverrideDetectorTest.kt)
+
+Overriding `getContentDescription()` may prevent some accessibility
+services from properly navigating content exposed by your view. Instead,
+call `setContentDescription()` when the content description needs to be
+changed.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/MyView.java:13:Error: Overriding getContentDescription() on
+a View is not recommended [GetContentDescriptionOverride]
+ public CharSequence getContentDescription() {
+ ---------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/MyView.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.content.Context;
+import android.view.View;
+
+public class MyView extends View {
+
+ public MyView(Context context) {
+ super(context);
+ }
+
+ @Override
+ public CharSequence getContentDescription() {
+ return "";
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/GetContentDescriptionOverrideDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("GetContentDescriptionOverride")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("GetContentDescriptionOverride")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection GetContentDescriptionOverride
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="GetContentDescriptionOverride" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'GetContentDescriptionOverride'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore GetContentDescriptionOverride ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/GetInstance.md.html b/docs/checks/GetInstance.md.html
new file mode 100644
index 00000000..900f198f
--- /dev/null
+++ b/docs/checks/GetInstance.md.html
@@ -0,0 +1,141 @@
+
+(#) Cipher.getInstance with ECB
+
+!!! WARNING: Cipher.getInstance with ECB
+ This is a warning.
+
+Id
+: `GetInstance`
+Summary
+: Cipher.getInstance with ECB
+Severity
+: Warning
+Category
+: Security
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://goo.gle/GetInstance
+Implementation
+: [Source Code](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/CipherGetInstanceDetector.kt)
+Tests
+: [Source Code](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/CipherGetInstanceDetectorTest.kt)
+Copyright Year
+: 2014
+
+`Cipher#getInstance` should not be called with ECB as the cipher mode or
+without setting the cipher mode because the default mode on android is
+ECB, which is insecure.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/CipherGetInstanceAES.java:8:Warning: Cipher.getInstance
+should not be called without setting the encryption mode and padding
+[GetInstance]
+ Cipher.getInstance("AES");
+ -----
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/CipherGetInstanceAES.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import javax.crypto.Cipher;
+
+@SuppressWarnings({"ClassNameDiffersFromFileName", "MethodMayBeStatic"})
+public class CipherGetInstanceAES {
+ private void foo() throws Exception {
+ Cipher.getInstance("AES");
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/CipherGetInstanceDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `CipherGetInstanceDetector.testCipherGetInstanceAES`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("GetInstance")
+ fun method() {
+ getInstance(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("GetInstance")
+ void method() {
+ getInstance(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection GetInstance
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="GetInstance" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'GetInstance'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore GetInstance ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/GetLocales.md.html b/docs/checks/GetLocales.md.html
new file mode 100644
index 00000000..921679fc
--- /dev/null
+++ b/docs/checks/GetLocales.md.html
@@ -0,0 +1,158 @@
+
+(#) Locale crash
+
+!!! ERROR: Locale crash
+ This is an error.
+
+Id
+: `GetLocales`
+Summary
+: Locale crash
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.0.0 (October 2017)
+Affects
+: Kotlin and Java files, library bytecode and resource folders
+Editing
+: This check can *not* run live in the IDE editor
+Implementation
+: [Source Code](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/LocaleFolderDetector.java)
+Tests
+: [Source Code](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/LocaleFolderDetectorTest.kt)
+
+This check looks for usage of Lollipop-style locale folders (e.g. 3
+letter language codes, or BCP 47 qualifiers) combined with an
+`AssetManager#getLocales()` call. This leads to crashes.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/myapplication/MyLibrary.java:9:Error: The app will crash on
+platforms older than v21 (minSdkVersion is 18) because
+AssetManager#getLocales is called and it contains one or more v21-style
+(3-letter or BCP47 locale) folders: values-b+kok+IN, values-fil
+[GetLocales]
+ String[] locales = assets.getLocales();
+ -------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/test/pkg/myapplication/MyLibrary.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg.myapplication;
+
+import android.content.res.AssetManager;
+import android.content.res.Resources;
+
+public class MyLibrary {
+ public static void doSomething(Resources resources) {
+ AssetManager assets = resources.getAssets();
+ String[] locales = assets.getLocales();
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values-no/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<resources>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values-fil/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<resources>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values-b+kok+IN/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<resources>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/LocaleFolderDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `LocaleFolderDetector.testCrashApi19FromSource`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("GetLocales")
+ fun method() {
+ getLocales(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("GetLocales")
+ void method() {
+ getLocales(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection GetLocales
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="GetLocales" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'GetLocales'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore GetLocales ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/GifUsage.md.html b/docs/checks/GifUsage.md.html
new file mode 100644
index 00000000..3a66bea2
--- /dev/null
+++ b/docs/checks/GifUsage.md.html
@@ -0,0 +1,76 @@
+
+(#) Using `.gif` format for bitmaps is discouraged
+
+!!! WARNING: Using `.gif` format for bitmaps is discouraged
+ This is a warning.
+
+Id
+: `GifUsage`
+Summary
+: Using `.gif` format for bitmaps is discouraged
+Severity
+: Warning
+Category
+: Usability: Icons
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check can *not* run live in the IDE editor
+See
+: https://developer.android.com/guide/topics/resources/drawable-resource.html#Bitmap
+Implementation
+: [Source Code](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/IconDetector.java)
+Tests
+: [Source Code](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/IconDetectorTest.java)
+Copyright Year
+: 2011
+
+The `.gif` file format is discouraged. Consider using `.png` (preferred)
+or `.jpg` (acceptable) instead.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="GifUsage" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'GifUsage'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore GifUsage ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/GoogleAppIndexingApiWarning.md.html b/docs/checks/GoogleAppIndexingApiWarning.md.html
new file mode 100644
index 00000000..f79e86ea
--- /dev/null
+++ b/docs/checks/GoogleAppIndexingApiWarning.md.html
@@ -0,0 +1,8 @@
+
+(#) GoogleAppIndexingApiWarning
+
+The issue for this id has been deleted or marked obsolete and can now be
+ignored.
+
+(Additional metadata not available.)
+
\ No newline at end of file
diff --git a/docs/checks/GoogleAppIndexingWarning.md.html b/docs/checks/GoogleAppIndexingWarning.md.html
new file mode 100644
index 00000000..f819ebee
--- /dev/null
+++ b/docs/checks/GoogleAppIndexingWarning.md.html
@@ -0,0 +1,8 @@
+
+(#) GoogleAppIndexingWarning
+
+The issue for this id has been deleted or marked obsolete and can now be
+ignored.
+
+(Additional metadata not available.)
+
\ No newline at end of file
diff --git a/docs/checks/GradleCompatible.md.html b/docs/checks/GradleCompatible.md.html
new file mode 100644
index 00000000..9cbd894d
--- /dev/null
+++ b/docs/checks/GradleCompatible.md.html
@@ -0,0 +1,146 @@
+
+(#) Incompatible Gradle Versions
+
+!!! ERROR: Incompatible Gradle Versions
+ This is an error, and is also enforced at build time when
+ supported by the build system. For Android this means it will
+ run during release builds.
+
+Id
+: `GradleCompatible`
+Summary
+: Incompatible Gradle Versions
+Severity
+: Fatal
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Gradle build files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/GradleDetector.kt)
+Tests
+: [Source Code](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/GradleDetectorTest.kt)
+Copyright Year
+: 2014
+
+There are some combinations of libraries, or tools and libraries, that
+are incompatible, or can lead to bugs. One such incompatibility is
+compiling with a version of the Android support libraries that is not
+the latest version (or in particular, a version lower than your
+`targetSdkVersion`).
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+build.gradle:26:Error: Project depends on
+com.google.android.support:wearable:1.2.0, so it must also depend (as a
+provided dependency) on com.google.android.wearable:wearable:1.2.0
+[GradleCompatible]
+ compile 'com.google.android.support:wearable:1.2.0'
+ -----------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`build.gradle`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~groovy linenumbers
+apply plugin: 'android'
+
+android {
+ compileSdkVersion 36
+ buildToolsVersion "19.0.0"
+
+ defaultConfig {
+ minSdkVersion 7
+ targetSdkVersion 17
+ versionCode 1
+ versionName "1.0"
+ }
+
+ productFlavors {
+ free {
+ }
+ pro {
+ }
+ }
+}
+
+dependencies {
+ compile 'com.android.support:appcompat-v7:+'
+ freeCompile 'com.google.guava:guava:11.0.2'
+ compile 'com.android.support:appcompat-v7:13.0.0'
+ compile 'com.google.android.support:wearable:1.2.0'
+ compile 'com.android.support:multidex:1.0.0'
+
+ androidTestCompile 'com.android.support.test:runner:0.3'
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/GradleDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `GradleDetector.testBasic`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection GradleCompatible
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="GradleCompatible" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'GradleCompatible'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore GradleCompatible ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/GradleDependency.md.html b/docs/checks/GradleDependency.md.html
new file mode 100644
index 00000000..fd50c613
--- /dev/null
+++ b/docs/checks/GradleDependency.md.html
@@ -0,0 +1,161 @@
+
+(#) Obsolete Gradle Dependency
+
+!!! WARNING: Obsolete Gradle Dependency
+ This is a warning.
+
+Id
+: `GradleDependency`
+Summary
+: Obsolete Gradle Dependency
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Gradle build files and TOML files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/GradleDetector.kt)
+Tests
+: [Source Code](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/GradleDetectorTest.kt)
+Copyright Year
+: 2014
+
+This detector looks for usages of libraries where the version you are
+using is not the current stable release. Using older versions is fine,
+and there are cases where you deliberately want to stick with an older
+version. However, you may simply not be aware that a more recent version
+is available, and that is what this lint check helps find.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+build.gradle:24:Warning: A newer version of com.google.guava:guava than
+11.0.2 is available: 17.0 [GradleDependency]
+ freeCompile 'com.google.guava:guava:11.0.2'
+ -------------------------------
+build.gradle:25:Warning: A newer version of
+com.android.support:appcompat-v7 than 13.0.0 is available: 25.3.1
+[GradleDependency]
+ compile 'com.android.support:appcompat-v7:13.0.0'
+ -----------------------------------------
+build.gradle:26:Warning: A newer version of
+com.google.android.support:wearable than 1.2.0 is available: 1.3.0
+[GradleDependency]
+ compile 'com.google.android.support:wearable:1.2.0'
+ -------------------------------------------
+build.gradle:27:Warning: A newer version of com.android.support:multidex
+than 1.0.0 is available: 1.0.1 [GradleDependency]
+ compile 'com.android.support:multidex:1.0.0'
+ ------------------------------------
+build.gradle:29:Warning: A newer version of
+com.android.support.test:runner than 0.3 is available: 0.5
+[GradleDependency]
+ androidTestCompile 'com.android.support.test:runner:0.3'
+ -------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`build.gradle`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~groovy linenumbers
+apply plugin: 'android'
+
+android {
+ compileSdkVersion 36
+ buildToolsVersion "19.0.0"
+
+ defaultConfig {
+ minSdkVersion 7
+ targetSdkVersion 17
+ versionCode 1
+ versionName "1.0"
+ }
+
+ productFlavors {
+ free {
+ }
+ pro {
+ }
+ }
+}
+
+dependencies {
+ compile 'com.android.support:appcompat-v7:+'
+ freeCompile 'com.google.guava:guava:11.0.2'
+ compile 'com.android.support:appcompat-v7:13.0.0'
+ compile 'com.google.android.support:wearable:1.2.0'
+ compile 'com.android.support:multidex:1.0.0'
+
+ androidTestCompile 'com.android.support.test:runner:0.3'
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/GradleDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `GradleDetector.testBasic`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection GradleDependency
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="GradleDependency" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'GradleDependency'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore GradleDependency ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/GradleDeprecated.md.html b/docs/checks/GradleDeprecated.md.html
new file mode 100644
index 00000000..07964fc0
--- /dev/null
+++ b/docs/checks/GradleDeprecated.md.html
@@ -0,0 +1,139 @@
+
+(#) Deprecated Gradle Construct
+
+!!! WARNING: Deprecated Gradle Construct
+ This is a warning.
+
+Id
+: `GradleDeprecated`
+Summary
+: Deprecated Gradle Construct
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Gradle build files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/GradleDetector.kt)
+Tests
+: [Source Code](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/GradleDetectorTest.kt)
+Copyright Year
+: 2014
+
+This detector looks for deprecated Gradle constructs which currently
+work but will likely stop working in a future update.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+build.gradle:1:Warning: 'android' is deprecated; use
+'com.android.application' instead [GradleDeprecated]
+apply plugin: 'android'
+-----------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`build.gradle`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~groovy linenumbers
+apply plugin: 'android'
+
+android {
+ compileSdkVersion 36
+ buildToolsVersion "19.0.0"
+
+ defaultConfig {
+ minSdkVersion 7
+ targetSdkVersion 17
+ versionCode 1
+ versionName "1.0"
+ }
+
+ productFlavors {
+ free {
+ }
+ pro {
+ }
+ }
+}
+
+dependencies {
+ compile 'com.android.support:appcompat-v7:+'
+ freeCompile 'com.google.guava:guava:11.0.2'
+ compile 'com.android.support:appcompat-v7:13.0.0'
+ compile 'com.google.android.support:wearable:1.2.0'
+ compile 'com.android.support:multidex:1.0.0'
+
+ androidTestCompile 'com.android.support.test:runner:0.3'
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/GradleDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `GradleDetector.testBasic`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection GradleDeprecated
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="GradleDeprecated" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'GradleDeprecated'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore GradleDeprecated ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/GradleDeprecatedConfiguration.md.html b/docs/checks/GradleDeprecatedConfiguration.md.html
new file mode 100644
index 00000000..61a284c1
--- /dev/null
+++ b/docs/checks/GradleDeprecatedConfiguration.md.html
@@ -0,0 +1,129 @@
+
+(#) Deprecated Gradle Configuration
+
+!!! WARNING: Deprecated Gradle Configuration
+ This is a warning.
+
+Id
+: `GradleDeprecatedConfiguration`
+Summary
+: Deprecated Gradle Configuration
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.5.0 (August 2019)
+Affects
+: Gradle build files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://d.android.com/r/tools/update-dependency-configurations
+Implementation
+: [Source Code](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/GradleDetector.kt)
+Tests
+: [Source Code](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/GradleDetectorTest.kt)
+
+Some Gradle configurations have been deprecated since Android Gradle
+Plugin 3.0.0 and will be removed in a future version of the Android
+Gradle Plugin.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+build.gradle:9:Warning: compile is deprecated; replace with either api
+to maintain current behavior, or implementation to improve build
+performance by not sharing this dependency transitively.
+[GradleDeprecatedConfiguration]
+ compile 'androidx.appcompat:appcompat:1.0.0'
+ -------
+build.gradle:10:Warning: debugCompile is deprecated; replace with either
+debugApi to maintain current behavior, or debugImplementation to improve
+build performance by not sharing this dependency transitively.
+[GradleDeprecatedConfiguration]
+ debugCompile 'androidx.appcompat:appcompat:1.0.0'
+ ------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`build.gradle`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~groovy linenumbers
+buildscript {
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.0.0'
+ }
+}
+apply plugin: 'com.android.library'
+
+dependencies {
+ compile 'androidx.appcompat:appcompat:1.0.0'
+ debugCompile 'androidx.appcompat:appcompat:1.0.0'
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/GradleDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `GradleDetector.testCompileDeprecationInConsumableModule`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection GradleDeprecatedConfiguration
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="GradleDeprecatedConfiguration" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'GradleDeprecatedConfiguration'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore GradleDeprecatedConfiguration ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/GradleDynamicVersion.md.html b/docs/checks/GradleDynamicVersion.md.html
new file mode 100644
index 00000000..a590a600
--- /dev/null
+++ b/docs/checks/GradleDynamicVersion.md.html
@@ -0,0 +1,144 @@
+
+(#) Gradle Dynamic Version
+
+!!! WARNING: Gradle Dynamic Version
+ This is a warning.
+
+Id
+: `GradleDynamicVersion`
+Summary
+: Gradle Dynamic Version
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Gradle build files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/GradleDetector.kt)
+Tests
+: [Source Code](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/GradleDetectorTest.kt)
+Copyright Year
+: 2014
+
+Using `+` in dependencies lets you automatically pick up the latest
+available version rather than a specific, named version. However, this
+is not recommended; your builds are not repeatable; you may have tested
+with a slightly different version than what the build server used.
+(Using a dynamic version as the major version number is more problematic
+than using it in the minor version position.)
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+build.gradle:23:Warning: Avoid using + in version numbers; can lead to
+unpredictable and unrepeatable builds
+(com.android.support:appcompat-v7:+) [GradleDynamicVersion]
+ compile 'com.android.support:appcompat-v7:+'
+ ------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`build.gradle`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~groovy linenumbers
+apply plugin: 'android'
+
+android {
+ compileSdkVersion 36
+ buildToolsVersion "19.0.0"
+
+ defaultConfig {
+ minSdkVersion 7
+ targetSdkVersion 17
+ versionCode 1
+ versionName "1.0"
+ }
+
+ productFlavors {
+ free {
+ }
+ pro {
+ }
+ }
+}
+
+dependencies {
+ compile 'com.android.support:appcompat-v7:+'
+ freeCompile 'com.google.guava:guava:11.0.2'
+ compile 'com.android.support:appcompat-v7:13.0.0'
+ compile 'com.google.android.support:wearable:1.2.0'
+ compile 'com.android.support:multidex:1.0.0'
+
+ androidTestCompile 'com.android.support.test:runner:0.3'
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/GradleDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `GradleDetector.testBasic`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection GradleDynamicVersion
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="GradleDynamicVersion" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'GradleDynamicVersion'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore GradleDynamicVersion ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/GradleGetter.md.html b/docs/checks/GradleGetter.md.html
new file mode 100644
index 00000000..e92002d4
--- /dev/null
+++ b/docs/checks/GradleGetter.md.html
@@ -0,0 +1,145 @@
+
+(#) Gradle Implicit Getter Call
+
+!!! ERROR: Gradle Implicit Getter Call
+ This is an error.
+
+Id
+: `GradleGetter`
+Summary
+: Gradle Implicit Getter Call
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Gradle build files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/GradleDetector.kt)
+Tests
+: [Source Code](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/GradleDetectorTest.kt)
+Copyright Year
+: 2014
+
+Gradle will let you replace specific constants in your build scripts
+with method calls, so you can for example dynamically compute a version
+string based on your current version control revision number, rather
+than hardcoding a number.
+
+When computing a version name, it's tempting to for example call the
+method to do that `getVersionName`. However, when you put that method
+call inside the `defaultConfig` block, you will actually be calling the
+Groovy getter for the `versionName` property instead. Therefore, you
+need to name your method something which does not conflict with the
+existing implicit getters. Consider using `compute` as a prefix instead
+of `get`.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+build.gradle:18:Error: Bad method name: pick a unique method name which
+does not conflict with the implicit getters for the defaultConfig
+properties. For example, try using the prefix compute- instead of get-.
+[GradleGetter]
+ versionCode getVersionCode
+ --------------------------
+build.gradle:19:Error: Bad method name: pick a unique method name which
+does not conflict with the implicit getters for the defaultConfig
+properties. For example, try using the prefix compute- instead of get-.
+[GradleGetter]
+ versionName getVersionName
+ --------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`build.gradle`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~groovy linenumbers
+apply plugin: 'com.android.application'
+
+def getVersionName() {
+ "1.0"
+}
+
+def getVersionCode() {
+ 50
+}
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.0"
+
+ defaultConfig {
+ minSdkVersion 7
+ targetSdkVersion 17
+ versionCode getVersionCode
+ versionName getVersionName
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/GradleDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `GradleDetector.testSetter`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection GradleGetter
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="GradleGetter" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'GradleGetter'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore GradleGetter ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/GradleIdeError.md.html b/docs/checks/GradleIdeError.md.html
new file mode 100644
index 00000000..0ccec2a7
--- /dev/null
+++ b/docs/checks/GradleIdeError.md.html
@@ -0,0 +1,83 @@
+
+(#) Gradle IDE Support Issues
+
+!!! ERROR: Gradle IDE Support Issues
+ This is an error.
+
+Id
+: `GradleIdeError`
+Summary
+: Gradle IDE Support Issues
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Gradle build files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/GradleDetector.kt)
+Tests
+: [Source Code](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/GradleDetectorTest.kt)
+Copyright Year
+: 2014
+
+Gradle is highly flexible, and there are things you can do in Gradle
+files which can make it hard or impossible for IDEs to properly handle
+the project. This lint check looks for constructs that potentially break
+IDE support.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection GradleIdeError
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="GradleIdeError" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'GradleIdeError'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore GradleIdeError ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/GradleLikelyBug.md.html b/docs/checks/GradleLikelyBug.md.html
new file mode 100644
index 00000000..ff33a816
--- /dev/null
+++ b/docs/checks/GradleLikelyBug.md.html
@@ -0,0 +1,145 @@
+
+(#) Use of this API is likely a bug
+
+!!! ERROR: Use of this API is likely a bug
+ This is an error.
+
+Id
+: `GradleLikelyBug`
+Summary
+: Use of this API is likely a bug
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Identifier
+: androidx.lint:lint-gradle
+Feedback
+: https://issuetracker.google.com/issues/new?component=1147525
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.lint:lint-gradle](androidx_lint_lint-gradle.md.html)
+Since
+: 1.0.0-alpha04
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/lint/lint-gradle/src/main/java/androidx/lint/gradle/DiscouragedGradleMethodDetector.kt)
+Copyright Year
+: 2024
+
+Calling Provider.toString() will return you a generic hash of the
+instance of this provider.
+You most likely want to call Provider.get() method to get the actual
+value instead of the
+provider.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.lint:lint-gradle:1.0.0-alpha04")
+
+// build.gradle
+implementation 'androidx.lint:lint-gradle:1.0.0-alpha04'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.lint.gradle)
+
+# libs.versions.toml
+[versions]
+lint-gradle = "1.0.0-alpha04"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+lint-gradle = {
+ module = "androidx.lint:lint-gradle",
+ version.ref = "lint-gradle"
+}
+```
+
+1.0.0-alpha04 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.lint:lint-gradle](androidx_lint_lint-gradle.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("GradleLikelyBug")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("GradleLikelyBug")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection GradleLikelyBug
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="GradleLikelyBug" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'GradleLikelyBug'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore GradleLikelyBug ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/GradleOverrides.md.html b/docs/checks/GradleOverrides.md.html
new file mode 100644
index 00000000..ae52b8e3
--- /dev/null
+++ b/docs/checks/GradleOverrides.md.html
@@ -0,0 +1,131 @@
+
+(#) Value overridden by Gradle build script
+
+!!! WARNING: Value overridden by Gradle build script
+ This is a warning.
+
+Id
+: `GradleOverrides`
+Summary
+: Value overridden by Gradle build script
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/ManifestDetector.kt)
+Tests
+: [Source Code](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/ManifestDetectorTest.kt)
+Copyright Year
+: 2011
+
+The value of (for example) `minSdkVersion` is only used if it is not
+specified in the `build.gradle` build scripts. When specified in the
+Gradle build scripts, the manifest value is ignored and can be
+misleading, so should be removed to avoid ambiguity.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/main/AndroidManifest.xml:2:Warning: Cannot use placeholder for the
+package in the manifest; set applicationId in build.gradle instead
+[GradleOverrides]
+ package="${packageName}" >
+ ------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/main/AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="${packageName}" >
+ <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="17" />
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name" >
+ </application>
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`build.gradle`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~groovy linenumbers
+android {
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ManifestDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ManifestDetector.testManifestPackagePlaceholder`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="GradleOverrides"` on
+ the problematic XML element (or one of its enclosing elements). You
+ may also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <application tools:ignore="GradleOverrides" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="GradleOverrides" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'GradleOverrides'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore GradleOverrides ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/GradlePath.md.html b/docs/checks/GradlePath.md.html
new file mode 100644
index 00000000..c5e5b74c
--- /dev/null
+++ b/docs/checks/GradlePath.md.html
@@ -0,0 +1,123 @@
+
+(#) Gradle Path Issues
+
+!!! WARNING: Gradle Path Issues
+ This is a warning.
+
+Id
+: `GradlePath`
+Summary
+: Gradle Path Issues
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Gradle build files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/GradleDetector.kt)
+Tests
+: [Source Code](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/GradleDetectorTest.kt)
+Copyright Year
+: 2014
+
+Gradle build scripts are meant to be cross platform, so file paths use
+Unix-style path separators (a forward slash) rather than Windows path
+separators (a backslash). Similarly, to keep projects portable and
+repeatable, avoid using absolute paths on the system; keep files within
+the project instead. To share code between projects, consider creating
+an android-library and an AAR dependency.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+build.gradle:4:Warning: Do not use Windows file separators in .gradle
+files; use / instead [GradlePath]
+ compile files('my\\libs\\http.jar')
+ ---------------------------
+build.gradle:5:Warning: Avoid using absolute paths in .gradle files
+[GradlePath]
+ compile files('/libs/android-support-v4.jar')
+ -------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`build.gradle`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~groovy linenumbers
+apply plugin: 'com.android.application'
+
+dependencies {
+ compile files('my\\libs\\http.jar')
+ compile files('/libs/android-support-v4.jar')
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/GradleDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `GradleDetector.testPaths`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection GradlePath
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="GradlePath" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'GradlePath'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore GradlePath ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/GradlePluginVersion.md.html b/docs/checks/GradlePluginVersion.md.html
new file mode 100644
index 00000000..d7c50db1
--- /dev/null
+++ b/docs/checks/GradlePluginVersion.md.html
@@ -0,0 +1,124 @@
+
+(#) Incompatible Android Gradle Plugin
+
+!!! ERROR: Incompatible Android Gradle Plugin
+ This is an error.
+
+Id
+: `GradlePluginVersion`
+Summary
+: Incompatible Android Gradle Plugin
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 2.0.0 (April 2016)
+Affects
+: Gradle build files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/GradleDetector.kt)
+Tests
+: [Source Code](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/GradleDetectorTest.kt)
+
+Not all versions of the Android Gradle plugin are compatible with all
+versions of the SDK. If you update your tools, or if you are trying to
+open a project that was built with an old version of the tools, you may
+need to update your plugin version number.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+build.gradle:6:Error: You must use a newer version of the Android Gradle
+plugin. The minimum supported version is 3.2.0 and the recommended
+version is 7.0.3 [GradlePluginVersion]
+ classpath 'com.android.tools.build:gradle:0.1.0'
+ ------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`build.gradle`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~groovy linenumbers
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.1.0'
+ }
+}
+
+allprojects {
+ repositories {
+ mavenCentral()
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/GradleDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `GradleDetector.testIncompatiblePlugin`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection GradlePluginVersion
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="GradlePluginVersion" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'GradlePluginVersion'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore GradlePluginVersion ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/GradleProjectIsolation.md.html b/docs/checks/GradleProjectIsolation.md.html
new file mode 100644
index 00000000..4f53dc67
--- /dev/null
+++ b/docs/checks/GradleProjectIsolation.md.html
@@ -0,0 +1,146 @@
+
+(#) Avoid using APIs that are not project isolation safe
+
+!!! ERROR: Avoid using APIs that are not project isolation safe
+ This is an error.
+
+Id
+: `GradleProjectIsolation`
+Summary
+: Avoid using APIs that are not project isolation safe
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Identifier
+: androidx.lint:lint-gradle
+Feedback
+: https://issuetracker.google.com/issues/new?component=1147525
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.lint:lint-gradle](androidx_lint_lint-gradle.md.html)
+Since
+: 1.0.0-alpha02
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/lint/lint-gradle/src/main/java/androidx/lint/gradle/DiscouragedGradleMethodDetector.kt)
+Copyright Year
+: 2024
+
+Using APIs that reach out cross projects makes it not safe for Gradle
+project
+isolation.
+See https://docs.gradle.org/nightly/userguide/isolated_projects.html
+for
+more details.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.lint:lint-gradle:1.0.0-alpha04")
+
+// build.gradle
+implementation 'androidx.lint:lint-gradle:1.0.0-alpha04'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.lint.gradle)
+
+# libs.versions.toml
+[versions]
+lint-gradle = "1.0.0-alpha04"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+lint-gradle = {
+ module = "androidx.lint:lint-gradle",
+ version.ref = "lint-gradle"
+}
+```
+
+1.0.0-alpha04 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.lint:lint-gradle](androidx_lint_lint-gradle.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("GradleProjectIsolation")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("GradleProjectIsolation")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection GradleProjectIsolation
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="GradleProjectIsolation" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'GradleProjectIsolation'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore GradleProjectIsolation ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/GrantAllUris.md.html b/docs/checks/GrantAllUris.md.html
new file mode 100644
index 00000000..c55febe5
--- /dev/null
+++ b/docs/checks/GrantAllUris.md.html
@@ -0,0 +1,186 @@
+
+(#) Content provider shares everything
+
+!!! WARNING: Content provider shares everything
+ This is a warning.
+
+Id
+: `GrantAllUris`
+Summary
+: Content provider shares everything
+Severity
+: Warning
+Category
+: Security
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://goo.gle/GrantAllUris
+Implementation
+: [Source Code](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/SecurityDetector.java)
+Tests
+: [Source Code](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/SecurityDetectorTest.java)
+Copyright Year
+: 2011
+
+The `` element allows specific paths to be shared.
+This detector checks for a path URL of just '/' (everything), which is
+probably not what you want; you should limit access to a subset.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:25:Warning: Content provider shares everything; this
+is potentially dangerous [GrantAllUris]
+ <grant-uri-permission android:path="/"/>
+ ----------------
+AndroidManifest.xml:26:Warning: Content provider shares everything; this
+is potentially dangerous [GrantAllUris]
+ <grant-uri-permission android:pathPrefix="/"/>
+ ----------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="foo.bar2"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk android:minSdkVersion="14" />
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name" >
+ <activity
+ android:label="@string/app_name"
+ android:name=".Foo2Activity"
+ android:permission="Foo" >
+ <intent-filter >
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ <!-- good: -->
+ <grant-uri-permission android:pathPrefix="/all_downloads/"/>
+ <!-- bad: -->
+ <grant-uri-permission android:path="/"/>
+ <grant-uri-permission android:pathPrefix="/"/>
+ <grant-uri-permission android:pathPattern=".*"/>
+ </application>
+
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <!-- Home -->
+ <string name="home_title">Home Sample</string>
+ <string name="show_all_apps">All</string>
+
+ <!-- Home Menus -->
+ <string name="menu_wallpaper">Wallpaper</string>
+ <string name="menu_search">Search</string>
+ <string name="menu_settings">Settings</string>
+ <string name="sample" translatable="false">Ignore Me</string>
+
+ <!-- Wallpaper -->
+ <string name="wallpaper_instructions">Tap picture to set portrait wallpaper</string>
+</resources>
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/SecurityDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `SecurityDetector.testUri`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="GrantAllUris"` on
+ the problematic XML element (or one of its enclosing elements). You
+ may also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <service tools:ignore="GrantAllUris" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="GrantAllUris" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'GrantAllUris'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore GrantAllUris ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/GridLayout.md.html b/docs/checks/GridLayout.md.html
new file mode 100644
index 00000000..087eee4b
--- /dev/null
+++ b/docs/checks/GridLayout.md.html
@@ -0,0 +1,160 @@
+
+(#) GridLayout validation
+
+!!! ERROR: GridLayout validation
+ This is an error, and is also enforced at build time when
+ supported by the build system. For Android this means it will
+ run during release builds.
+
+Id
+: `GridLayout`
+Summary
+: GridLayout validation
+Severity
+: Fatal
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/GridLayoutDetector.java)
+Tests
+: [Source Code](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/GridLayoutDetectorTest.java)
+Copyright Year
+: 2011
+
+Declaring a layout_row or layout_column that falls outside the declared
+size of a GridLayout's `rowCount` or `columnCount` is usually an
+unintentional error.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/gridlayout.xml:36:Error: Column attribute (3) exceeds
+declared grid column count (2) [GridLayout]
+ android:layout_column="3"
+ -------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/layout/gridlayout.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<GridLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:columnCount="2" >
+ <Space
+ android:layout_row="0"
+ android:layout_column="0"
+ android:layout_width="109dip"
+ android:layout_height="108dip"/>
+
+ <Button
+ android:text="Button 1"
+ android:layout_row="0"
+ android:layout_column="1"
+ />
+
+ <Button
+ android:text="Button 2"
+ android:layout_row="1"
+ android:layout_column="3"
+ />
+
+</GridLayout>
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/GridLayoutDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `GridLayoutDetector.testGridLayout1`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="GridLayout"` on the
+ problematic XML element (or one of its enclosing elements). You may
+ also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <GridLayout xmlns:tools="http://schemas.android.com/tools"
+ tools:ignore="GridLayout" ...>
+ ...
+ </GridLayout>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="GridLayout" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'GridLayout'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore GridLayout ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/GuavaChecksUsed.md.html b/docs/checks/GuavaChecksUsed.md.html
new file mode 100644
index 00000000..c081c084
--- /dev/null
+++ b/docs/checks/GuavaChecksUsed.md.html
@@ -0,0 +1,206 @@
+
+(#) Use Slack's JavaPreconditions instead of Guava's Preconditions checks
+
+!!! ERROR: Use Slack's JavaPreconditions instead of Guava's Preconditions checks
+ This is an error.
+
+Id
+: `GuavaChecksUsed`
+Summary
+: Use Slack's JavaPreconditions instead of Guava's Preconditions checks
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.1.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/GuavaPreconditionsDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/GuavaPreconditionsDetectorTest.kt)
+Copyright Year
+: 2021
+
+Precondition checks in Java should use Slack's internal
+`JavaPreconditions.kt` instead of Guava's Preconditions.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/foo/Foo.java:7:Error: Use Slack's JavaPreconditions instead of
+Guava's Preconditions checks [GuavaChecksUsed]
+ boolean isTrue = Preconditions.checkState(1 == 1);
+ ----------
+src/foo/Foo.java:10:Error: Use Slack's JavaPreconditions instead of
+Guava's Preconditions checks [GuavaChecksUsed]
+ Preconditions.checkState(1 == 1);
+ ----------
+src/foo/Foo.java:11:Error: Use Slack's JavaPreconditions instead of
+Guava's Preconditions checks [GuavaChecksUsed]
+ Preconditions.checkArgument(1 == 1);
+ -------------
+src/foo/Foo.java:12:Error: Use Slack's JavaPreconditions instead of
+Guava's Preconditions checks [GuavaChecksUsed]
+ Preconditions.checkNotNull("Hello");
+ ------------
+src/foo/Foo.java:13:Error: Use Slack's JavaPreconditions instead of
+Guava's Preconditions checks [GuavaChecksUsed]
+ Preconditions.checkElementIndex(0, 1);
+ -----------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/foo/Foo.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package foo;
+
+import com.google.common.base.Preconditions;
+
+public class Foo {
+
+ boolean isTrue = Preconditions.checkState(1 == 1);
+
+ void act() {
+ Preconditions.checkState(1 == 1);
+ Preconditions.checkArgument(1 == 1);
+ Preconditions.checkNotNull("Hello");
+ Preconditions.checkElementIndex(0, 1);
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/GuavaPreconditionsDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `GuavaPreconditionsDetector.Java - Using Guava Preconditions with static reference will show warnings`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/slack-lints.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("GuavaChecksUsed")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("GuavaChecksUsed")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection GuavaChecksUsed
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="GuavaChecksUsed" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'GuavaChecksUsed'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore GuavaChecksUsed ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/GuavaPreconditionsUsedInKotlin.md.html b/docs/checks/GuavaPreconditionsUsedInKotlin.md.html
new file mode 100644
index 00000000..2d6b3981
--- /dev/null
+++ b/docs/checks/GuavaPreconditionsUsedInKotlin.md.html
@@ -0,0 +1,207 @@
+
+(#) Kotlin precondition checks should use the Kotlin standard library checks
+
+!!! ERROR: Kotlin precondition checks should use the Kotlin standard library checks
+ This is an error.
+
+Id
+: `GuavaPreconditionsUsedInKotlin`
+Summary
+: Kotlin precondition checks should use the Kotlin standard library checks
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.1.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/GuavaPreconditionsDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/GuavaPreconditionsDetectorTest.kt)
+Copyright Year
+: 2021
+
+All Kotlin classes that require precondition checks should use the
+ preconditions checks that are available in the Kotlin standard library
+in Preconditions.kt.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/foo/Foo.kt:7:Error: Kotlin precondition checks should use the Kotlin
+standard library checks [GuavaPreconditionsUsedInKotlin]
+ val isTrue = Preconditions.checkState(false)
+ ----------
+src/foo/Foo.kt:10:Error: Kotlin precondition checks should use the
+Kotlin standard library checks [GuavaPreconditionsUsedInKotlin]
+ Preconditions.checkState(true)
+ ----------
+src/foo/Foo.kt:11:Error: Kotlin precondition checks should use the
+Kotlin standard library checks [GuavaPreconditionsUsedInKotlin]
+ Preconditions.checkArgument(false)
+ -------------
+src/foo/Foo.kt:12:Error: Kotlin precondition checks should use the
+Kotlin standard library checks [GuavaPreconditionsUsedInKotlin]
+ Preconditions.checkNotNull("Hello")
+ ------------
+src/foo/Foo.kt:13:Error: Kotlin precondition checks should use the
+Kotlin standard library checks [GuavaPreconditionsUsedInKotlin]
+ Preconditions.checkElementIndex(0, 1)
+ -----------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/foo/Foo.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package foo
+
+import com.google.common.base.Preconditions
+
+class Foo {
+
+ val isTrue = Preconditions.checkState(false)
+
+ fun act() {
+ Preconditions.checkState(true)
+ Preconditions.checkArgument(false)
+ Preconditions.checkNotNull("Hello")
+ Preconditions.checkElementIndex(0, 1)
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/GuavaPreconditionsDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `GuavaPreconditionsDetector.Kotlin - Using Guava Preconditions with static reference will show warnings`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/slack-lints.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("GuavaPreconditionsUsedInKotlin")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("GuavaPreconditionsUsedInKotlin")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection GuavaPreconditionsUsedInKotlin
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="GuavaPreconditionsUsedInKotlin" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'GuavaPreconditionsUsedInKotlin'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore GuavaPreconditionsUsedInKotlin ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/HalfFloat.md.html b/docs/checks/HalfFloat.md.html
new file mode 100644
index 00000000..71dd6cb7
--- /dev/null
+++ b/docs/checks/HalfFloat.md.html
@@ -0,0 +1,217 @@
+
+(#) Incorrect Half Float
+
+!!! ERROR: Incorrect Half Float
+ This is an error.
+
+Id
+: `HalfFloat`
+Summary
+: Incorrect Half Float
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.1.0 (March 2018)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/ResourceTypeDetector.kt)
+Tests
+: [Source Code](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/ResourceTypeDetectorTest.kt)
+
+Half-precision floating point are stored in a short data type, and
+should be manipulated using the `android.util.Half` class. This check
+flags usages where it appears that these values are used incorrectly.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/HalfFloatTest.java:23:Error: Expected a half float here,
+not a resource id [HalfFloat]
+ method1(getDimension1()); // ERROR
+ ---------------
+src/test/pkg/HalfFloatTest.java:24:Error: Expected a half float here,
+not a dimension [HalfFloat]
+ method1(getDimension2()); // ERROR
+ ---------------
+src/test/pkg/HalfFloatTest.java:25:Error: Expected a half float here,
+not a color [HalfFloat]
+ method1(getActualColor()); // ERROR
+ ----------------
+src/test/pkg/HalfFloatTest.java:26:Error: Expected a half float here,
+not a resource id [HalfFloat]
+ method1(getTextId()); // ERROR
+ -----------
+src/test/pkg/HalfFloatTest.java:43:Error: Half-float type in expression
+widened to int [HalfFloat]
+ int result3 = float1 + 1; // error: widening
+ ------
+src/test/pkg/HalfFloatTest.java:44:Error: Half-float type in expression
+widened to int [HalfFloat]
+ boolean result4 = float1 + 1 > 5; // error: widening
+ ------
+src/test/pkg/HalfFloatTest.java:50:Error: Half-float type in expression
+widened to int [HalfFloat]
+ Math.round(float1); // Error: should use Half.round
+ ------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/HalfFloatTest.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+
+import androidx.annotation.ColorInt;
+import androidx.annotation.DimenRes;
+import androidx.annotation.HalfFloat;
+import androidx.annotation.Px;
+import androidx.annotation.StringRes;
+
+@SuppressWarnings({"UnnecessaryLocalVariable", "ResultOfMethodCallIgnored", "WeakerAccess"})
+public class HalfFloatTest {
+ public void method1(@HalfFloat short foo) {
+ }
+
+ @HalfFloat
+ public short method2() {
+ }
+
+ public void testHalfFloat() {
+ int myFloat = method2(); // WARN: widening
+ short myFloat2 = method2();
+ boolean x1 = myFloat2 != 0; // implicit conversion
+ method1(getDimension1()); // ERROR
+ method1(getDimension2()); // ERROR
+ method1(getActualColor()); // ERROR
+ method1(getTextId()); // ERROR
+ }
+
+ public void testConstants() {
+ // TODO: Look for constant usages
+ }
+
+ public void testOperations(@HalfFloat short float1, short float2) {
+ boolean x1 = float1 < float2;
+ boolean x2 = float2 > float1;
+ // because implicit promotions to int
+ }
+
+ public void testWidening(@HalfFloat short float1, short float2) {
+ short result1 = float1; // ok
+ int result2 = float2; // error: widening
+ Math.abs(float2); // error: widening
+ int result3 = float1 + 1; // error: widening
+ boolean result4 = float1 + 1 > 5; // error: widening
+ byte b = 1;
+ method1(b); // ERROR: widening
+ }
+
+ public void testWrongMethod(@HalfFloat short float1) {
+ Math.round(float1); // Error: should use Half.round
+ }
+
+
+ @DimenRes
+ public abstract int getDimension1();
+ @ColorInt
+ public abstract int getActualColor();
+ @StringRes
+ public abstract int getTextId();
+ public abstract void setDimension1(@DimenRes int dimension);
+ @Px
+ public abstract int getDimension2();
+ public abstract void setDimension2(@Px int dimension);
+
+ // TODO: Arrays
+ // TODO: Add cast
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ResourceTypeDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ResourceTypeDetector.testHalfFloats`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("HalfFloat")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("HalfFloat")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection HalfFloat
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="HalfFloat" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'HalfFloat'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore HalfFloat ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/HandlerLeak.md.html b/docs/checks/HandlerLeak.md.html
new file mode 100644
index 00000000..190d1fd8
--- /dev/null
+++ b/docs/checks/HandlerLeak.md.html
@@ -0,0 +1,181 @@
+
+(#) Handler reference leaks
+
+!!! WARNING: Handler reference leaks
+ This is a warning.
+
+Id
+: `HandlerLeak`
+Summary
+: Handler reference leaks
+Severity
+: Warning
+Category
+: Performance
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/HandlerDetector.java)
+Tests
+: [Source Code](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/HandlerDetectorTest.java)
+Copyright Year
+: 2012
+
+Since this Handler is declared as an inner class, it may prevent the
+outer class from being garbage collected. If the Handler is using a
+`Looper` or `MessageQueue` for a thread other than the main thread, then
+there is no issue. If the `Handler` is using the `Looper` or
+`MessageQueue` of the main thread, you need to fix your `Handler`
+declaration, as follows: Declare the `Handler` as a static class; In the
+outer class, instantiate a `WeakReference` to the outer class and pass
+this object to your `Handler` when you instantiate the `Handler`; Make
+all references to members of the outer class using the `WeakReference`
+object.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/HandlerTest.java:12:Warning: This Handler class should be
+static or leaks might occur (test.pkg.HandlerTest.Inner) [HandlerLeak]
+ public class Inner extends Handler { // ERROR
+ -----
+src/test/pkg/HandlerTest.java:18:Warning: This Handler class should be
+static or leaks might occur (anonymous android.os.Handler)
+[HandlerLeak]
+ Handler anonymous = new Handler() { // ERROR
+ ^
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/HandlerTest.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+import android.os.Looper;
+import android.os.Handler;
+import android.os.Message;
+
+public class HandlerTest extends Handler { // OK
+ public static class StaticInner extends Handler { // OK
+ public void dispatchMessage(Message msg) {
+ super.dispatchMessage(msg);
+ }
+ }
+ public class Inner extends Handler { // ERROR
+ public void dispatchMessage(Message msg) {
+ super.dispatchMessage(msg);
+ }
+ }
+ void method() {
+ Handler anonymous = new Handler() { // ERROR
+ public void dispatchMessage(Message msg) {
+ super.dispatchMessage(msg);
+ }
+ };
+
+ Looper looper = null;
+ Handler anonymous2 = new Handler(looper) { // OK
+ public void dispatchMessage(Message msg) {
+ super.dispatchMessage(msg);
+ }
+ };
+ }
+
+ public class WithArbitraryLooper extends Handler {
+ public WithArbitraryLooper(String unused, Looper looper) { // OK
+ super(looper, null);
+ }
+
+ public void dispatchMessage(Message msg) {
+ super.dispatchMessage(msg);
+ }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/HandlerDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `HandlerDetector.testRegistered`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("HandlerLeak")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("HandlerLeak")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection HandlerLeak
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="HandlerLeak" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'HandlerLeak'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore HandlerLeak ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/HardcodedDebugMode.md.html b/docs/checks/HardcodedDebugMode.md.html
new file mode 100644
index 00000000..72ef6098
--- /dev/null
+++ b/docs/checks/HardcodedDebugMode.md.html
@@ -0,0 +1,141 @@
+
+(#) Hardcoded value of `android:debuggable` in the manifest
+
+!!! ERROR: Hardcoded value of `android:debuggable` in the manifest
+ This is an error, and is also enforced at build time when
+ supported by the build system. For Android this means it will
+ run during release builds.
+
+Id
+: `HardcodedDebugMode`
+Summary
+: Hardcoded value of `android:debuggable` in the manifest
+Severity
+: Fatal
+Category
+: Security
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://goo.gle/HardcodedDebugMode
+Implementation
+: [Source Code](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/HardcodedDebugModeDetector.java)
+Tests
+: [Source Code](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/HardcodedDebugModeDetectorTest.kt)
+Copyright Year
+: 2012
+
+It's best to leave out the `android:debuggable` attribute from the
+manifest. If you do, then the tools will automatically insert
+`android:debuggable=true` when building an APK to debug on an emulator
+or device. And when you perform a release build, such as Exporting APK,
+it will automatically set it to `false`.
+
+If on the other hand you specify a specific value in the manifest file,
+then the tools will always use it. This can lead to accidentally
+publishing your app with debug information.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:10:Error: Avoid hardcoding the debug mode; leaving
+it out allows debug and release builds to automatically assign one
+[HardcodedDebugMode]
+ android:debuggable="true"
+ -------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="foo.bar2"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk android:minSdkVersion="14" />
+
+ <application
+ android:debuggable="true"
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name" >
+ <activity
+ android:label="@string/app_name"
+ android:name=".Foo2Activity" >
+ <intent-filter >
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/HardcodedDebugModeDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `HardcodedDebugModeDetector.test`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="HardcodedDebugMode"`
+ on the problematic XML element (or one of its enclosing elements).
+ You may also need to add the following namespace declaration on the
+ root element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="HardcodedDebugMode" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'HardcodedDebugMode'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore HardcodedDebugMode ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/HardcodedText.md.html b/docs/checks/HardcodedText.md.html
new file mode 100644
index 00000000..658156ff
--- /dev/null
+++ b/docs/checks/HardcodedText.md.html
@@ -0,0 +1,127 @@
+
+(#) Hardcoded text
+
+!!! WARNING: Hardcoded text
+ This is a warning.
+
+Id
+: `HardcodedText`
+Summary
+: Hardcoded text
+Severity
+: Warning
+Category
+: Internationalization
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/HardcodedValuesDetector.kt)
+Tests
+: [Source Code](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/HardcodedValuesDetectorTest.kt)
+Copyright Year
+: 2011
+
+Hardcoding text attributes directly in layout files is bad for several
+reasons:
+
+* When creating configuration variations (for example for landscape or
+ portrait) you have to repeat the actual text (and keep it up to date
+ when making changes)
+
+* The application cannot be translated to other languages by just adding
+ new translations for existing string resources.
+
+There are quickfixes to automatically extract this hardcoded string into
+a resource lookup.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/accessibility.xml:2:Warning: Hardcoded string "Button",
+should use @string resource [HardcodedText]
+ <Button android:text="Button" android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
+ ---------------------
+res/layout/accessibility.xml:5:Warning: Hardcoded string "Button",
+should use @string resource [HardcodedText]
+ <Button android:text="Button" android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
+ ---------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/layout/accessibility.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/newlinear" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent">
+ <Button android:text="Button" android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
+ <ImageView android:id="@+id/android_logo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="http://github.com/@drawable/android_button" android:focusable="false" android:clickable="false" android:layout_weight="1.0" />
+ <ImageButton android:importantForAccessibility="yes" android:id="@+id/android_logo2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="http://github.com/@drawable/android_button" android:focusable="false" android:clickable="false" android:layout_weight="1.0" />
+ <Button android:text="Button" android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
+ <Button android:id="@+android:id/summary" android:contentDescription="@string/label" />
+ <ImageButton android:importantForAccessibility="no" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="http://github.com/@drawable/android_button" android:focusable="false" android:clickable="false" android:layout_weight="1.0" />
+</LinearLayout>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/HardcodedValuesDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `HardcodedValuesDetector.testStrings`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="HardcodedText"` on
+ the problematic XML element (or one of its enclosing elements). You
+ may also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="HardcodedText" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'HardcodedText'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore HardcodedText ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/HardwareIds.md.html b/docs/checks/HardwareIds.md.html
new file mode 100644
index 00000000..7afef299
--- /dev/null
+++ b/docs/checks/HardwareIds.md.html
@@ -0,0 +1,139 @@
+
+(#) Hardware Id Usage
+
+!!! WARNING: Hardware Id Usage
+ This is a warning.
+
+Id
+: `HardwareIds`
+Summary
+: Hardware Id Usage
+Severity
+: Warning
+Category
+: Security
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 2.2.0 (September 2016)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/training/articles/user-data-ids.html
+Implementation
+: [Source Code](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/HardwareIdDetector.java)
+Tests
+: [Source Code](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/HardwareIdDetectorTest.kt)
+
+Using these device identifiers is not recommended other than for high
+value fraud prevention and advanced telephony use-cases. For advertising
+use-cases, use `AdvertisingIdClient$Info#getId` and for analytics, use
+`InstanceId#getId`.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/AppUtils.java:8:Warning: Using getAddress to get device
+identifiers is not recommended [HardwareIds]
+ return adapter.getAddress();
+ --------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/AppUtils.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.bluetooth.BluetoothAdapter;
+
+public class AppUtils {
+ public String getBAddress() {
+ BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+ return adapter.getAddress();
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/HardwareIdDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `HardwareIdDetector.testBluetoothAdapterGetAddressCall`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("HardwareIds")
+ fun method() {
+ getAddress(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("HardwareIds")
+ void method() {
+ getAddress(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection HardwareIds
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="HardwareIds" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'HardwareIds'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore HardwareIds ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/HighAppVersionCode.md.html b/docs/checks/HighAppVersionCode.md.html
new file mode 100644
index 00000000..6247c792
--- /dev/null
+++ b/docs/checks/HighAppVersionCode.md.html
@@ -0,0 +1,115 @@
+
+(#) VersionCode too high
+
+!!! ERROR: VersionCode too high
+ This is an error.
+
+Id
+: `HighAppVersionCode`
+Summary
+: VersionCode too high
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 2.3.0 (March 2017)
+Affects
+: Gradle build files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/studio/publish/versioning.html
+Implementation
+: [Source Code](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/GradleDetector.kt)
+Tests
+: [Source Code](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/GradleDetectorTest.kt)
+
+The declared `versionCode` is an Integer. Ensure that the version number
+is not close to the limit. It is recommended to monotonically increase
+this number each minor or major release of the app. Note that updating
+an app with a versionCode over `Integer.MAX_VALUE` is not possible.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+build.gradle:5:Error: The 'versionCode' is very high and close to the
+max allowed value [HighAppVersionCode]
+ versionCode 2146435071
+ ----------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`build.gradle`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~groovy linenumbers
+apply plugin: 'com.android.application'
+
+android {
+ defaultConfig {
+ versionCode 2146435071
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/GradleDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `GradleDetector.testHighAppVersionCode`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection HighAppVersionCode
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="HighAppVersionCode" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'HighAppVersionCode'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore HighAppVersionCode ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/HighSamplingRate.md.html b/docs/checks/HighSamplingRate.md.html
new file mode 100644
index 00000000..da7c449f
--- /dev/null
+++ b/docs/checks/HighSamplingRate.md.html
@@ -0,0 +1,124 @@
+
+(#) High sensor sampling rate
+
+!!! WARNING: High sensor sampling rate
+ This is a warning.
+
+Id
+: `HighSamplingRate`
+Summary
+: High sensor sampling rate
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 7.0.0 (July 2021)
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/HighSensorSamplingRateDetector.kt)
+Tests
+: [Source Code](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/HighSensorSamplingRateDetectorTest.kt)
+
+Most apps don't need access to high sensor sampling rate. Double check
+your use case to ensure your app absolutely needs access to sensor
+sampling rate > 200Hz. Be prepared for your app to be rejected from
+listing on Play Store until your use case for high sensor sampling rate
+has been reviewed and validated by the policy team.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:4:Warning: Most apps don't need access to high
+sensor sampling rate. [HighSamplingRate]
+ <uses-permission android:name="android.permission.HIGH_SAMPLING_RATE_SENSORS"/>
+ ---------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="test.pkg">
+
+ <uses-permission android:name="android.permission.HIGH_SAMPLING_RATE_SENSORS"/>
+
+ <uses-sdk android:minSdkVersion="31" />
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name" >
+ <receiver android:name="com.google.android.c2dm.C2DMBroadcastReceiver">
+ </receiver>
+ </application>
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/HighSensorSamplingRateDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="HighSamplingRate"`
+ on the problematic XML element (or one of its enclosing elements).
+ You may also need to add the following namespace declaration on the
+ root element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <uses-permission tools:ignore="HighSamplingRate" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="HighSamplingRate" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'HighSamplingRate'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore HighSamplingRate ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/IconColors.md.html b/docs/checks/IconColors.md.html
new file mode 100644
index 00000000..7b47d8fc
--- /dev/null
+++ b/docs/checks/IconColors.md.html
@@ -0,0 +1,122 @@
+
+(#) Icon colors do not follow the recommended visual style
+
+!!! WARNING: Icon colors do not follow the recommended visual style
+ This is a warning.
+
+Id
+: `IconColors`
+Summary
+: Icon colors do not follow the recommended visual style
+Severity
+: Warning
+Category
+: Usability: Icons
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Kotlin and Java files, manifest files and resource files
+Editing
+: This check can *not* run live in the IDE editor
+Implementation
+: [Source Code](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/IconDetector.java)
+Tests
+: [Source Code](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/IconDetectorTest.java)
+Copyright Year
+: 2011
+
+Notification icons and Action Bar icons should only white and shades of
+gray. See the Android Design Guide for more details. Note that the way
+Lint decides whether an icon is an action bar icon or a notification
+icon is based on the filename prefix: `ic_menu_` for action bar icons,
+`ic_stat_` for notification icons etc. These correspond to the naming
+conventions documented in
+https://d.android.com/r/studio-ui/designer/material/iconography.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("IconColors")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("IconColors")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection IconColors
+ problematicStatement()
+ ```
+
+* Adding the suppression attribute `tools:ignore="IconColors"` on the
+ problematic XML element (or one of its enclosing elements). You may
+ also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <application tools:ignore="IconColors" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="IconColors" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'IconColors'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore IconColors ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/IconDensities.md.html b/docs/checks/IconDensities.md.html
new file mode 100644
index 00000000..facd0e32
--- /dev/null
+++ b/docs/checks/IconDensities.md.html
@@ -0,0 +1,83 @@
+
+(#) Icon densities validation
+
+!!! WARNING: Icon densities validation
+ This is a warning.
+
+Id
+: `IconDensities`
+Summary
+: Icon densities validation
+Severity
+: Warning
+Category
+: Usability: Icons
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check can *not* run live in the IDE editor
+See
+: https://developer.android.com/guide/practices/screens_support.html
+Implementation
+: [Source Code](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/IconDetector.java)
+Tests
+: [Source Code](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/IconDetectorTest.java)
+Copyright Year
+: 2011
+
+Icons will look best if a custom version is provided for each of the
+major screen density classes (low, medium, high, extra high). This lint
+check identifies icons which do not have complete coverage across the
+densities.
+
+Low density is not really used much anymore, so this check ignores the
+ldpi density. To force lint to include it, set the environment variable
+`ANDROID_LINT_INCLUDE_LDPI=true`. For more information on current
+density usage, see https://developer.android.com/about/dashboards.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="IconDensities" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'IconDensities'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore IconDensities ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/IconDipSize.md.html b/docs/checks/IconDipSize.md.html
new file mode 100644
index 00000000..b890d181
--- /dev/null
+++ b/docs/checks/IconDipSize.md.html
@@ -0,0 +1,104 @@
+
+(#) Icon density-independent size validation
+
+!!! WARNING: Icon density-independent size validation
+ This is a warning.
+
+Id
+: `IconDipSize`
+Summary
+: Icon density-independent size validation
+Severity
+: Warning
+Category
+: Usability: Icons
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check can *not* run live in the IDE editor
+Implementation
+: [Source Code](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/IconDetector.java)
+Tests
+: [Source Code](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/IconDetectorTest.java)
+Copyright Year
+: 2011
+
+Checks the all icons which are provided in multiple densities, all
+compute to roughly the same density-independent pixel (`dip`) size. This
+catches errors where images are either placed in the wrong folder, or
+icons are changed to new sizes but some folders are forgotten.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/drawable-mdpi/my_lossy_72dp.webp:Warning: Suspicious file name
+my_lossy_72dp.webp: The implied 72 dp size does not match the actual dp
+size (pixel size 58×56 in a drawable-mdpi folder computes to 58×56 dp)
+[IconDipSize]
+0 errors, 3 warnings
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant test files:
+
+
+
+
+
+
+
+You can also visit the
+[source code](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/IconDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `IconDetector.testClaimedSizeWebp`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="IconDipSize" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'IconDipSize'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore IconDipSize ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/IconDuplicates.md.html b/docs/checks/IconDuplicates.md.html
new file mode 100644
index 00000000..f950ceb1
--- /dev/null
+++ b/docs/checks/IconDuplicates.md.html
@@ -0,0 +1,77 @@
+
+(#) Duplicated icons under different names
+
+!!! WARNING: Duplicated icons under different names
+ This is a warning.
+
+Id
+: `IconDuplicates`
+Summary
+: Duplicated icons under different names
+Severity
+: Warning
+Category
+: Usability: Icons
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check can *not* run live in the IDE editor
+Implementation
+: [Source Code](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/IconDetector.java)
+Tests
+: [Source Code](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/IconDetectorTest.java)
+Copyright Year
+: 2011
+
+If an icon is repeated under different names, you can consolidate and
+just use one of the icons and delete the others to make your application
+smaller. However, duplicated icons usually are not intentional and can
+sometimes point to icons that were accidentally overwritten or
+accidentally not updated.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="IconDuplicates" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'IconDuplicates'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore IconDuplicates ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/IconDuplicatesConfig.md.html b/docs/checks/IconDuplicatesConfig.md.html
new file mode 100644
index 00000000..5c6c827a
--- /dev/null
+++ b/docs/checks/IconDuplicatesConfig.md.html
@@ -0,0 +1,76 @@
+
+(#) Identical bitmaps across various configurations
+
+!!! WARNING: Identical bitmaps across various configurations
+ This is a warning.
+
+Id
+: `IconDuplicatesConfig`
+Summary
+: Identical bitmaps across various configurations
+Severity
+: Warning
+Category
+: Usability: Icons
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check can *not* run live in the IDE editor
+Implementation
+: [Source Code](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/IconDetector.java)
+Tests
+: [Source Code](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/IconDetectorTest.java)
+Copyright Year
+: 2011
+
+If an icon is provided under different configuration parameters such as
+`drawable-hdpi` or `-v11`, they should typically be different. This
+detector catches cases where the same icon is provided in different
+configuration folder which is usually not intentional.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="IconDuplicatesConfig" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'IconDuplicatesConfig'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore IconDuplicatesConfig ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/IconExpectedSize.md.html b/docs/checks/IconExpectedSize.md.html
new file mode 100644
index 00000000..fcf32040
--- /dev/null
+++ b/docs/checks/IconExpectedSize.md.html
@@ -0,0 +1,122 @@
+
+(#) Icon has incorrect size
+
+!!! WARNING: Icon has incorrect size
+ This is a warning.
+
+Id
+: `IconExpectedSize`
+Summary
+: Icon has incorrect size
+Note
+: **This issue is disabled by default**; use `--enable IconExpectedSize`
+Severity
+: Warning
+Category
+: Usability: Icons
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Kotlin and Java files, manifest files and resource files
+Editing
+: This check can *not* run live in the IDE editor
+See
+: https://d.android.com/r/studio-ui/designer/material/iconography
+Implementation
+: [Source Code](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/IconDetector.java)
+Tests
+: [Source Code](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/IconDetectorTest.java)
+Copyright Year
+: 2011
+
+There are predefined sizes (for each density) for launcher icons. You
+should follow these conventions to make sure your icons fit in with the
+overall look of the platform.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("IconExpectedSize")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("IconExpectedSize")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection IconExpectedSize
+ problematicStatement()
+ ```
+
+* Adding the suppression attribute `tools:ignore="IconExpectedSize"`
+ on the problematic XML element (or one of its enclosing elements).
+ You may also need to add the following namespace declaration on the
+ root element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <application tools:ignore="IconExpectedSize" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="IconExpectedSize" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'IconExpectedSize'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore IconExpectedSize ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/IconExtension.md.html b/docs/checks/IconExtension.md.html
new file mode 100644
index 00000000..f8c8979e
--- /dev/null
+++ b/docs/checks/IconExtension.md.html
@@ -0,0 +1,99 @@
+
+(#) Icon format does not match the file extension
+
+!!! WARNING: Icon format does not match the file extension
+ This is a warning.
+
+Id
+: `IconExtension`
+Summary
+: Icon format does not match the file extension
+Severity
+: Warning
+Category
+: Usability: Icons
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check can *not* run live in the IDE editor
+Implementation
+: [Source Code](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/IconDetector.java)
+Tests
+: [Source Code](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/IconDetectorTest.java)
+Copyright Year
+: 2011
+
+Ensures that icons have the correct file extension (e.g. a `.png` file
+is really in the PNG format and not for example a GIF file named
+`.png`).
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/drawable-mdpi/foo.png:Warning: Misleading file extension; named .png
+but the file format is webp [IconExtension]
+0 errors, 1 warnings
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant test files:
+
+
+
+
+
+You can also visit the
+[source code](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/IconDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `IconDetector.testMisleadingWebpFileName`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="IconExtension" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'IconExtension'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore IconExtension ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/IconLauncherFormat.md.html b/docs/checks/IconLauncherFormat.md.html
new file mode 100644
index 00000000..27d68616
--- /dev/null
+++ b/docs/checks/IconLauncherFormat.md.html
@@ -0,0 +1,8 @@
+
+(#) IconLauncherFormat
+
+The issue for this id has been deleted or marked obsolete and can now be
+ignored.
+
+(Additional metadata not available.)
+
\ No newline at end of file
diff --git a/docs/checks/IconLauncherShape.md.html b/docs/checks/IconLauncherShape.md.html
new file mode 100644
index 00000000..987289b0
--- /dev/null
+++ b/docs/checks/IconLauncherShape.md.html
@@ -0,0 +1,123 @@
+
+(#) The launcher icon shape should use a distinct silhouette
+
+!!! WARNING: The launcher icon shape should use a distinct silhouette
+ This is a warning.
+
+Id
+: `IconLauncherShape`
+Summary
+: The launcher icon shape should use a distinct silhouette
+Severity
+: Warning
+Category
+: Usability: Icons
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Kotlin and Java files, manifest files and resource files
+Editing
+: This check can *not* run live in the IDE editor
+Implementation
+: [Source Code](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/IconDetector.java)
+Tests
+: [Source Code](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/IconDetectorTest.java)
+Copyright Year
+: 2011
+
+According to the Android Design Guide
+(https://d.android.com/r/studio-ui/designer/material/iconography) your
+launcher icons should "use a distinct silhouette", a "three-dimensional,
+front view, with a slight perspective as if viewed from above, so that
+users perceive some depth."
+
+The unique silhouette implies that your launcher icon should not be a
+filled square.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("IconLauncherShape")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("IconLauncherShape")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection IconLauncherShape
+ problematicStatement()
+ ```
+
+* Adding the suppression attribute `tools:ignore="IconLauncherShape"`
+ on the problematic XML element (or one of its enclosing elements).
+ You may also need to add the following namespace declaration on the
+ root element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <application tools:ignore="IconLauncherShape" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="IconLauncherShape" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'IconLauncherShape'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore IconLauncherShape ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/IconLocation.md.html b/docs/checks/IconLocation.md.html
new file mode 100644
index 00000000..f61a035a
--- /dev/null
+++ b/docs/checks/IconLocation.md.html
@@ -0,0 +1,80 @@
+
+(#) Image defined in density-independent drawable folder
+
+!!! WARNING: Image defined in density-independent drawable folder
+ This is a warning.
+
+Id
+: `IconLocation`
+Summary
+: Image defined in density-independent drawable folder
+Severity
+: Warning
+Category
+: Usability: Icons
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check can *not* run live in the IDE editor
+See
+: https://developer.android.com/guide/practices/screens_support.html
+Implementation
+: [Source Code](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/IconDetector.java)
+Tests
+: [Source Code](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/IconDetectorTest.java)
+Copyright Year
+: 2011
+
+The res/drawable folder is intended for density-independent graphics
+such as shapes defined in XML. For bitmaps, move it to `drawable-mdpi`
+and consider providing higher and lower resolution versions in
+`drawable-ldpi`, `drawable-hdpi` and `drawable-xhdpi`. If the icon
+**really** is density independent (for example a solid color) you can
+place it in `drawable-nodpi`.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="IconLocation" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'IconLocation'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore IconLocation ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/IconMissingDensityFolder.md.html b/docs/checks/IconMissingDensityFolder.md.html
new file mode 100644
index 00000000..b8ccb15c
--- /dev/null
+++ b/docs/checks/IconMissingDensityFolder.md.html
@@ -0,0 +1,115 @@
+
+(#) Missing density folder
+
+!!! WARNING: Missing density folder
+ This is a warning.
+
+Id
+: `IconMissingDensityFolder`
+Summary
+: Missing density folder
+Severity
+: Warning
+Category
+: Usability: Icons
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check can *not* run live in the IDE editor
+See
+: https://developer.android.com/guide/practices/screens_support.html
+Implementation
+: [Source Code](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/IconDetector.java)
+Tests
+: [Source Code](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/IconDetectorTest.java)
+Copyright Year
+: 2011
+
+Icons will look best if a custom version is provided for each of the
+major screen density classes (low, medium, high, extra-high,
+extra-extra-high). This lint check identifies folders which are missing,
+such as `drawable-hdpi`.
+
+Low density is not really used much anymore, so this check ignores the
+ldpi density. To force lint to include it, set the environment variable
+`ANDROID_LINT_INCLUDE_LDPI=true`. For more information on current
+density usage, see https://developer.android.com/about/dashboards.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/drawable-nodpi/frame.xml:Warning: Missing density variation folders
+in res: drawable-hdpi, drawable-xhdpi, drawable-xxhdpi
+[IconMissingDensityFolder]
+0 errors, 3 warnings
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/drawable-nodpi/frame.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:color="#ff000000"/> <!-- WRONG, SHOULD BE LAST -->
+ <item android:state_pressed="true"
+ android:color="#ffff0000"/> <!-- pressed -->
+ <item android:state_focused="true"
+ android:color="#ff0000ff"/> <!-- focused -->
+</selector>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/IconDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `IconDetector.testNoDpiMix`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="IconMissingDensityFolder" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'IconMissingDensityFolder'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore IconMissingDensityFolder ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/IconMixedNinePatch.md.html b/docs/checks/IconMixedNinePatch.md.html
new file mode 100644
index 00000000..1890e16a
--- /dev/null
+++ b/docs/checks/IconMixedNinePatch.md.html
@@ -0,0 +1,76 @@
+
+(#) Clashing PNG and 9-PNG files
+
+!!! WARNING: Clashing PNG and 9-PNG files
+ This is a warning.
+
+Id
+: `IconMixedNinePatch`
+Summary
+: Clashing PNG and 9-PNG files
+Severity
+: Warning
+Category
+: Usability: Icons
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check can *not* run live in the IDE editor
+Implementation
+: [Source Code](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/IconDetector.java)
+Tests
+: [Source Code](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/IconDetectorTest.java)
+Copyright Year
+: 2011
+
+If you accidentally name two separate resources `file.png` and
+`file.9.png`, the image file and the nine patch file will both map to
+the same drawable resource, `@drawable/file`, which is probably not what
+was intended.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="IconMixedNinePatch" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'IconMixedNinePatch'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore IconMixedNinePatch ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/IconNoDpi.md.html b/docs/checks/IconNoDpi.md.html
new file mode 100644
index 00000000..2986519c
--- /dev/null
+++ b/docs/checks/IconNoDpi.md.html
@@ -0,0 +1,78 @@
+
+(#) Icon appears in both `-nodpi` and dpi folders
+
+!!! WARNING: Icon appears in both `-nodpi` and dpi folders
+ This is a warning.
+
+Id
+: `IconNoDpi`
+Summary
+: Icon appears in both `-nodpi` and dpi folders
+Severity
+: Warning
+Category
+: Usability: Icons
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check can *not* run live in the IDE editor
+Implementation
+: [Source Code](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/IconDetector.java)
+Tests
+: [Source Code](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/IconDetectorTest.java)
+Copyright Year
+: 2011
+
+Bitmaps that appear in `drawable-nodpi` folders will not be scaled by
+the Android framework. If a drawable resource of the same name appears
+**both** in a `-nodpi` folder as well as a dpi folder such as
+`drawable-hdpi`, then the behavior is ambiguous and probably not
+intentional. Delete one or the other, or use different names for the
+icons.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="IconNoDpi" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'IconNoDpi'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore IconNoDpi ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/IconXmlAndPng.md.html b/docs/checks/IconXmlAndPng.md.html
new file mode 100644
index 00000000..915d2b60
--- /dev/null
+++ b/docs/checks/IconXmlAndPng.md.html
@@ -0,0 +1,104 @@
+
+(#) Icon is specified both as `.xml` file and as a bitmap
+
+!!! WARNING: Icon is specified both as `.xml` file and as a bitmap
+ This is a warning.
+
+Id
+: `IconXmlAndPng`
+Summary
+: Icon is specified both as `.xml` file and as a bitmap
+Severity
+: Warning
+Category
+: Usability: Icons
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check can *not* run live in the IDE editor
+Implementation
+: [Source Code](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/IconDetector.java)
+Tests
+: [Source Code](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/IconDetectorTest.java)
+Copyright Year
+: 2011
+
+If a drawable resource appears as an `.xml` file in the `drawable/`
+folder, it's usually not intentional for it to also appear as a bitmap
+using the same name; generally you expect the drawable XML file to
+define states and each state has a corresponding drawable bitmap.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/drawable/background.xml:Warning: The following images appear both as
+density independent .xml files and as bitmap files:
+res/drawable-mdpi/background.png, res/drawable/background.xml
+[IconXmlAndPng]
+ res/drawable-mdpi/background.png: <No location-specific message>
+0 errors, 1 warnings
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/drawable/background.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<tag/>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/IconDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `IconDetector.testMixed`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="IconXmlAndPng" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'IconXmlAndPng'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore IconXmlAndPng ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/IdleBatteryChargingConstraints.md.html b/docs/checks/IdleBatteryChargingConstraints.md.html
new file mode 100644
index 00000000..2551c222
--- /dev/null
+++ b/docs/checks/IdleBatteryChargingConstraints.md.html
@@ -0,0 +1,180 @@
+
+(#) Constraints may not be met for some devices
+
+!!! WARNING: Constraints may not be met for some devices
+ This is a warning.
+
+Id
+: `IdleBatteryChargingConstraints`
+Summary
+: Constraints may not be met for some devices
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Identifier
+: androidx.work
+Feedback
+: https://issuetracker.google.com/issues/new?component=409906
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.work:work-runtime](androidx_work_work-runtime.md.html)
+Since
+: 2.4.0
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/work/work-lint/src/main/java/androidx/work/lint/IdleBatteryChargingConstraintsDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/work/work-lint/src/test/java/androidx/work/lint/IdleBatteryChargingConstraintsDetectorTest.kt)
+Copyright Year
+: 2020
+
+Some devices are never considered charging and idle at the same time.
+Consider removing one of these constraints.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+com/example/App.kt:8:Warning: Constraints may not be met for some
+devices [IdleBatteryChargingConstraints]
+ builder.setRequiresDeviceIdle(true)
+ ^
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`com/example/App.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package com.example
+
+import androidx.work.Constraints
+
+class App {
+ fun onCreate() {
+ val builder = Constraints.Builder()
+ builder.setRequiresDeviceIdle(true)
+ .setRequiresCharging(true)
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/work/work-lint/src/test/java/androidx/work/lint/IdleBatteryChargingConstraintsDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `IdleBatteryChargingConstraintsDetector.testWarnWithIdleCharging`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=409906.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.work:work-runtime:2.10.1")
+
+// build.gradle
+implementation 'androidx.work:work-runtime:2.10.1'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.work.runtime)
+
+# libs.versions.toml
+[versions]
+work-runtime = "2.10.1"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+work-runtime = {
+ module = "androidx.work:work-runtime",
+ version.ref = "work-runtime"
+}
+```
+
+2.10.1 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.work:work-runtime](androidx_work_work-runtime.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("IdleBatteryChargingConstraints")
+ fun method() {
+ setRequiresDeviceIdle(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("IdleBatteryChargingConstraints")
+ void method() {
+ setRequiresDeviceIdle(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection IdleBatteryChargingConstraints
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="IdleBatteryChargingConstraints" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'IdleBatteryChargingConstraints'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore IdleBatteryChargingConstraints ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/IgnoreWithoutReason.md.html b/docs/checks/IgnoreWithoutReason.md.html
new file mode 100644
index 00000000..6df95a14
--- /dev/null
+++ b/docs/checks/IgnoreWithoutReason.md.html
@@ -0,0 +1,160 @@
+
+(#) @Ignore without Reason
+
+!!! WARNING: @Ignore without Reason
+ This is a warning.
+
+Id
+: `IgnoreWithoutReason`
+Summary
+: @Ignore without Reason
+Severity
+: Warning
+Category
+: Testing
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.4.0 (April 2019)
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/IgnoreWithoutReasonDetector.kt)
+Tests
+: [Source Code](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/IgnoreWithoutReasonDetectorTest.kt)
+
+Ignoring a test without a reason makes it difficult to figure out the
+problem later. Please define an explicit reason why it is ignored, and
+when it can be resolved.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Options
+
+You can configure this lint checks using the following options:
+
+(###) allow-comments
+
+Whether to allow a comment next to the @Ignore tag to be considered providing a reason.
+Normally you have to specify an annotation argument to the `@Ignore` annotation, but with this option you can configure whether it should also allow ignore reasons to specified by a comment adjacent to the ignore tag.
+
+Default is true.
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="IgnoreWithoutReason">
+ <option name="allow-comments" value="true" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/foo/MyTest.java:7:Warning: Test is ignored without giving any
+explanation [IgnoreWithoutReason]
+@Ignore class MyTest {
+-------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/foo/MyTest.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package foo;
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+@SuppressWarnings("ClassNameDiffersFromFileName")
+@Ignore class MyTest {
+ @Test public void something() {
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/IgnoreWithoutReasonDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `IgnoreWithoutReasonDetector.testAnnotationWithoutReasonOnClass`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("IgnoreWithoutReason")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("IgnoreWithoutReason")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection IgnoreWithoutReason
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="IgnoreWithoutReason" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'IgnoreWithoutReason'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore IgnoreWithoutReason ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/IllegalResourceRef.md.html b/docs/checks/IllegalResourceRef.md.html
new file mode 100644
index 00000000..d194e5c8
--- /dev/null
+++ b/docs/checks/IllegalResourceRef.md.html
@@ -0,0 +1,143 @@
+
+(#) Name and version must be integer or string, not resource
+
+!!! WARNING: Name and version must be integer or string, not resource
+ This is a warning.
+
+Id
+: `IllegalResourceRef`
+Summary
+: Name and version must be integer or string, not resource
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/ManifestDetector.kt)
+Tests
+: [Source Code](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/ManifestDetectorTest.kt)
+Copyright Year
+: 2011
+
+For the `versionCode` attribute, you have to specify an actual integer
+literal; you cannot use an indirection with a `@dimen/name` resource.
+Similarly, the `versionName` attribute should be an actual string, not a
+string resource url.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:3:Warning: The android:versionCode cannot be a
+resource url, it must be a literal integer [IllegalResourceRef]
+ android:versionCode="@dimen/versionCode"
+ ----------------------------------------
+AndroidManifest.xml:6:Warning: The android:targetSdkVersion cannot be a
+resource url, it must be a literal integer (or string if a preview
+codename) [IllegalResourceRef]
+ <uses-sdk android:minSdkVersion="@dimen/minSdkVersion" android:targetSdkVersion="@dimen/targetSdkVersion" />
+ --------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="foo.bar2"
+ android:versionCode="@dimen/versionCode"
+ android:versionName="@dimen/versionName" >
+
+ <uses-sdk android:minSdkVersion="@dimen/minSdkVersion" android:targetSdkVersion="@dimen/targetSdkVersion" />
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name" >
+ <activity
+ android:label="@string/app_name"
+ android:name=".Foo2Activity" >
+ <intent-filter >
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ManifestDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ManifestDetector.testIllegalReference`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="IllegalResourceRef"`
+ on the problematic XML element (or one of its enclosing elements).
+ You may also need to add the following namespace declaration on the
+ root element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <application tools:ignore="IllegalResourceRef" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="IllegalResourceRef" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'IllegalResourceRef'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore IllegalResourceRef ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ImplicitSamInstance.md.html b/docs/checks/ImplicitSamInstance.md.html
new file mode 100644
index 00000000..0f79ebb5
--- /dev/null
+++ b/docs/checks/ImplicitSamInstance.md.html
@@ -0,0 +1,294 @@
+
+(#) Implicit SAM Instances
+
+!!! WARNING: Implicit SAM Instances
+ This is a warning.
+
+Id
+: `ImplicitSamInstance`
+Summary
+: Implicit SAM Instances
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.4.0 (April 2019)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://kotlinlang.org/docs/fun-interfaces.html#sam-conversions
+Implementation
+: [Source Code](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/SamDetector.kt)
+Tests
+: [Source Code](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/SamDetectorTest.kt)
+
+Kotlin's support for SAM (single abstract method) interfaces lets you
+pass a lambda to the interface. This will create a new instance on the
+fly even though there is no explicit constructor call. If you pass one
+of these lambdas or method references into a method which (for example)
+stores or compares the object identity, unexpected results may happen.
+
+In particular, passing a lambda variable in as a listener, and then
+later attempting to remove the listener will not work because a
+different instance is passed in.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/test.kt:21:Warning: Implicit new MyInterface instance being
+passed to method which ends up checking instance equality; this can lead
+to subtle bugs [ImplicitSamInstance]
+ handler.delete(lambda) // ERROR 1
+ ------
+src/test/pkg/test.kt:22:Warning: Implicit new MyInterface instance being
+passed to method which ends up checking instance equality; this can lead
+to subtle bugs [ImplicitSamInstance]
+ handler.compareIdentity1(lambda) // ERROR 2
+ ------
+src/test/pkg/test.kt:23:Warning: Implicit new MyInterface instance being
+passed to method which ends up checking instance equality; this can lead
+to subtle bugs [ImplicitSamInstance]
+ handler.compareIdentity2(lambda) // ERROR 3
+ ------
+src/test/pkg/test.kt:31:Warning: Implicit new MyInterface instance being
+passed to method which ends up checking instance equality; this can lead
+to subtle bugs [ImplicitSamInstance]
+ handler.delete(lambda2) // ERROR 4
+ -------
+src/test/pkg/test.kt:35:Warning: Implicit new MyInterface instance being
+passed to method which ends up checking instance equality; this can lead
+to subtle bugs [ImplicitSamInstance]
+ handler.delete(lambda3) // ERROR 5
+ -------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/test/pkg/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+@file:Suppress("RedundantSamConstructor", "MoveLambdaOutsideParentheses")
+
+package test.pkg
+
+fun test(handler: MyHandler, list: List) {
+ handler.handle(MyInterface { println("hello") }) // OK
+ handler.handle({ println("hello") }) // OK
+ handler.stash(MyInterface { println("hello") }, list) // OK
+ handler.stash({ println("hello") }, list) // OK
+ handler.store({ println("hello") }) // OK
+ handler.delete({ println("hello") }) // OK
+ handler.delete(MyInterface { println("hello") }) // OK
+ handler.compareIdentity1({ println("hello") }) // OK
+ handler.compareIdentity2({ println("hello") }) // OK
+ handler.compareEquals1({ println("hello") }) // OK
+ handler.compareEquals2({ println("hello") }) // OK
+
+ val lambda = { println("hello") }
+ handler.stash(lambda, list) // OK
+ handler.store(lambda) // OK
+ handler.delete(lambda) // ERROR 1
+ handler.compareIdentity1(lambda) // ERROR 2
+ handler.compareIdentity2(lambda) // ERROR 3
+ handler.compareEquals1(lambda) // OK
+ handler.compareEquals2(lambda) // OK
+
+ @Suppress("CanBeVal", "JoinDeclarationAndAssignment")
+ var lambda2: () -> Unit
+ lambda2 = { println("hello") }
+ handler.stash(lambda2, list) // OK
+ handler.delete(lambda2) // ERROR 4
+
+ val lambda3: () -> Unit = { println("hello") }
+ handler.stash(lambda3, list) // OK
+ handler.delete(lambda3) // ERROR 5
+
+ handler.act({ println("hello") }) // OK
+ handler.act(::callback) // OK
+}
+
+fun callback() {}
+
+fun viewpost(view: android.view.View) {
+ view.postDelayed({ println ("Hello") }, 50)
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/JavaTest.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import java.util.List;
+
+public class JavaTest {
+ public void test(MyHandler handler, List list) {
+ handler.handle(() -> System.out.println("hello")); // OK
+ handler.stash(() -> System.out.println("hello"), list); // OK
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyInterface.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+public interface MyInterface {
+ void act();
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyHandler.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import java.util.List;
+
+public class MyHandler {
+ public void handle(MyInterface actor) {
+ actor.act();
+ System.out.println(actor);
+ MyInterface copy = actor;
+ System.out.println(copy);
+ }
+
+ public void stash(MyInterface actor, List actors) {
+ actors.add(actor);
+ }
+
+ public void store(MyInterface actor) {
+ last = actor;
+ }
+
+ private MyInterface last;
+
+ private void removeActor(MyInterface actor) {
+ }
+
+ public fun delete(MyInterface actor) {
+ remove(actor);
+ }
+
+ public void compareIdentity1(MyInterface actor) {
+ if (actor == last) {
+ System.out.println("last");
+ }
+ }
+
+ public void compareIdentity2(MyInterface actor) {
+ if (actor != last) {
+ System.out.println("not last");
+ }
+ }
+
+ public void compareEquals1(MyInterface actor) {
+ if (actor.equals(last)) {
+ System.out.println("last");
+ }
+ }
+
+ public void compareEquals2(MyInterface actor) {
+ if (last.equals(actor)) {
+ System.out.println("last");
+ }
+ }
+
+ public void act(MyInterface actor) {
+ if (actor != null) {
+ actor.act();
+ }
+ //noinspection StatementWithEmptyBody
+ if (actor == null) {
+ } else {
+ actor.act();
+ }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/SamDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `SamDetector.testStashingImplicitInstances`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("ImplicitSamInstance")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("ImplicitSamInstance")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection ImplicitSamInstance
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ImplicitSamInstance" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ImplicitSamInstance'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ImplicitSamInstance ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ImplicitStringPlaceholder.md.html b/docs/checks/ImplicitStringPlaceholder.md.html
new file mode 100644
index 00000000..6f38a644
--- /dev/null
+++ b/docs/checks/ImplicitStringPlaceholder.md.html
@@ -0,0 +1,159 @@
+
+(#) Marks implicit placeholders in strings without an index
+
+!!! WARNING: Marks implicit placeholders in strings without an index
+ This is a warning.
+
+Id
+: `ImplicitStringPlaceholder`
+Summary
+: Marks implicit placeholders in strings without an index
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: vanniktech/lint-rules/
+Feedback
+: https://github.com/vanniktech/lint-rules/issues
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [com.vanniktech:lint-rules-android](com_vanniktech_lint-rules-android.md.html)
+Since
+: 0.24.0
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/main/kotlin/com/vanniktech/lintrules/android/ImplicitStringPlaceholderDetector.kt)
+Tests
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/test/kotlin/com/vanniktech/lintrules/android/ImplicitStringPlaceholderDetectorTest.kt)
+
+It's better and more explicit to use numbered placeholders.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/values/strings.xml:2:Warning: Implicit placeholder
+[ImplicitStringPlaceholder]
+ <string name="my_string">Hello %s</string>
+ ^
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/values/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<resources>
+ <string name="my_string">Hello %s</string>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/test/kotlin/com/vanniktech/lintrules/android/ImplicitStringPlaceholderDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ImplicitStringPlaceholderDetector.invalid`.
+To report a problem with this extracted sample, visit
+https://github.com/vanniktech/lint-rules/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.vanniktech:lint-rules-android:0.25.0")
+
+// build.gradle
+lintChecks 'com.vanniktech:lint-rules-android:0.25.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.lint.rules.android)
+
+# libs.versions.toml
+[versions]
+lint-rules-android = "0.25.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+lint-rules-android = {
+ module = "com.vanniktech:lint-rules-android",
+ version.ref = "lint-rules-android"
+}
+```
+
+0.25.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.vanniktech:lint-rules-android](com_vanniktech_lint-rules-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="ImplicitStringPlaceholder"` on the problematic XML
+ element (or one of its enclosing elements). You may also need to add
+ the following namespace declaration on the root element in the XML
+ file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <resources xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <string tools:ignore="ImplicitStringPlaceholder" .../>
+ ...
+ </resources>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ImplicitStringPlaceholder" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ImplicitStringPlaceholder'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ImplicitStringPlaceholder ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ImpliedQuantity.md.html b/docs/checks/ImpliedQuantity.md.html
new file mode 100644
index 00000000..92e842e9
--- /dev/null
+++ b/docs/checks/ImpliedQuantity.md.html
@@ -0,0 +1,170 @@
+
+(#) Implied Quantities
+
+!!! ERROR: Implied Quantities
+ This is an error.
+
+Id
+: `ImpliedQuantity`
+Summary
+: Implied Quantities
+Severity
+: Error
+Category
+: Correctness: Messages
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/guide/topics/resources/string-resource.html#Plurals
+Implementation
+: [Source Code](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/PluralsDetector.kt)
+Tests
+: [Source Code](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/PluralsDetectorTest.java)
+Copyright Year
+: 2013
+
+Plural strings should generally include a `%s` or `%d` formatting
+argument. In locales like English, the `one` quantity only applies to a
+single value, 1, but that's not true everywhere. For example, in
+Slovene, the `one` quantity will apply to 1, 101, 201, 301, and so on.
+Similarly, there are locales where multiple values match the `zero` and
+`two` quantities.
+
+In these locales, it is usually an error to have a message which does
+not include a formatting argument (such as '%d'), since it will not be
+clear from the grammar what quantity the quantity string is describing.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/values-sl/plurals2.xml:4:Error: The quantity 'one' matches more than
+one specific number in this locale (1, 101, 201, 301, 401, 501, 601,
+701, 1001, …), but the message did not include a formatting argument
+(such as %d). This is usually an internationalization error. See full
+issue explanation for more. [ImpliedQuantity]
+ <item quantity="one">Znaleziono jedną piosenkę.</item>
+ ------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`res/values/plurals.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <plurals name="my_plural">
+ <item quantity="one">@string/hello</item>
+ <item quantity="few">@string/hello</item>
+ <item quantity="other">@string/hello</item>
+ </plurals>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values/plurals2.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <plurals name="numberOfSongsAvailable">
+ <item quantity="one">One song found.</item>
+ <item quantity="other">%d songs found.</item>
+ </plurals>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values-pl/plurals2.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <plurals name="numberOfSongsAvailable">
+ <item quantity="one">Znaleziono jedną piosenkę.</item>
+ <item quantity="few">Znaleziono %d piosenki.</item>
+ <item quantity="other">Znaleziono %d piosenek.</item>
+ </plurals>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values-sl/plurals2.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <plurals name="numberOfSongsAvailable">
+ <item quantity="one">Znaleziono jedną piosenkę.</item>
+ <item quantity="few">Znaleziono %d piosenki.</item>
+ <item quantity="other">Znaleziono %d piosenek.</item>
+ </plurals>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/PluralsDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `PluralsDetector.testImpliedQuantity`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="ImpliedQuantity"` on
+ the problematic XML element (or one of its enclosing elements). You
+ may also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <resources xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <plurals tools:ignore="ImpliedQuantity" .../>
+ ...
+ </resources>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ImpliedQuantity" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ImpliedQuantity'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ImpliedQuantity ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ImpliedTouchscreenHardware.md.html b/docs/checks/ImpliedTouchscreenHardware.md.html
new file mode 100644
index 00000000..462cd0fd
--- /dev/null
+++ b/docs/checks/ImpliedTouchscreenHardware.md.html
@@ -0,0 +1,125 @@
+
+(#) Touchscreen not optional
+
+!!! ERROR: Touchscreen not optional
+ This is an error.
+
+Id
+: `ImpliedTouchscreenHardware`
+Summary
+: Touchscreen not optional
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 2.3.0 (March 2017)
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/guide/topics/manifest/uses-feature-element.html
+Implementation
+: [Source Code](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/AndroidTvDetector.java)
+Tests
+: [Source Code](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/AndroidTvDetectorTest.java)
+
+Apps require the `android.hardware.touchscreen` feature by default. If
+you want your app to be available on TV, you must also explicitly
+declare that a touchscreen is not required as follows:
+` `
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:2:Error: Hardware feature
+android.hardware.touchscreen not explicitly marked as optional
+[ImpliedTouchscreenHardware]
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ --------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools">
+ <uses-feature android:name="android.software.leanback"/>
+ <uses-feature android:name="android.hardware.telephony"/>
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/AndroidTvDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `AndroidTvDetector.testMissingUsesFeatureTouchScreen`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="ImpliedTouchscreenHardware"` on the problematic XML
+ element (or one of its enclosing elements). You may also need to add
+ the following namespace declaration on the root element in the XML
+ file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <application tools:ignore="ImpliedTouchscreenHardware" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ImpliedTouchscreenHardware" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ImpliedTouchscreenHardware'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ImpliedTouchscreenHardware ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InOrMmUsage.md.html b/docs/checks/InOrMmUsage.md.html
new file mode 100644
index 00000000..f2e28ef0
--- /dev/null
+++ b/docs/checks/InOrMmUsage.md.html
@@ -0,0 +1,179 @@
+
+(#) Using `mm` or `in` dimensions
+
+!!! WARNING: Using `mm` or `in` dimensions
+ This is a warning.
+
+Id
+: `InOrMmUsage`
+Summary
+: Using `mm` or `in` dimensions
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/PxUsageDetector.java)
+Tests
+: [Source Code](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/PxUsageDetectorTest.java)
+Copyright Year
+: 2011
+
+Avoid using `mm` (millimeters) or `in` (inches) as the unit for
+dimensions.
+
+While it should work in principle, unfortunately many devices do not
+report the correct true physical density, which means that the dimension
+calculations won't work correctly. You are better off using `dp` (and
+for font sizes, `sp`).
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/now_playing_after.xml:49:Warning: Avoid using "mm" as units
+(it does not work accurately on all devices); use "dp" instead
+[InOrMmUsage]
+ android:layout_width="100mm"
+ ----------------------------
+res/layout/now_playing_after.xml:50:Warning: Avoid using "in" as units
+(it does not work accurately on all devices); use "dp" instead
+[InOrMmUsage]
+ android:layout_height="120in"
+ -----------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/layout/now_playing_after.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/now_playing"
+ android:layout_width="fill_parent"
+ android:layout_height="@dimen/now_playing_height"
+ android:orientation="horizontal">
+ <LinearLayout
+ android:background="@color/background2"
+ android:paddingLeft="14dip"
+ android:paddingRight="14dip"
+ android:paddingTop="10dip"
+ android:paddingBottom="10dip"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:layout_weight="1"
+ android:orientation="vertical">
+ <TextView
+ android:id="@+id/now_playing_title"
+ android:duplicateParentState="true"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:textStyle="bold"
+ android:textSize="@dimen/text_size_large"
+ android:textColor="@color/foreground1"
+ android:text="@string/now_playing_after_title"
+ android:maxLines="2"
+ android:ellipsize="end" />
+ <TextView
+ android:id="@+id/now_playing_subtitle"
+ android:duplicateParentState="true"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="3dip"
+ android:textColor="@color/foreground2"
+ android:textSize="@dimen/text_size_small"
+ android:text="@string/now_playing_after_subtitle"
+ android:singleLine="true"
+ android:ellipsize="end" />
+ </LinearLayout>
+ <View
+ android:layout_width="2px"
+ android:layout_height="fill_parent"
+ android:background="@android:color/white" />
+ <ImageButton
+ android:background="@drawable/btn_now_playing_more"
+ android:id="@+id/now_playing_more"
+ android:src="http://github.com/@drawable/ic_now_playing_logo"
+ android:padding="12dip"
+ android:layout_width="100mm"
+ android:layout_height="120in"
+ android:onClick="onNowPlayingLogoClick"
+ android:maxHeight="1px"
+ android:scaleType="center" />
+</LinearLayout>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/PxUsageDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `PxUsageDetector.testPxWarnings`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="InOrMmUsage"` on the
+ problematic XML element (or one of its enclosing elements). You may
+ also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <resources xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <style tools:ignore="InOrMmUsage" .../>
+ ...
+ </resources>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InOrMmUsage" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InOrMmUsage'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InOrMmUsage ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/IncludeLayoutParam.md.html b/docs/checks/IncludeLayoutParam.md.html
new file mode 100644
index 00000000..216cbbcd
--- /dev/null
+++ b/docs/checks/IncludeLayoutParam.md.html
@@ -0,0 +1,220 @@
+
+(#) Ignored layout params on include
+
+!!! ERROR: Ignored layout params on include
+ This is an error.
+
+Id
+: `IncludeLayoutParam`
+Summary
+: Ignored layout params on include
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://stackoverflow.com/questions/2631614/does-android-xml-layouts-include-tag-really-work
+Implementation
+: [Source Code](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/IncludeDetector.java)
+Tests
+: [Source Code](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/IncludeDetectorTest.java)
+Copyright Year
+: 2014
+
+Layout parameters specified on an `` tag will only be used if
+you also override `layout_width` and `layout_height` on the ``
+tag; otherwise they will be ignored.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/include_params.xml:43:Error: Layout parameter layout_margin
+ignored unless both layout_width and layout_height are also specified on
+ tag [IncludeLayoutParam]
+ android:layout_margin="20dp"
+ ----------------------------
+res/layout/include_params.xml:44:Error: Layout parameter layout_weight
+ignored unless both layout_width and layout_height are also specified on
+ tag [IncludeLayoutParam]
+ android:layout_weight="1.5"
+ ---------------------------
+res/layout/include_params.xml:51:Error: Layout parameter layout_weight
+ignored unless layout_width is also specified on tag
+[IncludeLayoutParam]
+ android:layout_weight="1.5"
+ ---------------------------
+res/layout/include_params.xml:58:Error: Layout parameter layout_weight
+ignored unless layout_height is also specified on tag
+[IncludeLayoutParam]
+ android:layout_weight="1.5"
+ ---------------------------
+res/layout/include_params.xml:65:Error: Layout parameter layout_width
+ignored unless layout_height is also specified on tag
+[IncludeLayoutParam]
+ android:layout_width="fill_parent"
+ ----------------------------------
+res/layout/include_params.xml:72:Error: Layout parameter layout_height
+ignored unless layout_width is also specified on tag
+[IncludeLayoutParam]
+ android:layout_height="fill_parent"
+ -----------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/layout/include_params.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <!-- Ok: No layout params -->
+ <include layout="@layout/myincluded" />
+
+ <!-- Ok: No layout params -->
+ <include
+ android:id="@+id/myInclude"
+ layout="@layout/myincluded"
+ android:gravity="left"
+ android:visibility="visible" />
+
+ <!-- Ok: No layout params -->
+ <include
+ layout="@layout/myincluded"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent" />
+
+ <!-- Ok: Specifies both width and height -->
+ <include
+ layout="@layout/myincluded"
+ android:layout_width="fill_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1.5"
+ android:visibility="visible" />
+
+ <!-- Ok: ignored -->
+ <include
+ layout="@layout/myincluded"
+ android:layout_width="fill_parent"
+ android:layout_weight="1.5"
+ android:visibility="visible"
+ tools:ignore="IncludeLayoutParam" />
+
+ <!-- Wrong: Missing both -->
+ <include
+ layout="@layout/myincluded"
+ android:layout_margin="20dp"
+ android:layout_weight="1.5"
+ android:visibility="visible" />
+
+ <!-- Wrong: Missing width -->
+ <include
+ layout="@layout/myincluded"
+ android:layout_height="0dp"
+ android:layout_weight="1.5"
+ android:visibility="visible" />
+
+ <!-- Wrong: Missing height -->
+ <include
+ layout="@layout/myincluded"
+ android:layout_width="fill_parent"
+ android:layout_weight="1.5"
+ android:visibility="visible" />
+
+ <!-- Wrong: Specified only width -->
+ <include
+ android:id="@+id/myInclude"
+ layout="@layout/myincluded"
+ android:layout_width="fill_parent"
+ android:visibility="visible" />
+
+ <!-- Wrong: Specified only height -->
+ <include
+ android:id="@+id/myInclude"
+ layout="@layout/myincluded"
+ android:layout_height="fill_parent"
+ android:visibility="visible" />
+
+</LinearLayout>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/IncludeDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `IncludeDetector.test`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="IncludeLayoutParam"`
+ on the problematic XML element (or one of its enclosing elements).
+ You may also need to add the following namespace declaration on the
+ root element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <include xmlns:tools="http://schemas.android.com/tools"
+ tools:ignore="IncludeLayoutParam" ...>
+ ...
+ </include>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="IncludeLayoutParam" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'IncludeLayoutParam'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore IncludeLayoutParam ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InclusiveNaming.md.html b/docs/checks/InclusiveNaming.md.html
new file mode 100644
index 00000000..a68e4494
--- /dev/null
+++ b/docs/checks/InclusiveNaming.md.html
@@ -0,0 +1,154 @@
+
+(#) Use inclusive naming
+
+!!! ERROR: Use inclusive naming
+ This is an error.
+
+Id
+: `InclusiveNaming`
+Summary
+: Use inclusive naming
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.1.0
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/inclusive/InclusiveNamingResourceScanner.kt)
+Copyright Year
+: 2021
+
+We try to use inclusive naming at Slack. Terms such as blacklist,
+whitelist, master, slave, etc, while maybe widely used today, can be
+socially charged and make others feel excluded or uncomfortable.
+
+(##) Options
+
+You can configure this lint checks using the following options:
+
+(###) block-list
+
+A comma-separated list of words that should not be used in source code..
+This property should define a comma-separated list of words that should not be used in source code.
+
+
+Example `lint.xml`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<lint>
+ <issue id="InclusiveNaming">
+ <option name="block-list" value="some string" />
+ </issue>
+</lint>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(##) Conflicts
+
+This issue id has also been used by other, unrelated lint checks. Issue
+id's must be unique, so you cannot combine these libraries. Also defined
+in:
+* InclusiveNaming: Use inclusive naming (this issue)
+* [InclusiveNaming from com.slack.lint:slack-lint-checks:0.9.0](InclusiveNaming.md.html)
+* [InclusiveNaming from com.slack.lint:slack-lint-checks:0.9.0](InclusiveNaming.md.html)
+
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="InclusiveNaming"` on
+ the problematic XML element (or one of its enclosing elements). You
+ may also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InclusiveNaming" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InclusiveNaming'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InclusiveNaming ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/IncompatibleMediaBrowserServiceCompatVersion.md.html b/docs/checks/IncompatibleMediaBrowserServiceCompatVersion.md.html
new file mode 100644
index 00000000..f9731305
--- /dev/null
+++ b/docs/checks/IncompatibleMediaBrowserServiceCompatVersion.md.html
@@ -0,0 +1,156 @@
+
+(#) Obsolete version of MediaBrowserServiceCompat
+
+!!! WARNING: Obsolete version of MediaBrowserServiceCompat
+ This is a warning.
+
+Id
+: `IncompatibleMediaBrowserServiceCompatVersion`
+Summary
+: Obsolete version of MediaBrowserServiceCompat
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.0.0 (October 2017)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/MediaBrowserServiceCompatVersionDetector.kt)
+Tests
+: [Source Code](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/MediaBrowserServiceCompatVersionDetectorTest.kt)
+
+`MediaBrowserServiceCompat` from version 23.2.0 to 23.4.0 of the Support
+v4 Library used private APIs and will not be compatible with future
+versions of Android beyond Android N. Please upgrade to version 24.0.0
+or higher of the Support Library.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+build.gradle:4:Warning: Using a version of the class that is not forward
+compatible [IncompatibleMediaBrowserServiceCompatVersion]
+ compile 'com.android.support:support-v4:23.4.0'
+ -------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/test/pkg/MyBrowserService.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.os.Bundle;
+import android.support.v4.media.MediaBrowserCompat;
+import android.support.v4.media.MediaBrowserServiceCompat;
+
+import java.util.List;
+
+public class MyBrowserService extends MediaBrowserServiceCompat {
+
+ @Override
+ public BrowserRoot onGetRoot(String clientPackageName, int clientUid, Bundle rootHints) {
+ return null;
+ }
+
+ @Override
+ public void onLoadChildren(String parentId, Result> result) {
+
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`build.gradle`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~groovy linenumbers
+apply plugin: 'com.android.application'
+
+dependencies {
+ compile 'com.android.support:support-v4:23.4.0'
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/MediaBrowserServiceCompatVersionDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `MediaBrowserServiceCompatVersionDetector.testMediaBrowserServiceCompatOldVersion`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("IncompatibleMediaBrowserServiceCompatVersion")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("IncompatibleMediaBrowserServiceCompatVersion")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection IncompatibleMediaBrowserServiceCompatVersion
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="IncompatibleMediaBrowserServiceCompatVersion" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'IncompatibleMediaBrowserServiceCompatVersion'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore IncompatibleMediaBrowserServiceCompatVersion ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InconsistentArrays.md.html b/docs/checks/InconsistentArrays.md.html
new file mode 100644
index 00000000..f6af0927
--- /dev/null
+++ b/docs/checks/InconsistentArrays.md.html
@@ -0,0 +1,211 @@
+
+(#) Inconsistencies in array element counts
+
+!!! WARNING: Inconsistencies in array element counts
+ This is a warning.
+
+Id
+: `InconsistentArrays`
+Summary
+: Inconsistencies in array element counts
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/ArraySizeDetector.java)
+Tests
+: [Source Code](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/ArraySizeDetectorTest.kt)
+Copyright Year
+: 2011
+
+When an array is translated in a different locale, it should normally
+have the same number of elements as the original array. When adding or
+removing elements to an array, it is easy to forget to update all the
+locales, and this lint warning finds inconsistencies like these.
+
+Note however that there may be cases where you really want to declare a
+different number of array items in each configuration (for example where
+the array represents available options, and those options differ for
+different layout orientations and so on), so use your own judgment to
+decide if this is really an error.
+
+You can suppress this error type if it finds false errors in your
+project.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/values/arrays.xml:3:Warning: Array security_questions has an
+inconsistent number of items (3 in values-nl-rNL/arrays.xml, 4 in
+values-cs/arrays.xml) [InconsistentArrays]
+ <string-array name="security_questions">
+ ^
+res/values/arrays.xml:10:Warning: Array signal_strength has an
+inconsistent number of items (5 in values/arrays.xml, 6 in
+values-land/arrays.xml) [InconsistentArrays]
+ <array name="signal_strength">
+ ^
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`res/values/arrays.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<resources>
+ <!-- Choices for Locations in SetupWizard's Set Time and Data Activity -->
+ <string-array name="security_questions">
+ <item>Favorite food?</item>
+ <item>City of birth?</item>
+ <item>Best childhood friend\'s name?</item>
+ <item>Highschool name?</item>
+ </string-array>
+
+ <array name="signal_strength">
+ <item>@drawable/ic_setups_signal_0</item>
+ <item>@drawable/ic_setups_signal_1</item>
+ <item>@drawable/ic_setups_signal_2</item>
+ <item>@drawable/ic_setups_signal_3</item>
+ <item>@drawable/ic_setups_signal_4</item>
+ </array>
+</resources>
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values-cs/arrays.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="security_questions">
+ <item>"Oblíbené jídlo?"</item>
+ <item>"Město narození."</item>
+ <item>"Jméno nejlepšího kamaráda z dětství?"</item>
+ <item>"Název střední školy"</item>
+ </string-array>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values-land/arrays.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<resources>
+ <array name="signal_strength">
+ <item>@drawable/ic_setups_signal_0</item>
+ <item>@drawable/ic_setups_signal_1</item>
+ <item>@drawable/ic_setups_signal_2</item>
+ <item>@drawable/ic_setups_signal_3</item>
+ <item>@drawable/ic_setups_signal_4</item>
+ <item>@drawable/extra</item>
+ </array>
+</resources>
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values-nl-rNL/arrays.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="security_questions">
+ <item>"Favoriete eten?"</item>
+ <item>"Geboorteplaats?"</item>
+ <item>"Naam van middelbare school?"</item>
+ </string-array>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values-es/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="home_title">"Casa"</string>
+ <string name="show_all_apps">"Todo"</string>
+ <string name="menu_wallpaper">"Papel tapiz"</string>
+ <string name="menu_search">"Búsqueda"</string>
+ <!-- no translation found for menu_settings (1769059051084007158) -->
+ <skip />
+ <string name="wallpaper_instructions">"Puntee en la imagen para establecer papel tapiz vertical"</string>
+
+ <string-array name="security_questions">
+ <item>"Comida favorita"</item>
+ <item>"Ciudad de nacimiento"</item>
+ <item>"Nombre de tu mejor amigo/a de la infancia"</item>
+ <item>"Nombre de tu colegio"</item>
+ </string-array>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ArraySizeDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ArraySizeDetector.testArraySizes`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="InconsistentArrays"`
+ on the problematic XML element (or one of its enclosing elements).
+ You may also need to add the following namespace declaration on the
+ root element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <resources xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <array tools:ignore="InconsistentArrays" .../>
+ ...
+ </resources>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InconsistentArrays" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InconsistentArrays'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InconsistentArrays ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InconsistentLayout.md.html b/docs/checks/InconsistentLayout.md.html
new file mode 100644
index 00000000..750ea37e
--- /dev/null
+++ b/docs/checks/InconsistentLayout.md.html
@@ -0,0 +1,223 @@
+
+(#) Inconsistent Layouts
+
+!!! WARNING: Inconsistent Layouts
+ This is a warning.
+
+Id
+: `InconsistentLayout`
+Summary
+: Inconsistent Layouts
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Kotlin and Java files and resource files
+Editing
+: This check can *not* run live in the IDE editor
+Implementation
+: [Source Code](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/LayoutConsistencyDetector.java)
+Tests
+: [Source Code](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/LayoutConsistencyDetectorTest.java)
+Copyright Year
+: 2013
+
+This check ensures that a layout resource which is defined in multiple
+resource folders, specifies the same set of widgets.
+
+This finds cases where you have accidentally forgotten to add a widget
+to all variations of the layout, which could result in a runtime crash
+for some resource configurations when a `findViewById()` fails.
+
+There **are** cases where this is intentional. For example, you may have
+a dedicated large tablet layout which adds some extra widgets that are
+not present in the phone version of the layout. As long as the code
+accessing the layout resource is careful to handle this properly, it is
+valid. In that case, you can suppress this lint check for the given
+extra or missing views, or the whole layout.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/layout1.xml:11:Warning: The id "button1" in layout "layout1"
+is missing from the following layout configurations: layout-xlarge
+(present in layout) [InconsistentLayout]
+ android:id="@+id/button1"
+ -------------------------
+res/layout/layout1.xml:38:Warning: The id "button4" in layout "layout1"
+is missing from the following layout configurations: layout-xlarge
+(present in layout) [InconsistentLayout]
+ android:id="@+id/button4"
+ -------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/test/pkg/X.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+public class X {
+ public void X(Y parent) {
+ parent.foo(R.id.button1);
+ parent.foo(R.id.button4);
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/layout/layout1.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/RelativeLayout1"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+
+ <!-- my_id1 is defined in ids.xml, my_id2 is defined in main2, my_id3 does not exist -->
+
+ <Button
+ android:id="@+id/button1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignBottom="@+id/button5"
+ android:layout_alignLeft="@+id/my_id2"
+ android:layout_alignParentTop="true"
+ android:layout_alignRight="@+id/my_id3"
+ android:layout_alignTop="@+id/my_id1"
+ android:text="Button" />
+
+ <Button
+ android:id="@+id/button2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentLeft="true"
+ android:layout_below="@+id/button1"
+ android:text="Button" />
+
+ <Button
+ android:id="@+id/button3"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentLeft="true"
+ android:layout_below="@+id/button2"
+ android:text="Button" />
+
+ <Button
+ android:id="@+id/button4"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentLeft="true"
+ android:layout_below="@+id/button3"
+ android:text="Button" />
+
+</RelativeLayout>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/layout-xlarge/layout1.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <Button
+ android:id="@+id/my_id2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Button" />
+
+</LinearLayout>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/LayoutConsistencyDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `LayoutConsistencyDetector.test`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("InconsistentLayout")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("InconsistentLayout")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection InconsistentLayout
+ problematicStatement()
+ ```
+
+* Adding the suppression attribute `tools:ignore="InconsistentLayout"`
+ on the problematic XML element (or one of its enclosing elements).
+ You may also need to add the following namespace declaration on the
+ root element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InconsistentLayout" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InconsistentLayout'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InconsistentLayout ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/IncorrectChainMarginsUsage.md.html b/docs/checks/IncorrectChainMarginsUsage.md.html
new file mode 100644
index 00000000..6ca716b7
--- /dev/null
+++ b/docs/checks/IncorrectChainMarginsUsage.md.html
@@ -0,0 +1,147 @@
+
+(#) Use `LayoutReference.withChainParams()` to define margins for elements in a Chain
+
+!!! WARNING: Use `LayoutReference.withChainParams()` to define margins for elements in a Chain
+ This is a warning.
+
+Id
+: `IncorrectChainMarginsUsage`
+Summary
+: Use `LayoutReference.withChainParams()` to define margins for elements in a Chain
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Identifier
+: androidx.constraintlayout.compose
+Feedback
+: https://issuetracker.google.com/issues/new?component=323867&template=1023345
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.constraintlayout:constraintlayout-compose](androidx_constraintlayout_constraintlayout-compose.md.html)
+Since
+: 1.1.0
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/constraintlayout/constraintlayout-compose-lint/src/main/java/androidx/constraintlayout/compose/lint/ConstraintLayoutDslDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/constraintlayout/constraintlayout-compose-lint/src/test/java/androidx/constraintlayout/compose/lint/ConstraintLayoutDslDetectorTest.kt)
+Copyright Year
+: 2022
+
+If you understand how a chain works, it might seem obvious to add
+margins by re-creating the constraints with the desired margin. However,
+in Compose, helpers will ignore custom constraints in favor of their
+layout implementation. So instead, use
+`LayoutReference.withChainParams()` to define margins for Chains.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.constraintlayout:constraintlayout-compose:1.1.1")
+
+// build.gradle
+implementation 'androidx.constraintlayout:constraintlayout-compose:1.1.1'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.constraintlayout.compose)
+
+# libs.versions.toml
+[versions]
+constraintlayout-compose = "1.1.1"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+constraintlayout-compose = {
+ module = "androidx.constraintlayout:constraintlayout-compose",
+ version.ref = "constraintlayout-compose"
+}
+```
+
+1.1.1 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.constraintlayout:constraintlayout-compose](androidx_constraintlayout_constraintlayout-compose.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("IncorrectChainMarginsUsage")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("IncorrectChainMarginsUsage")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection IncorrectChainMarginsUsage
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="IncorrectChainMarginsUsage" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'IncorrectChainMarginsUsage'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore IncorrectChainMarginsUsage ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/IncorrectMatchParentUsage.md.html b/docs/checks/IncorrectMatchParentUsage.md.html
new file mode 100644
index 00000000..3991a428
--- /dev/null
+++ b/docs/checks/IncorrectMatchParentUsage.md.html
@@ -0,0 +1,146 @@
+
+(#) Prefer using `Dimension.percent(1f)` when defining custom constraints
+
+!!! WARNING: Prefer using `Dimension.percent(1f)` when defining custom constraints
+ This is a warning.
+
+Id
+: `IncorrectMatchParentUsage`
+Summary
+: Prefer using `Dimension.percent(1f)` when defining custom constraints
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Identifier
+: androidx.constraintlayout.compose
+Feedback
+: https://issuetracker.google.com/issues/new?component=323867&template=1023345
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.constraintlayout:constraintlayout-compose](androidx_constraintlayout_constraintlayout-compose.md.html)
+Since
+: 1.1.0
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/constraintlayout/constraintlayout-compose-lint/src/main/java/androidx/constraintlayout/compose/lint/ConstraintLayoutDslDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/constraintlayout/constraintlayout-compose-lint/src/test/java/androidx/constraintlayout/compose/lint/ConstraintLayoutDslDetectorTest.kt)
+Copyright Year
+: 2022
+
+`Dimension.matchParent` forces the constraints to be an equivalent of
+`centerHorizontallyTo(parent)` or `centerVerticallyTo(parent)` according
+to the assigned dimension which can lead to unexpected behavior. To
+avoid that, prefer using `Dimension.percent(1f)`
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.constraintlayout:constraintlayout-compose:1.1.1")
+
+// build.gradle
+implementation 'androidx.constraintlayout:constraintlayout-compose:1.1.1'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.constraintlayout.compose)
+
+# libs.versions.toml
+[versions]
+constraintlayout-compose = "1.1.1"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+constraintlayout-compose = {
+ module = "androidx.constraintlayout:constraintlayout-compose",
+ version.ref = "constraintlayout-compose"
+}
+```
+
+1.1.1 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.constraintlayout:constraintlayout-compose](androidx_constraintlayout_constraintlayout-compose.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("IncorrectMatchParentUsage")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("IncorrectMatchParentUsage")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection IncorrectMatchParentUsage
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="IncorrectMatchParentUsage" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'IncorrectMatchParentUsage'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore IncorrectMatchParentUsage ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/IncorrectReferencesDeclaration.md.html b/docs/checks/IncorrectReferencesDeclaration.md.html
new file mode 100644
index 00000000..28ad1ced
--- /dev/null
+++ b/docs/checks/IncorrectReferencesDeclaration.md.html
@@ -0,0 +1,209 @@
+
+(#) `createRefsFor(vararg ids: Any)` should have at least one argument and match assigned variables
+
+!!! ERROR: `createRefsFor(vararg ids: Any)` should have at least one argument and match assigned variables
+ This is an error.
+
+Id
+: `IncorrectReferencesDeclaration`
+Summary
+: `createRefsFor(vararg ids: Any)` should have at least one argument and match assigned variables
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Identifier
+: androidx.constraintlayout.compose
+Feedback
+: https://issuetracker.google.com/issues/new?component=323867&template=1023345
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.constraintlayout:constraintlayout-compose](androidx_constraintlayout_constraintlayout-compose.md.html)
+Since
+: 1.1.0
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/constraintlayout/constraintlayout-compose-lint/src/main/java/androidx/constraintlayout/compose/lint/ConstraintLayoutDslDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/constraintlayout/constraintlayout-compose-lint/src/test/java/androidx/constraintlayout/compose/lint/ConstraintLayoutDslDetectorTest.kt)
+Copyright Year
+: 2022
+
+`createRefsFor(vararg ids: Any)` conveniently allows creating multiple
+references using destructuring. However, providing an un-equal amount of
+arguments to the assigned variables will result in unexpected behavior
+since the variables may reference a ConstrainedLayoutReference with
+unknown ID.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/example/test.kt:8:Error: Arguments of createRefsFor (2) do not match
+assigned variables (3) [IncorrectReferencesDeclaration]
+ val (box1, text1, image1) = createRefsFor("box", "text")
+ -------------
+src/example/test.kt:9:Error: Arguments of createRefsFor (3) do not match
+assigned variables (2) [IncorrectReferencesDeclaration]
+ val (box2, text2) = createRefsFor("box", "text", "image")
+ -------------
+src/example/test.kt:19:Error: Arguments of createRefsFor (2) do not
+match assigned variables (3) [IncorrectReferencesDeclaration]
+ val (box1, text1, image1) = createRefsFor("box", "text")
+ -------------
+src/example/test.kt:20:Error: Arguments of createRefsFor (3) do not
+match assigned variables (2) [IncorrectReferencesDeclaration]
+ val (box2, text2) = createRefsFor("box", "text", "image")
+ -------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/example/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package example
+
+import androidx.constraintlayout.compose.*
+
+fun Test() {
+ val scopeApplier: ConstraintSetScope.() -> Unit = {
+ val (box, text) = createRefsFor("box", "text")
+ val (box1, text1, image1) = createRefsFor("box", "text")
+ val (box2, text2) = createRefsFor("box", "text", "image")
+
+ val ids = arrayOf("box", "text")
+ val (box3, text3, image3) = createRefsFor(*ids)
+ }
+}
+
+fun Test2() {
+ val scopeApplier: MotionSceneScope.() -> Unit = {
+ val (box, text) = createRefsFor("box", "text")
+ val (box1, text1, image1) = createRefsFor("box", "text")
+ val (box2, text2) = createRefsFor("box", "text", "image")
+
+ val ids = arrayOf("box", "text")
+ val (box3, text3, image3) = createRefsFor(*ids)
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/constraintlayout/constraintlayout-compose-lint/src/test/java/androidx/constraintlayout/compose/lint/ConstraintLayoutDslDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ConstraintLayoutDslDetector.createRefsForArgumentTest`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=323867&template=1023345.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.constraintlayout:constraintlayout-compose:1.1.1")
+
+// build.gradle
+implementation 'androidx.constraintlayout:constraintlayout-compose:1.1.1'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.constraintlayout.compose)
+
+# libs.versions.toml
+[versions]
+constraintlayout-compose = "1.1.1"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+constraintlayout-compose = {
+ module = "androidx.constraintlayout:constraintlayout-compose",
+ version.ref = "constraintlayout-compose"
+}
+```
+
+1.1.1 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.constraintlayout:constraintlayout-compose](androidx_constraintlayout_constraintlayout-compose.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("IncorrectReferencesDeclaration")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("IncorrectReferencesDeclaration")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection IncorrectReferencesDeclaration
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="IncorrectReferencesDeclaration" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'IncorrectReferencesDeclaration'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore IncorrectReferencesDeclaration ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InefficientWeight.md.html b/docs/checks/InefficientWeight.md.html
new file mode 100644
index 00000000..2cbc8364
--- /dev/null
+++ b/docs/checks/InefficientWeight.md.html
@@ -0,0 +1,182 @@
+
+(#) Inefficient layout weight
+
+!!! WARNING: Inefficient layout weight
+ This is a warning.
+
+Id
+: `InefficientWeight`
+Summary
+: Inefficient layout weight
+Severity
+: Warning
+Category
+: Performance
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/InefficientWeightDetector.java)
+Tests
+: [Source Code](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/InefficientWeightDetectorTest.java)
+Copyright Year
+: 2011
+
+When only a single widget in a `LinearLayout` defines a weight, it is
+more efficient to assign a width/height of `0dp` to it since it will
+absorb all the remaining space anyway. With a declared width/height of
+`0dp` it does not have to measure its own size first.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/inefficient_weight.xml:10:Warning: Use a layout_width of 0dp
+instead of match_parent for better performance [InefficientWeight]
+ android:layout_width="match_parent"
+ -----------------------------------
+res/layout/inefficient_weight.xml:24:Warning: Use a layout_height of 0dp
+instead of wrap_content for better performance [InefficientWeight]
+ android:layout_height="wrap_content"
+ ------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/layout/inefficient_weight.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <Button
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1.0" />
+
+ <LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+
+ android:orientation="vertical">
+
+ <Button
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1.0" />
+
+ </LinearLayout>
+
+ <LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+
+ android:orientation="vertical">
+
+ <Button
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1.0" />
+
+ </LinearLayout>
+
+ <LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ style="@style/MyStyle"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <Button
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <Button
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ </LinearLayout>
+
+
+</LinearLayout>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/InefficientWeightDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `InefficientWeightDetector.testWeights`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="InefficientWeight"`
+ on the problematic XML element (or one of its enclosing elements).
+ You may also need to add the following namespace declaration on the
+ root element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <LinearLayout xmlns:tools="http://schemas.android.com/tools"
+ tools:ignore="InefficientWeight" ...>
+ ...
+ </LinearLayout>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InefficientWeight" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InefficientWeight'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InefficientWeight ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InflateParams.md.html b/docs/checks/InflateParams.md.html
new file mode 100644
index 00000000..37eb24ce
--- /dev/null
+++ b/docs/checks/InflateParams.md.html
@@ -0,0 +1,199 @@
+
+(#) Layout Inflation without a Parent
+
+!!! WARNING: Layout Inflation without a Parent
+ This is a warning.
+
+Id
+: `InflateParams`
+Summary
+: Layout Inflation without a Parent
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Kotlin and Java files and resource files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://www.bignerdranch.com/blog/understanding-androids-layoutinflater-inflate/
+Implementation
+: [Source Code](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/LayoutInflationDetector.kt)
+Tests
+: [Source Code](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/LayoutInflationDetectorTest.java)
+Copyright Year
+: 2014
+
+When inflating a layout, avoid passing in null as the parent view, since
+otherwise any layout parameters on the root of the inflated layout will
+be ignored.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/LayoutInflationTest.java:13:Warning: Avoid passing null as
+the view root (needed to resolve layout parameters on the inflated
+layout's root element) [InflateParams]
+ convertView = mInflater.inflate(R.layout.your_layout, null);
+ ----
+src/test/pkg/LayoutInflationTest.java:14:Warning: Avoid passing null as
+the view root (needed to resolve layout parameters on the inflated
+layout's root element) [InflateParams]
+ convertView = mInflater.inflate(R.layout.your_layout, null, true);
+ ----
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/test/pkg/LayoutInflationTest.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.annotation.SuppressLint;
+import java.util.ArrayList;
+
+public abstract class LayoutInflationTest extends BaseAdapter {
+ public View getView(int position, View convertView, ViewGroup parent) {
+ convertView = mInflater.inflate(R.layout.your_layout, null);
+ convertView = mInflater.inflate(R.layout.your_layout, null, true);
+ //convertView = mInflater.inflate(R.layout.your_layout);
+ convertView = mInflater.inflate(R.layout.your_layout, parent);
+ convertView = WeirdInflater.inflate(convertView, null);
+
+ return convertView;
+ }
+
+ @SuppressLint("InflateParams")
+ public View getView2(int position, View convertView, ViewGroup parent) {
+ convertView = mInflater.inflate(R.layout.your_layout, null);
+ convertView = mInflater.inflate(R.layout.your_layout, null, true);
+ convertView = mInflater.inflate(R.layout.your_layout, parent);
+ convertView = WeirdInflater.inflate(convertView, null);
+
+ return convertView;
+ }
+ private LayoutInflater mInflater;
+ private static class R {
+ private static class layout {
+ public static final int your_layout = 1;
+ }
+ }
+ private static class WeirdInflater {
+ public static View inflate(View view, Object params) { return null; }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/layout/your_layout.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/LinearLayout1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" />
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/layout-port/your_layout.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@id/text1"
+ style="?android:attr/listSeparatorTextViewStyle" />
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/LayoutInflationDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `LayoutInflationDetector.testFull`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("InflateParams")
+ fun method() {
+ inflate(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("InflateParams")
+ void method() {
+ inflate(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection InflateParams
+ problematicStatement()
+ ```
+
+* Adding the suppression attribute `tools:ignore="InflateParams"` on
+ the problematic XML element (or one of its enclosing elements). You
+ may also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InflateParams" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InflateParams'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InflateParams ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InflationInItemDecoration.md.html b/docs/checks/InflationInItemDecoration.md.html
new file mode 100644
index 00000000..ef12c0a8
--- /dev/null
+++ b/docs/checks/InflationInItemDecoration.md.html
@@ -0,0 +1,147 @@
+
+(#) Avoid inflating a view to display text
+
+!!! WARNING: Avoid inflating a view to display text
+ This is a warning.
+
+Id
+: `InflationInItemDecoration`
+Summary
+: Avoid inflating a view to display text
+Severity
+: Warning
+Category
+: Accessibility
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.8.1
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/ui/ItemDecorationViewBindingDetector.kt)
+Copyright Year
+: 2024
+
+ViewBinding should not be used in `ItemDecoration`. If an inflated view
+contains meaningful textual information, it will not be visible to
+TalkBack. This means that screen reader users will not be able to know
+what is on the screen.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("InflationInItemDecoration")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("InflationInItemDecoration")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection InflationInItemDecoration
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InflationInItemDecoration" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InflationInItemDecoration'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InflationInItemDecoration ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InjectInJava.md.html b/docs/checks/InjectInJava.md.html
new file mode 100644
index 00000000..3882a2ff
--- /dev/null
+++ b/docs/checks/InjectInJava.md.html
@@ -0,0 +1,228 @@
+
+(#) Only Kotlin classes should be injected in order for Anvil to work
+
+!!! ERROR: Only Kotlin classes should be injected in order for Anvil to work
+ This is an error.
+
+Id
+: `InjectInJava`
+Summary
+: Only Kotlin classes should be injected in order for Anvil to work
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.1.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/InjectInJavaDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/InjectInJavaDetectorTest.kt)
+Copyright Year
+: 2021
+
+Only Kotlin classes should be injected in order for Anvil to work. If
+you cannot easily convert this to Kotlin, consider manually providing it
+via a Kotlin `@Module`-annotated object.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/JavaClass.java:9:Error: Only Kotlin classes should be
+injected in order for Anvil to work. [InjectInJava]
+ @Inject String memberInjected;
+ -------
+src/test/pkg/JavaClass.java:11:Error: Only Kotlin classes should be
+injected in order for Anvil to work. [InjectInJava]
+ @Inject JavaClass(String constructorInjected) {
+ -------
+src/test/pkg/JavaClass.java:15:Error: Only Kotlin classes should be
+injected in order for Anvil to work. [InjectInJava]
+ @Inject void methodInject(String value) {
+ -------
+src/test/pkg/JavaClass.java:21:Error: Only Kotlin classes should be
+injected in order for Anvil to work. [InjectInJava]
+ @AssistedInject JavaAssistedClass(@Assisted String assistedParam) {
+ ---------------
+src/test/pkg/JavaClass.java:25:Error: Only Kotlin classes should be
+injected in order for Anvil to work. [InjectInJava]
+ @AssistedFactory
+ ----------------
+src/test/pkg/JavaClass.java:31:Error: Only Kotlin classes should be
+injected in order for Anvil to work. [InjectInJava]
+ @Module static abstract class ExampleModule {
+ -------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/JavaClass.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import javax.inject.Inject;
+import dagger.Module;
+import dagger.assisted.AssistedInject;
+import dagger.assisted.AssistedFactory;
+
+class JavaClass {
+ @Inject String memberInjected;
+
+ @Inject JavaClass(String constructorInjected) {
+
+ }
+
+ @Inject void methodInject(String value) {
+
+ }
+
+ static class JavaAssistedClass {
+
+ @AssistedInject JavaAssistedClass(@Assisted String assistedParam) {
+
+ }
+
+ @AssistedFactory
+ interface Factory {
+ JavaAssistedClass create(String assistedParam);
+ }
+ }
+
+ @Module static abstract class ExampleModule {
+
+ }
+}
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/InjectInJavaDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `InjectInJavaDetector.javaIsNotOk`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/slack-lints.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("InjectInJava")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("InjectInJava")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection InjectInJava
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InjectInJava" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InjectInJava'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InjectInJava ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InlinedApi.md.html b/docs/checks/InlinedApi.md.html
new file mode 100644
index 00000000..16ea1fc9
--- /dev/null
+++ b/docs/checks/InlinedApi.md.html
@@ -0,0 +1,162 @@
+
+(#) Using inlined constants on older versions
+
+!!! WARNING: Using inlined constants on older versions
+ This is a warning.
+
+Id
+: `InlinedApi`
+Summary
+: Using inlined constants on older versions
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/ApiDetector.kt)
+Tests
+: [Source Code](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/ApiDetectorTest.java)
+Copyright Year
+: 2012
+
+This check scans through all the Android API field references in the
+application and flags certain constants, such as static final integers
+and Strings, which were introduced in later versions. These will
+actually be copied into the class files rather than being referenced,
+which means that the value is available even when running on older
+devices. In some cases that's fine, and in other cases it can result in
+a runtime crash or incorrect behavior. It depends on the context, so
+consider the code carefully and decide whether it's safe and can be
+suppressed or whether the code needs to be guarded.
+
+If you really want to use this API and don't need to support older
+devices just set the `minSdkVersion` in your `build.gradle` or
+`AndroidManifest.xml` files.
+
+If your code is **deliberately** accessing newer APIs, and you have
+ensured (e.g. with conditional execution) that this code will only ever
+be called on a supported platform, then you can annotate your class or
+method with the `@TargetApi` annotation specifying the local minimum SDK
+to apply, such as `@TargetApi(11)`, such that this check considers 11
+rather than your manifest file's minimum SDK as the required API level.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test.kt:8:Warning: Field requires API level 29 (current min is 21):
+android.media.MediaFormat#MIMETYPE_AUDIO_AC4 [InlinedApi]
+ val format: String = MediaFormat.MIMETYPE_AUDIO_AC4
+ ------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+ <uses-sdk
+ android:minSdkVersion="21"
+ android:targetSdkVersion="30" />
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+import android.media.MediaFormat
+
+fun test() {
+ // This constant will be copied in by value, which means
+ // it will run without crashing on older devices. However,
+ // depending on what we *do* with the value, the code may
+ // may not work correctly.
+ val format: String = MediaFormat.MIMETYPE_AUDIO_AC4
+ encode(format) // might crash!
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ApiDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("InlinedApi")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("InlinedApi")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection InlinedApi
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InlinedApi" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InlinedApi'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InlinedApi ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InnerclassSeparator.md.html b/docs/checks/InnerclassSeparator.md.html
new file mode 100644
index 00000000..d08f1dcf
--- /dev/null
+++ b/docs/checks/InnerclassSeparator.md.html
@@ -0,0 +1,135 @@
+
+(#) Inner classes should use `$` rather than `.`
+
+!!! WARNING: Inner classes should use `$` rather than `.`
+ This is a warning.
+
+Id
+: `InnerclassSeparator`
+Summary
+: Inner classes should use `$` rather than `.`
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Manifest files and resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/MissingClassDetector.kt)
+Tests
+: [Source Code](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/MissingClassDetectorTest.kt)
+Copyright Year
+: 2012
+
+When you reference an inner class in a manifest file, you must use '$'
+instead of '.' as the separator character, i.e. Outer$Inner instead of
+Outer.Inner.
+
+(If you get this warning for a class which is not actually an inner
+class, it's because you are using uppercase characters in your package
+name, which is not conventional.)
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:5:Warning: Use '$' instead of '.' for inner classes;
+replace ".Foo.Bar" with ".Foo$Bar" [InnerclassSeparator]
+ android:name=".Foo.Bar"
+ --------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="test.pkg" >
+ <application>
+ <activity
+ android:name=".Foo.Bar"
+ android:label="@string/app_name" >
+ </activity>
+ </application>
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/Foo.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.app.Activity;
+
+public class Foo {
+ public static class Bar extends Activity {
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/MissingClassDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `MissingClassDetector.testInnerClassFix`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="InnerclassSeparator"` on the problematic XML element
+ (or one of its enclosing elements). You may also need to add the
+ following namespace declaration on the root element in the XML file
+ if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InnerclassSeparator" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InnerclassSeparator'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InnerclassSeparator ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InsecureBaseConfiguration.md.html b/docs/checks/InsecureBaseConfiguration.md.html
new file mode 100644
index 00000000..d1c84664
--- /dev/null
+++ b/docs/checks/InsecureBaseConfiguration.md.html
@@ -0,0 +1,118 @@
+
+(#) Insecure Base Configuration
+
+!!! WARNING: Insecure Base Configuration
+ This is a warning.
+
+Id
+: `InsecureBaseConfiguration`
+Summary
+: Insecure Base Configuration
+Severity
+: Warning
+Category
+: Security
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.5.0 (August 2019)
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://goo.gle/InsecureBaseConfiguration
+See
+: https://developer.android.com/preview/features/security-config.html
+Implementation
+: [Source Code](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/NetworkSecurityConfigDetector.java)
+Tests
+: [Source Code](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/NetworkSecurityConfigDetectorTest.java)
+
+Permitting cleartext traffic could allow eavesdroppers to intercept data
+sent by your app, which impacts the privacy of your users. Consider only
+allowing encrypted traffic by setting the `cleartextTrafficPermitted`
+tag to `false`.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/xml/network_config.xml:3:Warning: Insecure Base Configuration
+[InsecureBaseConfiguration]
+ <base-config cleartextTrafficPermitted="true">
+ ----
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/xml/network_config.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+ <base-config cleartextTrafficPermitted="true">
+ </base-config>
+</network-security-config>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/NetworkSecurityConfigDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `NetworkSecurityConfigDetector.testInsecureBaseConfiguration`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="InsecureBaseConfiguration"` on the problematic XML
+ element (or one of its enclosing elements). You may also need to add
+ the following namespace declaration on the root element in the XML
+ file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InsecureBaseConfiguration" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InsecureBaseConfiguration'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InsecureBaseConfiguration ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InsecureDnsSdkLevel.md.html b/docs/checks/InsecureDnsSdkLevel.md.html
new file mode 100644
index 00000000..0ed54b40
--- /dev/null
+++ b/docs/checks/InsecureDnsSdkLevel.md.html
@@ -0,0 +1,170 @@
+
+(#) Application vulnerable to DNS spoofing attacks
+
+!!! WARNING: Application vulnerable to DNS spoofing attacks
+ This is a warning.
+
+Id
+: `InsecureDnsSdkLevel`
+Summary
+: Application vulnerable to DNS spoofing attacks
+Severity
+: Warning
+Category
+: Security
+Platform
+: Android
+Vendor
+: Google - Android 3P Vulnerability Research
+Contact
+: https://github.com/google/android-security-lints
+Feedback
+: https://github.com/google/android-security-lints/issues
+Min
+: Lint 4.1
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [com.android.security.lint:lint](com_android_security_lint_lint.md.html)
+Since
+: 1.0.1
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://goo.gle/InsecureDnsSdkLevel
+Implementation
+: [Source Code](https://github.com/google/android-security-lints/tree/main/checks/src/main/java/com/example/lint/checks/DnsConfigDetector.kt)
+Tests
+: [Source Code](https://github.com/google/android-security-lints/tree/main/checks/src/test/java/com/example/lint/checks/DnsConfigDetectorTest.kt)
+Copyright Year
+: 2024
+
+Apps targeting SDK versions earlier than 28 are susceptible to DNS
+attacks like DNS spoofing or cache poisoning.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:2:Warning: Update your application's target SDK
+version to 28 and above to make use of the Android OS's built-in
+transport security features [InsecureDnsSdkLevel]
+<uses-sdk android:targetSdkVersion='27'/>
+ --
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest xmlns:android='http://schemas.android.com/apk/res/android' package='test.pkg'>
+<uses-sdk android:targetSdkVersion='27'/>
+<application android:debuggable='false'>
+ <activity android:name='com.example.MainActivity'></activity>
+</application>
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/google/android-security-lints/tree/main/checks/src/test/java/com/example/lint/checks/DnsConfigDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `DnsConfigDetector.testWhenTargetSdkBelowSecureDnsTransportPatch_showsWarning`.
+To report a problem with this extracted sample, visit
+https://github.com/google/android-security-lints/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.android.security.lint:lint:1.0.3")
+
+// build.gradle
+lintChecks 'com.android.security.lint:lint:1.0.3'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.com.android.security.lint.lint)
+
+# libs.versions.toml
+[versions]
+com-android-security-lint-lint = "1.0.3"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+com-android-security-lint-lint = {
+ module = "com.android.security.lint:lint",
+ version.ref = "com-android-security-lint-lint"
+}
+```
+
+1.0.3 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.android.security.lint:lint](com_android_security_lint_lint.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="InsecureDnsSdkLevel"` on the problematic XML element
+ (or one of its enclosing elements). You may also need to add the
+ following namespace declaration on the root element in the XML file
+ if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <uses-sdk tools:ignore="InsecureDnsSdkLevel" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InsecureDnsSdkLevel" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InsecureDnsSdkLevel'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InsecureDnsSdkLevel ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InsecurePermissionProtectionLevel.md.html b/docs/checks/InsecurePermissionProtectionLevel.md.html
new file mode 100644
index 00000000..29147a02
--- /dev/null
+++ b/docs/checks/InsecurePermissionProtectionLevel.md.html
@@ -0,0 +1,173 @@
+
+(#) Custom permission created with a normal `protectionLevel`
+
+!!! WARNING: Custom permission created with a normal `protectionLevel`
+ This is a warning.
+
+Id
+: `InsecurePermissionProtectionLevel`
+Summary
+: Custom permission created with a normal `protectionLevel`
+Severity
+: Warning
+Category
+: Security
+Platform
+: Android
+Vendor
+: Google - Android 3P Vulnerability Research
+Contact
+: https://github.com/google/android-security-lints
+Feedback
+: https://github.com/google/android-security-lints/issues
+Min
+: Lint 4.1
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [com.android.security.lint:lint](com_android_security_lint_lint.md.html)
+Since
+: 1.0.1
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://goo.gle/InsecurePermissionProtectionLevel
+Implementation
+: [Source Code](https://github.com/google/android-security-lints/tree/main/checks/src/main/java/com/example/lint/checks/PermissionDetector.kt)
+Tests
+: [Source Code](https://github.com/google/android-security-lints/tree/main/checks/src/test/java/com/example/lint/checks/PermissionDetectorTest.kt)
+Copyright Year
+: 2024
+
+Custom permissions are designed for sharing resources and capabilities
+with other apps. However, typos and insufficient protection levels can
+negate the usage of these custom permissions altogether. In general, use
+`signature` or higher protection levels whenever possible, as this
+ensures only other apps signed with the same certificate can access
+these protected features.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:2:Warning: Custom permissions should have signature
+`protectionLevel`s or higher [InsecurePermissionProtectionLevel]
+<permission android:name="com.android.example.permission.CUSTOM_PERMISSION" />
+------------------------------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest xmlns:android='http://schemas.android.com/apk/res/android' package='test.pkg'>
+<permission android:name="com.android.example.permission.CUSTOM_PERMISSION" />
+<application android:debuggable='false'>
+ <activity android:name='com.example.MainActivity'></activity>
+</application>
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/google/android-security-lints/tree/main/checks/src/test/java/com/example/lint/checks/PermissionDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `PermissionDetector.testWhenCustomPermissionNoSpecifiedProtectionLevel_showsWarning`.
+To report a problem with this extracted sample, visit
+https://github.com/google/android-security-lints/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.android.security.lint:lint:1.0.3")
+
+// build.gradle
+lintChecks 'com.android.security.lint:lint:1.0.3'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.com.android.security.lint.lint)
+
+# libs.versions.toml
+[versions]
+com-android-security-lint-lint = "1.0.3"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+com-android-security-lint-lint = {
+ module = "com.android.security.lint:lint",
+ version.ref = "com-android-security-lint-lint"
+}
+```
+
+1.0.3 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.android.security.lint:lint](com_android_security_lint_lint.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="InsecurePermissionProtectionLevel"` on the
+ problematic XML element (or one of its enclosing elements). You may
+ also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <permission tools:ignore="InsecurePermissionProtectionLevel" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InsecurePermissionProtectionLevel" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InsecurePermissionProtectionLevel'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InsecurePermissionProtectionLevel ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InsecureStickyBroadcastsMethod.md.html b/docs/checks/InsecureStickyBroadcastsMethod.md.html
new file mode 100644
index 00000000..6f5ce93f
--- /dev/null
+++ b/docs/checks/InsecureStickyBroadcastsMethod.md.html
@@ -0,0 +1,189 @@
+
+(#) Usage of insecure sticky broadcasts
+
+!!! WARNING: Usage of insecure sticky broadcasts
+ This is a warning.
+
+Id
+: `InsecureStickyBroadcastsMethod`
+Summary
+: Usage of insecure sticky broadcasts
+Severity
+: Warning
+Category
+: Security
+Platform
+: Any
+Vendor
+: Google - Android 3P Vulnerability Research
+Contact
+: https://github.com/google/android-security-lints
+Feedback
+: https://github.com/google/android-security-lints/issues
+Min
+: Lint 4.1
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [com.android.security.lint:lint](com_android_security_lint_lint.md.html)
+Since
+: 1.0.2
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://goo.gle/InsecureStickyBroadcastsMethod
+Implementation
+: [Source Code](https://github.com/google/android-security-lints/tree/main/checks/src/main/java/com/example/lint/checks/StickyBroadcastsDetector.kt)
+Tests
+: [Source Code](https://github.com/google/android-security-lints/tree/main/checks/src/test/java/com/example/lint/checks/StickyBroadcastsDetectorTest.kt)
+Copyright Year
+: 2024
+
+Sticky broadcasts can be accessed, sent, or modified by anyone,
+resulting in potential security issues. For this reason, it was
+deprecated in API level 21 and other mechanisms such as databases or
+non-sticky broadcasts should be used instead.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/fake/pkg/MainActivity.java:12:Warning: Sticky broadcasts can be
+accessed, sent or modified by anyone. Use non-sticky broadcasts instead.
+[InsecureStickyBroadcastsMethod]
+ sendStickyOrderedBroadcast();
+ ----------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/fake/pkg/MainActivity.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package fake.pkg;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+@Suppress("DEPRECATION")
+public class MainActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ sendStickyOrderedBroadcast();
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/google/android-security-lints/tree/main/checks/src/test/java/com/example/lint/checks/StickyBroadcastsDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `StickyBroadcastsDetector.stickyBroadcastMethodCall_showsWarning`.
+To report a problem with this extracted sample, visit
+https://github.com/google/android-security-lints/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.android.security.lint:lint:1.0.3")
+
+// build.gradle
+lintChecks 'com.android.security.lint:lint:1.0.3'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.com.android.security.lint.lint)
+
+# libs.versions.toml
+[versions]
+com-android-security-lint-lint = "1.0.3"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+com-android-security-lint-lint = {
+ module = "com.android.security.lint:lint",
+ version.ref = "com-android-security-lint-lint"
+}
+```
+
+1.0.3 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.android.security.lint:lint](com_android_security_lint_lint.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("InsecureStickyBroadcastsMethod")
+ fun method() {
+ sendStickyOrderedBroadcast(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("InsecureStickyBroadcastsMethod")
+ void method() {
+ sendStickyOrderedBroadcast(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection InsecureStickyBroadcastsMethod
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InsecureStickyBroadcastsMethod" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InsecureStickyBroadcastsMethod'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InsecureStickyBroadcastsMethod ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InsecureStickyBroadcastsPermission.md.html b/docs/checks/InsecureStickyBroadcastsPermission.md.html
new file mode 100644
index 00000000..398ed902
--- /dev/null
+++ b/docs/checks/InsecureStickyBroadcastsPermission.md.html
@@ -0,0 +1,169 @@
+
+(#) Usage of insecure sticky broadcasts
+
+!!! WARNING: Usage of insecure sticky broadcasts
+ This is a warning.
+
+Id
+: `InsecureStickyBroadcastsPermission`
+Summary
+: Usage of insecure sticky broadcasts
+Severity
+: Warning
+Category
+: Security
+Platform
+: Android
+Vendor
+: Google - Android 3P Vulnerability Research
+Contact
+: https://github.com/google/android-security-lints
+Feedback
+: https://github.com/google/android-security-lints/issues
+Min
+: Lint 4.1
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [com.android.security.lint:lint](com_android_security_lint_lint.md.html)
+Since
+: 1.0.2
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://goo.gle/InsecureStickyBroadcastsPermission
+Implementation
+: [Source Code](https://github.com/google/android-security-lints/tree/main/checks/src/main/java/com/example/lint/checks/StickyBroadcastsDetector.kt)
+Tests
+: [Source Code](https://github.com/google/android-security-lints/tree/main/checks/src/test/java/com/example/lint/checks/StickyBroadcastsDetectorTest.kt)
+Copyright Year
+: 2024
+
+Sticky broadcasts can be accessed, sent, or modified by anyone,
+resulting in potential security issues. For this reason, it was
+deprecated in API level 21 and other mechanisms such as databases or
+non-sticky broadcasts should be used instead.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:2:Warning: Sticky broadcasts can be accessed, sent
+or modified by anyone. Use non-sticky broadcasts instead.
+[InsecureStickyBroadcastsPermission]
+ <uses-permission android:name="android.permission.BROADCAST_STICKY"/>
+ ---------------------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest xmlns:android='http://schemas.android.com/apk/res/android' package='test.pkg'>
+ <uses-permission android:name="android.permission.BROADCAST_STICKY"/>
+ <application>
+ <activity android:name='com.example.MainActivity'></activity>
+ </application>
+ </manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/google/android-security-lints/tree/main/checks/src/test/java/com/example/lint/checks/StickyBroadcastsDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `StickyBroadcastsDetector.stickyBroadcastPermissionInManifest_showsWarning`.
+To report a problem with this extracted sample, visit
+https://github.com/google/android-security-lints/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.android.security.lint:lint:1.0.3")
+
+// build.gradle
+lintChecks 'com.android.security.lint:lint:1.0.3'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.com.android.security.lint.lint)
+
+# libs.versions.toml
+[versions]
+com-android-security-lint-lint = "1.0.3"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+com-android-security-lint-lint = {
+ module = "com.android.security.lint:lint",
+ version.ref = "com-android-security-lint-lint"
+}
+```
+
+1.0.3 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.android.security.lint:lint](com_android_security_lint_lint.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="InsecureStickyBroadcastsPermission"` on the
+ problematic XML element (or one of its enclosing elements). You may
+ also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <uses-permission tools:ignore="InsecureStickyBroadcastsPermission" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InsecureStickyBroadcastsPermission" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InsecureStickyBroadcastsPermission'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InsecureStickyBroadcastsPermission ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InstantApps.md.html b/docs/checks/InstantApps.md.html
new file mode 100644
index 00000000..c0308175
--- /dev/null
+++ b/docs/checks/InstantApps.md.html
@@ -0,0 +1,8 @@
+
+(#) InstantApps
+
+The issue for this id has been deleted or marked obsolete and can now be
+ignored.
+
+(Additional metadata not available.)
+
\ No newline at end of file
diff --git a/docs/checks/Instantiatable.md.html b/docs/checks/Instantiatable.md.html
new file mode 100644
index 00000000..ac5600db
--- /dev/null
+++ b/docs/checks/Instantiatable.md.html
@@ -0,0 +1,141 @@
+
+(#) Registered class is not instantiatable
+
+!!! ERROR: Registered class is not instantiatable
+ This is an error, and is also enforced at build time when
+ supported by the build system. For Android this means it will
+ run during release builds.
+
+Id
+: `Instantiatable`
+Summary
+: Registered class is not instantiatable
+Severity
+: Fatal
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Manifest files and resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/MissingClassDetector.kt)
+Tests
+: [Source Code](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/MissingClassDetectorTest.kt)
+Copyright Year
+: 2012
+
+Activities, services, broadcast receivers etc. registered in the
+manifest file (or for custom views, in a layout file) must be
+"instantiatable" by the system, which means that the class must be
+public, it must have an empty public constructor, and if it's an inner
+class, it must be a static inner class.
+
+If you use a custom `AppComponentFactory` to instantiate app components
+yourself, consider disabling this Lint issue in order to avoid false
+positives.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/menu/my_menu.xml:13:Error: NotView must extend android.view.View
+[Instantiatable]
+ android:actionViewClass="test.pkg.NotView" />
+ ----------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`res/menu/my_menu.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:id="@+id/locale_search_menu"
+ android:title="@string/locale_search_menu"
+ android:icon="@*android:drawable/ic_search_api_material"
+ android:showAsAction="always|collapseActionView"
+ android:actionViewClass="test.pkg.SearchView" />
+ <item
+ android:id="@+id/locale_search_menu"
+ android:title="@string/locale_search_menu"
+ android:icon="@*android:drawable/ic_search_api_material"
+ android:showAsAction="always|collapseActionView"
+ android:actionViewClass="test.pkg.NotView" />
+</menu>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/SearchView.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import android.widget.TextView
+abstract class SearchView : TextView(null)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/NotView.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+abstract class NotView : android.app.Fragment()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/MissingClassDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `MissingClassDetector.testMenu`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="Instantiatable"` on
+ the problematic XML element (or one of its enclosing elements). You
+ may also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="Instantiatable" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'Instantiatable'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore Instantiatable ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/IntentFilterExportedReceiver.md.html b/docs/checks/IntentFilterExportedReceiver.md.html
new file mode 100644
index 00000000..ddf206e6
--- /dev/null
+++ b/docs/checks/IntentFilterExportedReceiver.md.html
@@ -0,0 +1,154 @@
+
+(#) Unspecified `android:exported` in manifest
+
+!!! WARNING: Unspecified `android:exported` in manifest
+ This is a warning.
+
+Id
+: `IntentFilterExportedReceiver`
+Summary
+: Unspecified `android:exported` in manifest
+Severity
+: Warning
+Category
+: Security
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 7.2.0 (May 2022)
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://goo.gle/IntentFilterExportedReceiver
+Implementation
+: [Source Code](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/ExportedFlagDetector.kt)
+Tests
+: [Source Code](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/ExportedFlagDetectorTest.kt)
+
+Apps targeting Android 12 and higher are required to specify an explicit
+value for `android:exported` when the corresponding component has an
+intent filter defined. Otherwise, installation will fail. Set it to
+`true` to make this activity accessible to other apps, and `false` to
+limit it to be used only by this app or the OS. For launch activities,
+this should be set to true; otherwise, the app will fail to launch.
+
+Previously, `android:exported` for components without any intent filters
+present used to default to `false`, and when intent filters were
+present, the default was `true`. Defaults which change value based on
+other values are confusing and lead to apps accidentally exporting
+components as a side-effect of adding intent filters. This is a security
+risk, and we have made this change to avoid introducing accidental
+vulnerabilities.
+
+While the default without intent filters remains unchanged, it is now
+required to explicitly specify a value when intent filters are present.
+Any app failing to meet this requirement will fail to install on any
+Android version after Android 11.
+
+We recommend setting `android:exported` to false (even on previous
+versions of Android prior to this requirement) unless you have a good
+reason to export a particular component.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:7:Warning: As of Android 12, android:exported must
+be set; use true to make the activity available to other apps, and false
+otherwise. [IntentFilterExportedReceiver]
+ <receiver android:name="com.google.android.c2dm.C2DMBroadcastReceiver">
+ --------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="test.pkg">
+ <uses-sdk android:minSdkVersion="30"/>
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name" >
+ <receiver android:name="com.google.android.c2dm.C2DMBroadcastReceiver">
+ <intent-filter>
+ <action android:name="com.google.android.c2dm.intent.RECEIVE"/>
+ <action android:name="com.google.android.c2dm.intent.REGISTRATION"/>
+ </intent-filter>
+ </receiver>
+ </application>
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ExportedFlagDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ExportedFlagDetector.testNoExportReceiver`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="IntentFilterExportedReceiver"` on the problematic XML
+ element (or one of its enclosing elements). You may also need to add
+ the following namespace declaration on the root element in the XML
+ file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <activity tools:ignore="IntentFilterExportedReceiver" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="IntentFilterExportedReceiver" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'IntentFilterExportedReceiver'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore IntentFilterExportedReceiver ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/IntentFilterUniqueDataAttributes.md.html b/docs/checks/IntentFilterUniqueDataAttributes.md.html
new file mode 100644
index 00000000..59c66a4e
--- /dev/null
+++ b/docs/checks/IntentFilterUniqueDataAttributes.md.html
@@ -0,0 +1,164 @@
+
+(#) Data tags should only declare unique attributes
+
+!!! WARNING: Data tags should only declare unique attributes
+ This is a warning.
+
+Id
+: `IntentFilterUniqueDataAttributes`
+Summary
+: Data tags should only declare unique attributes
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 7.1.0 (January 2022)
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/guide/components/intents-filters
+Implementation
+: [Source Code](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/AppLinksValidDetector.kt)
+Tests
+: [Source Code](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/AppLinksValidDetectorTest.kt)
+
+`` `` tags should only declare a single unique
+attribute (i.e. scheme OR host, but not both). This better matches the
+runtime behavior of intent filters, as they combine all of the declared
+data attributes into a single matcher which is allowed to handle any
+combination across attribute types.
+
+For example, the following two `` declarations are the
+same:
+```xml
+
+
+
+
+```
+
+```xml
+
+
+
+
+
+
+```
+
+They both handle all of the following:
+* http://example.com
+* https://example.com
+* http://example.org
+* https://example.org
+
+The second one better communicates the combining behavior and is clearer
+to an external reader that one should not rely on the scheme/host being
+self contained. It is not obvious in the first that http://example.org
+is also matched, which can lead to confusion (or incorrect behavior)
+with a more complex set of schemes/hosts.
+
+Note that this does not apply to host + port, as those must be declared
+in the same `` tag and are only associated with each other.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:5:Warning: Consider splitting data tag into multiple
+tags with individual attributes to avoid confusion
+[IntentFilterUniqueDataAttributes]
+ <data alt-android:scheme="https" alt-android:host="example.com"/>
+ -----------------------------------------------------------------
+AndroidManifest.xml:6:Warning: Consider splitting data tag into multiple
+tags with individual attributes to avoid confusion
+[IntentFilterUniqueDataAttributes]
+ <data alt-android:scheme="http" alt-android:host="example.org"/>
+ ----------------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest xmlns:alt-android="http://schemas.android.com/apk/res/android"
+ package="com.example.helloworld" >
+ <activity alt-android:name="com.example.Activity">
+ <intent-filter>
+ <data alt-android:scheme="https" alt-android:host="example.com"/>
+ <data alt-android:scheme="http" alt-android:host="example.org"/>
+ </intent-filter>
+ </activity>
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/AppLinksValidDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="IntentFilterUniqueDataAttributes"` on the problematic
+ XML element (or one of its enclosing elements). You may also need to
+ add the following namespace declaration on the root element in the
+ XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <activity tools:ignore="IntentFilterUniqueDataAttributes" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="IntentFilterUniqueDataAttributes" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'IntentFilterUniqueDataAttributes'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore IntentFilterUniqueDataAttributes ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/IntentReset.md.html b/docs/checks/IntentReset.md.html
new file mode 100644
index 00000000..74c35927
--- /dev/null
+++ b/docs/checks/IntentReset.md.html
@@ -0,0 +1,203 @@
+
+(#) Suspicious mix of `setType` and `setData`
+
+!!! WARNING: Suspicious mix of `setType` and `setData`
+ This is a warning.
+
+Id
+: `IntentReset`
+Summary
+: Suspicious mix of `setType` and `setData`
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.2.0 (September 2018)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/IntentDetector.kt)
+Tests
+: [Source Code](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/IntentDetectorTest.kt)
+
+Intent provides the following APIs: `setData(Uri)` and
+`setType(String)`. Unfortunately, setting one clears the other. If you
+want to set both, you should call `setDataAndType(Uri, String)`
+instead.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/IntentTest.java:18:Warning: Calling setType after calling
+setData will clear the data: Call setDataAndType instead? [IntentReset]
+ intent.setType(type); // ERROR 1.1
+ -------------
+src/test/pkg/IntentTest.java:25:Warning: Calling setData after calling
+setType will clear the type: Call setDataAndType instead? [IntentReset]
+ intent.setData(uri); // ERROR 2.1
+ ------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/IntentTest.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.content.Intent;
+import android.net.Uri;
+
+public class IntentTest {
+ public void test1() {
+ // OK: Nulls are allowed
+ Intent intent = new Intent();
+ intent.setData(null); // OK 1
+ intent.setType(null); // OK 2
+ }
+
+ public void test2(Uri uri, String type) {
+ // Error: Cleared
+ Intent intent = new Intent();
+ intent.setData(uri); // ERROR 1.2
+ intent.setType(type); // ERROR 1.1
+ }
+
+ public void test3(Uri uri, String type) {
+ // Error: Cleared (reverse order from test2)
+ Intent intent = new Intent();
+ intent.setType(type); // ERROR 2.2
+ intent.setData(uri); // ERROR 2.1
+ }
+
+ public void test4(Uri uri, String type, boolean setData) {
+ // OK: Different code paths
+ Intent intent = new Intent();
+ if (setData) {
+ intent.setData(uri); // OK 3
+ } else {
+ intent.setType(type); // OK 4
+ }
+ if (setData)
+ intent.setData(uri); // OK 5
+ else
+ intent.setType(type); // OK 6
+ }
+
+ public void test5(Uri uri, String type) {
+ // Ok: on different objects
+ Intent intent1 = new Intent();
+ Intent intent2 = new Intent();
+ intent1.setData(uri); // OK 7
+ intent2.setType(type); // OK 8
+ }
+
+ public void test6(boolean setData, Uri dataUri,
+ boolean setType, String mime) {
+ Intent intent = new Intent();
+ if (setData) {
+ intent.setData(dataUri); // OK 9
+ }
+ if (setType) {
+ intent.setType(mime); // OK 10
+ }
+ }
+
+ public void test7(int flavor, Uri dataUri, String mime) {
+ Intent intent = new Intent();
+ switch (flavor) {
+ case 1:
+ intent.setData(dataUri); // OK 11
+ break;
+ case 2:
+ intent.setType(mime); // OK 12
+ break;
+ }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/IntentDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `IntentDetector.testBasic`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("IntentReset")
+ fun method() {
+ Intent(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("IntentReset")
+ void method() {
+ new Intent(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection IntentReset
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="IntentReset" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'IntentReset'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore IntentReset ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/IntentWithNullActionLaunch.md.html b/docs/checks/IntentWithNullActionLaunch.md.html
new file mode 100644
index 00000000..4ee39ff7
--- /dev/null
+++ b/docs/checks/IntentWithNullActionLaunch.md.html
@@ -0,0 +1,151 @@
+
+(#) Unsafe intent launched with no action set
+
+!!! WARNING: Unsafe intent launched with no action set
+ This is a warning.
+
+Id
+: `IntentWithNullActionLaunch`
+Summary
+: Unsafe intent launched with no action set
+Severity
+: Warning
+Category
+: Security
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 8.2.0 (November 2023)
+Affects
+: Kotlin and Java files and manifest files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/IntentWillNullActionDetector.kt)
+Tests
+: [Source Code](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/IntentWillNullActionDetectorTest.kt)
+
+Intents that have no action and do not specify a component are a
+potential security risk, and using them will result in a crash in an
+upcoming version of Android. If a specific app is being targeted
+(including the case where the current app is the target) then set the
+targeted component using `setComponent()`, `setClass()`,
+`setClassName()`, or the Intent constructors that take a Class
+parameter. If the intent is not intended for a specific app then the
+action name should be set.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/TestActivity.java:10:Warning: This intent has no action set
+and is not explicit by component. You should either make this intent
+explicit by component or set an action matching the targeted intent
+filter. [IntentWithNullActionLaunch]
+ Intent intent = new Intent();
+ ------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/TestActivity.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.content.Intent;
+import android.app.Activity;
+
+public class TestActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ Intent intent = new Intent();
+ startActivity(intent);
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/IntentWillNullActionDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("IntentWithNullActionLaunch")
+ fun method() {
+ Intent(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("IntentWithNullActionLaunch")
+ void method() {
+ new Intent(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection IntentWithNullActionLaunch
+ problematicStatement()
+ ```
+
+* Adding the suppression attribute
+ `tools:ignore="IntentWithNullActionLaunch"` on the problematic XML
+ element (or one of its enclosing elements). You may also need to add
+ the following namespace declaration on the root element in the XML
+ file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="IntentWithNullActionLaunch" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'IntentWithNullActionLaunch'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore IntentWithNullActionLaunch ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InternalAgpApiUsage.md.html b/docs/checks/InternalAgpApiUsage.md.html
new file mode 100644
index 00000000..edb0f919
--- /dev/null
+++ b/docs/checks/InternalAgpApiUsage.md.html
@@ -0,0 +1,173 @@
+
+(#) Avoid using internal Android Gradle Plugin APIs
+
+!!! ERROR: Avoid using internal Android Gradle Plugin APIs
+ This is an error.
+
+Id
+: `InternalAgpApiUsage`
+Summary
+: Avoid using internal Android Gradle Plugin APIs
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Identifier
+: androidx.lint:lint-gradle
+Feedback
+: https://issuetracker.google.com/issues/new?component=1147525
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.lint:lint-gradle](androidx_lint_lint-gradle.md.html)
+Since
+: 1.0.0-alpha02
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/lint/lint-gradle/src/main/java/androidx/lint/gradle/InternalApiUsageDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/lint/lint-gradle/src/test/java/androidx/lint/gradle/InternalApiUsageDetectorTest.kt)
+Copyright Year
+: 2024
+
+Using internal APIs results in fragile plugin behavior as these types
+have no binary
+compatibility guarantees. It is best to create a feature request to open
+up these
+APIs if you find them useful.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test.kt:1:Error: Avoid using internal Android Gradle Plugin APIs
+[InternalAgpApiUsage]
+import com.android.build.gradle.internal.lint.VariantInputs
+-----------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+import com.android.build.gradle.internal.lint.VariantInputs
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/lint/lint-gradle/src/test/java/androidx/lint/gradle/InternalApiUsageDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `InternalApiUsageDetector.Test usage of internal Android Gradle API`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=1147525.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.lint:lint-gradle:1.0.0-alpha04")
+
+// build.gradle
+implementation 'androidx.lint:lint-gradle:1.0.0-alpha04'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.lint.gradle)
+
+# libs.versions.toml
+[versions]
+lint-gradle = "1.0.0-alpha04"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+lint-gradle = {
+ module = "androidx.lint:lint-gradle",
+ version.ref = "lint-gradle"
+}
+```
+
+1.0.0-alpha04 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.lint:lint-gradle](androidx_lint_lint-gradle.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("InternalAgpApiUsage")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("InternalAgpApiUsage")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection InternalAgpApiUsage
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InternalAgpApiUsage" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InternalAgpApiUsage'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InternalAgpApiUsage ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InternalGradleApiUsage.md.html b/docs/checks/InternalGradleApiUsage.md.html
new file mode 100644
index 00000000..e5bf7e01
--- /dev/null
+++ b/docs/checks/InternalGradleApiUsage.md.html
@@ -0,0 +1,182 @@
+
+(#) Avoid using internal Gradle APIs
+
+!!! ERROR: Avoid using internal Gradle APIs
+ This is an error.
+
+Id
+: `InternalGradleApiUsage`
+Summary
+: Avoid using internal Gradle APIs
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Identifier
+: androidx.lint:lint-gradle
+Feedback
+: https://issuetracker.google.com/issues/new?component=1147525
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.lint:lint-gradle](androidx_lint_lint-gradle.md.html)
+Since
+: 1.0.0-alpha02
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/lint/lint-gradle/src/main/java/androidx/lint/gradle/InternalApiUsageDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/lint/lint-gradle/src/test/java/androidx/lint/gradle/InternalApiUsageDetectorTest.kt)
+Copyright Year
+: 2024
+
+Using internal APIs results in fragile plugin behavior as these types
+have no binary
+compatibility guarantees. It is best to create a feature request to open
+up these
+APIs if you find them useful.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test.kt:2:Error: Avoid using internal Gradle APIs
+[InternalGradleApiUsage]
+import org.gradle.api.internal.component.SoftwareComponentInternal
+------------------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+import org.gradle.api.component.SoftwareComponent
+import org.gradle.api.internal.component.SoftwareComponentInternal
+
+fun getSoftwareComponent() : SoftwareComponent {
+ return object : SoftwareComponentInternal {
+ override fun getUsages(): Set {
+ TODO()
+ }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/lint/lint-gradle/src/test/java/androidx/lint/gradle/InternalApiUsageDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `InternalApiUsageDetector.Test usage of internal Gradle API`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=1147525.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.lint:lint-gradle:1.0.0-alpha04")
+
+// build.gradle
+implementation 'androidx.lint:lint-gradle:1.0.0-alpha04'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.lint.gradle)
+
+# libs.versions.toml
+[versions]
+lint-gradle = "1.0.0-alpha04"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+lint-gradle = {
+ module = "androidx.lint:lint-gradle",
+ version.ref = "lint-gradle"
+}
+```
+
+1.0.0-alpha04 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.lint:lint-gradle](androidx_lint_lint-gradle.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("InternalGradleApiUsage")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("InternalGradleApiUsage")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection InternalGradleApiUsage
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InternalGradleApiUsage" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InternalGradleApiUsage'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InternalGradleApiUsage ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InternalInsetResource.md.html b/docs/checks/InternalInsetResource.md.html
new file mode 100644
index 00000000..f877a998
--- /dev/null
+++ b/docs/checks/InternalInsetResource.md.html
@@ -0,0 +1,130 @@
+
+(#) Using internal inset dimension resource
+
+!!! WARNING: Using internal inset dimension resource
+ This is a warning.
+
+Id
+: `InternalInsetResource`
+Summary
+: Using internal inset dimension resource
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 7.3.0 (September 2022)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/InternalInsetResourceDetector.kt)
+Tests
+: [Source Code](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/InternalInsetResourceDetectorTest.kt)
+
+The internal inset dimension resources are not a supported way to
+retrieve the relevant insets for your application. The insets are
+dynamic values that can change while your app is visible, and your app's
+window may not intersect with the system UI. To get the relevant value
+for your app and listen to updates, use
+`androidx.core.view.WindowInsetsCompat` and related APIs.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/test.kt:6:Warning: Using internal inset dimension resource
+status_bar_height is not supported [InternalInsetResource]
+ getIdentifier("status_bar_height", "dimen", "android")
+ ------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+
+import android.content.res.Resources
+
+fun Resources.getStatusBarHeightIdentifier(): Int =
+ getIdentifier("status_bar_height", "dimen", "android")
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/InternalInsetResourceDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("InternalInsetResource")
+ fun method() {
+ getIdentifier(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("InternalInsetResource")
+ void method() {
+ getIdentifier(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection InternalInsetResource
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InternalInsetResource" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InternalInsetResource'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InternalInsetResource ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InvalidAccessibility.md.html b/docs/checks/InvalidAccessibility.md.html
new file mode 100644
index 00000000..5713a093
--- /dev/null
+++ b/docs/checks/InvalidAccessibility.md.html
@@ -0,0 +1,152 @@
+
+(#) Marks invalid accessibility usages
+
+!!! WARNING: Marks invalid accessibility usages
+ This is a warning.
+
+Id
+: `InvalidAccessibility`
+Summary
+: Marks invalid accessibility usages
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: vanniktech/lint-rules/
+Feedback
+: https://github.com/vanniktech/lint-rules/issues
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [com.vanniktech:lint-rules-android](com_vanniktech_lint-rules-android.md.html)
+Since
+: 0.24.0
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/main/kotlin/com/vanniktech/lintrules/android/InvalidAccessibilityDetector.kt)
+Tests
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/test/kotlin/com/vanniktech/lintrules/android/InvalidAccessibilityDetectorTest.kt)
+
+Marks usages of invalid accessibility and suggests corrections.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/ids.xml:5:Warning: Either set a proper accessibility text or
+use importantForAccessibility [InvalidAccessibility]
+ android:contentDescription="@null"/>
+ -----
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/layout/ids.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<ImageView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:contentDescription="@null"/>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/test/kotlin/com/vanniktech/lintrules/android/InvalidAccessibilityDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `InvalidAccessibilityDetector.contentDescriptionNull`.
+To report a problem with this extracted sample, visit
+https://github.com/vanniktech/lint-rules/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.vanniktech:lint-rules-android:0.25.0")
+
+// build.gradle
+lintChecks 'com.vanniktech:lint-rules-android:0.25.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.lint.rules.android)
+
+# libs.versions.toml
+[versions]
+lint-rules-android = "0.25.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+lint-rules-android = {
+ module = "com.vanniktech:lint-rules-android",
+ version.ref = "lint-rules-android"
+}
+```
+
+0.25.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.vanniktech:lint-rules-android](com_vanniktech_lint-rules-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="InvalidAccessibility"` on the problematic XML element
+ (or one of its enclosing elements). You may also need to add the
+ following namespace declaration on the root element in the XML file
+ if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InvalidAccessibility" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InvalidAccessibility'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InvalidAccessibility ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InvalidAnalyticsName.md.html b/docs/checks/InvalidAnalyticsName.md.html
new file mode 100644
index 00000000..e074271b
--- /dev/null
+++ b/docs/checks/InvalidAnalyticsName.md.html
@@ -0,0 +1,136 @@
+
+(#) Invalid Analytics Name
+
+!!! ERROR: Invalid Analytics Name
+ This is an error.
+
+Id
+: `InvalidAnalyticsName`
+Summary
+: Invalid Analytics Name
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 2.3.0 (March 2017)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://firebase.google.com/docs/reference/android/com/google/firebase/analytics/FirebaseAnalytics#logEvent(java.lang.String,%20android.os.Bundle)
+Implementation
+: [Source Code](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/FirebaseAnalyticsDetector.java)
+Tests
+: [Source Code](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/FirebaseAnalyticsDetectorTest.java)
+
+Event names and parameters must follow the naming conventions defined in
+the`FirebaseAnalytics#logEvent()` documentation.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/MainActivity.java:6:Error: Analytics event name must only
+consist of letters, numbers and underscores (found a;)
+[InvalidAnalyticsName]
+ FirebaseAnalytics.getInstance(this).logEvent("a;", new Bundle());
+ ----------------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/MainActivity.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+import android.os.Bundle;
+import com.google.firebase.analytics.FirebaseAnalytics;
+public class MainActivity {
+ public MainActivity() {
+ FirebaseAnalytics.getInstance(this).logEvent("a;", new Bundle());
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/FirebaseAnalyticsDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `FirebaseAnalyticsDetector.testInvalidCharacters`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("InvalidAnalyticsName")
+ fun method() {
+ logEvent(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("InvalidAnalyticsName")
+ void method() {
+ logEvent(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection InvalidAnalyticsName
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InvalidAnalyticsName" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InvalidAnalyticsName'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InvalidAnalyticsName ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InvalidColorHexValue.md.html b/docs/checks/InvalidColorHexValue.md.html
new file mode 100644
index 00000000..966632d9
--- /dev/null
+++ b/docs/checks/InvalidColorHexValue.md.html
@@ -0,0 +1,192 @@
+
+(#) Invalid Color hex value
+
+!!! WARNING: Invalid Color hex value
+ This is a warning.
+
+Id
+: `InvalidColorHexValue`
+Summary
+: Invalid Color hex value
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Jetpack Compose
+Identifier
+: androidx.compose.ui.graphics
+Feedback
+: https://issuetracker.google.com/issues/new?component=612128
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.compose.ui:ui-graphics-android](androidx_compose_ui_ui-graphics-android.md.html)
+Since
+: 1.5.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/ui/ui-graphics-lint/src/main/java/androidx/compose/ui/graphics/lint/ColorDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/ui/ui-graphics-lint/src/test/java/androidx/compose/ui/graphics/lint/ColorDetectorTest.kt)
+Copyright Year
+: 2021
+
+Creating a Color with a hex value requires a 32 bit value (such as
+0xFF000000), with 8 bits being used per channel (ARGB). Not passing a
+full 32 bit value will result in channels being undefined / incorrect.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/test.kt:6:Warning: Invalid Color hex value
+[InvalidColorHexValue]
+ val color = Color(0x00000)
+ -------
+src/test/test.kt:7:Warning: Invalid Color hex value
+[InvalidColorHexValue]
+ val color2 = Color(0xEEEEE)
+ -------
+src/test/test.kt:8:Warning: Invalid Color hex value
+[InvalidColorHexValue]
+ val color3 = Color(0x00_0_0_0L)
+ -----------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test
+
+import androidx.compose.ui.graphics.*
+
+val color = Color(0x00000)
+val color2 = Color(0xEEEEE)
+val color3 = Color(0x00_0_0_0L)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/ui/ui-graphics-lint/src/test/java/androidx/compose/ui/graphics/lint/ColorDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ColorDetector.incorrectChannels`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=612128.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.compose.ui:ui-graphics-android:1.9.0-alpha01")
+
+// build.gradle
+implementation 'androidx.compose.ui:ui-graphics-android:1.9.0-alpha01'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.ui.graphics.android)
+
+# libs.versions.toml
+[versions]
+ui-graphics-android = "1.9.0-alpha01"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+ui-graphics-android = {
+ module = "androidx.compose.ui:ui-graphics-android",
+ version.ref = "ui-graphics-android"
+}
+```
+
+1.9.0-alpha01 is the version this documentation was generated from;
+there may be newer versions available.
+
+NOTE: These lint checks are **also** made available separate from the main library.
+You can also use `androidx.compose.ui:ui-graphics-lint:1.9.0-alpha01`.
+
+
+[Additional details about androidx.compose.ui:ui-graphics-android](androidx_compose_ui_ui-graphics-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("InvalidColorHexValue")
+ fun method() {
+ Color(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("InvalidColorHexValue")
+ void method() {
+ Color(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection InvalidColorHexValue
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InvalidColorHexValue" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InvalidColorHexValue'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InvalidColorHexValue ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InvalidFragmentVersionForActivityResult.md.html b/docs/checks/InvalidFragmentVersionForActivityResult.md.html
new file mode 100644
index 00000000..ee40536f
--- /dev/null
+++ b/docs/checks/InvalidFragmentVersionForActivityResult.md.html
@@ -0,0 +1,188 @@
+
+(#) Update to Fragment 1.3.0 to use ActivityResult APIs
+
+!!! ERROR: Update to Fragment 1.3.0 to use ActivityResult APIs
+ This is an error, and is also enforced at build time when
+ supported by the build system. For Android this means it will
+ run during release builds.
+
+Id
+: `InvalidFragmentVersionForActivityResult`
+Summary
+: Update to Fragment 1.3.0 to use ActivityResult APIs
+Severity
+: Fatal
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Identifier
+: androidx.activity
+Feedback
+: https://issuetracker.google.com/issues/new?component=527362
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.activity:activity](androidx_activity_activity.md.html)
+Since
+: 1.2.0
+Affects
+: Gradle build files and Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/training/permissions/requesting#make-the-request
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/activity/activity-lint/src/main/java/androidx/activity/lint/ActivityResultFragmentVersionDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/activity/activity-lint/src/test/java/androidx/activity/lint/ActivityResultFragmentVersionDetectorTest.kt)
+Copyright Year
+: 2020
+
+In order to use the ActivityResult APIs you must upgrade your
+ Fragment version to 1.3.0. Previous versions of FragmentActivity
+ failed to call super.onRequestPermissionsResult() and used
+invalid request codes.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/main/kotlin/com/example/test.kt:6:Error: Upgrade Fragment version to
+at least . [InvalidFragmentVersionForActivityResult]
+val launcher = ActivityResultCaller().registerForActivityResult(ActivityResultContract())
+ --------------------------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`build.gradle`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~groovy linenumbers
+dependencies {
+ api("androidx.fragment:fragment:1.2.4")
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/main/kotlin/com/example/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package com.example
+
+import androidx.activity.result.ActivityResultCaller
+import androidx.activity.result.contract.ActivityResultContract
+
+val launcher = ActivityResultCaller().registerForActivityResult(ActivityResultContract())
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/activity/activity-lint/src/test/java/androidx/activity/lint/ActivityResultFragmentVersionDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ActivityResultFragmentVersionDetector.expectFailRegisterForActivityResult`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=527362.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.activity:activity:1.11.0-rc01")
+
+// build.gradle
+implementation 'androidx.activity:activity:1.11.0-rc01'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.activity)
+
+# libs.versions.toml
+[versions]
+activity = "1.11.0-rc01"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+activity = {
+ module = "androidx.activity:activity",
+ version.ref = "activity"
+}
+```
+
+1.11.0-rc01 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.activity:activity](androidx_activity_activity.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection InvalidFragmentVersionForActivityResult
+ problematicStatement()
+ ```
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("InvalidFragmentVersionForActivityResult")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("InvalidFragmentVersionForActivityResult")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InvalidFragmentVersionForActivityResult" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InvalidFragmentVersionForActivityResult'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InvalidFragmentVersionForActivityResult ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InvalidId.md.html b/docs/checks/InvalidId.md.html
new file mode 100644
index 00000000..c580250e
--- /dev/null
+++ b/docs/checks/InvalidId.md.html
@@ -0,0 +1,182 @@
+
+(#) Invalid ID declaration
+
+!!! ERROR: Invalid ID declaration
+ This is an error, and is also enforced at build time when
+ supported by the build system. For Android this means it will
+ run during release builds.
+
+Id
+: `InvalidId`
+Summary
+: Invalid ID declaration
+Severity
+: Fatal
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/WrongIdDetector.java)
+Tests
+: [Source Code](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/WrongIdDetectorTest.kt)
+Copyright Year
+: 2011
+
+An id definition **must** be of the form `@+id/yourname`. The tools have
+not rejected strings of the form `@+foo/bar` in the past, but that was
+an error, and could lead to tricky errors because of the way the id
+integers are assigned.
+
+If you really want to have different "scopes" for your id's, use
+prefixes instead, such as `login_button1` and `login_button2`.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/invalid_ids.xml:23:Error: ID definitions must be of the form
+@+id/name; try using @+id/menu_Reload [InvalidId]
+ android:id="@+menu/Reload"
+ --------------------------
+res/layout/invalid_ids.xml:31:Error: ID definitions must be of the form
+@+id/name; try using @+id/_id_foo [InvalidId]
+ android:id="@+/id_foo"
+ ----------------------
+res/layout/invalid_ids.xml:37:Error: ID definitions must be of the form
+@+id/name; try using @+id/myid_button5 [InvalidId]
+ android:id="@+myid/button5"
+ ---------------------------
+res/layout/invalid_ids.xml:43:Error: ID definitions must be of the form
+@+id/name; try using @+id/string_whatevs [InvalidId]
+ android:id="@+string/whatevs"
+ -----------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/layout/invalid_ids.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+
+<!--
+ ~ Copyright (C) 2013 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <Button
+ android:id="@+menu/Reload"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentTop="true"
+ android:text="Button" />
+
+ <LinearLayout
+ android:id="@+/id_foo"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical" >
+
+ <Button
+ android:id="@+myid/button5"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Button" />
+
+ <Button
+ android:id="@+string/whatevs"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Button" />
+ </LinearLayout>
+
+</RelativeLayout>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/WrongIdDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `WrongIdDetector.testInvalidIds1`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="InvalidId"` on the
+ problematic XML element (or one of its enclosing elements). You may
+ also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <resources xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <RelativeLayout id="..." tools:ignore="InvalidId" .../>
+ ...
+ </resources>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InvalidId" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InvalidId'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InvalidId ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InvalidImeActionId.md.html b/docs/checks/InvalidImeActionId.md.html
new file mode 100644
index 00000000..b02a34c3
--- /dev/null
+++ b/docs/checks/InvalidImeActionId.md.html
@@ -0,0 +1,109 @@
+
+(#) Invalid imeActionId declaration
+
+!!! ERROR: Invalid imeActionId declaration
+ This is an error.
+
+Id
+: `InvalidImeActionId`
+Summary
+: Invalid imeActionId declaration
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.0.0 (October 2017)
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/reference/android/view/inputmethod/EditorInfo.html
+Implementation
+: [Source Code](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/InvalidImeActionIdDetector.java)
+Tests
+: [Source Code](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/InvalidImeActionIdDetectorTest.kt)
+
+`android:imeActionId` should not be a resource ID such as
+`@+id/resName`. It must be an integer constant, or an integer resource
+reference, as defined in `EditorInfo`.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/namespace.xml:2:Error: Invalid resource type, expected
+integer value [InvalidImeActionId]
+ <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:imeActionId="@+id/login"/>
+ --------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/layout/namespace.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical">
+ <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:imeActionId="@+id/login"/>
+</LinearLayout>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/InvalidImeActionIdDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `InvalidImeActionIdDetector.testInvalidResourceType`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="InvalidImeActionId"`
+ on the problematic XML element (or one of its enclosing elements).
+ You may also need to add the following namespace declaration on the
+ root element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InvalidImeActionId" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InvalidImeActionId'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InvalidImeActionId ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InvalidImport.md.html b/docs/checks/InvalidImport.md.html
new file mode 100644
index 00000000..6dba29fb
--- /dev/null
+++ b/docs/checks/InvalidImport.md.html
@@ -0,0 +1,172 @@
+
+(#) Flags invalid imports
+
+!!! WARNING: Flags invalid imports
+ This is a warning.
+
+Id
+: `InvalidImport`
+Summary
+: Flags invalid imports
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: vanniktech/lint-rules/
+Feedback
+: https://github.com/vanniktech/lint-rules/issues
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [com.vanniktech:lint-rules-android](com_vanniktech_lint-rules-android.md.html)
+Since
+: 0.6.0
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/main/kotlin/com/vanniktech/lintrules/android/InvalidImportDetector.kt)
+Tests
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/test/kotlin/com/vanniktech/lintrules/android/InvalidImportDetectorTest.kt)
+
+Flags invalid imports. One example is com.foo.bar.R.drawable. Instead
+just the generated class R should be imported and not R.drawable. Also
+you should never import anything that's in an internal package.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/foo/Example.java:3:Warning: Forbidden import [InvalidImport]
+import foo.R.drawable;
+ --------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/foo/Example.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package foo;
+
+import foo.R.drawable;
+
+class Example {
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/test/kotlin/com/vanniktech/lintrules/android/InvalidImportDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `InvalidImportDetector.rDrawableImport`.
+To report a problem with this extracted sample, visit
+https://github.com/vanniktech/lint-rules/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.vanniktech:lint-rules-android:0.25.0")
+
+// build.gradle
+lintChecks 'com.vanniktech:lint-rules-android:0.25.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.lint.rules.android)
+
+# libs.versions.toml
+[versions]
+lint-rules-android = "0.25.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+lint-rules-android = {
+ module = "com.vanniktech:lint-rules-android",
+ version.ref = "lint-rules-android"
+}
+```
+
+0.25.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.vanniktech:lint-rules-android](com_vanniktech_lint-rules-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("InvalidImport")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("InvalidImport")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection InvalidImport
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InvalidImport" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InvalidImport'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InvalidImport ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InvalidLanguageTagDelimiter.md.html b/docs/checks/InvalidLanguageTagDelimiter.md.html
new file mode 100644
index 00000000..dd1461f8
--- /dev/null
+++ b/docs/checks/InvalidLanguageTagDelimiter.md.html
@@ -0,0 +1,182 @@
+
+(#) Underscore (`_`) is an unsupported delimiter for subtags
+
+!!! ERROR: Underscore (`_`) is an unsupported delimiter for subtags
+ This is an error.
+
+Id
+: `InvalidLanguageTagDelimiter`
+Summary
+: Underscore (`_`) is an unsupported delimiter for subtags
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Jetpack Compose
+Identifier
+: androidx.compose.ui.text
+Feedback
+: https://issuetracker.google.com/issues/new?component=779818
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.compose.ui:ui-text-android](androidx_compose_ui_ui-text-android.md.html)
+Since
+: 1.7.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/ui/ui-text-lint/src/main/java/androidx/compose/ui/text/lint/LocaleInvalidLanguageTagDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/ui/ui-text-lint/src/test/java/androidx/compose/ui/text/lint/LocaleInvalidLanguageTagDetectorTest.kt)
+Copyright Year
+: 2024
+
+A language tag must be compliant with IETF BCP47, specifically a
+sequence of subtags must be separated by hyphens (-) instead of
+underscores (_)
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/test.kt:8:Error: A hyphen (-), not an underscore (_) delimiter
+should be used in a language tag [InvalidLanguageTagDelimiter]
+ bar(Locale("en_UK"))
+ -------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test
+
+import androidx.compose.ui.text.intl.Locale
+
+fun bar(locale: Locale) {}
+fun foo() {
+ bar(Locale("en_UK"))
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/ui/ui-text-lint/src/test/java/androidx/compose/ui/text/lint/LocaleInvalidLanguageTagDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `LocaleInvalidLanguageTagDetector.underscoreDelimiter_locale_shouldWarn`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=779818.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.compose.ui:ui-text-android:1.9.0-alpha01")
+
+// build.gradle
+implementation 'androidx.compose.ui:ui-text-android:1.9.0-alpha01'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.ui.text.android)
+
+# libs.versions.toml
+[versions]
+ui-text-android = "1.9.0-alpha01"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+ui-text-android = {
+ module = "androidx.compose.ui:ui-text-android",
+ version.ref = "ui-text-android"
+}
+```
+
+1.9.0-alpha01 is the version this documentation was generated from;
+there may be newer versions available.
+
+NOTE: These lint checks are **also** made available separate from the main library.
+You can also use `androidx.compose.ui:ui-text-lint:1.9.0-alpha01`.
+
+
+[Additional details about androidx.compose.ui:ui-text-android](androidx_compose_ui_ui-text-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("InvalidLanguageTagDelimiter")
+ fun method() {
+ LocaleList(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("InvalidLanguageTagDelimiter")
+ void method() {
+ new LocaleList(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection InvalidLanguageTagDelimiter
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InvalidLanguageTagDelimiter" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InvalidLanguageTagDelimiter'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InvalidLanguageTagDelimiter ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InvalidNavigation.md.html b/docs/checks/InvalidNavigation.md.html
new file mode 100644
index 00000000..d8c8b0eb
--- /dev/null
+++ b/docs/checks/InvalidNavigation.md.html
@@ -0,0 +1,130 @@
+
+(#) No start destination specified
+
+!!! WARNING: No start destination specified
+ This is a warning.
+
+Id
+: `InvalidNavigation`
+Summary
+: No start destination specified
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.2.0 (September 2018)
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/StartDestinationDetector.kt)
+Tests
+: [Source Code](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/StartDestinationDetectorTest.kt)
+
+All `` elements must have a start destination specified, and
+it must be a direct child of that ``.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/navigation/navigation.xml:5:Warning: Invalid start destination
+@id/includedId [InvalidNavigation]
+ app:startDestination="@id/includedId">
+ --------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`res/navigation/navigation.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+ <navigation
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ app:startDestination="@id/includedId">
+ <include app:graph="@navigation/foo"/>
+ </navigation>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/navigation/foo.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+ <navigation
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id='@+id/includedId2'
+ app:startDestination="@id/foo2">
+ <fragment android:id="@+id/foo2"/>
+ </navigation>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/StartDestinationDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `StartDestinationDetector.testIncludeInvalid`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="InvalidNavigation"`
+ on the problematic XML element (or one of its enclosing elements).
+ You may also need to add the following namespace declaration on the
+ root element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <navigation xmlns:tools="http://schemas.android.com/tools"
+ tools:ignore="InvalidNavigation" ...>
+ ...
+ </navigation>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InvalidNavigation" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InvalidNavigation'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InvalidNavigation ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InvalidPackage.md.html b/docs/checks/InvalidPackage.md.html
new file mode 100644
index 00000000..2f053a02
--- /dev/null
+++ b/docs/checks/InvalidPackage.md.html
@@ -0,0 +1,187 @@
+
+(#) Package not included in Android
+
+!!! ERROR: Package not included in Android
+ This is an error.
+
+Id
+: `InvalidPackage`
+Summary
+: Package not included in Android
+Note
+: **This issue is disabled by default**; use `--enable InvalidPackage`
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Library bytecode
+Editing
+: This check can *not* run live in the IDE editor
+Implementation
+: [Source Code](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/InvalidPackageDetector.java)
+Tests
+: [Source Code](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/InvalidPackageDetectorTest.java)
+Copyright Year
+: 2012
+
+This check scans through libraries looking for calls to APIs that are
+not included in Android.
+
+When you create Android projects, the classpath is set up such that you
+can only access classes in the API packages that are included in
+Android. However, if you add other projects to your libs/ folder, there
+is no guarantee that those .jar files were built with an Android
+specific classpath, and in particular, they could be accessing
+unsupported APIs such as java.applet.
+
+This check scans through library jars and looks for references to API
+packages that are not included in Android and flags these. This is only
+an error if your code calls one of the library classes which wind up
+referencing the unsupported package.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+libs/unsupported.jar:Error: Invalid package reference in library; not
+included in Android: javax.swing. Referenced from test.pkg.LibraryClass.
+[InvalidPackage]
+2 errors, 0 warnings
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant test files:
+
+`res/layout/layout.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <!-- Requires API 5 -->
+
+ <QuickContactBadge
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <!-- Requires API 11 -->
+
+ <CalendarView
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent" />
+
+ <!-- Requires API 14 -->
+
+ <GridLayout
+ foo="@android:attr/actionBarSplitStyle"
+ bar="@android:color/holo_red_light"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent" >
+
+ <Button
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent" />
+ </GridLayout>
+
+</LinearLayout>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values/themes.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <style name="Theme" parent="android:Theme"/>
+
+ <style name="Theme.Test" parent="android:style/Theme.Light">
+ <item name="android:windowNoTitle">true</item>
+ <item name="android:windowContentOverlay">@null</item>
+ <!-- Requires API 14 -->
+ <item name="android:windowBackground"> @android:color/holo_red_light </item>
+ </style>
+
+ <style name="Theme.Test.Transparent">
+ <item name="android:windowBackground">@android:color/transparent</item>
+ </style>
+
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/color/colors.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <style name="Theme" parent="android:Theme"/>
+
+ <style name="Theme.Test" parent="android:style/Theme.Light">
+ <item name="android:windowNoTitle">true</item>
+ <item name="android:windowContentOverlay">@null</item>
+ <!-- Requires API 14 -->
+ <item name="android:windowBackground"> @android:color/holo_red_light </item>
+ </style>
+
+ <style name="Theme.Test.Transparent">
+ <item name="android:windowBackground">@android:color/transparent</item>
+ </style>
+
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+[libs/unsupported.jar](examples/libs/unsupported.jar)
+
+You can also visit the
+[source code](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/InvalidPackageDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `InvalidPackageDetector.testUnsupportedJavaLibraryCode`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InvalidPackage" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InvalidPackage'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InvalidPackage ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InvalidPeriodicWorkRequestInterval.md.html b/docs/checks/InvalidPeriodicWorkRequestInterval.md.html
new file mode 100644
index 00000000..986cda09
--- /dev/null
+++ b/docs/checks/InvalidPeriodicWorkRequestInterval.md.html
@@ -0,0 +1,192 @@
+
+(#) Invalid interval duration
+
+!!! ERROR: Invalid interval duration
+ This is an error, and is also enforced at build time when
+ supported by the build system. For Android this means it will
+ run during release builds.
+
+Id
+: `InvalidPeriodicWorkRequestInterval`
+Summary
+: Invalid interval duration
+Severity
+: Fatal
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Identifier
+: androidx.work
+Feedback
+: https://issuetracker.google.com/issues/new?component=409906
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.work:work-runtime](androidx_work_work-runtime.md.html)
+Since
+: 2.3.4
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/work/work-lint/src/main/java/androidx/work/lint/InvalidPeriodicWorkRequestIntervalDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/work/work-lint/src/test/java/androidx/work/lint/InvalidPeriodicWorkRequestIntervalDetectorTest.kt)
+Copyright Year
+: 2020
+
+The interval duration for a `PeriodicWorkRequest` must be at least 15
+minutes.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+com/example/Test.kt:9:Error: Interval duration for
+`PeriodicWorkRequest`s must be at least 15 minutes.
+[InvalidPeriodicWorkRequestInterval]
+ val builder = PeriodicWorkRequest.Builder(TestWorker::class.java, 15L, TimeUnit.MILLISECONDS)
+ -------------------------------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`com/example/TestWorker.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package com.example
+
+import androidx.work.ListenableWorker
+
+class TestWorker: ListenableWorker()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`com/example/Test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package com.example
+
+import androidx.work.PeriodicWorkRequest
+import com.example.TestWorker
+import java.util.concurrent.TimeUnit
+
+class Test {
+ fun enqueue() {
+ val builder = PeriodicWorkRequest.Builder(TestWorker::class.java, 15L, TimeUnit.MILLISECONDS)
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/work/work-lint/src/test/java/androidx/work/lint/InvalidPeriodicWorkRequestIntervalDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `InvalidPeriodicWorkRequestIntervalDetector.testWithInvalidDurationTimeUnits`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=409906.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.work:work-runtime:2.10.1")
+
+// build.gradle
+implementation 'androidx.work:work-runtime:2.10.1'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.work.runtime)
+
+# libs.versions.toml
+[versions]
+work-runtime = "2.10.1"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+work-runtime = {
+ module = "androidx.work:work-runtime",
+ version.ref = "work-runtime"
+}
+```
+
+2.10.1 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.work:work-runtime](androidx_work_work-runtime.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("InvalidPeriodicWorkRequestInterval")
+ fun method() {
+ Builder(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("InvalidPeriodicWorkRequestInterval")
+ void method() {
+ new Builder(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection InvalidPeriodicWorkRequestInterval
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InvalidPeriodicWorkRequestInterval" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InvalidPeriodicWorkRequestInterval'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InvalidPeriodicWorkRequestInterval ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InvalidPermission.md.html b/docs/checks/InvalidPermission.md.html
new file mode 100644
index 00000000..1e43e41c
--- /dev/null
+++ b/docs/checks/InvalidPermission.md.html
@@ -0,0 +1,137 @@
+
+(#) Invalid Permission Attribute
+
+!!! ERROR: Invalid Permission Attribute
+ This is an error.
+
+Id
+: `InvalidPermission`
+Summary
+: Invalid Permission Attribute
+Severity
+: Error
+Category
+: Security
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 2.3.0 (March 2017)
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/ManifestPermissionAttributeDetector.java)
+Tests
+: [Source Code](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/ManifestPermissionAttributeDetectorTest.kt)
+
+Not all elements support the permission attribute. If a permission is
+set on an invalid element, it is a no-op and ignored. Ensure that this
+permission attribute was set on the correct element to protect the
+correct component.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:19:Error: Protecting an unsupported element with a
+permission is a no-op and potentially dangerous [InvalidPermission]
+ android:permission="android.permission.READ_CONTACTS"/>
+ -----------------------------------------------------
+AndroidManifest.xml:22:Error: Protecting an unsupported element with a
+permission is a no-op and potentially dangerous [InvalidPermission]
+ android:permission="android.permission.SET_WALLPAPER"/>
+ -----------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="foo.bar2"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk android:minSdkVersion="14"/>
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:permission="android.permission.READ_CONTACTS">
+ <activity
+ android:label="@string/app_name"
+ android:name="com.sample.service.serviceClass"
+ android:permission="android.permission.CAMERA">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"
+ android:permission="android.permission.READ_CONTACTS"/>
+
+ <category android:name="android.intent.category.LAUNCHER"
+ android:permission="android.permission.SET_WALLPAPER"/>
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ManifestPermissionAttributeDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ManifestPermissionAttributeDetector.testWrongTagPermissions1`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="InvalidPermission"`
+ on the problematic XML element (or one of its enclosing elements).
+ You may also need to add the following namespace declaration on the
+ root element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InvalidPermission" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InvalidPermission'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InvalidPermission ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InvalidResourceFolder.md.html b/docs/checks/InvalidResourceFolder.md.html
new file mode 100644
index 00000000..b793fdea
--- /dev/null
+++ b/docs/checks/InvalidResourceFolder.md.html
@@ -0,0 +1,129 @@
+
+(#) Invalid Resource Folder
+
+!!! ERROR: Invalid Resource Folder
+ This is an error.
+
+Id
+: `InvalidResourceFolder`
+Summary
+: Invalid Resource Folder
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 1.1.0 (February 2015)
+Affects
+: Resource folders
+Editing
+: This check can *not* run live in the IDE editor
+See
+: https://developer.android.com/guide/topics/resources/providing-resources.html
+See
+: https://tools.ietf.org/html/bcp47
+Implementation
+: [Source Code](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/LocaleFolderDetector.java)
+Tests
+: [Source Code](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/LocaleFolderDetectorTest.kt)
+
+This lint check looks for a folder name that is not a valid resource
+folder name; these will be ignored and not packaged by the Android
+Gradle build plugin.
+
+Note that the order of resources is very important; for example, you
+can't specify a language before a network code.
+
+Similarly, note that to use 3 letter region codes, you have to use a
+special BCP 47 syntax: the prefix b+ followed by the BCP 47 language tag
+but with `+` as the individual separators instead of `-`. Therefore, for
+the BCP 47 language tag `nl-ABW` you have to use `b+nl+ABW`.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/values-ldtrl-mnc123/strings.xml:Error: Invalid resource folder: make
+sure qualifiers appear in the correct order, are spelled correctly, etc.
+[InvalidResourceFolder]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`res/values/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<resources>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values-ldtrl-mnc123/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<resources>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values-kok-rIN/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<resources>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values-no-rNOR/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<resources>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/LocaleFolderDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `LocaleFolderDetector.testInvalidFolder`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InvalidResourceFolder" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InvalidResourceFolder'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InvalidResourceFolder ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InvalidSetHasFixedSize.md.html b/docs/checks/InvalidSetHasFixedSize.md.html
new file mode 100644
index 00000000..61d7b0eb
--- /dev/null
+++ b/docs/checks/InvalidSetHasFixedSize.md.html
@@ -0,0 +1,205 @@
+
+(#) When using `setHasFixedSize()` in an `RecyclerView`, `wrap_content` cannot be used as a value for `size` in the scrolling direction.
+
+!!! ERROR: When using `setHasFixedSize()` in an `RecyclerView`, `wrap_content` cannot be used as a value for `size` in the scrolling direction.
+ This is an error, and is also enforced at build time when
+ supported by the build system. For Android this means it will
+ run during release builds.
+
+Id
+: `InvalidSetHasFixedSize`
+Summary
+: When using `setHasFixedSize()` in an `RecyclerView`, `wrap_content` cannot be used as a value for `size` in the scrolling direction.
+Severity
+: Fatal
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Identifier
+: androidx.recyclerview
+Feedback
+: https://issuetracker.google.com/issues/new?component=460887
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [androidx.recyclerview:recyclerview](androidx_recyclerview_recyclerview.md.html)
+Since
+: 1.2.0
+Affects
+: Kotlin and Java files and resource files
+Editing
+: This check can *not* run live in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/recyclerview/recyclerview-lint/src/main/java/androidx/recyclerview/lint/InvalidSetHasFixedSizeDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/recyclerview/recyclerview-lint/src/test/java/androidx/recyclerview/lint/InvalidSetHasFixedSizeTest.kt)
+Copyright Year
+: 2020
+
+When a RecyclerView uses `setHasFixedSize(...)` you cannot use
+`wrap_content` for size in the scrolling direction.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+com/example/Example.kt:10:Error: When using `setHasFixedSize() in an
+RecyclerView, wrap_content cannot be used as a value for size in the
+scrolling direction. [InvalidSetHasFixedSize]
+ recyclerView?.setHasFixedSize(true)
+ -----------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`layout/recycler_view.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+ <androidx.recyclerview.widget.RecyclerView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/my_recycler_view"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`com/example/R.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package com.example
+
+object R {
+ object id {
+ const val my_recycler_view = 0
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`com/example/Example.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package com.example
+
+import android.view.View
+import androidx.recyclerview.widget.RecyclerView
+
+class Example {
+ fun main() {
+ val view: View = TODO()
+ val recyclerView = view.findViewById(R.id.my_recycler_view)
+ recyclerView?.setHasFixedSize(true)
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/recyclerview/recyclerview-lint/src/test/java/androidx/recyclerview/lint/InvalidSetHasFixedSizeTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `InvalidSetHasFixedSizeDetector.testInCorrectUsageOfFixedSize`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=460887.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.recyclerview:recyclerview:1.4.0")
+
+// build.gradle
+implementation 'androidx.recyclerview:recyclerview:1.4.0'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.recyclerview)
+
+# libs.versions.toml
+[versions]
+recyclerview = "1.4.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+recyclerview = {
+ module = "androidx.recyclerview:recyclerview",
+ version.ref = "recyclerview"
+}
+```
+
+1.4.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.recyclerview:recyclerview](androidx_recyclerview_recyclerview.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("InvalidSetHasFixedSize")
+ fun method() {
+ setHasFixedSize(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("InvalidSetHasFixedSize")
+ void method() {
+ setHasFixedSize(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection InvalidSetHasFixedSize
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InvalidSetHasFixedSize" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InvalidSetHasFixedSize'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InvalidSetHasFixedSize ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InvalidSingleLineComment.md.html b/docs/checks/InvalidSingleLineComment.md.html
new file mode 100644
index 00000000..b0959813
--- /dev/null
+++ b/docs/checks/InvalidSingleLineComment.md.html
@@ -0,0 +1,176 @@
+
+(#) Marks single line comments that are not sentences
+
+!!! WARNING: Marks single line comments that are not sentences
+ This is a warning.
+
+Id
+: `InvalidSingleLineComment`
+Summary
+: Marks single line comments that are not sentences
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: vanniktech/lint-rules/
+Feedback
+: https://github.com/vanniktech/lint-rules/issues
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [com.vanniktech:lint-rules-android](com_vanniktech_lint-rules-android.md.html)
+Since
+: 0.6.0
+Affects
+: Gradle build files and Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/main/kotlin/com/vanniktech/lintrules/android/InvalidSingleLineCommentDetector.kt)
+Tests
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/test/kotlin/com/vanniktech/lintrules/android/InvalidSingleLineCommentDetectorTest.kt)
+
+Single line comments should always be sentences. They're part of the
+code and hence they deserve as much detail and respect as code.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/foo/Example.java:5:Warning: Comment does not contain a space at the
+beginning [InvalidSingleLineComment]
+ //Something.
+ ---
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/foo/Example.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package foo;
+
+class Example {
+ public void foo() {
+ //Something.
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/test/kotlin/com/vanniktech/lintrules/android/InvalidSingleLineCommentDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `InvalidSingleLineCommentDetector.invalidSingleLineCommentNoSpace`.
+To report a problem with this extracted sample, visit
+https://github.com/vanniktech/lint-rules/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.vanniktech:lint-rules-android:0.25.0")
+
+// build.gradle
+lintChecks 'com.vanniktech:lint-rules-android:0.25.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.lint.rules.android)
+
+# libs.versions.toml
+[versions]
+lint-rules-android = "0.25.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+lint-rules-android = {
+ module = "com.vanniktech:lint-rules-android",
+ version.ref = "lint-rules-android"
+}
+```
+
+0.25.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.vanniktech:lint-rules-android](com_vanniktech_lint-rules-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("InvalidSingleLineComment")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("InvalidSingleLineComment")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection InvalidSingleLineComment
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InvalidSingleLineComment" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InvalidSingleLineComment'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InvalidSingleLineComment ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InvalidString.md.html b/docs/checks/InvalidString.md.html
new file mode 100644
index 00000000..2cb78097
--- /dev/null
+++ b/docs/checks/InvalidString.md.html
@@ -0,0 +1,160 @@
+
+(#) Marks invalid translation strings
+
+!!! WARNING: Marks invalid translation strings
+ This is a warning.
+
+Id
+: `InvalidString`
+Summary
+: Marks invalid translation strings
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: vanniktech/lint-rules/
+Feedback
+: https://github.com/vanniktech/lint-rules/issues
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [com.vanniktech:lint-rules-android](com_vanniktech_lint-rules-android.md.html)
+Since
+: 0.6.0
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/main/kotlin/com/vanniktech/lintrules/android/InvalidStringDetector.kt)
+Tests
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/test/kotlin/com/vanniktech/lintrules/android/InvalidStringDetectorTest.kt)
+
+A translation string is invalid if it contains new lines instead of the
+escaped \n or if it contains trailing whitespace.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/values/strings.xml:2:Warning: Text contains new line.
+[InvalidString]
+ <string name="my_string">My string"
+ ^
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/values/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<resources>
+ <string name="my_string">My string"
+</string>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/test/kotlin/com/vanniktech/lintrules/android/InvalidStringDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `InvalidStringDetector.stringContainingNewLine`.
+To report a problem with this extracted sample, visit
+https://github.com/vanniktech/lint-rules/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.vanniktech:lint-rules-android:0.25.0")
+
+// build.gradle
+lintChecks 'com.vanniktech:lint-rules-android:0.25.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.lint.rules.android)
+
+# libs.versions.toml
+[versions]
+lint-rules-android = "0.25.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+lint-rules-android = {
+ module = "com.vanniktech:lint-rules-android",
+ version.ref = "lint-rules-android"
+}
+```
+
+0.25.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.vanniktech:lint-rules-android](com_vanniktech_lint-rules-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="InvalidString"` on
+ the problematic XML element (or one of its enclosing elements). You
+ may also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <resources xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <string tools:ignore="InvalidString" .../>
+ ...
+ </resources>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InvalidString" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InvalidString'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InvalidString ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InvalidUseOfOnBackPressed.md.html b/docs/checks/InvalidUseOfOnBackPressed.md.html
new file mode 100644
index 00000000..01998e86
--- /dev/null
+++ b/docs/checks/InvalidUseOfOnBackPressed.md.html
@@ -0,0 +1,194 @@
+
+(#) Do not call onBackPressed() within OnBackPressedDisptacher
+
+!!! WARNING: Do not call onBackPressed() within OnBackPressedDisptacher
+ This is a warning.
+
+Id
+: `InvalidUseOfOnBackPressed`
+Summary
+: Do not call onBackPressed() within OnBackPressedDisptacher
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Identifier
+: androidx.activity
+Feedback
+: https://issuetracker.google.com/issues/new?component=527362
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.activity:activity](androidx_activity_activity.md.html)
+Since
+: 1.9.0
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/guide/navigation/custom-back/predictive-back-gesture#ui-logic
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/activity/activity-lint/src/main/java/androidx/activity/lint/OnBackPressedDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/activity/activity-lint/src/test/java/androidx/activity/lint/OnBackPressedDispatcherTest.kt)
+Copyright Year
+: 2024
+
+You should not used OnBackPressedCallback for non-UI cases. If you
+ |add a callback, you have to handle back completely in
+the callback.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/com/example/test.kt:12:Warning: Should not call onBackPressed inside
+of OnBackPressedCallback.handledOnBackPressed
+[InvalidUseOfOnBackPressed]
+ activity.onBackPressed()
+ ------------------------
+src/com/example/test.kt:14:Warning: Should not call onBackPressed inside
+of OnBackPressedCallback.handledOnBackPressed
+[InvalidUseOfOnBackPressed]
+ dispatcher.onBackPressed()
+ --------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/com/example/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package com.example
+
+import androidx.activity.ComponentActivity
+import androidx.activity.OnBackPressedCallback
+import androidx.activity.OnBackPressedDispatcher
+
+fun test() {
+ object: OnBackPressedCallback {
+ override fun handledOnBackPressed() {
+ val activity = ComponentActivity()
+ activity.onBackPressed()
+ val dispatcher = OnBackPressedDispatcher()
+ dispatcher.onBackPressed()
+ }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/activity/activity-lint/src/test/java/androidx/activity/lint/OnBackPressedDispatcherTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `OnBackPressedDetector.expectFailOnBackPressed`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=527362.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.activity:activity:1.11.0-rc01")
+
+// build.gradle
+implementation 'androidx.activity:activity:1.11.0-rc01'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.activity)
+
+# libs.versions.toml
+[versions]
+activity = "1.11.0-rc01"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+activity = {
+ module = "androidx.activity:activity",
+ version.ref = "activity"
+}
+```
+
+1.11.0-rc01 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.activity:activity](androidx_activity_activity.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("InvalidUseOfOnBackPressed")
+ fun method() {
+ onBackPressed(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("InvalidUseOfOnBackPressed")
+ void method() {
+ onBackPressed(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection InvalidUseOfOnBackPressed
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InvalidUseOfOnBackPressed" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InvalidUseOfOnBackPressed'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InvalidUseOfOnBackPressed ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InvalidUsesTagAttribute.md.html b/docs/checks/InvalidUsesTagAttribute.md.html
new file mode 100644
index 00000000..980b4c90
--- /dev/null
+++ b/docs/checks/InvalidUsesTagAttribute.md.html
@@ -0,0 +1,186 @@
+
+(#) Invalid `name` attribute for `uses` element
+
+!!! ERROR: Invalid `name` attribute for `uses` element
+ This is an error.
+
+Id
+: `InvalidUsesTagAttribute`
+Summary
+: Invalid `name` attribute for `uses` element
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 1.5.0 (November 2015)
+Affects
+: Kotlin and Java files, manifest files and resource files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/training/auto/start/index.html#auto-metadata
+Implementation
+: [Source Code](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/AndroidAutoDetector.java)
+Tests
+: [Source Code](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/AndroidAutoDetectorTest.java)
+
+The element in `` should contain a valid value for
+the `name` attribute. Valid values are `media`, `notification`, or
+`sms`.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/xml/automotive_app_desc.xml:3:Error: Expecting one of media,
+notification, sms, or template for the name attribute in uses tag
+[InvalidUsesTagAttribute]
+ <uses name="medias"/>
+ -------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="com.example.android.uamp">
+
+ <application
+ android:name=".UAMPApplication"
+ android:label="@string/app_name"
+ android:theme="@style/UAmpAppTheme">
+
+ <meta-data
+ android:name="com.google.android.gms.car.application"
+ android:resource="@xml/automotive_app_desc"/>
+
+ <service
+ android:name=".MusicService"
+ android:exported="true"
+ tools:ignore="ExportedService">
+ <intent-filter>
+ <action android:name="android.media.browse.MediaBrowserService"/>
+ </intent-filter>
+ <intent-filter>
+ <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ </intent-filter>
+ </service>
+
+ </application>
+
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/xml/automotive_app_desc.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<automotiveApp>
+ <uses name="medias"/>
+</automotiveApp>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/AndroidAutoDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `AndroidAutoDetector.testInvalidUsesTagInMetadataFile`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="InvalidUsesTagAttribute"` on the problematic XML
+ element (or one of its enclosing elements). You may also need to add
+ the following namespace declaration on the root element in the XML
+ file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <automotiveApp tools:ignore="InvalidUsesTagAttribute" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("InvalidUsesTagAttribute")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("InvalidUsesTagAttribute")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection InvalidUsesTagAttribute
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InvalidUsesTagAttribute" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InvalidUsesTagAttribute'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InvalidUsesTagAttribute ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InvalidVectorPath.md.html b/docs/checks/InvalidVectorPath.md.html
new file mode 100644
index 00000000..b53e5dd9
--- /dev/null
+++ b/docs/checks/InvalidVectorPath.md.html
@@ -0,0 +1,120 @@
+
+(#) Invalid vector paths
+
+!!! ERROR: Invalid vector paths
+ This is an error.
+
+Id
+: `InvalidVectorPath`
+Summary
+: Invalid vector paths
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.0.0 (October 2017)
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://issuetracker.google.com/37008268
+Implementation
+: [Source Code](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/VectorPathDetector.java)
+Tests
+: [Source Code](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/VectorPathDetectorTest.java)
+
+This check ensures that vector paths are valid. For example, it makes
+sure that the numbers are not using scientific notation (such as 1.0e3)
+which can lead to runtime crashes on older devices. As another example,
+it flags numbers like `.5` which should be written as `0.5` instead to
+avoid crashes on some pre-Marshmallow devices.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/drawable/my_vector.xml:7:Error: Avoid scientific notation (1.05e-4)
+in vector paths because it can lead to crashes on some devices. Use
+0.000105 instead. [InvalidVectorPath]
+ android:pathData="m 1.05e-4,2.75448" />
+ -------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/drawable/my_vector.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:name="root" android:width="48dp" android:height="48dp"
+ android:viewportHeight="48" android:viewportWidth="48">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="m 1.05e-4,2.75448" />
+</vector>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/VectorPathDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `VectorPathDetector.testInvalidScientificNotation`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="InvalidVectorPath"`
+ on the problematic XML element (or one of its enclosing elements).
+ You may also need to add the following namespace declaration on the
+ root element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InvalidVectorPath" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InvalidVectorPath'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InvalidVectorPath ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InvalidWakeLockTag.md.html b/docs/checks/InvalidWakeLockTag.md.html
new file mode 100644
index 00000000..05e1af87
--- /dev/null
+++ b/docs/checks/InvalidWakeLockTag.md.html
@@ -0,0 +1,141 @@
+
+(#) Invalid Wake Lock Tag
+
+!!! ERROR: Invalid Wake Lock Tag
+ This is an error.
+
+Id
+: `InvalidWakeLockTag`
+Summary
+: Invalid Wake Lock Tag
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.2.0 (September 2018)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/reference/android/os/PowerManager.html
+Implementation
+: [Source Code](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/PowerManagerDetector.java)
+Tests
+: [Source Code](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/PowerManagerDetectorTest.java)
+
+Wake Lock tags must follow the naming conventions defined in
+the`PowerManager` documentation.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/WakelockActivity.java:12:Error: Tag name should not be
+empty to make wake lock problems easier to debug [InvalidWakeLockTag]
+ mWakeLock = manager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
+ -------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/WakelockActivity.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.PowerManager;
+
+public class WakelockActivity extends Activity {
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ PowerManager manager = (PowerManager) getSystemService(POWER_SERVICE);
+ mWakeLock = manager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/PowerManagerDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `PowerManagerDetector.testInvalidEmptyTag`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("InvalidWakeLockTag")
+ fun method() {
+ newWakeLock(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("InvalidWakeLockTag")
+ void method() {
+ newWakeLock(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection InvalidWakeLockTag
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InvalidWakeLockTag" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InvalidWakeLockTag'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InvalidWakeLockTag ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/InvalidWearFeatureAttribute.md.html b/docs/checks/InvalidWearFeatureAttribute.md.html
new file mode 100644
index 00000000..95f52432
--- /dev/null
+++ b/docs/checks/InvalidWearFeatureAttribute.md.html
@@ -0,0 +1,126 @@
+
+(#) Invalid attribute for Wear uses-feature
+
+!!! ERROR: Invalid attribute for Wear uses-feature
+ This is an error.
+
+Id
+: `InvalidWearFeatureAttribute`
+Summary
+: Invalid attribute for Wear uses-feature
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.0.0 (October 2017)
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/training/wearables/apps/packaging.html
+Implementation
+: [Source Code](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/WearStandaloneAppDetector.java)
+Tests
+: [Source Code](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/WearStandaloneAppDetectorTest.java)
+
+For the `android.hardware.type.watch` uses-feature,
+android:required="false" is disallowed. A single APK for Wear and
+non-Wear devices is not supported.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:4:Error: android:required="false" is not supported
+for this feature [InvalidWearFeatureAttribute]
+ <uses-feature android:name="android.hardware.type.watch" android:required="false"/>
+ ------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" >
+ <uses-sdk android:targetSdkVersion="23" />
+ <uses-feature android:name="android.hardware.type.watch" android:required="false"/>
+ <application>
+ <meta-data
+ android:name="com.google.android.wearable.standalone"
+ android:value="true"
+ /> </application>
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/WearStandaloneAppDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `WearStandaloneAppDetector.testInvalidAttributeValueForUsesFeature`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="InvalidWearFeatureAttribute"` on the problematic XML
+ element (or one of its enclosing elements). You may also need to add
+ the following namespace declaration on the root element in the XML
+ file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <uses-feature tools:ignore="InvalidWearFeatureAttribute" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="InvalidWearFeatureAttribute" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'InvalidWearFeatureAttribute'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore InvalidWearFeatureAttribute ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/JCenter.md.html b/docs/checks/JCenter.md.html
new file mode 100644
index 00000000..baca7f0c
--- /dev/null
+++ b/docs/checks/JCenter.md.html
@@ -0,0 +1,153 @@
+
+(#) Marks usage of the jcenter() repository
+
+!!! WARNING: Marks usage of the jcenter() repository
+ This is a warning.
+
+Id
+: `JCenter`
+Summary
+: Marks usage of the jcenter() repository
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: vanniktech/lint-rules/
+Feedback
+: https://github.com/vanniktech/lint-rules/issues
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [com.vanniktech:lint-rules-android](com_vanniktech_lint-rules-android.md.html)
+Since
+: 0.8.0
+Affects
+: Gradle build files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/main/kotlin/com/vanniktech/lintrules/android/JcenterDetector.kt)
+Tests
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/test/kotlin/com/vanniktech/lintrules/android/JcenterDetectorTest.kt)
+
+JCenter has gotten less and less reliable and it's best to avoid if
+possible. This check will flag usages of jcenter() in your gradle
+files.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+build.gradle:3:Warning: Don't use jcenter() [JCenter]
+ jcenter()
+ ---------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`build.gradle`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~groovy linenumbers
+buildscript {
+ repositories {
+ jcenter()
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/test/kotlin/com/vanniktech/lintrules/android/JcenterDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `JcenterDetector.jcenter`.
+To report a problem with this extracted sample, visit
+https://github.com/vanniktech/lint-rules/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.vanniktech:lint-rules-android:0.25.0")
+
+// build.gradle
+lintChecks 'com.vanniktech:lint-rules-android:0.25.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.lint.rules.android)
+
+# libs.versions.toml
+[versions]
+lint-rules-android = "0.25.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+lint-rules-android = {
+ module = "com.vanniktech:lint-rules-android",
+ version.ref = "lint-rules-android"
+}
+```
+
+0.25.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.vanniktech:lint-rules-android](com_vanniktech_lint-rules-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection JCenter
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="JCenter" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'JCenter'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore JCenter ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/JavaOnlyDetector.md.html b/docs/checks/JavaOnlyDetector.md.html
new file mode 100644
index 00000000..48f8a0ea
--- /dev/null
+++ b/docs/checks/JavaOnlyDetector.md.html
@@ -0,0 +1,193 @@
+
+(#) Using @JavaOnly elements in Kotlin code
+
+!!! ERROR: Using @JavaOnly elements in Kotlin code
+ This is an error.
+
+Id
+: `JavaOnlyDetector`
+Summary
+: Using @JavaOnly elements in Kotlin code
+Severity
+: Error
+Category
+: Interoperability: Kotlin Interoperability
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.1.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/JavaOnlyDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/JavaOnlyDetectorTest.kt)
+Copyright Year
+: 2020
+
+This should not be called from Kotlin code.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+test/test/pkg/Test.kt:7:Error: This method should not be called from
+Kotlin, see its documentation for details. [JavaOnlyDetector]
+ g()
+ ---
+test/test/pkg/Test.kt:8:Error: This method should not be called from
+Kotlin: satisfying explanation [JavaOnlyDetector]
+ f()
+ ---
+test/test/pkg/Test.kt:9:Error: This method should not be called from
+Kotlin, see its documentation for details. [JavaOnlyDetector]
+ val r = this::g
+ -------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`test/test/pkg/Test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import slack.lint.annotations.JavaOnly
+class Test {
+ @JavaOnly fun g() {}
+ @JavaOnly("satisfying explanation") fun f() {}
+ fun m() {
+ g()
+ f()
+ val r = this::g
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/JavaOnlyDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `JavaOnlyDetector.positive`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/slack-lints.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("JavaOnlyDetector")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("JavaOnlyDetector")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection JavaOnlyDetector
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="JavaOnlyDetector" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'JavaOnlyDetector'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore JavaOnlyDetector ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/JavaPluginLanguageLevel.md.html b/docs/checks/JavaPluginLanguageLevel.md.html
new file mode 100644
index 00000000..012018cd
--- /dev/null
+++ b/docs/checks/JavaPluginLanguageLevel.md.html
@@ -0,0 +1,117 @@
+
+(#) No Explicit Java Language Level Given
+
+!!! WARNING: No Explicit Java Language Level Given
+ This is a warning.
+
+Id
+: `JavaPluginLanguageLevel`
+Summary
+: No Explicit Java Language Level Given
+Severity
+: Warning
+Category
+: Interoperability
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 4.2.0 (May 2021)
+Affects
+: Gradle build files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/GradleDetector.kt)
+Tests
+: [Source Code](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/GradleDetectorTest.kt)
+
+In modules using plugins deriving from the Gradle `java` plugin (e.g.
+`java-library` or `application`), the java source and target
+compatibility default to the version of the JDK being used to run
+Gradle, which may cause compatibility problems with Android (or other)
+modules.
+
+You can specify an explicit sourceCompatibility and targetCompatibility
+in this module to maintain compatibility no matter which JDK is used to
+run Gradle.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+build.gradle:2:Warning: no Java sourceCompatibility directive
+[JavaPluginLanguageLevel]
+ id 'java'
+ ---------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`build.gradle`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~groovy linenumbers
+plugins {
+ id 'java'
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/GradleDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `GradleDetector.testJavaLanguageLevelNoSourceCompatibility`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection JavaPluginLanguageLevel
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="JavaPluginLanguageLevel" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'JavaPluginLanguageLevel'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore JavaPluginLanguageLevel ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/JavascriptInterface.md.html b/docs/checks/JavascriptInterface.md.html
new file mode 100644
index 00000000..3d91dde9
--- /dev/null
+++ b/docs/checks/JavascriptInterface.md.html
@@ -0,0 +1,241 @@
+
+(#) Missing @JavascriptInterface on methods
+
+!!! ERROR: Missing @JavascriptInterface on methods
+ This is an error.
+
+Id
+: `JavascriptInterface`
+Summary
+: Missing @JavascriptInterface on methods
+Severity
+: Error
+Category
+: Security
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface(java.lang.Object, java.lang.String)
+See
+: https://goo.gle/JavascriptInterface
+Implementation
+: [Source Code](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/JavaScriptInterfaceDetector.kt)
+Tests
+: [Source Code](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/JavaScriptInterfaceDetectorTest.kt)
+Copyright Year
+: 2013
+
+As of API 17, you must annotate methods in objects registered with the
+`addJavascriptInterface` method with a `@JavascriptInterface`
+annotation.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/JavaScriptTest.java:11:Error: None of the methods in the
+added interface (NonAnnotatedObject) have been annotated with
+@android.webkit.JavascriptInterface; they will not be visible in API 17
+[JavascriptInterface]
+ webview.addJavascriptInterface(new NonAnnotatedObject(), "myobj");
+ ----------------------
+src/test/pkg/JavaScriptTest.java:14:Error: None of the methods in the
+added interface (NonAnnotatedObject) have been annotated with
+@android.webkit.JavascriptInterface; they will not be visible in API 17
+[JavascriptInterface]
+ webview.addJavascriptInterface(o, "myobj");
+ ----------------------
+src/test/pkg/JavaScriptTest.java:21:Error: None of the methods in the
+added interface (NonAnnotatedObject) have been annotated with
+@android.webkit.JavascriptInterface; they will not be visible in API 17
+[JavascriptInterface]
+ webview.addJavascriptInterface(object2, "myobj");
+ ----------------------
+src/test/pkg/JavaScriptTest.java:32:Error: None of the methods in the
+added interface (NonAnnotatedObject) have been annotated with
+@android.webkit.JavascriptInterface; they will not be visible in API 17
+[JavascriptInterface]
+ webview.addJavascriptInterface(t, "myobj");
+ ----------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/test/pkg/AnnotatedObject.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.webkit.JavascriptInterface;
+
+@SuppressWarnings("ClassNameDiffersFromFileName")
+public class AnnotatedObject {
+ @JavascriptInterface
+ public void test1() {
+ }
+
+ public void test2() {
+ }
+
+ @JavascriptInterface
+ public void test3() {
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/InheritsFromAnnotated.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.webkit.JavascriptInterface;
+
+@SuppressWarnings("ClassNameDiffersFromFileName")
+public class InheritsFromAnnotated extends AnnotatedObject {
+
+ @Override
+ public void test1() {
+ }
+
+ @Override
+ public void test2() {
+ }
+
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/NonAnnotatedObject.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+@SuppressWarnings("ClassNameDiffersFromFileName")
+public class NonAnnotatedObject {
+ public void test1() {
+ }
+ public void test2() {
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/JavaScriptTest.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.annotation.SuppressLint;
+import android.webkit.WebView;
+
+@SuppressWarnings({"ClassNameDiffersFromFileName", "MethodMayBeStatic"})
+public class JavaScriptTest {
+ public void test(WebView webview) {
+ webview.addJavascriptInterface(new AnnotatedObject(), "myobj");
+ webview.addJavascriptInterface(new InheritsFromAnnotated(), "myobj");
+ webview.addJavascriptInterface(new NonAnnotatedObject(), "myobj");
+
+ Object o = new NonAnnotatedObject();
+ webview.addJavascriptInterface(o, "myobj");
+ o = new InheritsFromAnnotated();
+ webview.addJavascriptInterface(o, "myobj");
+ }
+
+ public void test(WebView webview, AnnotatedObject object1, NonAnnotatedObject object2) {
+ webview.addJavascriptInterface(object1, "myobj");
+ webview.addJavascriptInterface(object2, "myobj");
+ }
+
+ @SuppressLint("JavascriptInterface")
+ public void testSuppressed(WebView webview) {
+ webview.addJavascriptInterface(new NonAnnotatedObject(), "myobj");
+ }
+
+ public void testLaterReassignment(WebView webview) {
+ Object o = new NonAnnotatedObject();
+ Object t = o;
+ webview.addJavascriptInterface(t, "myobj");
+ o = new AnnotatedObject();
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/JavaScriptInterfaceDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `JavaScriptInterfaceDetector.test`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("JavascriptInterface")
+ fun method() {
+ addJavascriptInterface(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("JavascriptInterface")
+ void method() {
+ addJavascriptInterface(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection JavascriptInterface
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="JavascriptInterface" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'JavascriptInterface'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore JavascriptInterface ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/JcenterRepositoryObsolete.md.html b/docs/checks/JcenterRepositoryObsolete.md.html
new file mode 100644
index 00000000..935e431f
--- /dev/null
+++ b/docs/checks/JcenterRepositoryObsolete.md.html
@@ -0,0 +1,132 @@
+
+(#) JCenter Maven repository is read-only
+
+!!! WARNING: JCenter Maven repository is read-only
+ This is a warning.
+
+Id
+: `JcenterRepositoryObsolete`
+Summary
+: JCenter Maven repository is read-only
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 4.2.0 (May 2021)
+Affects
+: Gradle build files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/r/tools/jcenter-end-of-service
+Implementation
+: [Source Code](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/GradleDetector.kt)
+Tests
+: [Source Code](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/GradleDetectorTest.kt)
+
+The JCenter Maven repository is no longer accepting submissions of Maven
+artifacts since 31st March 2021. Ensure that the project is configured
+to search in repositories with the latest versions of its dependencies.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+build.gradle:7:Warning: JCenter Maven repository is no longer receiving
+updates: newer library versions may be available elsewhere
+[JcenterRepositoryObsolete]
+ jcenter()
+ ---------
+build.gradle:14:Warning: JCenter Maven repository is no longer receiving
+updates: newer library versions may be available elsewhere
+[JcenterRepositoryObsolete]
+ jcenter()
+ ---------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`build.gradle`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~groovy linenumbers
+buildscript {
+ ext {
+ versions = [kotlin: '1.4.20']
+ }
+ repositories {
+ google()
+ jcenter()
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ jcenter()
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/GradleDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `GradleDetector.testJCenterObsolete`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection JcenterRepositoryObsolete
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="JcenterRepositoryObsolete" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'JcenterRepositoryObsolete'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore JcenterRepositoryObsolete ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/JobSchedulerService.md.html b/docs/checks/JobSchedulerService.md.html
new file mode 100644
index 00000000..35425e71
--- /dev/null
+++ b/docs/checks/JobSchedulerService.md.html
@@ -0,0 +1,218 @@
+
+(#) JobScheduler problems
+
+!!! WARNING: JobScheduler problems
+ This is a warning.
+
+Id
+: `JobSchedulerService`
+Summary
+: JobScheduler problems
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.0.0 (October 2017)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/topic/performance/scheduling.html
+Implementation
+: [Source Code](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/JobSchedulerDetector.java)
+Tests
+: [Source Code](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/JobSchedulerDetectorTest.java)
+
+This check looks for various common mistakes in using the JobScheduler
+API: the service class must extend `JobService`, the service must be
+registered in the manifest and the registration must require the
+permission `android.permission.BIND_JOB_SERVICE`.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/JobSchedulerTest.java:21:Warning: Scheduled job class
+NotAJobService must extend android.app.job.JobService
+[JobSchedulerService]
+ new ComponentName(this, NotAJobService.class));
+ ---------------------------------------------
+src/test/pkg/JobSchedulerTest.java:29:Warning: Scheduled job class
+NotAJobService must extend android.app.job.JobService
+[JobSchedulerService]
+ new ComponentName(this, NotAJobService.class));
+ ---------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/test/pkg/JobSchedulerTest.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.app.Activity;
+import android.app.job.JobInfo;
+import android.app.job.JobScheduler;
+import android.content.ComponentName;
+
+public class JobSchedulerTest extends Activity {
+ private static final int MY_ID = 0x52323;
+
+ public void testOk(JobScheduler jobScheduler) {
+ ComponentName componentName = new ComponentName(this, MyJobService.class);
+ JobInfo.Builder builder = new JobInfo.Builder(MY_ID, componentName);
+ jobScheduler.schedule(builder
+ .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
+ .build());
+ }
+
+ public void testWrong(JobScheduler jobScheduler) {
+ JobInfo.Builder builder = new JobInfo.Builder(MY_ID,
+ new ComponentName(this, NotAJobService.class));
+ jobScheduler.schedule(builder
+ .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
+ .build());
+ }
+
+ public void testWrongInlined(JobScheduler jobScheduler) {
+ JobInfo.Builder builder = new JobInfo.Builder(MY_ID,
+ new ComponentName(this, NotAJobService.class));
+ jobScheduler.schedule(builder
+ .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
+ .build());
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyJobService.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.annotation.TargetApi;
+import android.app.job.JobParameters;
+import android.app.job.JobService;
+import android.os.Build;
+
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
+public class MyJobService extends JobService {
+ @Override
+ public boolean onStartJob(JobParameters jobParameters) {
+ return false;
+ }
+
+ @Override
+ public boolean onStopJob(JobParameters jobParameters) {
+ return false;
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/NotAJobService.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.app.Service;
+
+public abstract class NotAJobService extends Service {
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="test.pkg">
+
+ <application>
+ <service android:name=".MyJobService"
+ android:permission="android.permission.BIND_JOB_SERVICE"
+ android:exported="true" />
+ <service android:name=".NotAJobService"
+ android:exported="true" />
+ </application>
+
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/JobSchedulerDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `JobSchedulerDetector.testFlagWrongClass`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("JobSchedulerService")
+ fun method() {
+ Builder(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("JobSchedulerService")
+ void method() {
+ new Builder(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection JobSchedulerService
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="JobSchedulerService" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'JobSchedulerService'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore JobSchedulerService ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/JvmStaticProvidesInObjectDetector.md.html b/docs/checks/JvmStaticProvidesInObjectDetector.md.html
new file mode 100644
index 00000000..dbfcb5ec
--- /dev/null
+++ b/docs/checks/JvmStaticProvidesInObjectDetector.md.html
@@ -0,0 +1,288 @@
+
+(#) @JvmStatic used for @Provides function in an object class
+
+!!! WARNING: @JvmStatic used for @Provides function in an object class
+ This is a warning.
+
+Id
+: `JvmStaticProvidesInObjectDetector`
+Summary
+: @JvmStatic used for @Provides function in an object class
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Google
+Identifier
+: com.google.dagger:dagger-lint
+Contact
+: https://github.com/google/dagger
+Feedback
+: https://github.com/google/dagger/issues
+Min
+: Lint 7.3 and 7.4
+Compiled
+: Lint 7.1
+Artifact
+: [com.google.dagger:dagger-lint](com_google_dagger_dagger-lint.md.html)
+Since
+: 2.40.2
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/google/dagger/tree/master/java/dagger/lint/DaggerKotlinIssueDetector.kt)
+Tests
+: [Source Code](https://github.com/google/dagger/tree/master/javatests/dagger/lint/DaggerKotlinIssueDetectorTest.kt)
+Copyright Year
+: 2020
+
+It's redundant to annotate @Provides functions in object classes with
+@JvmStatic.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/foo/MyQualifier.kt:26:Warning: @JvmStatic used for @Provides
+function in an object class [JvmStaticProvidesInObjectDetector]
+ @JvmStatic
+ ----------
+src/foo/MyQualifier.kt:43:Warning: @JvmStatic used for @Provides
+function in an object class [JvmStaticProvidesInObjectDetector]
+ @JvmStatic
+ ----------
+src/foo/MyQualifier.kt:56:Warning: @JvmStatic used for @Provides
+function in an object class [JvmStaticProvidesInObjectDetector]
+ @kotlin.jvm.JvmStatic
+ ---------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/foo/MyQualifier.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package foo
+import javax.inject.Inject
+import javax.inject.Qualifier
+import kotlin.jvm.JvmStatic
+import dagger.Provides
+import dagger.Module
+
+@Qualifier
+annotation class MyQualifier
+
+class InjectedTest {
+ // This should fail because of `:field`
+ @Inject
+ @field:MyQualifier
+ lateinit var prop: String
+
+ // This is fine!
+ @Inject
+ @MyQualifier
+ lateinit var prop2: String
+}
+
+@Module
+object ObjectModule {
+ // This should fail because it uses `@JvmStatic`
+ @JvmStatic
+ @Provides
+ fun provideFoo(): String {
+
+ }
+
+ // This is fine!
+ @Provides
+ fun provideBar(): String {
+
+ }
+}
+
+@Module
+class ClassModule {
+ companion object {
+ // This should fail because the companion object is part of ClassModule, so this is unnecessary.
+ @JvmStatic
+ @Provides
+ fun provideBaz(): String {
+
+ }
+ }
+}
+
+@Module
+class ClassModuleQualified {
+ companion object {
+ // This should fail because the companion object is part of ClassModule, so this is unnecessary.
+ // This specifically tests a fully qualified annotation
+ @kotlin.jvm.JvmStatic
+ @Provides
+ fun provideBaz(): String {
+
+ }
+ }
+}
+
+@Module
+class ClassModule2 {
+ // This should fail because the companion object is part of ClassModule
+ @Module
+ companion object {
+ @Provides
+ fun provideBaz(): String {
+
+ }
+ }
+}
+
+@Module
+class ClassModule2Qualified {
+ // This should fail because the companion object is part of ClassModule
+ // This specifically tests a fully qualified annotation
+ @dagger.Module
+ companion object {
+ @Provides
+ fun provideBaz(): String {
+
+ }
+ }
+}
+
+// This is correct as of Dagger 2.26!
+@Module
+class ClassModule3 {
+ companion object {
+ @Provides
+ fun provideBaz(): String {
+
+ }
+ }
+}
+
+class ClassModule4 {
+ // This is should fail because this should be extracted to a standalone object.
+ @Module
+ companion object {
+ @Provides
+ fun provideBaz(): String {
+
+ }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/google/dagger/tree/master/javatests/dagger/lint/DaggerKotlinIssueDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `DaggerKotlinIssueDetector.simpleSmokeTestForQualifiersAndProviders`.
+To report a problem with this extracted sample, visit
+https://github.com/google/dagger/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("com.google.dagger:dagger-lint:2.56.2")
+
+// build.gradle
+implementation 'com.google.dagger:dagger-lint:2.56.2'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.dagger.lint)
+
+# libs.versions.toml
+[versions]
+dagger-lint = "2.56.2"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+dagger-lint = {
+ module = "com.google.dagger:dagger-lint",
+ version.ref = "dagger-lint"
+}
+```
+
+2.56.2 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.google.dagger:dagger-lint](com_google_dagger_dagger-lint.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("JvmStaticProvidesInObjectDetector")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("JvmStaticProvidesInObjectDetector")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection JvmStaticProvidesInObjectDetector
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="JvmStaticProvidesInObjectDetector" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'JvmStaticProvidesInObjectDetector'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore JvmStaticProvidesInObjectDetector ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/KaptUsageInsteadOfKsp.md.html b/docs/checks/KaptUsageInsteadOfKsp.md.html
new file mode 100644
index 00000000..c02c93b7
--- /dev/null
+++ b/docs/checks/KaptUsageInsteadOfKsp.md.html
@@ -0,0 +1,144 @@
+
+(#) Kapt usage should be replaced with KSP
+
+!!! WARNING: Kapt usage should be replaced with KSP
+ This is a warning.
+
+Id
+: `KaptUsageInsteadOfKsp`
+Summary
+: Kapt usage should be replaced with KSP
+Severity
+: Warning
+Category
+: Performance
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 8.1.0 (July 2023)
+Affects
+: Gradle build files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/studio/build/migrate-to-ksp
+Implementation
+: [Source Code](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/GradleDetector.kt)
+Tests
+: [Source Code](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/GradleDetectorTest.kt)
+
+KSP is a more efficient replacement for kapt. For libraries that support
+both, KSP should be used to improve build times.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+build.gradle:9:Warning: This library supports using KSP instead of kapt,
+which greatly improves performance. Learn more:
+https://developer.android.com/studio/build/migrate-to-ksp
+[KaptUsageInsteadOfKsp]
+ kapt 'androidx.room:room-compiler:2.5.0'
+ ----------------------------------------
+build.gradle:10:Warning: This library supports using KSP instead of
+kapt, which greatly improves performance. Learn more:
+https://developer.android.com/studio/build/migrate-to-ksp
+[KaptUsageInsteadOfKsp]
+ kapt "androidx.room:room-compiler:$room_version"
+ ------------------------------------------------
+build.gradle:13:Warning: This library supports using KSP instead of
+kapt, which greatly improves performance. Learn more:
+https://developer.android.com/studio/build/migrate-to-ksp
+[KaptUsageInsteadOfKsp]
+ kapt 'com.github.bumptech.glide:compiler:4.14.2'
+ ------------------------------------------------
+build.gradle:14:Warning: This library supports using KSP instead of
+kapt, which greatly improves performance. Learn more:
+https://developer.android.com/studio/build/migrate-to-ksp
+[KaptUsageInsteadOfKsp]
+ kapt("com.github.bumptech.glide:compiler:glide_version")
+ --------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`build.gradle`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~groovy linenumbers
+plugins {
+ id 'com.android.application'
+ id 'kotlin-android'
+ id 'kotlin-kapt'
+ id 'com.google.devtools.ksp'
+}
+dependencies {
+ def room_version = "2.5.0"
+ kapt 'androidx.room:room-compiler:2.5.0'
+ kapt "androidx.room:room-compiler:$room_version"
+
+ def glide_version = "4.14.2"
+ kapt 'com.github.bumptech.glide:compiler:4.14.2'
+ kapt("com.github.bumptech.glide:compiler:glide_version")
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/GradleDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `GradleDetector.testKaptToKspMigration`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection KaptUsageInsteadOfKsp
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="KaptUsageInsteadOfKsp" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'KaptUsageInsteadOfKsp'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore KaptUsageInsteadOfKsp ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/KeyboardInaccessibleWidget.md.html b/docs/checks/KeyboardInaccessibleWidget.md.html
new file mode 100644
index 00000000..44c261a8
--- /dev/null
+++ b/docs/checks/KeyboardInaccessibleWidget.md.html
@@ -0,0 +1,110 @@
+
+(#) Keyboard inaccessible widget
+
+!!! WARNING: Keyboard inaccessible widget
+ This is a warning.
+
+Id
+: `KeyboardInaccessibleWidget`
+Summary
+: Keyboard inaccessible widget
+Severity
+: Warning
+Category
+: Accessibility
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.0.0 (October 2017)
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/KeyboardNavigationDetector.java)
+Tests
+: [Source Code](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/KeyboardNavigationDetectorTest.java)
+
+A widget that is declared to be clickable but not declared to be
+focusable is not accessible via the keyboard. Please add the `focusable`
+attribute as well.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/mywidget.xml:2:Warning: 'clickable' attribute found, please
+also add 'focusable' [KeyboardInaccessibleWidget]
+ android:clickable="true" />
+ ------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/layout/mywidget.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<Button xmlns:android="http://schemas.android.com/apk/res/android"
+ android:clickable="true" />
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/KeyboardNavigationDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `KeyboardNavigationDetector.testUnspecifiedFocusableElement_triggersIssue`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="KeyboardInaccessibleWidget"` on the problematic XML
+ element (or one of its enclosing elements). You may also need to add
+ the following namespace declaration on the root element in the XML
+ file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="KeyboardInaccessibleWidget" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'KeyboardInaccessibleWidget'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore KeyboardInaccessibleWidget ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/KnownPermissionError.md.html b/docs/checks/KnownPermissionError.md.html
new file mode 100644
index 00000000..2229de66
--- /dev/null
+++ b/docs/checks/KnownPermissionError.md.html
@@ -0,0 +1,148 @@
+
+(#) Value specified for permission is a known error
+
+!!! ERROR: Value specified for permission is a known error
+ This is an error.
+
+Id
+: `KnownPermissionError`
+Summary
+: Value specified for permission is a known error
+Severity
+: Error
+Category
+: Security
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 7.4.0 (January 2023)
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://goo.gle/KnownPermissionError
+Implementation
+: [Source Code](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/PermissionErrorDetector.kt)
+Tests
+: [Source Code](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/PermissionErrorDetectorTest.kt)
+
+This check looks for values specified in component permissions that are
+known errors, such as `android:permission="true"`.
+
+ Please double check the permission value you have supplied. The value
+is expected to be a permission string from the system, another app, or
+your own, NOT a boolean.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:4:Error: true is not a valid permission value
+[KnownPermissionError]
+ <application android:permission="true">
+ ----
+AndroidManifest.xml:5:Error: TRUE is not a valid permission value
+[KnownPermissionError]
+ <activity android:permission="TRUE" />
+ ----
+AndroidManifest.xml:6:Error: True is not a valid permission value
+[KnownPermissionError]
+ <activity-alias android:permission="True" />
+ ----
+AndroidManifest.xml:7:Error: true is not a valid permission value
+[KnownPermissionError]
+ <receiver android:permission="true" />
+ ----
+AndroidManifest.xml:8:Error: false is not a valid permission value
+[KnownPermissionError]
+ <service android:permission="false" />
+ -----
+AndroidManifest.xml:9:Error: false is not a valid permission value
+[KnownPermissionError]
+ <provider android:permission="false" />
+ -----
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="com.example.helloworld">
+ <application android:permission="true">
+ <activity android:permission="TRUE" />
+ <activity-alias android:permission="True" />
+ <receiver android:permission="true" />
+ <service android:permission="false" />
+ <provider android:permission="false" />
+ </application>
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/PermissionErrorDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="KnownPermissionError"` on the problematic XML element
+ (or one of its enclosing elements). You may also need to add the
+ following namespace declaration on the root element in the XML file
+ if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <permission tools:ignore="KnownPermissionError" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="KnownPermissionError" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'KnownPermissionError'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore KnownPermissionError ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/KotlinNullnessAnnotation.md.html b/docs/checks/KotlinNullnessAnnotation.md.html
new file mode 100644
index 00000000..28f3ec24
--- /dev/null
+++ b/docs/checks/KotlinNullnessAnnotation.md.html
@@ -0,0 +1,153 @@
+
+(#) Kotlin nullability annotation
+
+!!! ERROR: Kotlin nullability annotation
+ This is an error.
+
+Id
+: `KotlinNullnessAnnotation`
+Summary
+: Kotlin nullability annotation
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 7.3.0 (September 2022)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/KotlinNullnessAnnotationDetector.kt)
+Tests
+: [Source Code](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/KotlinNullnessAnnotationDetectorTest.kt)
+
+In Kotlin, nullness is part of the type system; `s: String` is **never**
+null and `s: String?` is sometimes null, whether or not you add in
+additional annotations stating `@NonNull` or `@Nullable`. These are
+likely copy/paste mistakes, and are misleading.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/test.kt:7:Warning: Do not use @NonNull in Kotlin; the
+nullability is already implied by the Kotlin type String not ending with
+? [KotlinNullnessAnnotation]
+fun testWarning(@NonNull string: String) { }
+ --------
+src/test/pkg/test.kt:11:Error: Do not use @Nullable in Kotlin; the
+nullability is determined by the Kotlin type String not ending with ?
+which declares it not nullable, contradicting the annotation
+[KotlinNullnessAnnotation]
+fun testError(@Nullable string: String) { }
+ ---------
+src/test/pkg/test.kt:15:Error: Do not use @NonNull in Kotlin; the
+nullability is determined by the Kotlin type Number? ending with ? which
+declares it nullable, contradicting the annotation
+[KotlinNullnessAnnotation]
+fun testError(@NonNull number: Number?) { }
+ --------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import androidx.annotation.NonNull
+import androidx.annotation.Nullable
+
+// Here we have an already non-null string annotated with @NonNull;
+// warn, since this is redundant
+fun testWarning(@NonNull string: String) { }
+
+// Here we have a non-null string which has been annotated with @Nullable,
+// which is totally misleading; the annotation is wrong
+fun testError(@Nullable string: String) { }
+
+// Here we have a nullable string which has been annotated with @NonNull,
+// which is totally misleading; the annotation is wrong.
+fun testError(@NonNull number: Number?) { }
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/KotlinNullnessAnnotationDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("KotlinNullnessAnnotation")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("KotlinNullnessAnnotation")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection KotlinNullnessAnnotation
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="KotlinNullnessAnnotation" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'KotlinNullnessAnnotation'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore KotlinNullnessAnnotation ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/KotlinPairNotCreated.md.html b/docs/checks/KotlinPairNotCreated.md.html
new file mode 100644
index 00000000..df07a83b
--- /dev/null
+++ b/docs/checks/KotlinPairNotCreated.md.html
@@ -0,0 +1,188 @@
+
+(#) Use Kotlin's kotlin.Pair instead of other Pair types from other libraries like AndroidX and Slack commons
+
+!!! WARNING: Use Kotlin's kotlin.Pair instead of other Pair types from other libraries like AndroidX and Slack commons
+ This is a warning.
+
+Id
+: `KotlinPairNotCreated`
+Summary
+: Use Kotlin's kotlin.Pair instead of other Pair types from other libraries like AndroidX and Slack commons
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.1.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/NonKotlinPairDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/NonKotlinPairDetectorTest.kt)
+Copyright Year
+: 2021
+
+We should consolidate to create and use a single type of Pair in the
+code base. Kotlin's Pair is preferred as it works well with Java and
+Kotlin. It comes with extension functions that Slack's Pair doesn't
+offer.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/slack/test/TestClass.java:10:Warning: Use Kotlin's kotlin.Pair
+instead of other Pair types from other libraries like AndroidX and Slack
+commons [KotlinPairNotCreated]
+ Pair pair = Pair.create("first", "second");
+ ------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/slack/test/TestClass.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package slack.test;
+
+import androidx.core.util.Pair;
+
+public class TestClass {
+
+ public void doStuff() {
+ new Integer(5);
+ new String("TestString").toString();
+ Pair pair = Pair.create("first", "second");
+ pair.first.toString();
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/NonKotlinPairDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `NonKotlinPairDetector.Java - AndroidX Pair create shows warning`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/slack-lints.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("KotlinPairNotCreated")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("KotlinPairNotCreated")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection KotlinPairNotCreated
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="KotlinPairNotCreated" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'KotlinPairNotCreated'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore KotlinPairNotCreated ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/KotlinPropertyAccess.md.html b/docs/checks/KotlinPropertyAccess.md.html
new file mode 100644
index 00000000..1ca4f3be
--- /dev/null
+++ b/docs/checks/KotlinPropertyAccess.md.html
@@ -0,0 +1,252 @@
+
+(#) Kotlin Property Access
+
+!!! WARNING: Kotlin Property Access
+ This is a warning.
+
+Id
+: `KotlinPropertyAccess`
+Summary
+: Kotlin Property Access
+Note
+: **This issue is disabled by default**; use `--enable KotlinPropertyAccess`
+Severity
+: Warning
+Category
+: Interoperability: Kotlin Interoperability
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.2.0 (September 2018)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://android.github.io/kotlin-guides/interop.html#property-prefixes
+Implementation
+: [Source Code](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/InteroperabilityDetector.kt)
+Tests
+: [Source Code](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/InteroperabilityDetectorTest.kt)
+
+For a method to be represented as a property in Kotlin, strict
+“bean”-style prefixing must be used.
+
+Accessor methods require a `get` prefix or for boolean-returning methods
+an `is` prefix can be used.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/GetterSetter.java:30:Warning: This method should be called
+getError1 such that error1 can be accessed as a property from Kotlin;
+see
+https://android.github.io/kotlin-guides/interop.html#property-prefixes
+[KotlinPropertyAccess]
+ public String hasError1() { return ""; }
+ ---------
+src/test/pkg/GetterSetter.java:34:Warning: This method should be called
+getError2 such that error2 can be accessed as a property from Kotlin;
+see
+https://android.github.io/kotlin-guides/interop.html#property-prefixes
+[KotlinPropertyAccess]
+ public String error2() { return ""; }
+ ------
+src/test/pkg/GetterSetter.java:38:Warning: This method should be called
+getError3 such that error3 can be accessed as a property from Kotlin;
+see
+https://android.github.io/kotlin-guides/interop.html#property-prefixes
+[KotlinPropertyAccess]
+ public String hazzError3() { return ""; }
+ ----------
+src/test/pkg/GetterSetter.java:42:Warning: The getter return type
+(Integer) and setter parameter type (String) getter and setter methods
+for property error4 should have exactly the same type to allow be
+accessed as a property from Kotlin; see
+https://android.github.io/kotlin-guides/interop.html#property-prefixes
+[KotlinPropertyAccess]
+ public Integer getError4() { return 0; }
+ ---------
+src/test/pkg/GetterSetter.java:46:Warning: This getter should be public
+such that error5 can be accessed as a property from Kotlin; see
+https://android.github.io/kotlin-guides/interop.html#property-prefixes
+[KotlinPropertyAccess]
+ protected String getError5() { return ""; }
+ ---------
+src/test/pkg/GetterSetter.java:50:Warning: This getter should not be
+static such that error6 can be accessed as a property from Kotlin; see
+https://android.github.io/kotlin-guides/interop.html#property-prefixes
+[KotlinPropertyAccess]
+ public static String getError6() { return ""; }
+ ------
+src/test/pkg/GetterSetter.java:70:Warning: The getter return type
+(Float) is not the same as the super return type (Number); they should
+have exactly the same type to allow number3 be accessed as a property
+from Kotlin; see
+https://android.github.io/kotlin-guides/interop.html#property-prefixes
+[KotlinPropertyAccess]
+ @Override public Float getNumber3() { return 0.0f; } // ERROR (even though we have corresponding setter)
+ ----------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/GetterSetter.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+@SuppressWarnings({"ClassNameDiffersFromFileName", "unused", "MethodMayBeStatic", "NonBooleanMethodNameMayNotStartWithQuestion"})
+public class GetterSetter {
+ // Correct Java Bean - get-prefix
+ public void setOk1(String s) { }
+ public String getOk1() { return ""; }
+
+ // Correct Java Bean - is-prefix
+ public void setOk2(String s) {}
+ public String isOk2() { return ""; }
+
+ // This is a read-only bean but we don't interpret these
+ public String getOk2() { return ""; }
+
+ // This is *potentially* an incorrectly named read-only Java Bean but we don't flag these
+ public String hasOk3() { return ""; }
+
+ // This is a write-only Java Bean we but we don't flag these
+ public void setOk4(String s) { }
+
+ // Using "wrong" return type on the setter is fine, Kotlin doesn't care
+ public String setOk5(String s) { return s; }
+ public String getOk5() { return ""; }
+
+ // Now the errors
+
+ // Using "has" instead of is
+ public void setError1(String s) { }
+ public String hasError1() { return ""; }
+
+ // Using property name itself
+ public void setError2(String s) { }
+ public String error2() { return ""; }
+
+ // Using some other suffix
+ public void setError3(String s) { }
+ public String hazzError3() { return ""; }
+
+ // Mismatched getter and setter types
+ public void setError4(String s) { }
+ public Integer getError4() { return 0; }
+
+ // Wrong access modifier
+ public void setError5(String s) { }
+ protected String getError5() { return ""; }
+
+ // Wrong static
+ public void setError6(String s) { }
+ public static String getError6() { return ""; }
+
+ private class NonApi {
+ // Not valid java bean but we don't flag stuff in private classes
+ public String setOk1(String s) { return ""; }
+ public String getOk1() { return ""; }
+ }
+
+ public static class SuperClass {
+ public Number getNumber1() { return 0.0; }
+ public void setNumber1(Number number) { }
+ public Number getNumber2() { return 0.0; }
+ public void setNumber2(Number number) { }
+ public Number getNumber3() { return 0.0; }
+ public void setNumber3(Number number) { }
+ }
+
+ public static class SubClass extends SuperClass {
+ @Override public Float getNumber1() { return 0.0f; } // OK
+ @Override public void setNumber2(Number number) { } // OK
+ @Override public Float getNumber3() { return 0.0f; } // ERROR (even though we have corresponding setter)
+ public void setNumber3(Float number) { } // OK
+ public Float getNumber4() { return 0.0f; } // OK
+ public void setNumber4(Float number) { } // OK
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/InteroperabilityDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `InteroperabilityDetector.testPropertyAccess`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("KotlinPropertyAccess")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("KotlinPropertyAccess")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection KotlinPropertyAccess
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="KotlinPropertyAccess" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'KotlinPropertyAccess'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore KotlinPropertyAccess ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/KotlinRequireNotNullUseMessage.md.html b/docs/checks/KotlinRequireNotNullUseMessage.md.html
new file mode 100644
index 00000000..76853c8f
--- /dev/null
+++ b/docs/checks/KotlinRequireNotNullUseMessage.md.html
@@ -0,0 +1,169 @@
+
+(#) Marks usage of the requireNotNull method without lazy messages
+
+!!! WARNING: Marks usage of the requireNotNull method without lazy messages
+ This is a warning.
+
+Id
+: `KotlinRequireNotNullUseMessage`
+Summary
+: Marks usage of the requireNotNull method without lazy messages
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: vanniktech/lint-rules/
+Feedback
+: https://github.com/vanniktech/lint-rules/issues
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [com.vanniktech:lint-rules-kotlin](com_vanniktech_lint-rules-kotlin.md.html)
+Since
+: 0.22.0
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-kotlin-lint/src/main/kotlin/com/vanniktech/lintrules/kotlin/KotlinRequireNotNullUseMessageDetector.kt)
+Tests
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-kotlin-lint/src/test/kotlin/com/vanniktech/lintrules/rxjava2/KotlinRequireNotNullUseMessageDetectorTest.kt)
+
+The default generated message from requireNotNull often lacks context,
+hence it's best to provide a custom message.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test.kt:2:Warning: Provide a message
+[KotlinRequireNotNullUseMessage]
+ requireNotNull(value)
+ --------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+fun test(value: Int?) {
+ requireNotNull(value)
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-kotlin-lint/src/test/kotlin/com/vanniktech/lintrules/rxjava2/KotlinRequireNotNullUseMessageDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `KotlinRequireNotNullUseMessageDetector.requireNotNull`.
+To report a problem with this extracted sample, visit
+https://github.com/vanniktech/lint-rules/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.vanniktech:lint-rules-kotlin:0.25.0")
+
+// build.gradle
+lintChecks 'com.vanniktech:lint-rules-kotlin:0.25.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.lint.rules.kotlin)
+
+# libs.versions.toml
+[versions]
+lint-rules-kotlin = "0.25.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+lint-rules-kotlin = {
+ module = "com.vanniktech:lint-rules-kotlin",
+ version.ref = "lint-rules-kotlin"
+}
+```
+
+0.25.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.vanniktech:lint-rules-kotlin](com_vanniktech_lint-rules-kotlin.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("KotlinRequireNotNullUseMessage")
+ fun method() {
+ requireNotNull(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("KotlinRequireNotNullUseMessage")
+ void method() {
+ requireNotNull(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection KotlinRequireNotNullUseMessage
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="KotlinRequireNotNullUseMessage" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'KotlinRequireNotNullUseMessage'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore KotlinRequireNotNullUseMessage ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/KotlincFE10.md.html b/docs/checks/KotlincFE10.md.html
new file mode 100644
index 00000000..da349885
--- /dev/null
+++ b/docs/checks/KotlincFE10.md.html
@@ -0,0 +1,217 @@
+
+(#) Avoid using old K1 Kotlin compiler APIs
+
+!!! WARNING: Avoid using old K1 Kotlin compiler APIs
+ This is a warning.
+
+Id
+: `KotlincFE10`
+Summary
+: Avoid using old K1 Kotlin compiler APIs
+Note
+: **This issue is disabled by default**; use `--enable KotlincFE10`
+Severity
+: Warning
+Category
+: Lint Implementation Issues
+Platform
+: JDK
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 8.1.0 (July 2023)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/KotlincFE10Detector.kt)
+Tests
+: [Source Code](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/KotlincFE10DetectorTest.kt)
+
+K2, the new version of Kotlin compiler, which encompasses the new
+frontend, is coming. Try to avoid using internal APIs from the old
+frontend if possible.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/TestVisitor.kt:28:Warning:
+org.jetbrains.kotlin.resolve.BindingContext appears to be part of the
+old K1 Kotlin compiler. Avoid using it if possible; K1 will be going
+away soon. [KotlincFE10]
+ val bindingContext = service.getBindingContext(declaration) // ERROR
+ --------------------------------------
+src/test/pkg/TestVisitor.kt:29:Warning:
+org.jetbrains.kotlin.resolve.BindingContext appears to be part of the
+old K1 Kotlin compiler. Avoid using it if possible; K1 will be going
+away soon. [KotlincFE10]
+ val type = bindingContext.getType(expression) ?: return // ERROR
+ --------------
+src/test/pkg/TestVisitor.kt:30:Warning:
+org.jetbrains.kotlin.types.KotlinType appears to be part of the old K1
+Kotlin compiler. Avoid using it if possible; K1 will be going away soon.
+[KotlincFE10]
+ if (type.isDynamic()) return // ERROR
+ ----
+src/test/pkg/TestVisitor.kt:37:Warning:
+org.jetbrains.kotlin.resolve.BindingContext appears to be part of the
+old K1 Kotlin compiler. Avoid using it if possible; K1 will be going
+away soon. [KotlincFE10]
+ bindingContext: BindingContext, // ERROR
+ --------------
+src/test/pkg/TestVisitor.kt:41:Warning:
+org.jetbrains.kotlin.resolve.BindingContext appears to be part of the
+old K1 Kotlin compiler. Avoid using it if possible; K1 will be going
+away soon. [KotlincFE10]
+ val descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, node.sourcePsi) // ERROR
+ --------------
+src/test/pkg/TestVisitor.kt:42:Warning:
+org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility
+appears to be part of the old K1 Kotlin compiler. Avoid using it if
+possible; K1 will be going away soon. [KotlincFE10]
+ if (descriptor is DeclarationDescriptorWithVisibility) { // ERROR
+ -----------------------------------
+src/test/pkg/TestVisitor.kt:43:Warning:
+org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility
+appears to be part of the old K1 Kotlin compiler. Avoid using it if
+possible; K1 will be going away soon. [KotlincFE10]
+ val effectiveVisibility = descriptor.visibility.effectiveVisibility(descriptor, false) // ERROR
+ ----------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/TestVisitor.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+
+import com.android.tools.lint.client.api.UElementHandler
+import com.android.tools.lint.detector.api.JavaContext
+import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility
+import org.jetbrains.kotlin.descriptors.EffectiveVisibility
+import org.jetbrains.kotlin.descriptors.effectiveVisibility
+import org.jetbrains.kotlin.psi.KtElement
+import org.jetbrains.kotlin.psi.KtCallableDeclaration
+import org.jetbrains.kotlin.psi.KtFunction
+import org.jetbrains.kotlin.psi.KtProperty
+import org.jetbrains.kotlin.resolve.BindingContext
+import org.jetbrains.kotlin.types.isDynamic
+import org.jetbrains.uast.UElement
+import org.jetbrains.uast.UMethod
+import org.jetbrains.uast.kotlin.KotlinUastResolveProviderService
+
+class TestVisitor(val context: JavaContext) : UElementHandler() {
+ // Example from [InteroperabilityDetector.KotlinVisitor#visitMethod]
+ override fun visitMethod(node: UMethod) {
+ val declaration = node.sourcePsi as? KtCallableDeclaration ?: return
+ val expression = when (declaration) {
+ is KtProperty -> declaration.initializer ?: declaration.delegateExpression ?: return
+ is KtFunction -> declaration.bodyExpression ?: declaration.bodyBlockExpression ?: return
+ else -> return
+ }
+ val service = declaration.project.getService(KotlinUastResolveProviderService::class.java)
+ val bindingContext = service.getBindingContext(declaration) // ERROR
+ val type = bindingContext.getType(expression) ?: return // ERROR
+ if (type.isDynamic()) return // ERROR
+ // report something at the end
+ }
+
+ // Example from [PsiModifierItem#computeFlag] in Metalava
+ private fun computeFlag(
+ node: UElement,
+ bindingContext: BindingContext, // ERROR
+ ) : Int {
+ var visibilityFlag = PACKAGE_PRIVATE
+ if (node.sourcePsi is KtElement) {
+ val descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, node.sourcePsi) // ERROR
+ if (descriptor is DeclarationDescriptorWithVisibility) { // ERROR
+ val effectiveVisibility = descriptor.visibility.effectiveVisibility(descriptor, false) // ERROR
+ if (effectiveVisibility == EffectiveVisibility.Internal) {
+ visibilityFlag = INTERNAL
+ }
+ }
+ }
+ return visibilityFlag
+ }
+
+ companion object {
+ private const val INTERNAL = 1
+ private const val PACKAGE_PRIVATE = 2
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/KotlincFE10DetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("KotlincFE10")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("KotlincFE10")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection KotlincFE10
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="KotlincFE10" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'KotlincFE10'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore KotlincFE10 ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/KtxExtensionAvailable.md.html b/docs/checks/KtxExtensionAvailable.md.html
new file mode 100644
index 00000000..38fd7336
--- /dev/null
+++ b/docs/checks/KtxExtensionAvailable.md.html
@@ -0,0 +1,124 @@
+
+(#) KTX Extension Available
+
+!!! Tip: KTX Extension Available
+ Advice from this check is just a hint; it's a "weak" warning.
+
+Id
+: `KtxExtensionAvailable`
+Summary
+: KTX Extension Available
+Severity
+: Hint
+Category
+: Productivity
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 4.1.0 (October 2020)
+Affects
+: Gradle build files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/kotlin/ktx
+Implementation
+: [Source Code](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/GradleDetector.kt)
+Tests
+: [Source Code](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/GradleDetectorTest.kt)
+
+Android KTX extensions augment some libraries with support for modern
+Kotlin language features like extension functions, extension properties,
+lambdas, named parameters, coroutines, and more.
+
+In Kotlin projects, use the KTX version of a library by replacing the
+dependency in your `build.gradle` file. For example, you can replace
+`androidx.fragment:fragment` with `androidx.fragment:fragment-ktx`.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+build.gradle:7:Hint: Add suffix -ktx to enable the Kotlin extensions for
+this library [KtxExtensionAvailable]
+ implementation "androidx.core:core:1.2.0"
+ --------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`build.gradle`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~groovy linenumbers
+plugins {
+ id 'com.android.application'
+ id 'kotlin-android'
+}
+dependencies {
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:1.0.0"
+ implementation "androidx.core:core:1.2.0"
+ implementation "androidx.core:core:999.2.0" // No KTX extensions for this version.
+ implementation "androidx.core:fake-artifact:1.2.0" // No KTX extensions for this artifact.
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/GradleDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `GradleDetector.testKtxExtensions`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection KtxExtensionAvailable
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="KtxExtensionAvailable" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'KtxExtensionAvailable'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore KtxExtensionAvailable ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/LabelFor.md.html b/docs/checks/LabelFor.md.html
new file mode 100644
index 00000000..8b4805d7
--- /dev/null
+++ b/docs/checks/LabelFor.md.html
@@ -0,0 +1,162 @@
+
+(#) Missing accessibility label
+
+!!! WARNING: Missing accessibility label
+ This is a warning.
+
+Id
+: `LabelFor`
+Summary
+: Missing accessibility label
+Severity
+: Warning
+Category
+: Accessibility
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/LabelForDetector.kt)
+Tests
+: [Source Code](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/LabelForDetectorTest.kt)
+Copyright Year
+: 2012
+
+Editable text fields should provide an `android:hint` or, provided your
+`minSdkVersion` is at least 17, they may be referenced by a view with a
+`android:labelFor` attribute.
+
+When using `android:labelFor`, be sure to provide an `android:text` or
+an `android:contentDescription`.
+
+If your view is labeled but by a label in a different layout which
+includes this one, just suppress this warning from lint.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/labelfororhint_empty_hint.xml:11:Warning: Empty android:hint
+attribute [LabelFor]
+ android:hint=""
+ ---------------
+res/layout/labelfororhint_empty_hint.xml:21:Warning: Empty android:hint
+attribute [LabelFor]
+ android:hint=""
+ ---------------
+res/layout/labelfororhint_empty_hint.xml:29:Warning: Empty android:hint
+attribute [LabelFor]
+ android:hint=""
+ ---------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/layout/labelfororhint_empty_hint.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <EditText
+ android:id="@+id/editText1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:ems="10"
+ android:hint=""
+ android:inputType="textPersonName">
+ <requestFocus/>
+ </EditText>
+
+ <AutoCompleteTextView
+ android:id="@+id/autoCompleteTextView1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:ems="10"
+ android:hint=""
+ android:text="AutoCompleteTextView"/>
+
+ <MultiAutoCompleteTextView
+ android:id="@+id/multiAutoCompleteTextView1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:ems="10"
+ android:hint=""
+ android:text="MultiAutoCompleteTextView"/>
+</LinearLayout>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/LabelForDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `LabelForDetector.testWithEmptyHint`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="LabelFor"` on the
+ problematic XML element (or one of its enclosing elements). You may
+ also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <EditText xmlns:tools="http://schemas.android.com/tools"
+ tools:ignore="LabelFor" ...>
+ ...
+ </EditText>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="LabelFor" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'LabelFor'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore LabelFor ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/LambdaLast.md.html b/docs/checks/LambdaLast.md.html
new file mode 100644
index 00000000..debda033
--- /dev/null
+++ b/docs/checks/LambdaLast.md.html
@@ -0,0 +1,171 @@
+
+(#) Lambda Parameters Last
+
+!!! WARNING: Lambda Parameters Last
+ This is a warning.
+
+Id
+: `LambdaLast`
+Summary
+: Lambda Parameters Last
+Note
+: **This issue is disabled by default**; use `--enable LambdaLast`
+Severity
+: Warning
+Category
+: Interoperability: Kotlin Interoperability
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.2.0 (September 2018)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://android.github.io/kotlin-guides/interop.html#lambda-parameters-last
+Implementation
+: [Source Code](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/InteroperabilityDetector.kt)
+Tests
+: [Source Code](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/InteroperabilityDetectorTest.kt)
+
+To improve calling this code from Kotlin, parameter types eligible for
+SAM conversion should be last.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/Test.java:11:Warning: Functional interface parameters (such
+as parameter 1, "run", in test.pkg.Test.error1) should be last to
+improve Kotlin interoperability; see
+https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
+[LambdaLast]
+ public void error1(Runnable run, int x) { }
+ -----
+src/test/pkg/Test.java:12:Warning: Functional interface parameters (such
+as parameter 1, "sam", in test.pkg.Test.error2) should be last to
+improve Kotlin interoperability; see
+https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
+[LambdaLast]
+ public void error2(SamInterface sam, int x) { }
+ -----
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/test/pkg/Test.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+@SuppressWarnings("ClassNameDiffersFromFileName")
+public class Test {
+ public void ok1() { }
+ public void ok1(int x) { }
+ public void ok2(int x, int y) { }
+ public void ok3(Runnable run) { }
+ public void ok4(int x, Runnable run) { }
+ public void ok5(Runnable run1, Runnable run2) { }
+ public void ok6(java.util.List list, boolean b) { }
+ public void error1(Runnable run, int x) { }
+ public void error2(SamInterface sam, int x) { }
+
+ public interface SamInterface {
+ void samMethod();
+ @Override String toString();
+ default void other() { }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+
+fun ok1(bar: (Int) -> Int) { }
+fun ok2(foo: Int) { }
+fun ok3(foo: Int, bar: (Int) -> Int) { }
+fun ok4(foo: Int, bar: (Int) -> Int, baz: (Int) -> Int) { }
+// Lamda not last, but we're not flagging issues in Kotlin files for the
+// interoperability issue
+fun error(bar: (Int) -> Int, foo: Int) { }
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/InteroperabilityDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `InteroperabilityDetector.testLambdaLast`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("LambdaLast")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("LambdaLast")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection LambdaLast
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="LambdaLast" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'LambdaLast'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore LambdaLast ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/LaunchActivityFromNotification.md.html b/docs/checks/LaunchActivityFromNotification.md.html
new file mode 100644
index 00000000..e92b19f3
--- /dev/null
+++ b/docs/checks/LaunchActivityFromNotification.md.html
@@ -0,0 +1,184 @@
+
+(#) Notification Launches Services or BroadcastReceivers
+
+!!! WARNING: Notification Launches Services or BroadcastReceivers
+ This is a warning.
+
+Id
+: `LaunchActivityFromNotification`
+Summary
+: Notification Launches Services or BroadcastReceivers
+Severity
+: Warning
+Category
+: Performance
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 4.3.0-alpha01 (December 2020)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/guide/topics/ui/notifiers/notifications?hl=en#Actions
+See
+: https://d.android.com/r/studio-ui/designer/material/notifications-behavior
+See
+: https://developer.android.com/guide/topics/ui/notifiers/notifications?hl=en
+Implementation
+: [Source Code](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/NotificationTrampolineDetector.kt)
+Tests
+: [Source Code](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/NotificationTrampolineDetectorTest.kt)
+
+Notifications should only launch activities -- that's what users expect
+(and has been the guidance in both the Android SDK and Material Design
+documentation for a while).
+
+A `Service` or a `BroadcastReceiver` should not be used as an
+intermediate, because this can lead to significant performance problems,
+and as a result, this will not be allowed in Android 12.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/NotificationTest.java:22:Warning: Notifications should only
+launch a Service from notification actions (addAction)
+[LaunchActivityFromNotification]
+ .setContentIntent(serviceIntent)
+ -------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/test/pkg/BroadcastTrampoline.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public class BroadcastTrampoline extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // The start below will be blocked
+ Intent i = new Intent();
+ i.setClassName("test.pkg", "test.pkg.SecondActivity");
+ i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(i);
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/NotificationTest.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import androidx.core.app.NotificationCompat;
+@SuppressWarnings("unused")
+public class NotificationTest {
+ public void testServices(Context context, String channelId, int id) {
+ NotificationManager notificationManager =
+ context.getSystemService(NotificationManager.class);
+ Intent notificationIntent = new Intent(context, ServiceTrampoline.class);
+ PendingIntent serviceIntent = PendingIntent.getService(context, 0, notificationIntent, 0);
+ NotificationCompat.Builder builder =
+ new NotificationCompat.Builder(context, channelId)
+ .setSmallIcon(android.R.drawable.ic_menu_my_calendar)
+ .setContentTitle("Notification Trampoline Test")
+ .setContentText("Tap this notification to launch a new service")
+ .setPriority(NotificationCompat.PRIORITY_DEFAULT)
+ .setContentIntent(serviceIntent)
+ .setAutoCancel(true);
+ Notification notification = builder.build();
+ notificationManager.notify(id, notification);
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/NotificationTrampolineDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `NotificationTrampolineDetector.testLaunchUnknownService`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("LaunchActivityFromNotification")
+ fun method() {
+ setContentIntent(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("LaunchActivityFromNotification")
+ void method() {
+ setContentIntent(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection LaunchActivityFromNotification
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="LaunchActivityFromNotification" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'LaunchActivityFromNotification'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore LaunchActivityFromNotification ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/LaunchDuringComposition.md.html b/docs/checks/LaunchDuringComposition.md.html
new file mode 100644
index 00000000..35a257a5
--- /dev/null
+++ b/docs/checks/LaunchDuringComposition.md.html
@@ -0,0 +1,242 @@
+
+(#) Calls to `launch` should happen inside of a SideEffect and not during composition
+
+!!! ERROR: Calls to `launch` should happen inside of a SideEffect and not during composition
+ This is an error.
+
+Id
+: `LaunchDuringComposition`
+Summary
+: Calls to `launch` should happen inside of a SideEffect and not during composition
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Jetpack Activity Compose
+Identifier
+: androidx.activity.compose
+Feedback
+: https://issuetracker.google.com/issues/new?component=612128
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.activity:activity-compose](androidx_activity_activity-compose.md.html)
+Since
+: 1.4.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/activity/activity-compose-lint/src/main/java/androidx/activity/compose/lint/ActivityResultLaunchDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/activity/activity-compose-lint/src/test/java/androidx/activity/compose/lint/ActivityResultLaunchDetectorTest.kt)
+Copyright Year
+: 2021
+
+Calling `launch` during composition is incorrect. Doing so will cause
+launch to be called multiple times resulting in a RuntimeException.
+Instead, use `SideEffect` and `launch` inside of the suspending block.
+The block will only run after a successful composition.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/com/example/test.kt:10:Error: Calls to launch should happen inside
+of a SideEffect and not during composition [LaunchDuringComposition]
+ launcher.launch("test")
+ ------
+src/com/example/test.kt:15:Error: Calls to launch should happen inside
+of a SideEffect and not during composition [LaunchDuringComposition]
+ launcher.launch("test")
+ ------
+src/com/example/test.kt:20:Error: Calls to launch should happen inside
+of a SideEffect and not during composition [LaunchDuringComposition]
+ launcher.launch("test")
+ ------
+src/com/example/test.kt:30:Error: Calls to launch should happen inside
+of a SideEffect and not during composition [LaunchDuringComposition]
+ launcher.launch("test")
+ ------
+src/com/example/test.kt:34:Error: Calls to launch should happen inside
+of a SideEffect and not during composition [LaunchDuringComposition]
+ launcher.launch("test")
+ ------
+src/com/example/test.kt:41:Error: Calls to launch should happen inside
+of a SideEffect and not during composition [LaunchDuringComposition]
+ launcher.launch("test")
+ ------
+src/com/example/test.kt:46:Error: Calls to launch should happen inside
+of a SideEffect and not during composition [LaunchDuringComposition]
+ launcher.launch("test")
+ ------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/com/example/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package com.example
+
+import androidx.compose.runtime.Composable
+import androidx.activity.compose.ManagedActivityResultLauncher
+
+@Composable
+fun Test() {
+ val launcher = ManagedActivityResultLauncher()
+ launcher.launch("test")
+}
+
+val lambda = @Composable {
+ val launcher = ManagedActivityResultLauncher()
+ launcher.launch("test")
+}
+
+val lambda2: @Composable () -> Unit = {
+ val launcher = ManagedActivityResultLauncher()
+ launcher.launch("test")
+}
+
+@Composable
+fun LambdaParameter(content: @Composable () -> Unit) {}
+
+@Composable
+fun Test2() {
+ LambdaParameter(content = {
+ val launcher = ManagedActivityResultLauncher()
+ launcher.launch("test")
+ })
+ LambdaParameter {
+ val launcher = ManagedActivityResultLauncher()
+ launcher.launch("test")
+ }
+}
+
+fun test3() {
+ val localLambda1 = @Composable {
+ val launcher = ManagedActivityResultLauncher()
+ launcher.launch("test")
+ }
+
+ val localLambda2: @Composable () -> Unit = {
+ val launcher = ManagedActivityResultLauncher()
+ launcher.launch("test")
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/activity/activity-compose-lint/src/test/java/androidx/activity/compose/lint/ActivityResultLaunchDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ActivityResultLaunchDetector.errors`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=612128.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.activity:activity-compose:1.11.0-rc01")
+
+// build.gradle
+implementation 'androidx.activity:activity-compose:1.11.0-rc01'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.activity.compose)
+
+# libs.versions.toml
+[versions]
+activity-compose = "1.11.0-rc01"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+activity-compose = {
+ module = "androidx.activity:activity-compose",
+ version.ref = "activity-compose"
+}
+```
+
+1.11.0-rc01 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.activity:activity-compose](androidx_activity_activity-compose.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("LaunchDuringComposition")
+ fun method() {
+ launch(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("LaunchDuringComposition")
+ void method() {
+ launch(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection LaunchDuringComposition
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="LaunchDuringComposition" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'LaunchDuringComposition'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore LaunchDuringComposition ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/LayoutFileNameMatchesClass.md.html b/docs/checks/LayoutFileNameMatchesClass.md.html
new file mode 100644
index 00000000..126aee32
--- /dev/null
+++ b/docs/checks/LayoutFileNameMatchesClass.md.html
@@ -0,0 +1,190 @@
+
+(#) Checks that the layout file matches the class name
+
+!!! WARNING: Checks that the layout file matches the class name
+ This is a warning.
+
+Id
+: `LayoutFileNameMatchesClass`
+Summary
+: Checks that the layout file matches the class name
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: vanniktech/lint-rules/
+Feedback
+: https://github.com/vanniktech/lint-rules/issues
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [com.vanniktech:lint-rules-android](com_vanniktech_lint-rules-android.md.html)
+Since
+: 0.7.1
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/main/kotlin/com/vanniktech/lintrules/android/LayoutFileNameMatchesClassDetector.kt)
+Tests
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/test/kotlin/com/vanniktech/lintrules/android/LayoutFileNameMatchesClassDetectorTest.kt)
+
+Layout file names should always match the name of the class. FooActivity
+should have a layout file named activity_foo hence.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/main/java/foo/FooActivity.java:5:Warning: Parameter should be named
+R.layout.unit_test_activity_foo [LayoutFileNameMatchesClass]
+ setContentView(R.layout.activity_bar);
+ ---------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/foo/Activity.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package foo;
+
+public abstract class Activity {
+ public void setContentView(int viewId) { }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/main/java/foo/FooActivity.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package foo;
+
+class FooActivity extends Activity {
+ void foo() {
+ setContentView(R.layout.activity_bar);
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`null`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text linenumbers
+unit_test_
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/test/kotlin/com/vanniktech/lintrules/android/LayoutFileNameMatchesClassDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `LayoutFileNameMatchesClassDetector.fooActivityUsesActivityBarWithResourcePrefix`.
+To report a problem with this extracted sample, visit
+https://github.com/vanniktech/lint-rules/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.vanniktech:lint-rules-android:0.25.0")
+
+// build.gradle
+lintChecks 'com.vanniktech:lint-rules-android:0.25.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.lint.rules.android)
+
+# libs.versions.toml
+[versions]
+lint-rules-android = "0.25.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+lint-rules-android = {
+ module = "com.vanniktech:lint-rules-android",
+ version.ref = "lint-rules-android"
+}
+```
+
+0.25.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.vanniktech:lint-rules-android](com_vanniktech_lint-rules-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("LayoutFileNameMatchesClass")
+ fun method() {
+ setContentView(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("LayoutFileNameMatchesClass")
+ void method() {
+ setContentView(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection LayoutFileNameMatchesClass
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="LayoutFileNameMatchesClass" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'LayoutFileNameMatchesClass'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore LayoutFileNameMatchesClass ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/LeanbackUsesWifi.md.html b/docs/checks/LeanbackUsesWifi.md.html
new file mode 100644
index 00000000..2aaa12c1
--- /dev/null
+++ b/docs/checks/LeanbackUsesWifi.md.html
@@ -0,0 +1,116 @@
+
+(#) Using android.hardware.wifi on TV
+
+!!! WARNING: Using android.hardware.wifi on TV
+ This is a warning.
+
+Id
+: `LeanbackUsesWifi`
+Summary
+: Using android.hardware.wifi on TV
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 7.0.0 (July 2021)
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/LeanbackWifiUsageDetector.kt)
+Tests
+: [Source Code](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/LeanbackWifiUsageDetectorTest.kt)
+
+WiFi is not required for Android TV and many devices connect to the
+internet via alternative methods e.g. Ethernet.
+
+If your app is not focused specifically on WiFi functionality and only
+wishes to connect to the internet, please modify your Manifest to
+contain: ` `
+
+Un-metered or non-roaming connections can be detected in software using
+`NetworkCapabilities#NET_CAPABILITY_NOT_METERED` and
+`NetworkCapabilities#NET_CAPABILITY_NOT_ROAMING.`
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:4:Warning: Requiring Wifi permissions limits app
+availability on TVs that support only Ethernet [LeanbackUsesWifi]
+ <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
+ ----------------------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="test.pkg">
+ <uses-feature android:name="android.software.leanback"/>
+ <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name" >
+ </application>
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/LeanbackWifiUsageDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="LeanbackUsesWifi"`
+ on the problematic XML element (or one of its enclosing elements).
+ You may also need to add the following namespace declaration on the
+ root element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="LeanbackUsesWifi" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'LeanbackUsesWifi'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore LeanbackUsesWifi ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/LibraryCustomView.md.html b/docs/checks/LibraryCustomView.md.html
new file mode 100644
index 00000000..81b95611
--- /dev/null
+++ b/docs/checks/LibraryCustomView.md.html
@@ -0,0 +1,142 @@
+
+(#) Custom views in libraries should use res-auto-namespace
+
+!!! ERROR: Custom views in libraries should use res-auto-namespace
+ This is an error, and is also enforced at build time when
+ supported by the build system. For Android this means it will
+ run during release builds.
+
+Id
+: `LibraryCustomView`
+Summary
+: Custom views in libraries should use res-auto-namespace
+Severity
+: Fatal
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Manifest files and resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/NamespaceDetector.kt)
+Tests
+: [Source Code](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/NamespaceDetectorTest.kt)
+Copyright Year
+: 2012
+
+When using a custom view with custom attributes in a library project,
+the layout must use the special namespace
+http://schemas.android.com/apk/res-auto instead of a URI which includes
+the library project's own package. This will be used to automatically
+adjust the namespace of the attributes when the library resources are
+merged into the application project.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/customview.xml:5:Error: When using a custom namespace
+attribute in a library project, use the namespace
+"http://schemas.android.com/apk/res-auto" instead [LibraryCustomView]
+ xmlns:foo="http://schemas.android.com/apk/res/foo"
+ --------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/layout/customview.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ xmlns:other="http://schemas.foo.bar.com/other"
+ xmlns:foo="http://schemas.android.com/apk/res/foo"
+ android:id="@+id/newlinear"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <foo.bar.Baz
+ android:id="@+id/button1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Button1"
+ foo:misc="Custom attribute"
+ tools:ignore="HardcodedText" >
+ </foo.bar.Baz>
+
+ <!-- Wrong namespace uri prefix: Don't warn -->
+ <foo.bar.Baz
+ android:id="@+id/button1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Button1"
+ other:misc="Custom attribute"
+ tools:ignore="HardcodedText" >
+ </foo.bar.Baz>
+
+</LinearLayout>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/NamespaceDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `NamespaceDetector.testCustom`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="LibraryCustomView"`
+ on the problematic XML element (or one of its enclosing elements).
+ You may also need to add the following namespace declaration on the
+ root element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="LibraryCustomView" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'LibraryCustomView'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore LibraryCustomView ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/LifecycleAnnotationProcessorWithJava8.md.html b/docs/checks/LifecycleAnnotationProcessorWithJava8.md.html
new file mode 100644
index 00000000..a5d87098
--- /dev/null
+++ b/docs/checks/LifecycleAnnotationProcessorWithJava8.md.html
@@ -0,0 +1,128 @@
+
+(#) Lifecycle Annotation Processor with Java 8 Compile Option
+
+!!! WARNING: Lifecycle Annotation Processor with Java 8 Compile Option
+ This is a warning.
+
+Id
+: `LifecycleAnnotationProcessorWithJava8`
+Summary
+: Lifecycle Annotation Processor with Java 8 Compile Option
+Severity
+: Warning
+Category
+: Performance
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.5.0 (August 2019)
+Affects
+: Gradle build files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://d.android.com/r/studio-ui/lifecycle-release-notes
+Implementation
+: [Source Code](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/GradleDetector.kt)
+Tests
+: [Source Code](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/GradleDetectorTest.kt)
+
+For faster incremental build, switch to the Lifecycle Java 8 API with
+these steps:
+
+First replace
+```gradle
+annotationProcessor "androidx.lifecycle:lifecycle-compiler:*version*"
+kapt "androidx.lifecycle:lifecycle-compiler:*version*"
+```
+with
+```gradle
+implementation "androidx.lifecycle:lifecycle-common-java8:*version*"
+```
+Then remove any `OnLifecycleEvent` annotations from `Observer` classes
+and make them implement the `DefaultLifecycleObserver` interface.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+build.gradle:3:Warning: Use the Lifecycle Java 8 API provided by the
+lifecycle-common library instead of Lifecycle annotations for faster
+incremental build. [LifecycleAnnotationProcessorWithJava8]
+ annotationProcessor "android.arch.lifecycle:compiler:1.1.1"
+ ---------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`build.gradle`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~groovy linenumbers
+dependencies {
+ implementation "android.arch.lifecycle:runtime:1.1.1"
+ annotationProcessor "android.arch.lifecycle:compiler:1.1.1"
+}android {
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/GradleDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `GradleDetector.testJava8WithLifecycleAnnotationProcessor`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection LifecycleAnnotationProcessorWithJava8
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="LifecycleAnnotationProcessorWithJava8" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'LifecycleAnnotationProcessorWithJava8'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore LifecycleAnnotationProcessorWithJava8 ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/LifecycleCurrentStateInComposition.md.html b/docs/checks/LifecycleCurrentStateInComposition.md.html
new file mode 100644
index 00000000..c603d657
--- /dev/null
+++ b/docs/checks/LifecycleCurrentStateInComposition.md.html
@@ -0,0 +1,249 @@
+
+(#) Lifecycle.currentState should not be called within composition
+
+!!! ERROR: Lifecycle.currentState should not be called within composition
+ This is an error.
+
+Id
+: `LifecycleCurrentStateInComposition`
+Summary
+: Lifecycle.currentState should not be called within composition
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Identifier
+: androidx.lifecycle
+Feedback
+: https://issuetracker.google.com/issues/new?component=413132
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.lifecycle:lifecycle-runtime-compose-android](androidx_lifecycle_lifecycle-runtime-compose-android.md.html)
+Since
+: 2.9.0-alpha10
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/lifecycle/lifecycle-runtime-compose-lint/src/main/java/androidx/lifecycle/runtime/compose/lint/ComposableLifecycleCurrentStateDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/lifecycle/lifecycle-runtime-compose-lint/src/test/java/androidx/lifecycle/runtime/compose/lint/ComposableLifecycleCurrentStateDetectorTest.kt)
+Copyright Year
+: 2025
+
+Calling Lifecycle.currentState within composition will not observe
+changes to the Lifecycle, so changes might not be reflected within the
+composition. Instead you should use lifecycle.currentStateAsState() to
+observe changes to the Lifecycle, and recompose when it changes.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/androidx/lifecycle/foo/test.kt:12:Error: Lifecycle.currentState
+should not be called within composition
+[LifecycleCurrentStateInComposition]
+ lifecycle.currentState
+ ------------
+src/androidx/lifecycle/foo/test.kt:16:Error: Lifecycle.currentState
+should not be called within composition
+[LifecycleCurrentStateInComposition]
+ lifecycle.currentState
+ ------------
+src/androidx/lifecycle/foo/test.kt:20:Error: Lifecycle.currentState
+should not be called within composition
+[LifecycleCurrentStateInComposition]
+ lifecycle.currentState
+ ------------
+src/androidx/lifecycle/foo/test.kt:29:Error: Lifecycle.currentState
+should not be called within composition
+[LifecycleCurrentStateInComposition]
+ lifecycle.currentState
+ ------------
+src/androidx/lifecycle/foo/test.kt:32:Error: Lifecycle.currentState
+should not be called within composition
+[LifecycleCurrentStateInComposition]
+ lifecycle.currentState
+ ------------
+src/androidx/lifecycle/foo/test.kt:38:Error: Lifecycle.currentState
+should not be called within composition
+[LifecycleCurrentStateInComposition]
+ lifecycle.currentState
+ ------------
+src/androidx/lifecycle/foo/test.kt:42:Error: Lifecycle.currentState
+should not be called within composition
+[LifecycleCurrentStateInComposition]
+ lifecycle.currentState
+ ------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/androidx/lifecycle/foo/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package androidx.lifecycle.foo
+
+import androidx.compose.runtime.Composable
+import androidx.lifecycle.Lifecycle
+
+val lifecycle: Lifecycle = object : Lifecycle() {
+ override val currentState get() = Lifecycle.State.CREATED
+}
+
+@Composable
+fun Test() {
+ lifecycle.currentState
+}
+
+val lambda = @Composable {
+ lifecycle.currentState
+}
+
+val lambda2: @Composable () -> Unit = {
+ lifecycle.currentState
+}
+
+@Composable
+fun LambdaParameter(content: @Composable () -> Unit) {}
+
+@Composable
+fun Test2() {
+ LambdaParameter(content = {
+ lifecycle.currentState
+ })
+ LambdaParameter {
+ lifecycle.currentState
+ }
+}
+
+fun test3() {
+ val localLambda1 = @Composable {
+ lifecycle.currentState
+ }
+
+ val localLambda2: @Composable () -> Unit = {
+ lifecycle.currentState
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/lifecycle/lifecycle-runtime-compose-lint/src/test/java/androidx/lifecycle/runtime/compose/lint/ComposableLifecycleCurrentStateDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ComposableLifecycleCurrentStateDetector.errors`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=413132.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.lifecycle:lifecycle-runtime-compose-android:2.9.0-rc01")
+
+// build.gradle
+implementation 'androidx.lifecycle:lifecycle-runtime-compose-android:2.9.0-rc01'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.lifecycle.runtime.compose.android)
+
+# libs.versions.toml
+[versions]
+lifecycle-runtime-compose-android = "2.9.0-rc01"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+lifecycle-runtime-compose-android = {
+ module = "androidx.lifecycle:lifecycle-runtime-compose-android",
+ version.ref = "lifecycle-runtime-compose-android"
+}
+```
+
+2.9.0-rc01 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about androidx.lifecycle:lifecycle-runtime-compose-android](androidx_lifecycle_lifecycle-runtime-compose-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("LifecycleCurrentStateInComposition")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("LifecycleCurrentStateInComposition")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection LifecycleCurrentStateInComposition
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="LifecycleCurrentStateInComposition" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'LifecycleCurrentStateInComposition'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore LifecycleCurrentStateInComposition ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/LintDocExample.md.html b/docs/checks/LintDocExample.md.html
new file mode 100644
index 00000000..cecc7dd8
--- /dev/null
+++ b/docs/checks/LintDocExample.md.html
@@ -0,0 +1,413 @@
+
+(#) Missing Documentation Example
+
+!!! WARNING: Missing Documentation Example
+ This is a warning.
+
+Id
+: `LintDocExample`
+Summary
+: Missing Documentation Example
+Note
+: **This issue is disabled by default**; use `--enable LintDocExample`
+Severity
+: Warning
+Category
+: Lint Implementation Issues
+Platform
+: JDK
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 7.0.0 (July 2021)
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/LintDetectorDetector.kt)
+Tests
+: [Source Code](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/LintDetectorDetectorTest.kt)
+
+Lint's tool for generating documentation for each issue has special
+support for including a code example which shows how to trigger the
+report. It will pick the first unit test it can find and pick out the
+source file referenced from the error message, but you can instead
+designate a unit test to be the documentation example, and in that case,
+all the files are included.
+
+To designate a unit test as the documentation example for an issue, name
+the test `testDocumentationExample`, or if your detector reports
+multiple issues, `testDocumentationExample`, such as
+`testDocumentationExampleMyId`.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/MyKotlinLintDetectorTest.kt:10:Warning: Expected to also
+find a documentation example test (testDocumentationExample) which shows
+a simple, typical scenario which triggers the test, and which will be
+extracted into lint's per-issue documentation pages [LintDocExample]
+ fun testBasic() {
+ ^
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/test/pkg/MyJavaLintDetector.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+/* Copyright (C) 2020 The Android Open Source Project */
+package test.pkg;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiCallExpression;
+import com.intellij.psi.PsiExpression;
+import com.intellij.psi.PsiField;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.android.tools.lint.detector.api.Detector;
+import org.jetbrains.uast.UFile;
+import org.jetbrains.uast.UMethod;
+import org.jetbrains.uast.UField;
+import com.android.tools.lint.detector.api.Category;
+import com.android.tools.lint.detector.api.Detector;
+import com.android.tools.lint.detector.api.Implementation;
+import com.android.tools.lint.detector.api.Issue;
+import com.android.tools.lint.detector.api.JavaContext;
+import com.android.tools.lint.detector.api.Scope;
+import com.android.tools.lint.detector.api.Severity;
+import org.jetbrains.uast.UCallExpression;
+import java.util.EnumSet;
+
+@SuppressWarnings({"MethodMayBeStatic", "ClassNameDiffersFromFileName", "StatementWithEmptyBody", "deprecation"})
+public class MyJavaLintDetector extends Detector {
+ public static final Issue ISSUE =
+ Issue.create(
+ "com.android.namespaced.lint.check.FooDetector",
+ "Wrong use of ",
+ "As described in "
+ + "https://code.google.com/p/android/issues/detail?id=65351%20blah%20blah%20blah.",
+ Category.A11Y,
+ 3,
+ Severity.WARNING,
+ new Implementation(MyJavaLintDetector.class, EnumSet.of(Scope.RESOURCE_FILE, Scope.JAVA_FILE)))
+ .addMoreInfo("file://explanation.doc")
+ .addMoreInfo("http://my.personal.blogger.com/aboutme.htm")
+ .addMoreInfo("mailto:lint@example.com");
+ public void testGetBody(PsiMethod method) {
+ method.getBody(); // ERROR - must use UAST
+ }
+ public void testGetBody(UMethod method) {
+ method.getBody(); // ERROR - must use UAST
+ }
+ public void testGetContainingClass(UMethod method, UField field) {
+ method.getContainingClass(); // ERROR - must use UAST
+ field.getContainingClass(); // ERROR - must use UAST
+ }
+ public void testGetContainingClass(PsiMethod method, PsiField field) {
+ method.getContainingClass(); // OK - legitimate uses after resolve
+ field.getContainingClass(); // OK - legitimate uses after resolve
+ }
+ public void testEquals(PsiCallExpression element1, PsiExpression element2) {
+ if (element1.equals(element2)) { }
+ if (element2.equals(element1)) { }
+ if (element1 == element2) { }
+ if (element1 != element2) { }
+ }
+ public void testGetInitializer(PsiField field) {
+ field.getInitializer(); // ERROR - must use UAST
+ }
+ public void testParents(PsiField field, UMethod method) {
+ PsiElement parent = field.getParent(); // OK
+ PsiElement parent = method.getParent(); // ERROR
+ PsiTreeUtil.getParentOfType(field, PsiClass.class); // OK
+ PsiTreeUtil.getParentOfType(method, PsiClass.class); // ERROR
+ }
+
+ public void testReport(JavaContext context, UCallExpression node) {
+ context.report(ISSUE, node, context.getLocation(node),
+ "Wrong use of LinearLayout.");
+ context.report(ISSUE, node, context.getLocation(node),
+ "First problem. Second problem.");
+ context.report(ISSUE, node, context.getLocation(node),
+ "This is teh typo");
+ String message = "Welcome to Andriod";
+ context.report(ISSUE, node, context.getLocation(node), message);
+ context.report(ISSUE, node, context.getLocation(node),
+ "Should you use `x ?: y` instead of ```foo ? 1 : 0``` ?");
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyKotlinLintDetector.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+/* Copyright (C) 2020 The Android Open Source Project */
+package test.pkg
+import com.intellij.psi.PsiCallExpression
+import com.intellij.psi.PsiExpression
+import com.intellij.psi.PsiField
+import com.intellij.psi.PsiMethod
+import com.intellij.psi.util.PsiTreeUtil
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import org.jetbrains.uast.UCallExpression
+
+class MyKotlinLintDetector : Detector() {
+ fun testGetBody(method: PsiMethod) {
+ val body = method.body // ERROR - must use UAST
+ }
+ @Suppress("ReplaceCallWithBinaryOperator","ControlFlowWithEmptyBody")
+ fun testEquals(element1: PsiCallExpression, element2: PsiExpression) {
+ if (element1.equals(element2)) { }
+ if (element2.equals(element1)) { }
+ if (element1 == element2) { }
+ if (element1 === element2) { }
+ if (element1 != element2) { }
+ if (element1 !== element2) { }
+ if (element1 == null) { } // OK
+ if (element1 === null) { } // OK
+ if (element1 != null) { } // OK
+ if (element1 !== null) { } // OK
+ }
+ @Suppress("UsePropertyAccessSyntax")
+ fun testGetInitializer(field: PsiField) {
+ field.getInitializer() // ERROR - must use UAST
+ field.initializer // ERROR - must use UAST
+ }
+ fun testParents(field: PsiField) {
+ val parent = field.parent
+ val method = PsiTreeUtil.getParentOfType(field, PsiMethod::class.java)
+ }
+
+ fun testReport(context: JavaContext, node: UCallExpression) {
+ context.report(ISSUE, node, context.getLocation(node),
+ """
+ |Instead you should call foo().bar().baz() here.
+ |""".trimIndent())
+ }
+
+ companion object {
+ private val IMPLEMENTATION =
+ Implementation(
+ MyKotlinLintDetector::class.java,
+ Scope.JAVA_FILE_SCOPE
+ )
+
+ val ISSUE =
+ Issue.create(
+ id = "badlyCapitalized id",
+ briefDescription = "checks MyLintDetector.",
+ explanation = """
+ Some description here.
+ Here's a call: foo.bar.baz(args).
+ This line continuation is okay. \
+ But this one is missing a space.\
+ Okay?
+ """.trimIndent(),
+ category = Category.INTEROPERABILITY_KOTLIN,
+ moreInfo = "https://code.google.com/p/android/issues/detail?id=65351", // OBSOLETE
+ priority = 4,
+ severity = Severity.WARNING,
+ implementation = IMPLEMENTATION
+ )
+ .addMoreInfo("https://issuetracker.google.com/issues/3733548") // ERROR - missing digit
+ .addMoreInfo("https://issuetracker.google.com/issues/373354878") // OK - including digit
+ .addMoreInfo("http://issuetracker.google.com/issues/37335487") // ERROR - http instead of https
+ .addMoreInfo("https://b.corp.google.com/issues/139153781") // ERROR - don't point to buganizer with internal link
+ .addMoreInfo("https://goo.gle/policy-storage-help") // OK - regression test for goo.gle
+ }
+
+ override fun visitAnnotationUsage(
+ context: JavaContext,
+ element: org.jetbrains.uast.UElement.UElement,
+ annotationInfo: com.android.tools.lint.detector.api.AnnotationInfo,
+ usageInfo: com.android.tools.lint.detector.api.AnnotationUsageInfo
+ ) {
+ // Invalid recursion!
+ super.visitAnnotationUsage(context, element, annotationInfo, usageInfo)
+ }
+
+ fun misc() {
+ System.out.print("Debugging")
+ println("Debugging code")
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyIssueRegistry.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import com.android.tools.lint.client.api.IssueRegistry
+class MyIssueRegistry : IssueRegistry() {
+ override val issues = listOf(
+ MyJavaLintDetector.ISSUE,
+ MyKotlinLintDetector.Companion.ISSUE
+ )
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyVendorIssueRegistry.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import com.android.tools.lint.client.api.IssueRegistry
+import com.android.tools.lint.client.api.Vendor
+class MyVendorIssueRegistry : IssueRegistry() {
+ // Supplies a vendor: no warning
+ override var vendor: Vendor? = Vendor("Unit test")
+ override val issues = listOf(
+ MyJavaLintDetector.ISSUE,
+ MyKotlinLintDetector.Companion.ISSUE
+ )
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/InheritingRegistry.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import com.android.tools.lint.client.api.IssueRegistry
+import com.android.tools.lint.client.api.Vendor
+class InheritingRegistry : MyVendorIssueRegistry() { // NO WARNING
+ // This registry doesn't supply a vendor but inherits one; no warning
+ override val issues = listOf(
+ MyJavaLintDetector.ISSUE,
+ MyKotlinLintDetector.Companion.ISSUE
+ )
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyKotlinLintDetectorTest.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+// Copyright (C) 2021 The Android Open Source Project
+package test.pkg
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest
+import com.android.tools.lint.detector.api.Detector
+class MyKotlinLintDetectorTest : LintDetectorTest() {
+ override fun getDetector(): Detector {
+ return MyKotlinLintDetector()
+ }
+
+ fun testBasic() {
+ val expected = """
+ src/test/pkg/AlarmTest.java:9: Warning: Value will be forced up to 5000 as of Android 5.1; don't rely on this to be exact [ShortAlarm]
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 50, 10, null); // ERROR
+ ~~
+ 0 errors, 1 warnings
+ """
+
+ lint().files(
+ kotlin(
+ """
+ fun test() {
+ println("Value=${"$"}")
+ }
+ """
+ ),
+ java(
+ "src/test/pkg/AlarmTest.java",
+ """
+ package test.pkg;
+
+ import android.app.AlarmManager;
+ @SuppressWarnings("ClassNameDiffersFromFileName")
+ public class AlarmTest {
+ public void test(AlarmManager alarmManager) {
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 5000, 60000, null); // OK
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 6000, 70000, null); // OK
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 50, 10, null); // ERROR
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 5000, // ERROR
+ OtherClass.MY_INTERVAL, null); // ERROR
+ }
+
+ private static class OtherClass {
+ public static final long MY_INTERVAL = 1000L;
+ }
+ }
+ """.trimIndent()
+ )
+ ).run().expect(expected)
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/LintDetectorDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `LintDetectorDetector.testProblems`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("LintDocExample")
+ fun method() {
+ expect(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("LintDocExample")
+ void method() {
+ expect(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection LintDocExample
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="LintDocExample" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'LintDocExample'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore LintDocExample ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/LintImplBadUrl.md.html b/docs/checks/LintImplBadUrl.md.html
new file mode 100644
index 00000000..e932a807
--- /dev/null
+++ b/docs/checks/LintImplBadUrl.md.html
@@ -0,0 +1,409 @@
+
+(#) Bad More Info Link
+
+!!! ERROR: Bad More Info Link
+ This is an error.
+
+Id
+: `LintImplBadUrl`
+Summary
+: Bad More Info Link
+Severity
+: Error
+Category
+: Lint Implementation Issues
+Platform
+: JDK
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 4.1.0 (October 2020)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/LintDetectorDetector.kt)
+Tests
+: [Source Code](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/LintDetectorDetectorTest.kt)
+
+More Info URLs let a link check point to additional resources about the
+problem and solution it's checking for.
+
+This check validates the URLs in various ways, such as making sure that
+issue tracker links look correct. It may also at some point touch the
+network to make sure that the URLs are actually still reachable.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/MyJavaLintDetector.java:30:Error: Don't point to old
+http://b.android.com links; should be using
+https://issuetracker.google.com instead [LintImplBadUrl]
+ + "https://code.google.com/p/android/issues/detail?id=65351%20blah%20blah%20blah.",
+ --------------------------------------------------------
+src/test/pkg/MyJavaLintDetector.java:35:Error: Unexpected protocol file
+in file://explanation.doc [LintImplBadUrl]
+ .addMoreInfo("file://explanation.doc")
+ ----------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/test/pkg/MyJavaLintDetector.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+/* Copyright (C) 2020 The Android Open Source Project */
+package test.pkg;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiCallExpression;
+import com.intellij.psi.PsiExpression;
+import com.intellij.psi.PsiField;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.android.tools.lint.detector.api.Detector;
+import org.jetbrains.uast.UFile;
+import org.jetbrains.uast.UMethod;
+import org.jetbrains.uast.UField;
+import com.android.tools.lint.detector.api.Category;
+import com.android.tools.lint.detector.api.Detector;
+import com.android.tools.lint.detector.api.Implementation;
+import com.android.tools.lint.detector.api.Issue;
+import com.android.tools.lint.detector.api.JavaContext;
+import com.android.tools.lint.detector.api.Scope;
+import com.android.tools.lint.detector.api.Severity;
+import org.jetbrains.uast.UCallExpression;
+import java.util.EnumSet;
+
+@SuppressWarnings({"MethodMayBeStatic", "ClassNameDiffersFromFileName", "StatementWithEmptyBody", "deprecation"})
+public class MyJavaLintDetector extends Detector {
+ public static final Issue ISSUE =
+ Issue.create(
+ "com.android.namespaced.lint.check.FooDetector",
+ "Wrong use of ",
+ "As described in "
+ + "https://code.google.com/p/android/issues/detail?id=65351%20blah%20blah%20blah.",
+ Category.A11Y,
+ 3,
+ Severity.WARNING,
+ new Implementation(MyJavaLintDetector.class, EnumSet.of(Scope.RESOURCE_FILE, Scope.JAVA_FILE)))
+ .addMoreInfo("file://explanation.doc")
+ .addMoreInfo("http://my.personal.blogger.com/aboutme.htm")
+ .addMoreInfo("mailto:lint@example.com");
+ public void testGetBody(PsiMethod method) {
+ method.getBody(); // ERROR - must use UAST
+ }
+ public void testGetBody(UMethod method) {
+ method.getBody(); // ERROR - must use UAST
+ }
+ public void testGetContainingClass(UMethod method, UField field) {
+ method.getContainingClass(); // ERROR - must use UAST
+ field.getContainingClass(); // ERROR - must use UAST
+ }
+ public void testGetContainingClass(PsiMethod method, PsiField field) {
+ method.getContainingClass(); // OK - legitimate uses after resolve
+ field.getContainingClass(); // OK - legitimate uses after resolve
+ }
+ public void testEquals(PsiCallExpression element1, PsiExpression element2) {
+ if (element1.equals(element2)) { }
+ if (element2.equals(element1)) { }
+ if (element1 == element2) { }
+ if (element1 != element2) { }
+ }
+ public void testGetInitializer(PsiField field) {
+ field.getInitializer(); // ERROR - must use UAST
+ }
+ public void testParents(PsiField field, UMethod method) {
+ PsiElement parent = field.getParent(); // OK
+ PsiElement parent = method.getParent(); // ERROR
+ PsiTreeUtil.getParentOfType(field, PsiClass.class); // OK
+ PsiTreeUtil.getParentOfType(method, PsiClass.class); // ERROR
+ }
+
+ public void testReport(JavaContext context, UCallExpression node) {
+ context.report(ISSUE, node, context.getLocation(node),
+ "Wrong use of LinearLayout.");
+ context.report(ISSUE, node, context.getLocation(node),
+ "First problem. Second problem.");
+ context.report(ISSUE, node, context.getLocation(node),
+ "This is teh typo");
+ String message = "Welcome to Andriod";
+ context.report(ISSUE, node, context.getLocation(node), message);
+ context.report(ISSUE, node, context.getLocation(node),
+ "Should you use `x ?: y` instead of ```foo ? 1 : 0``` ?");
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyKotlinLintDetector.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+/* Copyright (C) 2020 The Android Open Source Project */
+package test.pkg
+import com.intellij.psi.PsiCallExpression
+import com.intellij.psi.PsiExpression
+import com.intellij.psi.PsiField
+import com.intellij.psi.PsiMethod
+import com.intellij.psi.util.PsiTreeUtil
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import org.jetbrains.uast.UCallExpression
+
+class MyKotlinLintDetector : Detector() {
+ fun testGetBody(method: PsiMethod) {
+ val body = method.body // ERROR - must use UAST
+ }
+ @Suppress("ReplaceCallWithBinaryOperator","ControlFlowWithEmptyBody")
+ fun testEquals(element1: PsiCallExpression, element2: PsiExpression) {
+ if (element1.equals(element2)) { }
+ if (element2.equals(element1)) { }
+ if (element1 == element2) { }
+ if (element1 === element2) { }
+ if (element1 != element2) { }
+ if (element1 !== element2) { }
+ if (element1 == null) { } // OK
+ if (element1 === null) { } // OK
+ if (element1 != null) { } // OK
+ if (element1 !== null) { } // OK
+ }
+ @Suppress("UsePropertyAccessSyntax")
+ fun testGetInitializer(field: PsiField) {
+ field.getInitializer() // ERROR - must use UAST
+ field.initializer // ERROR - must use UAST
+ }
+ fun testParents(field: PsiField) {
+ val parent = field.parent
+ val method = PsiTreeUtil.getParentOfType(field, PsiMethod::class.java)
+ }
+
+ fun testReport(context: JavaContext, node: UCallExpression) {
+ context.report(ISSUE, node, context.getLocation(node),
+ """
+ |Instead you should call foo().bar().baz() here.
+ |""".trimIndent())
+ }
+
+ companion object {
+ private val IMPLEMENTATION =
+ Implementation(
+ MyKotlinLintDetector::class.java,
+ Scope.JAVA_FILE_SCOPE
+ )
+
+ val ISSUE =
+ Issue.create(
+ id = "badlyCapitalized id",
+ briefDescription = "checks MyLintDetector.",
+ explanation = """
+ Some description here.
+ Here's a call: foo.bar.baz(args).
+ This line continuation is okay. \
+ But this one is missing a space.\
+ Okay?
+ """.trimIndent(),
+ category = Category.INTEROPERABILITY_KOTLIN,
+ moreInfo = "https://code.google.com/p/android/issues/detail?id=65351", // OBSOLETE
+ priority = 4,
+ severity = Severity.WARNING,
+ implementation = IMPLEMENTATION
+ )
+ .addMoreInfo("https://issuetracker.google.com/issues/3733548") // ERROR - missing digit
+ .addMoreInfo("https://issuetracker.google.com/issues/373354878") // OK - including digit
+ .addMoreInfo("http://issuetracker.google.com/issues/37335487") // ERROR - http instead of https
+ .addMoreInfo("https://b.corp.google.com/issues/139153781") // ERROR - don't point to buganizer with internal link
+ .addMoreInfo("https://goo.gle/policy-storage-help") // OK - regression test for goo.gle
+ }
+
+ override fun visitAnnotationUsage(
+ context: JavaContext,
+ element: org.jetbrains.uast.UElement.UElement,
+ annotationInfo: com.android.tools.lint.detector.api.AnnotationInfo,
+ usageInfo: com.android.tools.lint.detector.api.AnnotationUsageInfo
+ ) {
+ // Invalid recursion!
+ super.visitAnnotationUsage(context, element, annotationInfo, usageInfo)
+ }
+
+ fun misc() {
+ System.out.print("Debugging")
+ println("Debugging code")
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyIssueRegistry.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import com.android.tools.lint.client.api.IssueRegistry
+class MyIssueRegistry : IssueRegistry() {
+ override val issues = listOf(
+ MyJavaLintDetector.ISSUE,
+ MyKotlinLintDetector.Companion.ISSUE
+ )
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyVendorIssueRegistry.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import com.android.tools.lint.client.api.IssueRegistry
+import com.android.tools.lint.client.api.Vendor
+class MyVendorIssueRegistry : IssueRegistry() {
+ // Supplies a vendor: no warning
+ override var vendor: Vendor? = Vendor("Unit test")
+ override val issues = listOf(
+ MyJavaLintDetector.ISSUE,
+ MyKotlinLintDetector.Companion.ISSUE
+ )
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/InheritingRegistry.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import com.android.tools.lint.client.api.IssueRegistry
+import com.android.tools.lint.client.api.Vendor
+class InheritingRegistry : MyVendorIssueRegistry() { // NO WARNING
+ // This registry doesn't supply a vendor but inherits one; no warning
+ override val issues = listOf(
+ MyJavaLintDetector.ISSUE,
+ MyKotlinLintDetector.Companion.ISSUE
+ )
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyKotlinLintDetectorTest.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+// Copyright (C) 2021 The Android Open Source Project
+package test.pkg
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest
+import com.android.tools.lint.detector.api.Detector
+class MyKotlinLintDetectorTest : LintDetectorTest() {
+ override fun getDetector(): Detector {
+ return MyKotlinLintDetector()
+ }
+
+ fun testBasic() {
+ val expected = """
+ src/test/pkg/AlarmTest.java:9: Warning: Value will be forced up to 5000 as of Android 5.1; don't rely on this to be exact [ShortAlarm]
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 50, 10, null); // ERROR
+ ~~
+ 0 errors, 1 warnings
+ """
+
+ lint().files(
+ kotlin(
+ """
+ fun test() {
+ println("Value=${"$"}")
+ }
+ """
+ ),
+ java(
+ "src/test/pkg/AlarmTest.java",
+ """
+ package test.pkg;
+
+ import android.app.AlarmManager;
+ @SuppressWarnings("ClassNameDiffersFromFileName")
+ public class AlarmTest {
+ public void test(AlarmManager alarmManager) {
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 5000, 60000, null); // OK
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 6000, 70000, null); // OK
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 50, 10, null); // ERROR
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 5000, // ERROR
+ OtherClass.MY_INTERVAL, null); // ERROR
+ }
+
+ private static class OtherClass {
+ public static final long MY_INTERVAL = 1000L;
+ }
+ }
+ """.trimIndent()
+ )
+ ).run().expect(expected)
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/LintDetectorDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `LintDetectorDetector.testProblems`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("LintImplBadUrl")
+ fun method() {
+ expect(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("LintImplBadUrl")
+ void method() {
+ expect(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection LintImplBadUrl
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="LintImplBadUrl" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'LintImplBadUrl'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore LintImplBadUrl ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/LintImplDollarEscapes.md.html b/docs/checks/LintImplDollarEscapes.md.html
new file mode 100644
index 00000000..6e98b7e2
--- /dev/null
+++ b/docs/checks/LintImplDollarEscapes.md.html
@@ -0,0 +1,415 @@
+
+(#) Using Dollar Escapes
+
+!!! ERROR: Using Dollar Escapes
+ This is an error.
+
+Id
+: `LintImplDollarEscapes`
+Summary
+: Using Dollar Escapes
+Severity
+: Error
+Category
+: Lint Implementation Issues
+Platform
+: JDK
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 4.1.0 (October 2020)
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/LintDetectorDetector.kt)
+Tests
+: [Source Code](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/LintDetectorDetectorTest.kt)
+
+Instead of putting `${"$"}` in your Kotlin raw string literals you can
+simply use $. This looks like the dollar sign but is instead the full
+width dollar sign, U+FF04. And this character does not need to be
+escaped in Kotlin raw strings, since it does not start a string
+template.
+
+Lint will automatically convert references to $ in unit test files into
+a real dollar sign, and when pulling results and error messages out of
+lint, the dollar sign back into the full width dollar sign.
+
+That means you can use $ everywhere instead of `${"$"}`, which makes the
+test strings more readable -- especially `$`-heavy code such as
+references to inner classes.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/MyKotlinLintDetectorTest.kt:22:Error: In unit tests, use
+the fullwidth dollar sign, $, instead of $, to avoid having to use
+cumbersome escapes. Lint will treat a $ as a $. [LintImplDollarEscapes]
+ println("Value=${"$"}")
+ ------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/test/pkg/MyJavaLintDetector.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+/* Copyright (C) 2020 The Android Open Source Project */
+package test.pkg;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiCallExpression;
+import com.intellij.psi.PsiExpression;
+import com.intellij.psi.PsiField;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.android.tools.lint.detector.api.Detector;
+import org.jetbrains.uast.UFile;
+import org.jetbrains.uast.UMethod;
+import org.jetbrains.uast.UField;
+import com.android.tools.lint.detector.api.Category;
+import com.android.tools.lint.detector.api.Detector;
+import com.android.tools.lint.detector.api.Implementation;
+import com.android.tools.lint.detector.api.Issue;
+import com.android.tools.lint.detector.api.JavaContext;
+import com.android.tools.lint.detector.api.Scope;
+import com.android.tools.lint.detector.api.Severity;
+import org.jetbrains.uast.UCallExpression;
+import java.util.EnumSet;
+
+@SuppressWarnings({"MethodMayBeStatic", "ClassNameDiffersFromFileName", "StatementWithEmptyBody", "deprecation"})
+public class MyJavaLintDetector extends Detector {
+ public static final Issue ISSUE =
+ Issue.create(
+ "com.android.namespaced.lint.check.FooDetector",
+ "Wrong use of ",
+ "As described in "
+ + "https://code.google.com/p/android/issues/detail?id=65351%20blah%20blah%20blah.",
+ Category.A11Y,
+ 3,
+ Severity.WARNING,
+ new Implementation(MyJavaLintDetector.class, EnumSet.of(Scope.RESOURCE_FILE, Scope.JAVA_FILE)))
+ .addMoreInfo("file://explanation.doc")
+ .addMoreInfo("http://my.personal.blogger.com/aboutme.htm")
+ .addMoreInfo("mailto:lint@example.com");
+ public void testGetBody(PsiMethod method) {
+ method.getBody(); // ERROR - must use UAST
+ }
+ public void testGetBody(UMethod method) {
+ method.getBody(); // ERROR - must use UAST
+ }
+ public void testGetContainingClass(UMethod method, UField field) {
+ method.getContainingClass(); // ERROR - must use UAST
+ field.getContainingClass(); // ERROR - must use UAST
+ }
+ public void testGetContainingClass(PsiMethod method, PsiField field) {
+ method.getContainingClass(); // OK - legitimate uses after resolve
+ field.getContainingClass(); // OK - legitimate uses after resolve
+ }
+ public void testEquals(PsiCallExpression element1, PsiExpression element2) {
+ if (element1.equals(element2)) { }
+ if (element2.equals(element1)) { }
+ if (element1 == element2) { }
+ if (element1 != element2) { }
+ }
+ public void testGetInitializer(PsiField field) {
+ field.getInitializer(); // ERROR - must use UAST
+ }
+ public void testParents(PsiField field, UMethod method) {
+ PsiElement parent = field.getParent(); // OK
+ PsiElement parent = method.getParent(); // ERROR
+ PsiTreeUtil.getParentOfType(field, PsiClass.class); // OK
+ PsiTreeUtil.getParentOfType(method, PsiClass.class); // ERROR
+ }
+
+ public void testReport(JavaContext context, UCallExpression node) {
+ context.report(ISSUE, node, context.getLocation(node),
+ "Wrong use of LinearLayout.");
+ context.report(ISSUE, node, context.getLocation(node),
+ "First problem. Second problem.");
+ context.report(ISSUE, node, context.getLocation(node),
+ "This is teh typo");
+ String message = "Welcome to Andriod";
+ context.report(ISSUE, node, context.getLocation(node), message);
+ context.report(ISSUE, node, context.getLocation(node),
+ "Should you use `x ?: y` instead of ```foo ? 1 : 0``` ?");
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyKotlinLintDetector.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+/* Copyright (C) 2020 The Android Open Source Project */
+package test.pkg
+import com.intellij.psi.PsiCallExpression
+import com.intellij.psi.PsiExpression
+import com.intellij.psi.PsiField
+import com.intellij.psi.PsiMethod
+import com.intellij.psi.util.PsiTreeUtil
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import org.jetbrains.uast.UCallExpression
+
+class MyKotlinLintDetector : Detector() {
+ fun testGetBody(method: PsiMethod) {
+ val body = method.body // ERROR - must use UAST
+ }
+ @Suppress("ReplaceCallWithBinaryOperator","ControlFlowWithEmptyBody")
+ fun testEquals(element1: PsiCallExpression, element2: PsiExpression) {
+ if (element1.equals(element2)) { }
+ if (element2.equals(element1)) { }
+ if (element1 == element2) { }
+ if (element1 === element2) { }
+ if (element1 != element2) { }
+ if (element1 !== element2) { }
+ if (element1 == null) { } // OK
+ if (element1 === null) { } // OK
+ if (element1 != null) { } // OK
+ if (element1 !== null) { } // OK
+ }
+ @Suppress("UsePropertyAccessSyntax")
+ fun testGetInitializer(field: PsiField) {
+ field.getInitializer() // ERROR - must use UAST
+ field.initializer // ERROR - must use UAST
+ }
+ fun testParents(field: PsiField) {
+ val parent = field.parent
+ val method = PsiTreeUtil.getParentOfType(field, PsiMethod::class.java)
+ }
+
+ fun testReport(context: JavaContext, node: UCallExpression) {
+ context.report(ISSUE, node, context.getLocation(node),
+ """
+ |Instead you should call foo().bar().baz() here.
+ |""".trimIndent())
+ }
+
+ companion object {
+ private val IMPLEMENTATION =
+ Implementation(
+ MyKotlinLintDetector::class.java,
+ Scope.JAVA_FILE_SCOPE
+ )
+
+ val ISSUE =
+ Issue.create(
+ id = "badlyCapitalized id",
+ briefDescription = "checks MyLintDetector.",
+ explanation = """
+ Some description here.
+ Here's a call: foo.bar.baz(args).
+ This line continuation is okay. \
+ But this one is missing a space.\
+ Okay?
+ """.trimIndent(),
+ category = Category.INTEROPERABILITY_KOTLIN,
+ moreInfo = "https://code.google.com/p/android/issues/detail?id=65351", // OBSOLETE
+ priority = 4,
+ severity = Severity.WARNING,
+ implementation = IMPLEMENTATION
+ )
+ .addMoreInfo("https://issuetracker.google.com/issues/3733548") // ERROR - missing digit
+ .addMoreInfo("https://issuetracker.google.com/issues/373354878") // OK - including digit
+ .addMoreInfo("http://issuetracker.google.com/issues/37335487") // ERROR - http instead of https
+ .addMoreInfo("https://b.corp.google.com/issues/139153781") // ERROR - don't point to buganizer with internal link
+ .addMoreInfo("https://goo.gle/policy-storage-help") // OK - regression test for goo.gle
+ }
+
+ override fun visitAnnotationUsage(
+ context: JavaContext,
+ element: org.jetbrains.uast.UElement.UElement,
+ annotationInfo: com.android.tools.lint.detector.api.AnnotationInfo,
+ usageInfo: com.android.tools.lint.detector.api.AnnotationUsageInfo
+ ) {
+ // Invalid recursion!
+ super.visitAnnotationUsage(context, element, annotationInfo, usageInfo)
+ }
+
+ fun misc() {
+ System.out.print("Debugging")
+ println("Debugging code")
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyIssueRegistry.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import com.android.tools.lint.client.api.IssueRegistry
+class MyIssueRegistry : IssueRegistry() {
+ override val issues = listOf(
+ MyJavaLintDetector.ISSUE,
+ MyKotlinLintDetector.Companion.ISSUE
+ )
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyVendorIssueRegistry.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import com.android.tools.lint.client.api.IssueRegistry
+import com.android.tools.lint.client.api.Vendor
+class MyVendorIssueRegistry : IssueRegistry() {
+ // Supplies a vendor: no warning
+ override var vendor: Vendor? = Vendor("Unit test")
+ override val issues = listOf(
+ MyJavaLintDetector.ISSUE,
+ MyKotlinLintDetector.Companion.ISSUE
+ )
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/InheritingRegistry.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import com.android.tools.lint.client.api.IssueRegistry
+import com.android.tools.lint.client.api.Vendor
+class InheritingRegistry : MyVendorIssueRegistry() { // NO WARNING
+ // This registry doesn't supply a vendor but inherits one; no warning
+ override val issues = listOf(
+ MyJavaLintDetector.ISSUE,
+ MyKotlinLintDetector.Companion.ISSUE
+ )
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyKotlinLintDetectorTest.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+// Copyright (C) 2021 The Android Open Source Project
+package test.pkg
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest
+import com.android.tools.lint.detector.api.Detector
+class MyKotlinLintDetectorTest : LintDetectorTest() {
+ override fun getDetector(): Detector {
+ return MyKotlinLintDetector()
+ }
+
+ fun testBasic() {
+ val expected = """
+ src/test/pkg/AlarmTest.java:9: Warning: Value will be forced up to 5000 as of Android 5.1; don't rely on this to be exact [ShortAlarm]
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 50, 10, null); // ERROR
+ ~~
+ 0 errors, 1 warnings
+ """
+
+ lint().files(
+ kotlin(
+ """
+ fun test() {
+ println("Value=${"$"}")
+ }
+ """
+ ),
+ java(
+ "src/test/pkg/AlarmTest.java",
+ """
+ package test.pkg;
+
+ import android.app.AlarmManager;
+ @SuppressWarnings("ClassNameDiffersFromFileName")
+ public class AlarmTest {
+ public void test(AlarmManager alarmManager) {
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 5000, 60000, null); // OK
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 6000, 70000, null); // OK
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 50, 10, null); // ERROR
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 5000, // ERROR
+ OtherClass.MY_INTERVAL, null); // ERROR
+ }
+
+ private static class OtherClass {
+ public static final long MY_INTERVAL = 1000L;
+ }
+ }
+ """.trimIndent()
+ )
+ ).run().expect(expected)
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/LintDetectorDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `LintDetectorDetector.testProblems`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("LintImplDollarEscapes")
+ fun method() {
+ expect(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("LintImplDollarEscapes")
+ void method() {
+ expect(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection LintImplDollarEscapes
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="LintImplDollarEscapes" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'LintImplDollarEscapes'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore LintImplDollarEscapes ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/LintImplIdFormat.md.html b/docs/checks/LintImplIdFormat.md.html
new file mode 100644
index 00000000..6fb3b93a
--- /dev/null
+++ b/docs/checks/LintImplIdFormat.md.html
@@ -0,0 +1,417 @@
+
+(#) Lint ID Format
+
+!!! ERROR: Lint ID Format
+ This is an error.
+
+Id
+: `LintImplIdFormat`
+Summary
+: Lint ID Format
+Severity
+: Error
+Category
+: Lint Implementation Issues
+Platform
+: JDK
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 4.1.0 (October 2020)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/LintDetectorDetector.kt)
+Tests
+: [Source Code](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/LintDetectorDetectorTest.kt)
+
+This check looks at lint issue id registrations and makes sure the id
+follows the expected conventions: capitalized, camel case, no spaces,
+and not too long.
+
+Note: You shouldn't change id's for lint checks that are already widely
+used, since the id can already appear in `@SuppressLint` annotations,
+`tools:ignore=` attributes, lint baselines, Gradle `lintOptions` blocks,
+`lint.xml` files, and so on. In these cases, just explicitly suppress
+this warning instead using something like
+
+```kotlin
+@JvmField
+val ISSUE = Issue.create(
+ // ID string is too long, but we can't change this now since
+ // this id is already used in user suppress configurations
+ //noinspection LintImplIdFormat
+ id = "IncompatibleMediaBrowserServiceCompatVersion",
+ ...
+```
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/MyKotlinLintDetector.kt:60:Error: Lint issue IDs should use
+capitalized camel case, such as MyIssueId [LintImplIdFormat]
+ id = "badlyCapitalized id",
+ ---------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/test/pkg/MyJavaLintDetector.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+/* Copyright (C) 2020 The Android Open Source Project */
+package test.pkg;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiCallExpression;
+import com.intellij.psi.PsiExpression;
+import com.intellij.psi.PsiField;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.android.tools.lint.detector.api.Detector;
+import org.jetbrains.uast.UFile;
+import org.jetbrains.uast.UMethod;
+import org.jetbrains.uast.UField;
+import com.android.tools.lint.detector.api.Category;
+import com.android.tools.lint.detector.api.Detector;
+import com.android.tools.lint.detector.api.Implementation;
+import com.android.tools.lint.detector.api.Issue;
+import com.android.tools.lint.detector.api.JavaContext;
+import com.android.tools.lint.detector.api.Scope;
+import com.android.tools.lint.detector.api.Severity;
+import org.jetbrains.uast.UCallExpression;
+import java.util.EnumSet;
+
+@SuppressWarnings({"MethodMayBeStatic", "ClassNameDiffersFromFileName", "StatementWithEmptyBody", "deprecation"})
+public class MyJavaLintDetector extends Detector {
+ public static final Issue ISSUE =
+ Issue.create(
+ "com.android.namespaced.lint.check.FooDetector",
+ "Wrong use of ",
+ "As described in "
+ + "https://code.google.com/p/android/issues/detail?id=65351%20blah%20blah%20blah.",
+ Category.A11Y,
+ 3,
+ Severity.WARNING,
+ new Implementation(MyJavaLintDetector.class, EnumSet.of(Scope.RESOURCE_FILE, Scope.JAVA_FILE)))
+ .addMoreInfo("file://explanation.doc")
+ .addMoreInfo("http://my.personal.blogger.com/aboutme.htm")
+ .addMoreInfo("mailto:lint@example.com");
+ public void testGetBody(PsiMethod method) {
+ method.getBody(); // ERROR - must use UAST
+ }
+ public void testGetBody(UMethod method) {
+ method.getBody(); // ERROR - must use UAST
+ }
+ public void testGetContainingClass(UMethod method, UField field) {
+ method.getContainingClass(); // ERROR - must use UAST
+ field.getContainingClass(); // ERROR - must use UAST
+ }
+ public void testGetContainingClass(PsiMethod method, PsiField field) {
+ method.getContainingClass(); // OK - legitimate uses after resolve
+ field.getContainingClass(); // OK - legitimate uses after resolve
+ }
+ public void testEquals(PsiCallExpression element1, PsiExpression element2) {
+ if (element1.equals(element2)) { }
+ if (element2.equals(element1)) { }
+ if (element1 == element2) { }
+ if (element1 != element2) { }
+ }
+ public void testGetInitializer(PsiField field) {
+ field.getInitializer(); // ERROR - must use UAST
+ }
+ public void testParents(PsiField field, UMethod method) {
+ PsiElement parent = field.getParent(); // OK
+ PsiElement parent = method.getParent(); // ERROR
+ PsiTreeUtil.getParentOfType(field, PsiClass.class); // OK
+ PsiTreeUtil.getParentOfType(method, PsiClass.class); // ERROR
+ }
+
+ public void testReport(JavaContext context, UCallExpression node) {
+ context.report(ISSUE, node, context.getLocation(node),
+ "Wrong use of LinearLayout.");
+ context.report(ISSUE, node, context.getLocation(node),
+ "First problem. Second problem.");
+ context.report(ISSUE, node, context.getLocation(node),
+ "This is teh typo");
+ String message = "Welcome to Andriod";
+ context.report(ISSUE, node, context.getLocation(node), message);
+ context.report(ISSUE, node, context.getLocation(node),
+ "Should you use `x ?: y` instead of ```foo ? 1 : 0``` ?");
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyKotlinLintDetector.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+/* Copyright (C) 2020 The Android Open Source Project */
+package test.pkg
+import com.intellij.psi.PsiCallExpression
+import com.intellij.psi.PsiExpression
+import com.intellij.psi.PsiField
+import com.intellij.psi.PsiMethod
+import com.intellij.psi.util.PsiTreeUtil
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import org.jetbrains.uast.UCallExpression
+
+class MyKotlinLintDetector : Detector() {
+ fun testGetBody(method: PsiMethod) {
+ val body = method.body // ERROR - must use UAST
+ }
+ @Suppress("ReplaceCallWithBinaryOperator","ControlFlowWithEmptyBody")
+ fun testEquals(element1: PsiCallExpression, element2: PsiExpression) {
+ if (element1.equals(element2)) { }
+ if (element2.equals(element1)) { }
+ if (element1 == element2) { }
+ if (element1 === element2) { }
+ if (element1 != element2) { }
+ if (element1 !== element2) { }
+ if (element1 == null) { } // OK
+ if (element1 === null) { } // OK
+ if (element1 != null) { } // OK
+ if (element1 !== null) { } // OK
+ }
+ @Suppress("UsePropertyAccessSyntax")
+ fun testGetInitializer(field: PsiField) {
+ field.getInitializer() // ERROR - must use UAST
+ field.initializer // ERROR - must use UAST
+ }
+ fun testParents(field: PsiField) {
+ val parent = field.parent
+ val method = PsiTreeUtil.getParentOfType(field, PsiMethod::class.java)
+ }
+
+ fun testReport(context: JavaContext, node: UCallExpression) {
+ context.report(ISSUE, node, context.getLocation(node),
+ """
+ |Instead you should call foo().bar().baz() here.
+ |""".trimIndent())
+ }
+
+ companion object {
+ private val IMPLEMENTATION =
+ Implementation(
+ MyKotlinLintDetector::class.java,
+ Scope.JAVA_FILE_SCOPE
+ )
+
+ val ISSUE =
+ Issue.create(
+ id = "badlyCapitalized id",
+ briefDescription = "checks MyLintDetector.",
+ explanation = """
+ Some description here.
+ Here's a call: foo.bar.baz(args).
+ This line continuation is okay. \
+ But this one is missing a space.\
+ Okay?
+ """.trimIndent(),
+ category = Category.INTEROPERABILITY_KOTLIN,
+ moreInfo = "https://code.google.com/p/android/issues/detail?id=65351", // OBSOLETE
+ priority = 4,
+ severity = Severity.WARNING,
+ implementation = IMPLEMENTATION
+ )
+ .addMoreInfo("https://issuetracker.google.com/issues/3733548") // ERROR - missing digit
+ .addMoreInfo("https://issuetracker.google.com/issues/373354878") // OK - including digit
+ .addMoreInfo("http://issuetracker.google.com/issues/37335487") // ERROR - http instead of https
+ .addMoreInfo("https://b.corp.google.com/issues/139153781") // ERROR - don't point to buganizer with internal link
+ .addMoreInfo("https://goo.gle/policy-storage-help") // OK - regression test for goo.gle
+ }
+
+ override fun visitAnnotationUsage(
+ context: JavaContext,
+ element: org.jetbrains.uast.UElement.UElement,
+ annotationInfo: com.android.tools.lint.detector.api.AnnotationInfo,
+ usageInfo: com.android.tools.lint.detector.api.AnnotationUsageInfo
+ ) {
+ // Invalid recursion!
+ super.visitAnnotationUsage(context, element, annotationInfo, usageInfo)
+ }
+
+ fun misc() {
+ System.out.print("Debugging")
+ println("Debugging code")
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyIssueRegistry.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import com.android.tools.lint.client.api.IssueRegistry
+class MyIssueRegistry : IssueRegistry() {
+ override val issues = listOf(
+ MyJavaLintDetector.ISSUE,
+ MyKotlinLintDetector.Companion.ISSUE
+ )
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyVendorIssueRegistry.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import com.android.tools.lint.client.api.IssueRegistry
+import com.android.tools.lint.client.api.Vendor
+class MyVendorIssueRegistry : IssueRegistry() {
+ // Supplies a vendor: no warning
+ override var vendor: Vendor? = Vendor("Unit test")
+ override val issues = listOf(
+ MyJavaLintDetector.ISSUE,
+ MyKotlinLintDetector.Companion.ISSUE
+ )
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/InheritingRegistry.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import com.android.tools.lint.client.api.IssueRegistry
+import com.android.tools.lint.client.api.Vendor
+class InheritingRegistry : MyVendorIssueRegistry() { // NO WARNING
+ // This registry doesn't supply a vendor but inherits one; no warning
+ override val issues = listOf(
+ MyJavaLintDetector.ISSUE,
+ MyKotlinLintDetector.Companion.ISSUE
+ )
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyKotlinLintDetectorTest.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+// Copyright (C) 2021 The Android Open Source Project
+package test.pkg
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest
+import com.android.tools.lint.detector.api.Detector
+class MyKotlinLintDetectorTest : LintDetectorTest() {
+ override fun getDetector(): Detector {
+ return MyKotlinLintDetector()
+ }
+
+ fun testBasic() {
+ val expected = """
+ src/test/pkg/AlarmTest.java:9: Warning: Value will be forced up to 5000 as of Android 5.1; don't rely on this to be exact [ShortAlarm]
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 50, 10, null); // ERROR
+ ~~
+ 0 errors, 1 warnings
+ """
+
+ lint().files(
+ kotlin(
+ """
+ fun test() {
+ println("Value=${"$"}")
+ }
+ """
+ ),
+ java(
+ "src/test/pkg/AlarmTest.java",
+ """
+ package test.pkg;
+
+ import android.app.AlarmManager;
+ @SuppressWarnings("ClassNameDiffersFromFileName")
+ public class AlarmTest {
+ public void test(AlarmManager alarmManager) {
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 5000, 60000, null); // OK
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 6000, 70000, null); // OK
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 50, 10, null); // ERROR
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 5000, // ERROR
+ OtherClass.MY_INTERVAL, null); // ERROR
+ }
+
+ private static class OtherClass {
+ public static final long MY_INTERVAL = 1000L;
+ }
+ }
+ """.trimIndent()
+ )
+ ).run().expect(expected)
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/LintDetectorDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `LintDetectorDetector.testProblems`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("LintImplIdFormat")
+ fun method() {
+ expect(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("LintImplIdFormat")
+ void method() {
+ expect(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection LintImplIdFormat
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="LintImplIdFormat" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'LintImplIdFormat'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore LintImplIdFormat ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/LintImplPsiEquals.md.html b/docs/checks/LintImplPsiEquals.md.html
new file mode 100644
index 00000000..f1a8f5a1
--- /dev/null
+++ b/docs/checks/LintImplPsiEquals.md.html
@@ -0,0 +1,407 @@
+
+(#) Comparing PsiElements with Equals
+
+!!! ERROR: Comparing PsiElements with Equals
+ This is an error.
+
+Id
+: `LintImplPsiEquals`
+Summary
+: Comparing PsiElements with Equals
+Note
+: **This issue is disabled by default**; use `--enable LintImplPsiEquals`
+Severity
+: Error
+Category
+: Lint Implementation Issues
+Platform
+: JDK
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 4.1.0 (October 2020)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/LintDetectorDetector.kt)
+Tests
+: [Source Code](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/LintDetectorDetectorTest.kt)
+
+You should never compare two PSI elements for equality with `equals`;
+use `PsiEquivalenceUtil.areElementsEquivalent(PsiElement, PsiElement)`
+instead.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/MyJavaLintDetector.java:53:Error: Don't compare PsiElements
+with equals, use isEquivalentTo(PsiElement) instead [LintImplPsiEquals]
+ if (element1.equals(element2)) { }
+ -------------------------
+src/test/pkg/MyJavaLintDetector.java:54:Error: Don't compare PsiElements
+with equals, use isEquivalentTo(PsiElement) instead [LintImplPsiEquals]
+ if (element2.equals(element1)) { }
+ -------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/test/pkg/MyJavaLintDetector.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+/* Copyright (C) 2020 The Android Open Source Project */
+package test.pkg;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiCallExpression;
+import com.intellij.psi.PsiExpression;
+import com.intellij.psi.PsiField;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.android.tools.lint.detector.api.Detector;
+import org.jetbrains.uast.UFile;
+import org.jetbrains.uast.UMethod;
+import org.jetbrains.uast.UField;
+import com.android.tools.lint.detector.api.Category;
+import com.android.tools.lint.detector.api.Detector;
+import com.android.tools.lint.detector.api.Implementation;
+import com.android.tools.lint.detector.api.Issue;
+import com.android.tools.lint.detector.api.JavaContext;
+import com.android.tools.lint.detector.api.Scope;
+import com.android.tools.lint.detector.api.Severity;
+import org.jetbrains.uast.UCallExpression;
+import java.util.EnumSet;
+
+@SuppressWarnings({"MethodMayBeStatic", "ClassNameDiffersFromFileName", "StatementWithEmptyBody", "deprecation"})
+public class MyJavaLintDetector extends Detector {
+ public static final Issue ISSUE =
+ Issue.create(
+ "com.android.namespaced.lint.check.FooDetector",
+ "Wrong use of ",
+ "As described in "
+ + "https://code.google.com/p/android/issues/detail?id=65351%20blah%20blah%20blah.",
+ Category.A11Y,
+ 3,
+ Severity.WARNING,
+ new Implementation(MyJavaLintDetector.class, EnumSet.of(Scope.RESOURCE_FILE, Scope.JAVA_FILE)))
+ .addMoreInfo("file://explanation.doc")
+ .addMoreInfo("http://my.personal.blogger.com/aboutme.htm")
+ .addMoreInfo("mailto:lint@example.com");
+ public void testGetBody(PsiMethod method) {
+ method.getBody(); // ERROR - must use UAST
+ }
+ public void testGetBody(UMethod method) {
+ method.getBody(); // ERROR - must use UAST
+ }
+ public void testGetContainingClass(UMethod method, UField field) {
+ method.getContainingClass(); // ERROR - must use UAST
+ field.getContainingClass(); // ERROR - must use UAST
+ }
+ public void testGetContainingClass(PsiMethod method, PsiField field) {
+ method.getContainingClass(); // OK - legitimate uses after resolve
+ field.getContainingClass(); // OK - legitimate uses after resolve
+ }
+ public void testEquals(PsiCallExpression element1, PsiExpression element2) {
+ if (element1.equals(element2)) { }
+ if (element2.equals(element1)) { }
+ if (element1 == element2) { }
+ if (element1 != element2) { }
+ }
+ public void testGetInitializer(PsiField field) {
+ field.getInitializer(); // ERROR - must use UAST
+ }
+ public void testParents(PsiField field, UMethod method) {
+ PsiElement parent = field.getParent(); // OK
+ PsiElement parent = method.getParent(); // ERROR
+ PsiTreeUtil.getParentOfType(field, PsiClass.class); // OK
+ PsiTreeUtil.getParentOfType(method, PsiClass.class); // ERROR
+ }
+
+ public void testReport(JavaContext context, UCallExpression node) {
+ context.report(ISSUE, node, context.getLocation(node),
+ "Wrong use of LinearLayout.");
+ context.report(ISSUE, node, context.getLocation(node),
+ "First problem. Second problem.");
+ context.report(ISSUE, node, context.getLocation(node),
+ "This is teh typo");
+ String message = "Welcome to Andriod";
+ context.report(ISSUE, node, context.getLocation(node), message);
+ context.report(ISSUE, node, context.getLocation(node),
+ "Should you use `x ?: y` instead of ```foo ? 1 : 0``` ?");
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyKotlinLintDetector.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+/* Copyright (C) 2020 The Android Open Source Project */
+package test.pkg
+import com.intellij.psi.PsiCallExpression
+import com.intellij.psi.PsiExpression
+import com.intellij.psi.PsiField
+import com.intellij.psi.PsiMethod
+import com.intellij.psi.util.PsiTreeUtil
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import org.jetbrains.uast.UCallExpression
+
+class MyKotlinLintDetector : Detector() {
+ fun testGetBody(method: PsiMethod) {
+ val body = method.body // ERROR - must use UAST
+ }
+ @Suppress("ReplaceCallWithBinaryOperator","ControlFlowWithEmptyBody")
+ fun testEquals(element1: PsiCallExpression, element2: PsiExpression) {
+ if (element1.equals(element2)) { }
+ if (element2.equals(element1)) { }
+ if (element1 == element2) { }
+ if (element1 === element2) { }
+ if (element1 != element2) { }
+ if (element1 !== element2) { }
+ if (element1 == null) { } // OK
+ if (element1 === null) { } // OK
+ if (element1 != null) { } // OK
+ if (element1 !== null) { } // OK
+ }
+ @Suppress("UsePropertyAccessSyntax")
+ fun testGetInitializer(field: PsiField) {
+ field.getInitializer() // ERROR - must use UAST
+ field.initializer // ERROR - must use UAST
+ }
+ fun testParents(field: PsiField) {
+ val parent = field.parent
+ val method = PsiTreeUtil.getParentOfType(field, PsiMethod::class.java)
+ }
+
+ fun testReport(context: JavaContext, node: UCallExpression) {
+ context.report(ISSUE, node, context.getLocation(node),
+ """
+ |Instead you should call foo().bar().baz() here.
+ |""".trimIndent())
+ }
+
+ companion object {
+ private val IMPLEMENTATION =
+ Implementation(
+ MyKotlinLintDetector::class.java,
+ Scope.JAVA_FILE_SCOPE
+ )
+
+ val ISSUE =
+ Issue.create(
+ id = "badlyCapitalized id",
+ briefDescription = "checks MyLintDetector.",
+ explanation = """
+ Some description here.
+ Here's a call: foo.bar.baz(args).
+ This line continuation is okay. \
+ But this one is missing a space.\
+ Okay?
+ """.trimIndent(),
+ category = Category.INTEROPERABILITY_KOTLIN,
+ moreInfo = "https://code.google.com/p/android/issues/detail?id=65351", // OBSOLETE
+ priority = 4,
+ severity = Severity.WARNING,
+ implementation = IMPLEMENTATION
+ )
+ .addMoreInfo("https://issuetracker.google.com/issues/3733548") // ERROR - missing digit
+ .addMoreInfo("https://issuetracker.google.com/issues/373354878") // OK - including digit
+ .addMoreInfo("http://issuetracker.google.com/issues/37335487") // ERROR - http instead of https
+ .addMoreInfo("https://b.corp.google.com/issues/139153781") // ERROR - don't point to buganizer with internal link
+ .addMoreInfo("https://goo.gle/policy-storage-help") // OK - regression test for goo.gle
+ }
+
+ override fun visitAnnotationUsage(
+ context: JavaContext,
+ element: org.jetbrains.uast.UElement.UElement,
+ annotationInfo: com.android.tools.lint.detector.api.AnnotationInfo,
+ usageInfo: com.android.tools.lint.detector.api.AnnotationUsageInfo
+ ) {
+ // Invalid recursion!
+ super.visitAnnotationUsage(context, element, annotationInfo, usageInfo)
+ }
+
+ fun misc() {
+ System.out.print("Debugging")
+ println("Debugging code")
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyIssueRegistry.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import com.android.tools.lint.client.api.IssueRegistry
+class MyIssueRegistry : IssueRegistry() {
+ override val issues = listOf(
+ MyJavaLintDetector.ISSUE,
+ MyKotlinLintDetector.Companion.ISSUE
+ )
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyVendorIssueRegistry.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import com.android.tools.lint.client.api.IssueRegistry
+import com.android.tools.lint.client.api.Vendor
+class MyVendorIssueRegistry : IssueRegistry() {
+ // Supplies a vendor: no warning
+ override var vendor: Vendor? = Vendor("Unit test")
+ override val issues = listOf(
+ MyJavaLintDetector.ISSUE,
+ MyKotlinLintDetector.Companion.ISSUE
+ )
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/InheritingRegistry.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import com.android.tools.lint.client.api.IssueRegistry
+import com.android.tools.lint.client.api.Vendor
+class InheritingRegistry : MyVendorIssueRegistry() { // NO WARNING
+ // This registry doesn't supply a vendor but inherits one; no warning
+ override val issues = listOf(
+ MyJavaLintDetector.ISSUE,
+ MyKotlinLintDetector.Companion.ISSUE
+ )
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyKotlinLintDetectorTest.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+// Copyright (C) 2021 The Android Open Source Project
+package test.pkg
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest
+import com.android.tools.lint.detector.api.Detector
+class MyKotlinLintDetectorTest : LintDetectorTest() {
+ override fun getDetector(): Detector {
+ return MyKotlinLintDetector()
+ }
+
+ fun testBasic() {
+ val expected = """
+ src/test/pkg/AlarmTest.java:9: Warning: Value will be forced up to 5000 as of Android 5.1; don't rely on this to be exact [ShortAlarm]
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 50, 10, null); // ERROR
+ ~~
+ 0 errors, 1 warnings
+ """
+
+ lint().files(
+ kotlin(
+ """
+ fun test() {
+ println("Value=${"$"}")
+ }
+ """
+ ),
+ java(
+ "src/test/pkg/AlarmTest.java",
+ """
+ package test.pkg;
+
+ import android.app.AlarmManager;
+ @SuppressWarnings("ClassNameDiffersFromFileName")
+ public class AlarmTest {
+ public void test(AlarmManager alarmManager) {
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 5000, 60000, null); // OK
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 6000, 70000, null); // OK
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 50, 10, null); // ERROR
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 5000, // ERROR
+ OtherClass.MY_INTERVAL, null); // ERROR
+ }
+
+ private static class OtherClass {
+ public static final long MY_INTERVAL = 1000L;
+ }
+ }
+ """.trimIndent()
+ )
+ ).run().expect(expected)
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/LintDetectorDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `LintDetectorDetector.testProblems`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("LintImplPsiEquals")
+ fun method() {
+ expect(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("LintImplPsiEquals")
+ void method() {
+ expect(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection LintImplPsiEquals
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="LintImplPsiEquals" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'LintImplPsiEquals'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore LintImplPsiEquals ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/LintImplTextFormat.md.html b/docs/checks/LintImplTextFormat.md.html
new file mode 100644
index 00000000..0de1cdd4
--- /dev/null
+++ b/docs/checks/LintImplTextFormat.md.html
@@ -0,0 +1,426 @@
+
+(#) Lint Text Format
+
+!!! WARNING: Lint Text Format
+ This is a warning.
+
+Id
+: `LintImplTextFormat`
+Summary
+: Lint Text Format
+Severity
+: Warning
+Category
+: Lint Implementation Issues
+Platform
+: JDK
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 4.1.0 (October 2020)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/LintDetectorDetector.kt)
+Tests
+: [Source Code](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/LintDetectorDetectorTest.kt)
+
+Lint supports various markdown like formatting directives in all of its
+strings (issue explanations, reported error messages, etc).
+
+This lint check looks for strings that look like they may benefit from
+additional formatting. For example, if a snippet looks like code it
+should be surrounded with backticks.
+
+Note: Be careful changing **existing** strings; this may stop baseline
+file matching from working, so consider suppressing existing violations
+of this check if this is an error many users may be filtering in
+baselines. (This is only an issue for strings used in `report` calls;
+for issue registration strings like summaries and explanations there's
+no risk changing the text contents.)
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/MyJavaLintDetector.java:70:Warning: Single sentence error
+messages should not end with a period [LintImplTextFormat]
+ "Wrong use of LinearLayout.");
+ --------------------------
+src/test/pkg/MyJavaLintDetector.java:74:Warning: "teh" is a common
+misspelling; did you mean "the"? [LintImplTextFormat]
+ "This is teh typo");
+ ---
+src/test/pkg/MyJavaLintDetector.java:76:Warning: "Andriod" is a common
+misspelling; did you mean "Android"? [LintImplTextFormat]
+ context.report(ISSUE, node, context.getLocation(node), message);
+ -------
+src/test/pkg/MyJavaLintDetector.java:78:Warning: Question marks should
+not be separated by a space [LintImplTextFormat]
+ "Should you use `x ?: y` instead of ```foo ? 1 : 0``` ?");
+ -
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/test/pkg/MyJavaLintDetector.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+/* Copyright (C) 2020 The Android Open Source Project */
+package test.pkg;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiCallExpression;
+import com.intellij.psi.PsiExpression;
+import com.intellij.psi.PsiField;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.android.tools.lint.detector.api.Detector;
+import org.jetbrains.uast.UFile;
+import org.jetbrains.uast.UMethod;
+import org.jetbrains.uast.UField;
+import com.android.tools.lint.detector.api.Category;
+import com.android.tools.lint.detector.api.Detector;
+import com.android.tools.lint.detector.api.Implementation;
+import com.android.tools.lint.detector.api.Issue;
+import com.android.tools.lint.detector.api.JavaContext;
+import com.android.tools.lint.detector.api.Scope;
+import com.android.tools.lint.detector.api.Severity;
+import org.jetbrains.uast.UCallExpression;
+import java.util.EnumSet;
+
+@SuppressWarnings({"MethodMayBeStatic", "ClassNameDiffersFromFileName", "StatementWithEmptyBody", "deprecation"})
+public class MyJavaLintDetector extends Detector {
+ public static final Issue ISSUE =
+ Issue.create(
+ "com.android.namespaced.lint.check.FooDetector",
+ "Wrong use of ",
+ "As described in "
+ + "https://code.google.com/p/android/issues/detail?id=65351%20blah%20blah%20blah.",
+ Category.A11Y,
+ 3,
+ Severity.WARNING,
+ new Implementation(MyJavaLintDetector.class, EnumSet.of(Scope.RESOURCE_FILE, Scope.JAVA_FILE)))
+ .addMoreInfo("file://explanation.doc")
+ .addMoreInfo("http://my.personal.blogger.com/aboutme.htm")
+ .addMoreInfo("mailto:lint@example.com");
+ public void testGetBody(PsiMethod method) {
+ method.getBody(); // ERROR - must use UAST
+ }
+ public void testGetBody(UMethod method) {
+ method.getBody(); // ERROR - must use UAST
+ }
+ public void testGetContainingClass(UMethod method, UField field) {
+ method.getContainingClass(); // ERROR - must use UAST
+ field.getContainingClass(); // ERROR - must use UAST
+ }
+ public void testGetContainingClass(PsiMethod method, PsiField field) {
+ method.getContainingClass(); // OK - legitimate uses after resolve
+ field.getContainingClass(); // OK - legitimate uses after resolve
+ }
+ public void testEquals(PsiCallExpression element1, PsiExpression element2) {
+ if (element1.equals(element2)) { }
+ if (element2.equals(element1)) { }
+ if (element1 == element2) { }
+ if (element1 != element2) { }
+ }
+ public void testGetInitializer(PsiField field) {
+ field.getInitializer(); // ERROR - must use UAST
+ }
+ public void testParents(PsiField field, UMethod method) {
+ PsiElement parent = field.getParent(); // OK
+ PsiElement parent = method.getParent(); // ERROR
+ PsiTreeUtil.getParentOfType(field, PsiClass.class); // OK
+ PsiTreeUtil.getParentOfType(method, PsiClass.class); // ERROR
+ }
+
+ public void testReport(JavaContext context, UCallExpression node) {
+ context.report(ISSUE, node, context.getLocation(node),
+ "Wrong use of LinearLayout.");
+ context.report(ISSUE, node, context.getLocation(node),
+ "First problem. Second problem.");
+ context.report(ISSUE, node, context.getLocation(node),
+ "This is teh typo");
+ String message = "Welcome to Andriod";
+ context.report(ISSUE, node, context.getLocation(node), message);
+ context.report(ISSUE, node, context.getLocation(node),
+ "Should you use `x ?: y` instead of ```foo ? 1 : 0``` ?");
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyKotlinLintDetector.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+/* Copyright (C) 2020 The Android Open Source Project */
+package test.pkg
+import com.intellij.psi.PsiCallExpression
+import com.intellij.psi.PsiExpression
+import com.intellij.psi.PsiField
+import com.intellij.psi.PsiMethod
+import com.intellij.psi.util.PsiTreeUtil
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import org.jetbrains.uast.UCallExpression
+
+class MyKotlinLintDetector : Detector() {
+ fun testGetBody(method: PsiMethod) {
+ val body = method.body // ERROR - must use UAST
+ }
+ @Suppress("ReplaceCallWithBinaryOperator","ControlFlowWithEmptyBody")
+ fun testEquals(element1: PsiCallExpression, element2: PsiExpression) {
+ if (element1.equals(element2)) { }
+ if (element2.equals(element1)) { }
+ if (element1 == element2) { }
+ if (element1 === element2) { }
+ if (element1 != element2) { }
+ if (element1 !== element2) { }
+ if (element1 == null) { } // OK
+ if (element1 === null) { } // OK
+ if (element1 != null) { } // OK
+ if (element1 !== null) { } // OK
+ }
+ @Suppress("UsePropertyAccessSyntax")
+ fun testGetInitializer(field: PsiField) {
+ field.getInitializer() // ERROR - must use UAST
+ field.initializer // ERROR - must use UAST
+ }
+ fun testParents(field: PsiField) {
+ val parent = field.parent
+ val method = PsiTreeUtil.getParentOfType(field, PsiMethod::class.java)
+ }
+
+ fun testReport(context: JavaContext, node: UCallExpression) {
+ context.report(ISSUE, node, context.getLocation(node),
+ """
+ |Instead you should call foo().bar().baz() here.
+ |""".trimIndent())
+ }
+
+ companion object {
+ private val IMPLEMENTATION =
+ Implementation(
+ MyKotlinLintDetector::class.java,
+ Scope.JAVA_FILE_SCOPE
+ )
+
+ val ISSUE =
+ Issue.create(
+ id = "badlyCapitalized id",
+ briefDescription = "checks MyLintDetector.",
+ explanation = """
+ Some description here.
+ Here's a call: foo.bar.baz(args).
+ This line continuation is okay. \
+ But this one is missing a space.\
+ Okay?
+ """.trimIndent(),
+ category = Category.INTEROPERABILITY_KOTLIN,
+ moreInfo = "https://code.google.com/p/android/issues/detail?id=65351", // OBSOLETE
+ priority = 4,
+ severity = Severity.WARNING,
+ implementation = IMPLEMENTATION
+ )
+ .addMoreInfo("https://issuetracker.google.com/issues/3733548") // ERROR - missing digit
+ .addMoreInfo("https://issuetracker.google.com/issues/373354878") // OK - including digit
+ .addMoreInfo("http://issuetracker.google.com/issues/37335487") // ERROR - http instead of https
+ .addMoreInfo("https://b.corp.google.com/issues/139153781") // ERROR - don't point to buganizer with internal link
+ .addMoreInfo("https://goo.gle/policy-storage-help") // OK - regression test for goo.gle
+ }
+
+ override fun visitAnnotationUsage(
+ context: JavaContext,
+ element: org.jetbrains.uast.UElement.UElement,
+ annotationInfo: com.android.tools.lint.detector.api.AnnotationInfo,
+ usageInfo: com.android.tools.lint.detector.api.AnnotationUsageInfo
+ ) {
+ // Invalid recursion!
+ super.visitAnnotationUsage(context, element, annotationInfo, usageInfo)
+ }
+
+ fun misc() {
+ System.out.print("Debugging")
+ println("Debugging code")
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyIssueRegistry.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import com.android.tools.lint.client.api.IssueRegistry
+class MyIssueRegistry : IssueRegistry() {
+ override val issues = listOf(
+ MyJavaLintDetector.ISSUE,
+ MyKotlinLintDetector.Companion.ISSUE
+ )
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyVendorIssueRegistry.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import com.android.tools.lint.client.api.IssueRegistry
+import com.android.tools.lint.client.api.Vendor
+class MyVendorIssueRegistry : IssueRegistry() {
+ // Supplies a vendor: no warning
+ override var vendor: Vendor? = Vendor("Unit test")
+ override val issues = listOf(
+ MyJavaLintDetector.ISSUE,
+ MyKotlinLintDetector.Companion.ISSUE
+ )
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/InheritingRegistry.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import com.android.tools.lint.client.api.IssueRegistry
+import com.android.tools.lint.client.api.Vendor
+class InheritingRegistry : MyVendorIssueRegistry() { // NO WARNING
+ // This registry doesn't supply a vendor but inherits one; no warning
+ override val issues = listOf(
+ MyJavaLintDetector.ISSUE,
+ MyKotlinLintDetector.Companion.ISSUE
+ )
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyKotlinLintDetectorTest.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+// Copyright (C) 2021 The Android Open Source Project
+package test.pkg
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest
+import com.android.tools.lint.detector.api.Detector
+class MyKotlinLintDetectorTest : LintDetectorTest() {
+ override fun getDetector(): Detector {
+ return MyKotlinLintDetector()
+ }
+
+ fun testBasic() {
+ val expected = """
+ src/test/pkg/AlarmTest.java:9: Warning: Value will be forced up to 5000 as of Android 5.1; don't rely on this to be exact [ShortAlarm]
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 50, 10, null); // ERROR
+ ~~
+ 0 errors, 1 warnings
+ """
+
+ lint().files(
+ kotlin(
+ """
+ fun test() {
+ println("Value=${"$"}")
+ }
+ """
+ ),
+ java(
+ "src/test/pkg/AlarmTest.java",
+ """
+ package test.pkg;
+
+ import android.app.AlarmManager;
+ @SuppressWarnings("ClassNameDiffersFromFileName")
+ public class AlarmTest {
+ public void test(AlarmManager alarmManager) {
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 5000, 60000, null); // OK
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 6000, 70000, null); // OK
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 50, 10, null); // ERROR
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 5000, // ERROR
+ OtherClass.MY_INTERVAL, null); // ERROR
+ }
+
+ private static class OtherClass {
+ public static final long MY_INTERVAL = 1000L;
+ }
+ }
+ """.trimIndent()
+ )
+ ).run().expect(expected)
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/LintDetectorDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `LintDetectorDetector.testProblems`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("LintImplTextFormat")
+ fun method() {
+ expect(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("LintImplTextFormat")
+ void method() {
+ expect(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection LintImplTextFormat
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="LintImplTextFormat" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'LintImplTextFormat'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore LintImplTextFormat ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/LintImplTrimIndent.md.html b/docs/checks/LintImplTrimIndent.md.html
new file mode 100644
index 00000000..7da57ea1
--- /dev/null
+++ b/docs/checks/LintImplTrimIndent.md.html
@@ -0,0 +1,418 @@
+
+(#) Calling `.trimIndent` on Lint Strings
+
+!!! ERROR: Calling `.trimIndent` on Lint Strings
+ This is an error.
+
+Id
+: `LintImplTrimIndent`
+Summary
+: Calling `.trimIndent` on Lint Strings
+Severity
+: Error
+Category
+: Lint Implementation Issues
+Platform
+: JDK
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 4.1.0 (October 2020)
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/LintDetectorDetector.kt)
+Tests
+: [Source Code](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/LintDetectorDetectorTest.kt)
+
+Lint implicitly calls `.trimIndent()` (lazily, at the last minute) in a
+number of places:
+* Issue explanations
+* Error messages
+* Lint test file descriptions
+* etc
+
+That means you don't need to put `.trimIndent()` in your source code to
+handle this.
+
+There are advantages to **not** putting `.trimIndent()` in the code. For
+test files, if you call for example `kotlin(""\"source code"\""\")` then
+IntelliJ/Android Studio will syntax highlight the source code as Kotlin.
+The second you add in a .trimIndent() on the string, the syntax
+highlighting goes away. For test files you can instead call
+".indented()" on the test file builder to get it to indent the string.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/MyKotlinLintDetector.kt:68:Error: No need to call
+.trimIndent() in issue registration strings; they are already trimmed by
+indent by lint when displaying to users [LintImplTrimIndent]
+ """.trimIndent(),
+ ------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/test/pkg/MyJavaLintDetector.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+/* Copyright (C) 2020 The Android Open Source Project */
+package test.pkg;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiCallExpression;
+import com.intellij.psi.PsiExpression;
+import com.intellij.psi.PsiField;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.android.tools.lint.detector.api.Detector;
+import org.jetbrains.uast.UFile;
+import org.jetbrains.uast.UMethod;
+import org.jetbrains.uast.UField;
+import com.android.tools.lint.detector.api.Category;
+import com.android.tools.lint.detector.api.Detector;
+import com.android.tools.lint.detector.api.Implementation;
+import com.android.tools.lint.detector.api.Issue;
+import com.android.tools.lint.detector.api.JavaContext;
+import com.android.tools.lint.detector.api.Scope;
+import com.android.tools.lint.detector.api.Severity;
+import org.jetbrains.uast.UCallExpression;
+import java.util.EnumSet;
+
+@SuppressWarnings({"MethodMayBeStatic", "ClassNameDiffersFromFileName", "StatementWithEmptyBody", "deprecation"})
+public class MyJavaLintDetector extends Detector {
+ public static final Issue ISSUE =
+ Issue.create(
+ "com.android.namespaced.lint.check.FooDetector",
+ "Wrong use of ",
+ "As described in "
+ + "https://code.google.com/p/android/issues/detail?id=65351%20blah%20blah%20blah.",
+ Category.A11Y,
+ 3,
+ Severity.WARNING,
+ new Implementation(MyJavaLintDetector.class, EnumSet.of(Scope.RESOURCE_FILE, Scope.JAVA_FILE)))
+ .addMoreInfo("file://explanation.doc")
+ .addMoreInfo("http://my.personal.blogger.com/aboutme.htm")
+ .addMoreInfo("mailto:lint@example.com");
+ public void testGetBody(PsiMethod method) {
+ method.getBody(); // ERROR - must use UAST
+ }
+ public void testGetBody(UMethod method) {
+ method.getBody(); // ERROR - must use UAST
+ }
+ public void testGetContainingClass(UMethod method, UField field) {
+ method.getContainingClass(); // ERROR - must use UAST
+ field.getContainingClass(); // ERROR - must use UAST
+ }
+ public void testGetContainingClass(PsiMethod method, PsiField field) {
+ method.getContainingClass(); // OK - legitimate uses after resolve
+ field.getContainingClass(); // OK - legitimate uses after resolve
+ }
+ public void testEquals(PsiCallExpression element1, PsiExpression element2) {
+ if (element1.equals(element2)) { }
+ if (element2.equals(element1)) { }
+ if (element1 == element2) { }
+ if (element1 != element2) { }
+ }
+ public void testGetInitializer(PsiField field) {
+ field.getInitializer(); // ERROR - must use UAST
+ }
+ public void testParents(PsiField field, UMethod method) {
+ PsiElement parent = field.getParent(); // OK
+ PsiElement parent = method.getParent(); // ERROR
+ PsiTreeUtil.getParentOfType(field, PsiClass.class); // OK
+ PsiTreeUtil.getParentOfType(method, PsiClass.class); // ERROR
+ }
+
+ public void testReport(JavaContext context, UCallExpression node) {
+ context.report(ISSUE, node, context.getLocation(node),
+ "Wrong use of LinearLayout.");
+ context.report(ISSUE, node, context.getLocation(node),
+ "First problem. Second problem.");
+ context.report(ISSUE, node, context.getLocation(node),
+ "This is teh typo");
+ String message = "Welcome to Andriod";
+ context.report(ISSUE, node, context.getLocation(node), message);
+ context.report(ISSUE, node, context.getLocation(node),
+ "Should you use `x ?: y` instead of ```foo ? 1 : 0``` ?");
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyKotlinLintDetector.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+/* Copyright (C) 2020 The Android Open Source Project */
+package test.pkg
+import com.intellij.psi.PsiCallExpression
+import com.intellij.psi.PsiExpression
+import com.intellij.psi.PsiField
+import com.intellij.psi.PsiMethod
+import com.intellij.psi.util.PsiTreeUtil
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import org.jetbrains.uast.UCallExpression
+
+class MyKotlinLintDetector : Detector() {
+ fun testGetBody(method: PsiMethod) {
+ val body = method.body // ERROR - must use UAST
+ }
+ @Suppress("ReplaceCallWithBinaryOperator","ControlFlowWithEmptyBody")
+ fun testEquals(element1: PsiCallExpression, element2: PsiExpression) {
+ if (element1.equals(element2)) { }
+ if (element2.equals(element1)) { }
+ if (element1 == element2) { }
+ if (element1 === element2) { }
+ if (element1 != element2) { }
+ if (element1 !== element2) { }
+ if (element1 == null) { } // OK
+ if (element1 === null) { } // OK
+ if (element1 != null) { } // OK
+ if (element1 !== null) { } // OK
+ }
+ @Suppress("UsePropertyAccessSyntax")
+ fun testGetInitializer(field: PsiField) {
+ field.getInitializer() // ERROR - must use UAST
+ field.initializer // ERROR - must use UAST
+ }
+ fun testParents(field: PsiField) {
+ val parent = field.parent
+ val method = PsiTreeUtil.getParentOfType(field, PsiMethod::class.java)
+ }
+
+ fun testReport(context: JavaContext, node: UCallExpression) {
+ context.report(ISSUE, node, context.getLocation(node),
+ """
+ |Instead you should call foo().bar().baz() here.
+ |""".trimIndent())
+ }
+
+ companion object {
+ private val IMPLEMENTATION =
+ Implementation(
+ MyKotlinLintDetector::class.java,
+ Scope.JAVA_FILE_SCOPE
+ )
+
+ val ISSUE =
+ Issue.create(
+ id = "badlyCapitalized id",
+ briefDescription = "checks MyLintDetector.",
+ explanation = """
+ Some description here.
+ Here's a call: foo.bar.baz(args).
+ This line continuation is okay. \
+ But this one is missing a space.\
+ Okay?
+ """.trimIndent(),
+ category = Category.INTEROPERABILITY_KOTLIN,
+ moreInfo = "https://code.google.com/p/android/issues/detail?id=65351", // OBSOLETE
+ priority = 4,
+ severity = Severity.WARNING,
+ implementation = IMPLEMENTATION
+ )
+ .addMoreInfo("https://issuetracker.google.com/issues/3733548") // ERROR - missing digit
+ .addMoreInfo("https://issuetracker.google.com/issues/373354878") // OK - including digit
+ .addMoreInfo("http://issuetracker.google.com/issues/37335487") // ERROR - http instead of https
+ .addMoreInfo("https://b.corp.google.com/issues/139153781") // ERROR - don't point to buganizer with internal link
+ .addMoreInfo("https://goo.gle/policy-storage-help") // OK - regression test for goo.gle
+ }
+
+ override fun visitAnnotationUsage(
+ context: JavaContext,
+ element: org.jetbrains.uast.UElement.UElement,
+ annotationInfo: com.android.tools.lint.detector.api.AnnotationInfo,
+ usageInfo: com.android.tools.lint.detector.api.AnnotationUsageInfo
+ ) {
+ // Invalid recursion!
+ super.visitAnnotationUsage(context, element, annotationInfo, usageInfo)
+ }
+
+ fun misc() {
+ System.out.print("Debugging")
+ println("Debugging code")
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyIssueRegistry.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import com.android.tools.lint.client.api.IssueRegistry
+class MyIssueRegistry : IssueRegistry() {
+ override val issues = listOf(
+ MyJavaLintDetector.ISSUE,
+ MyKotlinLintDetector.Companion.ISSUE
+ )
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyVendorIssueRegistry.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import com.android.tools.lint.client.api.IssueRegistry
+import com.android.tools.lint.client.api.Vendor
+class MyVendorIssueRegistry : IssueRegistry() {
+ // Supplies a vendor: no warning
+ override var vendor: Vendor? = Vendor("Unit test")
+ override val issues = listOf(
+ MyJavaLintDetector.ISSUE,
+ MyKotlinLintDetector.Companion.ISSUE
+ )
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/InheritingRegistry.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import com.android.tools.lint.client.api.IssueRegistry
+import com.android.tools.lint.client.api.Vendor
+class InheritingRegistry : MyVendorIssueRegistry() { // NO WARNING
+ // This registry doesn't supply a vendor but inherits one; no warning
+ override val issues = listOf(
+ MyJavaLintDetector.ISSUE,
+ MyKotlinLintDetector.Companion.ISSUE
+ )
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyKotlinLintDetectorTest.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+// Copyright (C) 2021 The Android Open Source Project
+package test.pkg
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest
+import com.android.tools.lint.detector.api.Detector
+class MyKotlinLintDetectorTest : LintDetectorTest() {
+ override fun getDetector(): Detector {
+ return MyKotlinLintDetector()
+ }
+
+ fun testBasic() {
+ val expected = """
+ src/test/pkg/AlarmTest.java:9: Warning: Value will be forced up to 5000 as of Android 5.1; don't rely on this to be exact [ShortAlarm]
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 50, 10, null); // ERROR
+ ~~
+ 0 errors, 1 warnings
+ """
+
+ lint().files(
+ kotlin(
+ """
+ fun test() {
+ println("Value=${"$"}")
+ }
+ """
+ ),
+ java(
+ "src/test/pkg/AlarmTest.java",
+ """
+ package test.pkg;
+
+ import android.app.AlarmManager;
+ @SuppressWarnings("ClassNameDiffersFromFileName")
+ public class AlarmTest {
+ public void test(AlarmManager alarmManager) {
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 5000, 60000, null); // OK
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 6000, 70000, null); // OK
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 50, 10, null); // ERROR
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 5000, // ERROR
+ OtherClass.MY_INTERVAL, null); // ERROR
+ }
+
+ private static class OtherClass {
+ public static final long MY_INTERVAL = 1000L;
+ }
+ }
+ """.trimIndent()
+ )
+ ).run().expect(expected)
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/LintDetectorDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `LintDetectorDetector.testProblems`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("LintImplTrimIndent")
+ fun method() {
+ expect(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("LintImplTrimIndent")
+ void method() {
+ expect(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection LintImplTrimIndent
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="LintImplTrimIndent" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'LintImplTrimIndent'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore LintImplTrimIndent ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/LintImplUnexpectedDomain.md.html b/docs/checks/LintImplUnexpectedDomain.md.html
new file mode 100644
index 00000000..f9747f7c
--- /dev/null
+++ b/docs/checks/LintImplUnexpectedDomain.md.html
@@ -0,0 +1,404 @@
+
+(#) Unexpected URL Domain
+
+!!! ERROR: Unexpected URL Domain
+ This is an error.
+
+Id
+: `LintImplUnexpectedDomain`
+Summary
+: Unexpected URL Domain
+Note
+: **This issue is disabled by default**; use `--enable LintImplUnexpectedDomain`
+Severity
+: Error
+Category
+: Lint Implementation Issues
+Platform
+: JDK
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 4.1.0 (October 2020)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/LintDetectorDetector.kt)
+Tests
+: [Source Code](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/LintDetectorDetectorTest.kt)
+
+This checks flags URLs to domains that have not been explicitly allowed
+for use as a documentation source.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/MyJavaLintDetector.java:36:Error: Unexpected URL host
+my.personal.blogger.com; for the builtin Android Lint checks make sure
+to use an authoritative link
+(http://my.personal.blogger.com/aboutme.htm) [LintImplUnexpectedDomain]
+ .addMoreInfo("http://my.personal.blogger.com/aboutme.htm")
+ ------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/test/pkg/MyJavaLintDetector.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+/* Copyright (C) 2020 The Android Open Source Project */
+package test.pkg;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiCallExpression;
+import com.intellij.psi.PsiExpression;
+import com.intellij.psi.PsiField;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.android.tools.lint.detector.api.Detector;
+import org.jetbrains.uast.UFile;
+import org.jetbrains.uast.UMethod;
+import org.jetbrains.uast.UField;
+import com.android.tools.lint.detector.api.Category;
+import com.android.tools.lint.detector.api.Detector;
+import com.android.tools.lint.detector.api.Implementation;
+import com.android.tools.lint.detector.api.Issue;
+import com.android.tools.lint.detector.api.JavaContext;
+import com.android.tools.lint.detector.api.Scope;
+import com.android.tools.lint.detector.api.Severity;
+import org.jetbrains.uast.UCallExpression;
+import java.util.EnumSet;
+
+@SuppressWarnings({"MethodMayBeStatic", "ClassNameDiffersFromFileName", "StatementWithEmptyBody", "deprecation"})
+public class MyJavaLintDetector extends Detector {
+ public static final Issue ISSUE =
+ Issue.create(
+ "com.android.namespaced.lint.check.FooDetector",
+ "Wrong use of ",
+ "As described in "
+ + "https://code.google.com/p/android/issues/detail?id=65351%20blah%20blah%20blah.",
+ Category.A11Y,
+ 3,
+ Severity.WARNING,
+ new Implementation(MyJavaLintDetector.class, EnumSet.of(Scope.RESOURCE_FILE, Scope.JAVA_FILE)))
+ .addMoreInfo("file://explanation.doc")
+ .addMoreInfo("http://my.personal.blogger.com/aboutme.htm")
+ .addMoreInfo("mailto:lint@example.com");
+ public void testGetBody(PsiMethod method) {
+ method.getBody(); // ERROR - must use UAST
+ }
+ public void testGetBody(UMethod method) {
+ method.getBody(); // ERROR - must use UAST
+ }
+ public void testGetContainingClass(UMethod method, UField field) {
+ method.getContainingClass(); // ERROR - must use UAST
+ field.getContainingClass(); // ERROR - must use UAST
+ }
+ public void testGetContainingClass(PsiMethod method, PsiField field) {
+ method.getContainingClass(); // OK - legitimate uses after resolve
+ field.getContainingClass(); // OK - legitimate uses after resolve
+ }
+ public void testEquals(PsiCallExpression element1, PsiExpression element2) {
+ if (element1.equals(element2)) { }
+ if (element2.equals(element1)) { }
+ if (element1 == element2) { }
+ if (element1 != element2) { }
+ }
+ public void testGetInitializer(PsiField field) {
+ field.getInitializer(); // ERROR - must use UAST
+ }
+ public void testParents(PsiField field, UMethod method) {
+ PsiElement parent = field.getParent(); // OK
+ PsiElement parent = method.getParent(); // ERROR
+ PsiTreeUtil.getParentOfType(field, PsiClass.class); // OK
+ PsiTreeUtil.getParentOfType(method, PsiClass.class); // ERROR
+ }
+
+ public void testReport(JavaContext context, UCallExpression node) {
+ context.report(ISSUE, node, context.getLocation(node),
+ "Wrong use of LinearLayout.");
+ context.report(ISSUE, node, context.getLocation(node),
+ "First problem. Second problem.");
+ context.report(ISSUE, node, context.getLocation(node),
+ "This is teh typo");
+ String message = "Welcome to Andriod";
+ context.report(ISSUE, node, context.getLocation(node), message);
+ context.report(ISSUE, node, context.getLocation(node),
+ "Should you use `x ?: y` instead of ```foo ? 1 : 0``` ?");
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyKotlinLintDetector.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+/* Copyright (C) 2020 The Android Open Source Project */
+package test.pkg
+import com.intellij.psi.PsiCallExpression
+import com.intellij.psi.PsiExpression
+import com.intellij.psi.PsiField
+import com.intellij.psi.PsiMethod
+import com.intellij.psi.util.PsiTreeUtil
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import org.jetbrains.uast.UCallExpression
+
+class MyKotlinLintDetector : Detector() {
+ fun testGetBody(method: PsiMethod) {
+ val body = method.body // ERROR - must use UAST
+ }
+ @Suppress("ReplaceCallWithBinaryOperator","ControlFlowWithEmptyBody")
+ fun testEquals(element1: PsiCallExpression, element2: PsiExpression) {
+ if (element1.equals(element2)) { }
+ if (element2.equals(element1)) { }
+ if (element1 == element2) { }
+ if (element1 === element2) { }
+ if (element1 != element2) { }
+ if (element1 !== element2) { }
+ if (element1 == null) { } // OK
+ if (element1 === null) { } // OK
+ if (element1 != null) { } // OK
+ if (element1 !== null) { } // OK
+ }
+ @Suppress("UsePropertyAccessSyntax")
+ fun testGetInitializer(field: PsiField) {
+ field.getInitializer() // ERROR - must use UAST
+ field.initializer // ERROR - must use UAST
+ }
+ fun testParents(field: PsiField) {
+ val parent = field.parent
+ val method = PsiTreeUtil.getParentOfType(field, PsiMethod::class.java)
+ }
+
+ fun testReport(context: JavaContext, node: UCallExpression) {
+ context.report(ISSUE, node, context.getLocation(node),
+ """
+ |Instead you should call foo().bar().baz() here.
+ |""".trimIndent())
+ }
+
+ companion object {
+ private val IMPLEMENTATION =
+ Implementation(
+ MyKotlinLintDetector::class.java,
+ Scope.JAVA_FILE_SCOPE
+ )
+
+ val ISSUE =
+ Issue.create(
+ id = "badlyCapitalized id",
+ briefDescription = "checks MyLintDetector.",
+ explanation = """
+ Some description here.
+ Here's a call: foo.bar.baz(args).
+ This line continuation is okay. \
+ But this one is missing a space.\
+ Okay?
+ """.trimIndent(),
+ category = Category.INTEROPERABILITY_KOTLIN,
+ moreInfo = "https://code.google.com/p/android/issues/detail?id=65351", // OBSOLETE
+ priority = 4,
+ severity = Severity.WARNING,
+ implementation = IMPLEMENTATION
+ )
+ .addMoreInfo("https://issuetracker.google.com/issues/3733548") // ERROR - missing digit
+ .addMoreInfo("https://issuetracker.google.com/issues/373354878") // OK - including digit
+ .addMoreInfo("http://issuetracker.google.com/issues/37335487") // ERROR - http instead of https
+ .addMoreInfo("https://b.corp.google.com/issues/139153781") // ERROR - don't point to buganizer with internal link
+ .addMoreInfo("https://goo.gle/policy-storage-help") // OK - regression test for goo.gle
+ }
+
+ override fun visitAnnotationUsage(
+ context: JavaContext,
+ element: org.jetbrains.uast.UElement.UElement,
+ annotationInfo: com.android.tools.lint.detector.api.AnnotationInfo,
+ usageInfo: com.android.tools.lint.detector.api.AnnotationUsageInfo
+ ) {
+ // Invalid recursion!
+ super.visitAnnotationUsage(context, element, annotationInfo, usageInfo)
+ }
+
+ fun misc() {
+ System.out.print("Debugging")
+ println("Debugging code")
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyIssueRegistry.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import com.android.tools.lint.client.api.IssueRegistry
+class MyIssueRegistry : IssueRegistry() {
+ override val issues = listOf(
+ MyJavaLintDetector.ISSUE,
+ MyKotlinLintDetector.Companion.ISSUE
+ )
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyVendorIssueRegistry.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import com.android.tools.lint.client.api.IssueRegistry
+import com.android.tools.lint.client.api.Vendor
+class MyVendorIssueRegistry : IssueRegistry() {
+ // Supplies a vendor: no warning
+ override var vendor: Vendor? = Vendor("Unit test")
+ override val issues = listOf(
+ MyJavaLintDetector.ISSUE,
+ MyKotlinLintDetector.Companion.ISSUE
+ )
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/InheritingRegistry.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import com.android.tools.lint.client.api.IssueRegistry
+import com.android.tools.lint.client.api.Vendor
+class InheritingRegistry : MyVendorIssueRegistry() { // NO WARNING
+ // This registry doesn't supply a vendor but inherits one; no warning
+ override val issues = listOf(
+ MyJavaLintDetector.ISSUE,
+ MyKotlinLintDetector.Companion.ISSUE
+ )
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyKotlinLintDetectorTest.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+// Copyright (C) 2021 The Android Open Source Project
+package test.pkg
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest
+import com.android.tools.lint.detector.api.Detector
+class MyKotlinLintDetectorTest : LintDetectorTest() {
+ override fun getDetector(): Detector {
+ return MyKotlinLintDetector()
+ }
+
+ fun testBasic() {
+ val expected = """
+ src/test/pkg/AlarmTest.java:9: Warning: Value will be forced up to 5000 as of Android 5.1; don't rely on this to be exact [ShortAlarm]
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 50, 10, null); // ERROR
+ ~~
+ 0 errors, 1 warnings
+ """
+
+ lint().files(
+ kotlin(
+ """
+ fun test() {
+ println("Value=${"$"}")
+ }
+ """
+ ),
+ java(
+ "src/test/pkg/AlarmTest.java",
+ """
+ package test.pkg;
+
+ import android.app.AlarmManager;
+ @SuppressWarnings("ClassNameDiffersFromFileName")
+ public class AlarmTest {
+ public void test(AlarmManager alarmManager) {
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 5000, 60000, null); // OK
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 6000, 70000, null); // OK
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 50, 10, null); // ERROR
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 5000, // ERROR
+ OtherClass.MY_INTERVAL, null); // ERROR
+ }
+
+ private static class OtherClass {
+ public static final long MY_INTERVAL = 1000L;
+ }
+ }
+ """.trimIndent()
+ )
+ ).run().expect(expected)
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/LintDetectorDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `LintDetectorDetector.testProblems`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("LintImplUnexpectedDomain")
+ fun method() {
+ expect(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("LintImplUnexpectedDomain")
+ void method() {
+ expect(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection LintImplUnexpectedDomain
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="LintImplUnexpectedDomain" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'LintImplUnexpectedDomain'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore LintImplUnexpectedDomain ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/LintImplUseKotlin.md.html b/docs/checks/LintImplUseKotlin.md.html
new file mode 100644
index 00000000..07d0cdbd
--- /dev/null
+++ b/docs/checks/LintImplUseKotlin.md.html
@@ -0,0 +1,405 @@
+
+(#) Non-Kotlin Lint Detectors
+
+!!! WARNING: Non-Kotlin Lint Detectors
+ This is a warning.
+
+Id
+: `LintImplUseKotlin`
+Summary
+: Non-Kotlin Lint Detectors
+Severity
+: Warning
+Category
+: Lint Implementation Issues
+Platform
+: JDK
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 4.1.0 (October 2020)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/LintDetectorDetector.kt)
+Tests
+: [Source Code](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/LintDetectorDetectorTest.kt)
+
+New lint checks should be written in Kotlin; the Lint API is written in
+Kotlin and uses a number of language features that makes it beneficial
+to also write the lint checks in Kotlin. Examples include many extension
+functions (as well as in UAST), default and named parameters (for the
+Issue registration methods for example where there are methods with 12+
+parameters with only a couple of required ones), and so on.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/MyJavaLintDetector.java:24:Warning: New lint checks should
+be implemented in Kotlin to take advantage of a lot of Kotlin-specific
+mechanisms in the Lint API [LintImplUseKotlin]
+public class MyJavaLintDetector extends Detector {
+ ------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/test/pkg/MyJavaLintDetector.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+/* Copyright (C) 2020 The Android Open Source Project */
+package test.pkg;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiCallExpression;
+import com.intellij.psi.PsiExpression;
+import com.intellij.psi.PsiField;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.android.tools.lint.detector.api.Detector;
+import org.jetbrains.uast.UFile;
+import org.jetbrains.uast.UMethod;
+import org.jetbrains.uast.UField;
+import com.android.tools.lint.detector.api.Category;
+import com.android.tools.lint.detector.api.Detector;
+import com.android.tools.lint.detector.api.Implementation;
+import com.android.tools.lint.detector.api.Issue;
+import com.android.tools.lint.detector.api.JavaContext;
+import com.android.tools.lint.detector.api.Scope;
+import com.android.tools.lint.detector.api.Severity;
+import org.jetbrains.uast.UCallExpression;
+import java.util.EnumSet;
+
+@SuppressWarnings({"MethodMayBeStatic", "ClassNameDiffersFromFileName", "StatementWithEmptyBody", "deprecation"})
+public class MyJavaLintDetector extends Detector {
+ public static final Issue ISSUE =
+ Issue.create(
+ "com.android.namespaced.lint.check.FooDetector",
+ "Wrong use of ",
+ "As described in "
+ + "https://code.google.com/p/android/issues/detail?id=65351%20blah%20blah%20blah.",
+ Category.A11Y,
+ 3,
+ Severity.WARNING,
+ new Implementation(MyJavaLintDetector.class, EnumSet.of(Scope.RESOURCE_FILE, Scope.JAVA_FILE)))
+ .addMoreInfo("file://explanation.doc")
+ .addMoreInfo("http://my.personal.blogger.com/aboutme.htm")
+ .addMoreInfo("mailto:lint@example.com");
+ public void testGetBody(PsiMethod method) {
+ method.getBody(); // ERROR - must use UAST
+ }
+ public void testGetBody(UMethod method) {
+ method.getBody(); // ERROR - must use UAST
+ }
+ public void testGetContainingClass(UMethod method, UField field) {
+ method.getContainingClass(); // ERROR - must use UAST
+ field.getContainingClass(); // ERROR - must use UAST
+ }
+ public void testGetContainingClass(PsiMethod method, PsiField field) {
+ method.getContainingClass(); // OK - legitimate uses after resolve
+ field.getContainingClass(); // OK - legitimate uses after resolve
+ }
+ public void testEquals(PsiCallExpression element1, PsiExpression element2) {
+ if (element1.equals(element2)) { }
+ if (element2.equals(element1)) { }
+ if (element1 == element2) { }
+ if (element1 != element2) { }
+ }
+ public void testGetInitializer(PsiField field) {
+ field.getInitializer(); // ERROR - must use UAST
+ }
+ public void testParents(PsiField field, UMethod method) {
+ PsiElement parent = field.getParent(); // OK
+ PsiElement parent = method.getParent(); // ERROR
+ PsiTreeUtil.getParentOfType(field, PsiClass.class); // OK
+ PsiTreeUtil.getParentOfType(method, PsiClass.class); // ERROR
+ }
+
+ public void testReport(JavaContext context, UCallExpression node) {
+ context.report(ISSUE, node, context.getLocation(node),
+ "Wrong use of LinearLayout.");
+ context.report(ISSUE, node, context.getLocation(node),
+ "First problem. Second problem.");
+ context.report(ISSUE, node, context.getLocation(node),
+ "This is teh typo");
+ String message = "Welcome to Andriod";
+ context.report(ISSUE, node, context.getLocation(node), message);
+ context.report(ISSUE, node, context.getLocation(node),
+ "Should you use `x ?: y` instead of ```foo ? 1 : 0``` ?");
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyKotlinLintDetector.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+/* Copyright (C) 2020 The Android Open Source Project */
+package test.pkg
+import com.intellij.psi.PsiCallExpression
+import com.intellij.psi.PsiExpression
+import com.intellij.psi.PsiField
+import com.intellij.psi.PsiMethod
+import com.intellij.psi.util.PsiTreeUtil
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import org.jetbrains.uast.UCallExpression
+
+class MyKotlinLintDetector : Detector() {
+ fun testGetBody(method: PsiMethod) {
+ val body = method.body // ERROR - must use UAST
+ }
+ @Suppress("ReplaceCallWithBinaryOperator","ControlFlowWithEmptyBody")
+ fun testEquals(element1: PsiCallExpression, element2: PsiExpression) {
+ if (element1.equals(element2)) { }
+ if (element2.equals(element1)) { }
+ if (element1 == element2) { }
+ if (element1 === element2) { }
+ if (element1 != element2) { }
+ if (element1 !== element2) { }
+ if (element1 == null) { } // OK
+ if (element1 === null) { } // OK
+ if (element1 != null) { } // OK
+ if (element1 !== null) { } // OK
+ }
+ @Suppress("UsePropertyAccessSyntax")
+ fun testGetInitializer(field: PsiField) {
+ field.getInitializer() // ERROR - must use UAST
+ field.initializer // ERROR - must use UAST
+ }
+ fun testParents(field: PsiField) {
+ val parent = field.parent
+ val method = PsiTreeUtil.getParentOfType(field, PsiMethod::class.java)
+ }
+
+ fun testReport(context: JavaContext, node: UCallExpression) {
+ context.report(ISSUE, node, context.getLocation(node),
+ """
+ |Instead you should call foo().bar().baz() here.
+ |""".trimIndent())
+ }
+
+ companion object {
+ private val IMPLEMENTATION =
+ Implementation(
+ MyKotlinLintDetector::class.java,
+ Scope.JAVA_FILE_SCOPE
+ )
+
+ val ISSUE =
+ Issue.create(
+ id = "badlyCapitalized id",
+ briefDescription = "checks MyLintDetector.",
+ explanation = """
+ Some description here.
+ Here's a call: foo.bar.baz(args).
+ This line continuation is okay. \
+ But this one is missing a space.\
+ Okay?
+ """.trimIndent(),
+ category = Category.INTEROPERABILITY_KOTLIN,
+ moreInfo = "https://code.google.com/p/android/issues/detail?id=65351", // OBSOLETE
+ priority = 4,
+ severity = Severity.WARNING,
+ implementation = IMPLEMENTATION
+ )
+ .addMoreInfo("https://issuetracker.google.com/issues/3733548") // ERROR - missing digit
+ .addMoreInfo("https://issuetracker.google.com/issues/373354878") // OK - including digit
+ .addMoreInfo("http://issuetracker.google.com/issues/37335487") // ERROR - http instead of https
+ .addMoreInfo("https://b.corp.google.com/issues/139153781") // ERROR - don't point to buganizer with internal link
+ .addMoreInfo("https://goo.gle/policy-storage-help") // OK - regression test for goo.gle
+ }
+
+ override fun visitAnnotationUsage(
+ context: JavaContext,
+ element: org.jetbrains.uast.UElement.UElement,
+ annotationInfo: com.android.tools.lint.detector.api.AnnotationInfo,
+ usageInfo: com.android.tools.lint.detector.api.AnnotationUsageInfo
+ ) {
+ // Invalid recursion!
+ super.visitAnnotationUsage(context, element, annotationInfo, usageInfo)
+ }
+
+ fun misc() {
+ System.out.print("Debugging")
+ println("Debugging code")
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyIssueRegistry.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import com.android.tools.lint.client.api.IssueRegistry
+class MyIssueRegistry : IssueRegistry() {
+ override val issues = listOf(
+ MyJavaLintDetector.ISSUE,
+ MyKotlinLintDetector.Companion.ISSUE
+ )
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyVendorIssueRegistry.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import com.android.tools.lint.client.api.IssueRegistry
+import com.android.tools.lint.client.api.Vendor
+class MyVendorIssueRegistry : IssueRegistry() {
+ // Supplies a vendor: no warning
+ override var vendor: Vendor? = Vendor("Unit test")
+ override val issues = listOf(
+ MyJavaLintDetector.ISSUE,
+ MyKotlinLintDetector.Companion.ISSUE
+ )
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/InheritingRegistry.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import com.android.tools.lint.client.api.IssueRegistry
+import com.android.tools.lint.client.api.Vendor
+class InheritingRegistry : MyVendorIssueRegistry() { // NO WARNING
+ // This registry doesn't supply a vendor but inherits one; no warning
+ override val issues = listOf(
+ MyJavaLintDetector.ISSUE,
+ MyKotlinLintDetector.Companion.ISSUE
+ )
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyKotlinLintDetectorTest.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+// Copyright (C) 2021 The Android Open Source Project
+package test.pkg
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest
+import com.android.tools.lint.detector.api.Detector
+class MyKotlinLintDetectorTest : LintDetectorTest() {
+ override fun getDetector(): Detector {
+ return MyKotlinLintDetector()
+ }
+
+ fun testBasic() {
+ val expected = """
+ src/test/pkg/AlarmTest.java:9: Warning: Value will be forced up to 5000 as of Android 5.1; don't rely on this to be exact [ShortAlarm]
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 50, 10, null); // ERROR
+ ~~
+ 0 errors, 1 warnings
+ """
+
+ lint().files(
+ kotlin(
+ """
+ fun test() {
+ println("Value=${"$"}")
+ }
+ """
+ ),
+ java(
+ "src/test/pkg/AlarmTest.java",
+ """
+ package test.pkg;
+
+ import android.app.AlarmManager;
+ @SuppressWarnings("ClassNameDiffersFromFileName")
+ public class AlarmTest {
+ public void test(AlarmManager alarmManager) {
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 5000, 60000, null); // OK
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 6000, 70000, null); // OK
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 50, 10, null); // ERROR
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 5000, // ERROR
+ OtherClass.MY_INTERVAL, null); // ERROR
+ }
+
+ private static class OtherClass {
+ public static final long MY_INTERVAL = 1000L;
+ }
+ }
+ """.trimIndent()
+ )
+ ).run().expect(expected)
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/LintDetectorDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `LintDetectorDetector.testProblems`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("LintImplUseKotlin")
+ fun method() {
+ expect(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("LintImplUseKotlin")
+ void method() {
+ expect(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection LintImplUseKotlin
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="LintImplUseKotlin" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'LintImplUseKotlin'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore LintImplUseKotlin ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/LintImplUseUast.md.html b/docs/checks/LintImplUseUast.md.html
new file mode 100644
index 00000000..47478f5c
--- /dev/null
+++ b/docs/checks/LintImplUseUast.md.html
@@ -0,0 +1,442 @@
+
+(#) Using Wrong UAST Method
+
+!!! ERROR: Using Wrong UAST Method
+ This is an error.
+
+Id
+: `LintImplUseUast`
+Summary
+: Using Wrong UAST Method
+Severity
+: Error
+Category
+: Lint Implementation Issues
+Platform
+: JDK
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 4.1.0 (October 2020)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/LintDetectorDetector.kt)
+Tests
+: [Source Code](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/LintDetectorDetectorTest.kt)
+
+UAST is a library that sits on top of PSI, and in many cases PSI is part
+of the UAST API; for example, UResolvable#resolve returns a PsiElement.
+
+Also, for convenience, a UClass is a PsiClass, a UMethod is a PsiMethod,
+and so on.
+
+However, there are some parts of the PSI API that does not work
+correctly when used in this way. For example, if you call
+`PsiMethod#getBody` or `PsiVariable#getInitializer`, this will only work
+in Java, not for Kotlin (or potentially other languages).
+
+There are UAST specific methods you need to call instead and lint will
+flag these.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/MyJavaLintDetector.java:39:Error: Don't call
+PsiMethod#getBody(); you must use UAST instead. If you don't have a
+UMethod call UastFacade.getMethodBody(method) [LintImplUseUast]
+ method.getBody(); // ERROR - must use UAST
+ ----------------
+src/test/pkg/MyJavaLintDetector.java:42:Error: Don't call
+PsiMethod#getBody(); you must use UAST instead. If you don't have a
+UMethod call UastFacade.getMethodBody(method) [LintImplUseUast]
+ method.getBody(); // ERROR - must use UAST
+ ----------------
+src/test/pkg/MyJavaLintDetector.java:45:Error: Don't call
+PsiMember#getContainingClass(); you should use UAST instead and call
+getContainingUClass() [LintImplUseUast]
+ method.getContainingClass(); // ERROR - must use UAST
+ ---------------------------
+src/test/pkg/MyJavaLintDetector.java:46:Error: Don't call
+PsiMember#getContainingClass(); you should use UAST instead and call
+getContainingUClass() [LintImplUseUast]
+ field.getContainingClass(); // ERROR - must use UAST
+ --------------------------
+src/test/pkg/MyJavaLintDetector.java:59:Error: Don't call
+PsiField#getInitializer(); you must use UAST instead. If you don't have
+a UField call UastFacade.getInitializerBody(field) [LintImplUseUast]
+ field.getInitializer(); // ERROR - must use UAST
+ ----------------------
+src/test/pkg/MyJavaLintDetector.java:63:Error: Don't call
+PsiElement#getParent(); you should use UAST instead and call
+getUastParent() [LintImplUseUast]
+ PsiElement parent = method.getParent(); // ERROR
+ ------------------
+src/test/pkg/MyJavaLintDetector.java:65:Error: Don't call
+PsiTreeUtil#getParentOfType(); you should use UAST instead and call
+UElement.parentOfType [LintImplUseUast]
+ PsiTreeUtil.getParentOfType(method, PsiClass.class); // ERROR
+ ---------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/test/pkg/MyJavaLintDetector.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+/* Copyright (C) 2020 The Android Open Source Project */
+package test.pkg;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiCallExpression;
+import com.intellij.psi.PsiExpression;
+import com.intellij.psi.PsiField;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.android.tools.lint.detector.api.Detector;
+import org.jetbrains.uast.UFile;
+import org.jetbrains.uast.UMethod;
+import org.jetbrains.uast.UField;
+import com.android.tools.lint.detector.api.Category;
+import com.android.tools.lint.detector.api.Detector;
+import com.android.tools.lint.detector.api.Implementation;
+import com.android.tools.lint.detector.api.Issue;
+import com.android.tools.lint.detector.api.JavaContext;
+import com.android.tools.lint.detector.api.Scope;
+import com.android.tools.lint.detector.api.Severity;
+import org.jetbrains.uast.UCallExpression;
+import java.util.EnumSet;
+
+@SuppressWarnings({"MethodMayBeStatic", "ClassNameDiffersFromFileName", "StatementWithEmptyBody", "deprecation"})
+public class MyJavaLintDetector extends Detector {
+ public static final Issue ISSUE =
+ Issue.create(
+ "com.android.namespaced.lint.check.FooDetector",
+ "Wrong use of ",
+ "As described in "
+ + "https://code.google.com/p/android/issues/detail?id=65351%20blah%20blah%20blah.",
+ Category.A11Y,
+ 3,
+ Severity.WARNING,
+ new Implementation(MyJavaLintDetector.class, EnumSet.of(Scope.RESOURCE_FILE, Scope.JAVA_FILE)))
+ .addMoreInfo("file://explanation.doc")
+ .addMoreInfo("http://my.personal.blogger.com/aboutme.htm")
+ .addMoreInfo("mailto:lint@example.com");
+ public void testGetBody(PsiMethod method) {
+ method.getBody(); // ERROR - must use UAST
+ }
+ public void testGetBody(UMethod method) {
+ method.getBody(); // ERROR - must use UAST
+ }
+ public void testGetContainingClass(UMethod method, UField field) {
+ method.getContainingClass(); // ERROR - must use UAST
+ field.getContainingClass(); // ERROR - must use UAST
+ }
+ public void testGetContainingClass(PsiMethod method, PsiField field) {
+ method.getContainingClass(); // OK - legitimate uses after resolve
+ field.getContainingClass(); // OK - legitimate uses after resolve
+ }
+ public void testEquals(PsiCallExpression element1, PsiExpression element2) {
+ if (element1.equals(element2)) { }
+ if (element2.equals(element1)) { }
+ if (element1 == element2) { }
+ if (element1 != element2) { }
+ }
+ public void testGetInitializer(PsiField field) {
+ field.getInitializer(); // ERROR - must use UAST
+ }
+ public void testParents(PsiField field, UMethod method) {
+ PsiElement parent = field.getParent(); // OK
+ PsiElement parent = method.getParent(); // ERROR
+ PsiTreeUtil.getParentOfType(field, PsiClass.class); // OK
+ PsiTreeUtil.getParentOfType(method, PsiClass.class); // ERROR
+ }
+
+ public void testReport(JavaContext context, UCallExpression node) {
+ context.report(ISSUE, node, context.getLocation(node),
+ "Wrong use of LinearLayout.");
+ context.report(ISSUE, node, context.getLocation(node),
+ "First problem. Second problem.");
+ context.report(ISSUE, node, context.getLocation(node),
+ "This is teh typo");
+ String message = "Welcome to Andriod";
+ context.report(ISSUE, node, context.getLocation(node), message);
+ context.report(ISSUE, node, context.getLocation(node),
+ "Should you use `x ?: y` instead of ```foo ? 1 : 0``` ?");
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyKotlinLintDetector.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+/* Copyright (C) 2020 The Android Open Source Project */
+package test.pkg
+import com.intellij.psi.PsiCallExpression
+import com.intellij.psi.PsiExpression
+import com.intellij.psi.PsiField
+import com.intellij.psi.PsiMethod
+import com.intellij.psi.util.PsiTreeUtil
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import org.jetbrains.uast.UCallExpression
+
+class MyKotlinLintDetector : Detector() {
+ fun testGetBody(method: PsiMethod) {
+ val body = method.body // ERROR - must use UAST
+ }
+ @Suppress("ReplaceCallWithBinaryOperator","ControlFlowWithEmptyBody")
+ fun testEquals(element1: PsiCallExpression, element2: PsiExpression) {
+ if (element1.equals(element2)) { }
+ if (element2.equals(element1)) { }
+ if (element1 == element2) { }
+ if (element1 === element2) { }
+ if (element1 != element2) { }
+ if (element1 !== element2) { }
+ if (element1 == null) { } // OK
+ if (element1 === null) { } // OK
+ if (element1 != null) { } // OK
+ if (element1 !== null) { } // OK
+ }
+ @Suppress("UsePropertyAccessSyntax")
+ fun testGetInitializer(field: PsiField) {
+ field.getInitializer() // ERROR - must use UAST
+ field.initializer // ERROR - must use UAST
+ }
+ fun testParents(field: PsiField) {
+ val parent = field.parent
+ val method = PsiTreeUtil.getParentOfType(field, PsiMethod::class.java)
+ }
+
+ fun testReport(context: JavaContext, node: UCallExpression) {
+ context.report(ISSUE, node, context.getLocation(node),
+ """
+ |Instead you should call foo().bar().baz() here.
+ |""".trimIndent())
+ }
+
+ companion object {
+ private val IMPLEMENTATION =
+ Implementation(
+ MyKotlinLintDetector::class.java,
+ Scope.JAVA_FILE_SCOPE
+ )
+
+ val ISSUE =
+ Issue.create(
+ id = "badlyCapitalized id",
+ briefDescription = "checks MyLintDetector.",
+ explanation = """
+ Some description here.
+ Here's a call: foo.bar.baz(args).
+ This line continuation is okay. \
+ But this one is missing a space.\
+ Okay?
+ """.trimIndent(),
+ category = Category.INTEROPERABILITY_KOTLIN,
+ moreInfo = "https://code.google.com/p/android/issues/detail?id=65351", // OBSOLETE
+ priority = 4,
+ severity = Severity.WARNING,
+ implementation = IMPLEMENTATION
+ )
+ .addMoreInfo("https://issuetracker.google.com/issues/3733548") // ERROR - missing digit
+ .addMoreInfo("https://issuetracker.google.com/issues/373354878") // OK - including digit
+ .addMoreInfo("http://issuetracker.google.com/issues/37335487") // ERROR - http instead of https
+ .addMoreInfo("https://b.corp.google.com/issues/139153781") // ERROR - don't point to buganizer with internal link
+ .addMoreInfo("https://goo.gle/policy-storage-help") // OK - regression test for goo.gle
+ }
+
+ override fun visitAnnotationUsage(
+ context: JavaContext,
+ element: org.jetbrains.uast.UElement.UElement,
+ annotationInfo: com.android.tools.lint.detector.api.AnnotationInfo,
+ usageInfo: com.android.tools.lint.detector.api.AnnotationUsageInfo
+ ) {
+ // Invalid recursion!
+ super.visitAnnotationUsage(context, element, annotationInfo, usageInfo)
+ }
+
+ fun misc() {
+ System.out.print("Debugging")
+ println("Debugging code")
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyIssueRegistry.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import com.android.tools.lint.client.api.IssueRegistry
+class MyIssueRegistry : IssueRegistry() {
+ override val issues = listOf(
+ MyJavaLintDetector.ISSUE,
+ MyKotlinLintDetector.Companion.ISSUE
+ )
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyVendorIssueRegistry.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import com.android.tools.lint.client.api.IssueRegistry
+import com.android.tools.lint.client.api.Vendor
+class MyVendorIssueRegistry : IssueRegistry() {
+ // Supplies a vendor: no warning
+ override var vendor: Vendor? = Vendor("Unit test")
+ override val issues = listOf(
+ MyJavaLintDetector.ISSUE,
+ MyKotlinLintDetector.Companion.ISSUE
+ )
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/InheritingRegistry.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+import com.android.tools.lint.client.api.IssueRegistry
+import com.android.tools.lint.client.api.Vendor
+class InheritingRegistry : MyVendorIssueRegistry() { // NO WARNING
+ // This registry doesn't supply a vendor but inherits one; no warning
+ override val issues = listOf(
+ MyJavaLintDetector.ISSUE,
+ MyKotlinLintDetector.Companion.ISSUE
+ )
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/MyKotlinLintDetectorTest.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+// Copyright (C) 2021 The Android Open Source Project
+package test.pkg
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest
+import com.android.tools.lint.detector.api.Detector
+class MyKotlinLintDetectorTest : LintDetectorTest() {
+ override fun getDetector(): Detector {
+ return MyKotlinLintDetector()
+ }
+
+ fun testBasic() {
+ val expected = """
+ src/test/pkg/AlarmTest.java:9: Warning: Value will be forced up to 5000 as of Android 5.1; don't rely on this to be exact [ShortAlarm]
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 50, 10, null); // ERROR
+ ~~
+ 0 errors, 1 warnings
+ """
+
+ lint().files(
+ kotlin(
+ """
+ fun test() {
+ println("Value=${"$"}")
+ }
+ """
+ ),
+ java(
+ "src/test/pkg/AlarmTest.java",
+ """
+ package test.pkg;
+
+ import android.app.AlarmManager;
+ @SuppressWarnings("ClassNameDiffersFromFileName")
+ public class AlarmTest {
+ public void test(AlarmManager alarmManager) {
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 5000, 60000, null); // OK
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 6000, 70000, null); // OK
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 50, 10, null); // ERROR
+ alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 5000, // ERROR
+ OtherClass.MY_INTERVAL, null); // ERROR
+ }
+
+ private static class OtherClass {
+ public static final long MY_INTERVAL = 1000L;
+ }
+ }
+ """.trimIndent()
+ )
+ ).run().expect(expected)
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/LintDetectorDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `LintDetectorDetector.testProblems`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("LintImplUseUast")
+ fun method() {
+ expect(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("LintImplUseUast")
+ void method() {
+ expect(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection LintImplUseUast
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="LintImplUseUast" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'LintImplUseUast'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore LintImplUseUast ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/LocalContextConfigurationRead.md.html b/docs/checks/LocalContextConfigurationRead.md.html
new file mode 100644
index 00000000..a468bf2e
--- /dev/null
+++ b/docs/checks/LocalContextConfigurationRead.md.html
@@ -0,0 +1,194 @@
+
+(#) Reading Configuration using LocalContext.current.resources.configuration
+
+!!! ERROR: Reading Configuration using LocalContext.current.resources.configuration
+ This is an error.
+
+Id
+: `LocalContextConfigurationRead`
+Summary
+: Reading Configuration using LocalContext.current.resources.configuration
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Jetpack Compose
+Identifier
+: androidx.compose.ui
+Feedback
+: https://issuetracker.google.com/issues/new?component=612128
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.compose.ui:ui-android](androidx_compose_ui_ui-android.md.html)
+Since
+: 1.8.0
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/ui/ui-lint/src/main/java/androidx/compose/ui/lint/LocalContextResourcesConfigurationReadDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/LocalContextResourcesConfigurationReadDetectorTest.kt)
+Copyright Year
+: 2024
+
+Changes to the Configuration object will not cause LocalContext reads to
+be invalidated, so you may end up with stale values when the
+Configuration changes. Instead, use LocalConfiguration.current to
+retrieve the Configuration - this will recompose callers when the
+Configuration object changes.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/test.kt:11:Error: Reading Configuration using
+LocalContext.current.resources.configuration
+[LocalContextConfigurationRead]
+ LocalContext.current.resources.configuration
+ --------------------------------------------
+src/test/test.kt:12:Error: Reading Configuration using
+LocalContext.current.resources.configuration
+[LocalContextConfigurationRead]
+ LocalContext.current.getResources().getConfiguration()
+ ------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test
+
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.platform.LocalContext
+
+@Composable
+fun Test() {
+ LocalContext.current.resources
+ LocalContext.current.getResources()
+ LocalContext.current.resources.configuration
+ LocalContext.current.getResources().getConfiguration()
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/LocalContextResourcesConfigurationReadDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `LocalContextResourcesConfigurationReadDetector.error`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=612128.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.compose.ui:ui-android:1.9.0-alpha01")
+
+// build.gradle
+implementation 'androidx.compose.ui:ui-android:1.9.0-alpha01'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.ui.android)
+
+# libs.versions.toml
+[versions]
+ui-android = "1.9.0-alpha01"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+ui-android = {
+ module = "androidx.compose.ui:ui-android",
+ version.ref = "ui-android"
+}
+```
+
+1.9.0-alpha01 is the version this documentation was generated from;
+there may be newer versions available.
+
+NOTE: These lint checks are **also** made available separate from the main library.
+You can also use `androidx.compose.ui:ui-lint:1.9.0-alpha01`.
+
+
+[Additional details about androidx.compose.ui:ui-android](androidx_compose_ui_ui-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("LocalContextConfigurationRead")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("LocalContextConfigurationRead")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection LocalContextConfigurationRead
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="LocalContextConfigurationRead" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'LocalContextConfigurationRead'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore LocalContextConfigurationRead ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/LocalContextResourcesRead.md.html b/docs/checks/LocalContextResourcesRead.md.html
new file mode 100644
index 00000000..50fd1fe5
--- /dev/null
+++ b/docs/checks/LocalContextResourcesRead.md.html
@@ -0,0 +1,193 @@
+
+(#) Reading Resources using LocalContext.current.resources
+
+!!! WARNING: Reading Resources using LocalContext.current.resources
+ This is a warning.
+
+Id
+: `LocalContextResourcesRead`
+Summary
+: Reading Resources using LocalContext.current.resources
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Jetpack Compose
+Identifier
+: androidx.compose.ui
+Feedback
+: https://issuetracker.google.com/issues/new?component=612128
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [androidx.compose.ui:ui-android](androidx_compose_ui_ui-android.md.html)
+Since
+: 1.9.0-alpha01
+Affects
+: Kotlin and Java files and test sources
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/ui/ui-lint/src/main/java/androidx/compose/ui/lint/LocalContextResourcesConfigurationReadDetector.kt)
+Tests
+: [Source Code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/LocalContextResourcesConfigurationReadDetectorTest.kt)
+Copyright Year
+: 2024
+
+Changes to the Configuration object will not cause
+LocalContext.current.resources reads to be invalidated, so calls to APIs
+suchas Resources.getString() will not be updated when the Configuration
+changes. Instead, use LocalResources.current to retrieve the Resources -
+this will invalidate callers when the Configuration changes, to ensure
+that these calls reflect the latest values.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/test.kt:9:Warning: Reading Resources using
+LocalContext.current.resources [LocalContextResourcesRead]
+ LocalContext.current.resources
+ ------------------------------
+src/test/test.kt:10:Warning: Reading Resources using
+LocalContext.current.resources [LocalContextResourcesRead]
+ LocalContext.current.getResources()
+ -----------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test
+
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.platform.LocalContext
+
+@Composable
+fun Test() {
+ LocalContext.current.resources
+ LocalContext.current.getResources()
+ LocalContext.current.resources.configuration
+ LocalContext.current.getResources().getConfiguration()
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/LocalContextResourcesConfigurationReadDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `LocalContextResourcesConfigurationReadDetector.error`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=612128.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project.
+
+```
+// build.gradle.kts
+implementation("androidx.compose.ui:ui-android:1.9.0-alpha01")
+
+// build.gradle
+implementation 'androidx.compose.ui:ui-android:1.9.0-alpha01'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.ui.android)
+
+# libs.versions.toml
+[versions]
+ui-android = "1.9.0-alpha01"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+ui-android = {
+ module = "androidx.compose.ui:ui-android",
+ version.ref = "ui-android"
+}
+```
+
+1.9.0-alpha01 is the version this documentation was generated from;
+there may be newer versions available.
+
+NOTE: These lint checks are **also** made available separate from the main library.
+You can also use `androidx.compose.ui:ui-lint:1.9.0-alpha01`.
+
+
+[Additional details about androidx.compose.ui:ui-android](androidx_compose_ui_ui-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("LocalContextResourcesRead")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("LocalContextResourcesRead")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection LocalContextResourcesRead
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="LocalContextResourcesRead" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'LocalContextResourcesRead'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore LocalContextResourcesRead ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/LocalSuppress.md.html b/docs/checks/LocalSuppress.md.html
new file mode 100644
index 00000000..d89c4b50
--- /dev/null
+++ b/docs/checks/LocalSuppress.md.html
@@ -0,0 +1,196 @@
+
+(#) @SuppressLint on invalid element
+
+!!! ERROR: @SuppressLint on invalid element
+ This is an error.
+
+Id
+: `LocalSuppress`
+Summary
+: @SuppressLint on invalid element
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/AnnotationDetector.kt)
+Tests
+: [Source Code](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/AnnotationDetectorTest.kt)
+Copyright Year
+: 2012
+
+The `@SuppressAnnotation` is used to suppress Lint warnings in Java
+files. However, while many lint checks analyzes the Java source code,
+where they can find annotations on (for example) local variables, some
+checks are analyzing the `.class` files. And in class files, annotations
+only appear on classes, fields and methods. Annotations placed on local
+variables disappear. If you attempt to suppress a lint error for a
+class-file based lint check, the suppress annotation not work. You must
+move the annotation out to the surrounding method.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/WrongAnnotation.java:10:Error: The @SuppressLint annotation
+cannot be used on a local variable with the lint check 'NewApi': move
+out to the surrounding method [LocalSuppress]
+ public static void foobar(View view, @SuppressLint("NewApi") int foo) { // $ Invalid: class-file check
+ -----------------------
+src/test/pkg/WrongAnnotation.java:11:Error: The @SuppressLint annotation
+cannot be used on a local variable with the lint check 'NewApi': move
+out to the surrounding method [LocalSuppress]
+ @SuppressLint("NewApi") // Invalid
+ -----------------------
+src/test/pkg/WrongAnnotation.java:13:Error: The @SuppressLint annotation
+cannot be used on a local variable with the lint check 'NewApi': move
+out to the surrounding method [LocalSuppress]
+ @SuppressLint({"SdCardPath", "NewApi"}) // Invalid: class-file based check on local variable
+ ---------------------------------------
+src/test/pkg/WrongAnnotation.java:15:Error: The @SuppressLint annotation
+cannot be used on a local variable with the lint check 'NewApi': move
+out to the surrounding method [LocalSuppress]
+ @android.annotation.SuppressLint({"SdCardPath", "NewApi"}) // Invalid (FQN)
+ ----------------------------------------------------------
+src/test/pkg/WrongAnnotation.java:29:Error: The @SuppressLint annotation
+cannot be used on a local variable with the lint check 'NewApi': move
+out to the surrounding method [LocalSuppress]
+ @SuppressLint("NewApi")
+ -----------------------
+src/test/pkg/WrongAnnotation.java:34:Error: The @SuppressLint annotation
+cannot be used on a local variable with the lint check 'NewApi': move
+out to the surrounding method [LocalSuppress]
+ @SuppressLint("NewApi") // Invalid
+ -----------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/WrongAnnotation.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+
+package test.pkg;
+
+import android.annotation.SuppressLint;
+import android.view.View;
+
+public class WrongAnnotation {
+
+ @SuppressLint("NewApi") // Valid: class-file check on method
+ public static void foobar(View view, @SuppressLint("NewApi") int foo) { // $ Invalid: class-file check
+ @SuppressLint("NewApi") // Invalid
+ boolean a;
+ @SuppressLint({"SdCardPath", "NewApi"}) // Invalid: class-file based check on local variable
+ boolean b;
+ @android.annotation.SuppressLint({"SdCardPath", "NewApi"}) // Invalid (FQN)
+ boolean c;
+ @SuppressLint("SdCardPath") // Valid: AST-based check
+ boolean d;
+ }
+
+ @SuppressLint("NewApi")
+ private int field1;
+
+ @SuppressLint("NewApi")
+ private int field2 = 5;
+
+ static {
+ // Local variable outside method: invalid
+ @SuppressLint("NewApi")
+ int localvar = 5;
+ }
+
+ private static void test() {
+ @SuppressLint("NewApi") // Invalid
+ int a = View.MEASURED_STATE_MASK;
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/AnnotationDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `AnnotationDetector.testBasic`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("LocalSuppress")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("LocalSuppress")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection LocalSuppress
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="LocalSuppress" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'LocalSuppress'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore LocalSuppress ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/LocaleFolder.md.html b/docs/checks/LocaleFolder.md.html
new file mode 100644
index 00000000..9d42a4b7
--- /dev/null
+++ b/docs/checks/LocaleFolder.md.html
@@ -0,0 +1,137 @@
+
+(#) Wrong locale name
+
+!!! WARNING: Wrong locale name
+ This is a warning.
+
+Id
+: `LocaleFolder`
+Summary
+: Wrong locale name
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource folders
+Editing
+: This check can *not* run live in the IDE editor
+See
+: https://developer.android.com/reference/java/util/Locale.html
+Implementation
+: [Source Code](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/LocaleFolderDetector.java)
+Tests
+: [Source Code](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/LocaleFolderDetectorTest.kt)
+Copyright Year
+: 2014
+
+From the `java.util.Locale` documentation:
+"Note that Java uses several deprecated two-letter codes. The Hebrew
+("he") language code is rewritten as "iw", Indonesian ("id") as "in",
+and Yiddish ("yi") as "ji". This rewriting happens even if you construct
+your own Locale object, not just for instances returned by the various
+lookup methods.
+
+Because of this, if you add your localized resources in for example
+`values-he` they will not be used, since the system will look for
+`values-iw` instead.
+
+To work around this, place your resources in a `values` folder using the
+deprecated language code instead.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/values-he/strings.xml:Warning: The locale folder "he" should be
+called "iw" instead; see the java.util.Locale documentation
+[LocaleFolder]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`res/values/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<resources>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values-no/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<resources>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values-he/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<resources>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values-id/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<resources>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values-yi/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<resources>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/LocaleFolderDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `LocaleFolderDetector.testDeprecated`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="LocaleFolder" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'LocaleFolder'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore LocaleFolder ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/LockedOrientationActivity.md.html b/docs/checks/LockedOrientationActivity.md.html
new file mode 100644
index 00000000..81111c30
--- /dev/null
+++ b/docs/checks/LockedOrientationActivity.md.html
@@ -0,0 +1,131 @@
+
+(#) Incompatible screenOrientation value
+
+!!! WARNING: Incompatible screenOrientation value
+ This is a warning.
+
+Id
+: `LockedOrientationActivity`
+Summary
+: Incompatible screenOrientation value
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 3.6.0 (February 2020)
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/topic/arc/window-management
+Implementation
+: [Source Code](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/ChromeOsDetector.java)
+Tests
+: [Source Code](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/ChromeOsDetectorTest.java)
+
+The `` element should not be locked to any orientation so that
+users can take advantage of the multi-window environments and larger
+screens available on Android. To fix the issue, consider declaring the
+corresponding activity element with `screenOrientation="unspecified"`or
+`fullSensor` attribute.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:5:Warning: Expecting
+android:screenOrientation="unspecified" or "fullSensor" for this
+activity so the user can use the application in any orientation and
+provide a great experience on Chrome OS devices
+[LockedOrientationActivity]
+ <activity android:name=".MainActivity" android:screenOrientation="portrait"/>
+ ------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools">
+ <application>
+ <activity android:name=".MainActivity" android:screenOrientation="portrait"/>
+ </application>
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ChromeOsDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ChromeOsDetector.testInvalidOrientationSetOnActivity`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute
+ `tools:ignore="LockedOrientationActivity"` on the problematic XML
+ element (or one of its enclosing elements). You may also need to add
+ the following namespace declaration on the root element in the XML
+ file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <uses-feature tools:ignore="LockedOrientationActivity" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="LockedOrientationActivity" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'LockedOrientationActivity'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore LockedOrientationActivity ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/LogConditional.md.html b/docs/checks/LogConditional.md.html
new file mode 100644
index 00000000..1a09b6e7
--- /dev/null
+++ b/docs/checks/LogConditional.md.html
@@ -0,0 +1,140 @@
+
+(#) Unconditional Logging Calls
+
+!!! WARNING: Unconditional Logging Calls
+ This is a warning.
+
+Id
+: `LogConditional`
+Summary
+: Unconditional Logging Calls
+Note
+: **This issue is disabled by default**; use `--enable LogConditional`
+Severity
+: Warning
+Category
+: Performance
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 1.1.0 (February 2015)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/LogDetector.kt)
+Tests
+: [Source Code](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/LogDetectorTest.kt)
+
+The `BuildConfig` class provides a constant, `DEBUG`, which indicates
+whether the code is being built in release mode or in debug mode. In
+release mode, you typically want to strip out all the logging calls.
+Since the compiler will automatically remove all code which is inside a
+`if (false)` check, surrounding your logging calls with a check for
+`BuildConfig.DEBUG` is a good idea.
+
+If you **really** intend for the logging to be present in release mode,
+you can suppress this warning with a `@SuppressLint` annotation for the
+intentional logging calls.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/LogExample.kt:7:Warning: The log call Log.i(...) should be
+conditional: surround with if (Log.isLoggable(...)) or if
+(BuildConfig.DEBUG) { ... } [LogConditional]
+ Log.i(TAG, "message" + m) // string is not constant; computed each time
+ -------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/LogExample.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+import android.util.Log
+
+const val TAG = "tag1"
+
+class LogExample {
+ fun test(m: String) {
+ Log.i(TAG, "message" + m) // string is not constant; computed each time
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/LogDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("LogConditional")
+ fun method() {
+ d(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("LogConditional")
+ void method() {
+ d(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection LogConditional
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="LogConditional" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'LogConditional'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore LogConditional ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/LogNotTimber.md.html b/docs/checks/LogNotTimber.md.html
new file mode 100644
index 00000000..3251ab3d
--- /dev/null
+++ b/docs/checks/LogNotTimber.md.html
@@ -0,0 +1,189 @@
+
+(#) Logging call to Log instead of Timber
+
+!!! WARNING: Logging call to Log instead of Timber
+ This is a warning.
+
+Id
+: `LogNotTimber`
+Summary
+: Logging call to Log instead of Timber
+Severity
+: Warning
+Category
+: Correctness: Messages
+Platform
+: Any
+Vendor
+: JakeWharton/timber
+Identifier
+: com.jakewharton.timber:timber:{version}
+Feedback
+: https://github.com/JakeWharton/timber/issues
+Min
+: Lint 4.0
+Compiled
+: Lint 7.0
+Artifact
+: [com.jakewharton.timber:timber](com_jakewharton_timber_timber.md.html)
+Since
+: 4.6.0
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/JakeWharton/timber/tree/trunk/timber-lint/src/main/java/timber/lint/WrongTimberUsageDetector.kt)
+Tests
+: [Source Code](https://github.com/JakeWharton/timber/tree/trunk/timber-lint/src/test/java/timber/lint/WrongTimberUsageDetectorTest.kt)
+
+Since Timber is included in the project, it is likely that calls to Log
+should instead be going to Timber.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/foo/Example.java:5:Warning: Using 'Log' instead of 'Timber'
+[LogNotTimber]
+ Log.d("TAG", "msg");
+ -------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/foo/Example.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package foo;
+import android.util.Log;
+public class Example {
+ public void log() {
+ Log.d("TAG", "msg");
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/foo/Example.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package foo
+import android.util.Log
+class Example {
+ fun log() {
+ Log.d("TAG", "msg")
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/JakeWharton/timber/tree/trunk/timber-lint/src/test/java/timber/lint/WrongTimberUsageDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `WrongTimberUsageDetector.usingAndroidLogWithTwoArguments`.
+To report a problem with this extracted sample, visit
+https://github.com/JakeWharton/timber/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+implementation("com.jakewharton.timber:timber:5.0.1")
+
+// build.gradle
+implementation 'com.jakewharton.timber:timber:5.0.1'
+
+// build.gradle.kts with version catalogs:
+implementation(libs.timber)
+
+# libs.versions.toml
+[versions]
+timber = "5.0.1"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+timber = {
+ module = "com.jakewharton.timber:timber",
+ version.ref = "timber"
+}
+```
+
+5.0.1 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.jakewharton.timber:timber](com_jakewharton_timber_timber.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("LogNotTimber")
+ fun method() {
+ tag(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("LogNotTimber")
+ void method() {
+ tag(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection LogNotTimber
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="LogNotTimber" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'LogNotTimber'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore LogNotTimber ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/LogTagMismatch.md.html b/docs/checks/LogTagMismatch.md.html
new file mode 100644
index 00000000..333d0829
--- /dev/null
+++ b/docs/checks/LogTagMismatch.md.html
@@ -0,0 +1,136 @@
+
+(#) Mismatched Log Tags
+
+!!! ERROR: Mismatched Log Tags
+ This is an error.
+
+Id
+: `LogTagMismatch`
+Summary
+: Mismatched Log Tags
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 1.1.0 (February 2015)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/LogDetector.kt)
+Tests
+: [Source Code](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/LogDetectorTest.kt)
+
+When guarding a `Log.v(tag, ...)` call with `Log.isLoggable(tag)`, the
+tag passed to both calls should be the same. Similarly, the level passed
+in to `Log.isLoggable` should typically match the type of `Log` call,
+e.g. if checking level `Log.DEBUG`, the corresponding `Log` call should
+be `Log.d`, not `Log.i`.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/LogExample.kt:9:Error: Mismatched tags: the d() and isLoggable()
+calls typically should pass the same tag: TAG1 versus TAG2
+[LogTagMismatch]
+ Log.d(TAG2, "message") // warn: mismatched tags - TAG1 and TAG2
+ ----
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/LogExample.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+import android.util.Log
+
+const val TAG1 = "tag1"
+const val TAG2 = "tag1"
+
+class LogExample {
+ fun test() {
+ if (Log.isLoggable(TAG1, Log.DEBUG)) {
+ Log.d(TAG2, "message") // warn: mismatched tags - TAG1 and TAG2
+ }
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/LogDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("LogTagMismatch")
+ fun method() {
+ d(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("LogTagMismatch")
+ void method() {
+ d(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection LogTagMismatch
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="LogTagMismatch" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'LogTagMismatch'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore LogTagMismatch ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/LongLogTag.md.html b/docs/checks/LongLogTag.md.html
new file mode 100644
index 00000000..cef6216d
--- /dev/null
+++ b/docs/checks/LongLogTag.md.html
@@ -0,0 +1,131 @@
+
+(#) Too Long Log Tags
+
+!!! ERROR: Too Long Log Tags
+ This is an error.
+
+Id
+: `LongLogTag`
+Summary
+: Too Long Log Tags
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 1.1.0 (February 2015)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/LogDetector.kt)
+Tests
+: [Source Code](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/LogDetectorTest.kt)
+
+Log tags are only allowed to be at most 23 tag characters long.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/pkg1/pkg2/pkg3/pkg4/pkg5/LogExampleInLongClassName.kt:9:Error: The
+logging tag can be at most 23 characters, was 35
+(SuperSuperLongLogTagWhichExceedsMax) [LongLogTag]
+ Log.d(TAG, "message")
+ ---
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/pkg1/pkg2/pkg3/pkg4/pkg5/LogExampleInLongClassName.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package pkg1.pkg2.pkg3.pkg4.pkg5
+
+import android.util.Log
+
+const val TAG = "SuperSuperLongLogTagWhichExceedsMax"
+
+class LogExampleInLongClassName {
+ fun test() {
+ Log.d(TAG, "message")
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/LogDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("LongLogTag")
+ fun method() {
+ d(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("LongLogTag")
+ void method() {
+ d(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection LongLogTag
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="LongLogTag" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'LongLogTag'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore LongLogTag ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/MainScopeUsage.md.html b/docs/checks/MainScopeUsage.md.html
new file mode 100644
index 00000000..8b04087c
--- /dev/null
+++ b/docs/checks/MainScopeUsage.md.html
@@ -0,0 +1,182 @@
+
+(#) Use slack.foundation.coroutines.android.MainScope
+
+!!! ERROR: Use slack.foundation.coroutines.android.MainScope
+ This is an error.
+
+Id
+: `MainScopeUsage`
+Summary
+: Use slack.foundation.coroutines.android.MainScope
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: slack
+Identifier
+: slack-lint
+Contact
+: https://github.com/slackhq/slack-lints
+Feedback
+: https://github.com/slackhq/slack-lints
+Min
+: Lint 8.7+
+Compiled
+: Lint 8.7+
+Artifact
+: [com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html)
+Since
+: 0.1.0
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/main/java/slack/lint/MainScopeUsageDetector.kt)
+Tests
+: [Source Code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/MainScopeUsageDetectorTest.kt)
+Copyright Year
+: 2021
+
+Prefer using Slack's internal `MainScope` function, which supports
+`SlackDispatchers` and uses Dispatchers.Main.immediate under the hood.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/test/pkg/test.kt:6:Error: Use
+slack.foundation.coroutines.android.MainScope. [MainScopeUsage]
+ val scope = MainScope()
+ -----------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`src/test/pkg/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package test.pkg
+
+import kotlinx.coroutines.MainScope
+
+fun example() {
+ val scope = MainScope()
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/slackhq/slack-lints/tree/main/slack-lint-checks/src/test/java/slack/lint/MainScopeUsageDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `MainScopeUsageDetector.simple`.
+To report a problem with this extracted sample, visit
+https://github.com/slackhq/slack-lints.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.slack.lint:slack-lint-checks:0.9.0")
+
+// build.gradle
+lintChecks 'com.slack.lint:slack-lint-checks:0.9.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.slack.lint.checks)
+
+# libs.versions.toml
+[versions]
+slack-lint-checks = "0.9.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+slack-lint-checks = {
+ module = "com.slack.lint:slack-lint-checks",
+ version.ref = "slack-lint-checks"
+}
+```
+
+0.9.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.slack.lint:slack-lint-checks](com_slack_lint_slack-lint-checks.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("MainScopeUsage")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("MainScopeUsage")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection MainScopeUsage
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="MainScopeUsage" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'MainScopeUsage'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore MainScopeUsage ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/MangledCRLF.md.html b/docs/checks/MangledCRLF.md.html
new file mode 100644
index 00000000..ce6cd6ac
--- /dev/null
+++ b/docs/checks/MangledCRLF.md.html
@@ -0,0 +1,112 @@
+
+(#) Mangled file line endings
+
+!!! ERROR: Mangled file line endings
+ This is an error.
+
+Id
+: `MangledCRLF`
+Summary
+: Mangled file line endings
+Note
+: **This issue is disabled by default**; use `--enable MangledCRLF`
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://bugs.eclipse.org/bugs/show_bug.cgi?id=375421
+Implementation
+: [Source Code](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/DosLineEndingDetector.kt)
+Tests
+: [Source Code](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/DosLineEndingDetectorTest.kt)
+Copyright Year
+: 2012
+
+On Windows, line endings are typically recorded as carriage return plus
+newline: \\r\\n.
+
+This detector looks for invalid line endings with repeated carriage
+return characters (without newlines). Previous versions of the ADT
+plugin could accidentally introduce these into the file, and when
+editing the file, the editor could produce confusing visual artifacts.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/crcrlf.xml:4:Error: Incorrect line ending: found carriage
+return (\r) without corresponding newline (\n) [MangledCRLF]
+ android:layout_height="match_parent" >
+^
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+[res/layout/crcrlf.xml](examples/layout/crcrlf.xml)
+
+You can also visit the
+[source code](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/DosLineEndingDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `DosLineEndingDetector.test`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="MangledCRLF"` on the
+ problematic XML element (or one of its enclosing elements). You may
+ also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="MangledCRLF" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'MangledCRLF'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore MangledCRLF ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ManifestOrder.md.html b/docs/checks/ManifestOrder.md.html
new file mode 100644
index 00000000..6198da3e
--- /dev/null
+++ b/docs/checks/ManifestOrder.md.html
@@ -0,0 +1,169 @@
+
+(#) Incorrect order of elements in manifest
+
+!!! WARNING: Incorrect order of elements in manifest
+ This is a warning.
+
+Id
+: `ManifestOrder`
+Summary
+: Incorrect order of elements in manifest
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/ManifestDetector.kt)
+Tests
+: [Source Code](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/ManifestDetectorTest.kt)
+Copyright Year
+: 2011
+
+The `` tag should appear after the elements which declare
+which version you need, which features you need, which libraries you
+need, and so on. In the past there have been subtle bugs (such as themes
+not getting applied correctly) when the `` tag appears
+before some of these other elements, so it's best to order your manifest
+in the logical dependency order.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:15:Warning: tag appears after
+ tag [ManifestOrder]
+ <uses-sdk android:minSdkVersion="Froyo" />
+ --------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.helloworld"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <application android:icon="@drawable/icon" android:label="@string/app_name">
+ <activity android:name=".HelloWorld"
+ android:label="@string/app_name">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+ <uses-sdk android:minSdkVersion="Froyo" />
+
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <!-- Home -->
+ <string name="home_title">Home Sample</string>
+ <string name="show_all_apps">All</string>
+
+ <!-- Home Menus -->
+ <string name="menu_wallpaper">Wallpaper</string>
+ <string name="menu_search">Search</string>
+ <string name="menu_settings">Settings</string>
+ <string name="sample" translatable="false">Ignore Me</string>
+
+ <!-- Wallpaper -->
+ <string name="wallpaper_instructions">Tap picture to set portrait wallpaper</string>
+</resources>
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ManifestDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ManifestDetector.testBrokenOrder`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="ManifestOrder"` on
+ the problematic XML element (or one of its enclosing elements). You
+ may also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <application tools:ignore="ManifestOrder" .../>
+ ...
+ </manifest>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ManifestOrder" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ManifestOrder'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ManifestOrder ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ManifestResource.md.html b/docs/checks/ManifestResource.md.html
new file mode 100644
index 00000000..511ecd33
--- /dev/null
+++ b/docs/checks/ManifestResource.md.html
@@ -0,0 +1,174 @@
+
+(#) Manifest Resource References
+
+!!! ERROR: Manifest Resource References
+ This is an error, and is also enforced at build time when
+ supported by the build system. For Android this means it will
+ run during release builds.
+
+Id
+: `ManifestResource`
+Summary
+: Manifest Resource References
+Severity
+: Fatal
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 1.5.0 (November 2015)
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/ManifestResourceDetector.java)
+Tests
+: [Source Code](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/ManifestResourceDetectorTest.kt)
+
+Elements in the manifest can reference resources, but those resources
+cannot vary across configurations (except as a special case, by version,
+and except for a few specific package attributes such as the application
+title and icon).
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:6:Error: Resources referenced from the manifest
+cannot vary by configuration (except for version qualifiers, e.g. -v21).
+Found variation in mcc [ManifestResource]
+ <application android:fullBackupContent="@xml/backup">
+ -----------
+AndroidManifest.xml:8:Error: Resources referenced from the manifest
+cannot vary by configuration (except for version qualifiers, e.g. -v21).
+Found variation in en-rUS [ManifestResource]
+ android:process="@string/location_process"
+ ------------------------
+AndroidManifest.xml:9:Error: Resources referenced from the manifest
+cannot vary by configuration (except for version qualifiers, e.g. -v21).
+Found variation in watch-v20 [ManifestResource]
+ android:enabled="@bool/enable_wearable_location_service">
+ --------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="test.pkg">
+ <uses-sdk android:minSdkVersion="14" />
+
+ <application android:fullBackupContent="@xml/backup">
+ <service
+ android:process="@string/location_process"
+ android:enabled="@bool/enable_wearable_location_service">
+ </service> </application>
+
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values/values.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<resources>
+ <string name="location_process">Location Process</string>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values/bools.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <bool name="enable_wearable_location_service">true</bool>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values-en-rUS/values.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<resources>
+ <string name="location_process">Location Process (English)</string>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values-watch/bools.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <bool name="enable_wearable_location_service">false</bool>
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/xml/backup.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<full-backup-content>
+ <include domain="file" path="dd"/>
+ <exclude domain="file" path="dd/fo3o.txt"/>
+ <exclude domain="file" path="dd/ss/foo.txt"/>
+</full-backup-content>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/xml-mcc/backup.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<full-backup-content>
+ <include domain="file" path="mcc"/>
+</full-backup-content>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ManifestResourceDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ManifestResourceDetector.testInvalidManifestReference`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="ManifestResource"`
+ on the problematic XML element (or one of its enclosing elements).
+ You may also need to add the following namespace declaration on the
+ root element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ManifestResource" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ManifestResource'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ManifestResource ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/ManifestTypo.md.html b/docs/checks/ManifestTypo.md.html
new file mode 100644
index 00000000..ccb7e5b8
--- /dev/null
+++ b/docs/checks/ManifestTypo.md.html
@@ -0,0 +1,170 @@
+
+(#) Typos in manifest tags
+
+!!! ERROR: Typos in manifest tags
+ This is an error, and is also enforced at build time when
+ supported by the build system. For Android this means it will
+ run during release builds.
+
+Id
+: `ManifestTypo`
+Summary
+: Typos in manifest tags
+Severity
+: Fatal
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Manifest files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/ManifestTypoDetector.java)
+Tests
+: [Source Code](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/ManifestTypoDetectorTest.java)
+Copyright Year
+: 2013
+
+This check looks through the manifest, and if it finds any tags that
+look like likely misspellings, they are flagged.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+AndroidManifest.xml:7:Error: Misspelled tag : Did you mean
+? [ManifestTypo]
+ <use-sdk android:minSdkVersion="14" />
+ --------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`AndroidManifest.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="foo.bar2"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <use-sdk android:minSdkVersion="14" />
+
+ <uses-permission android:name="com.example.helloworld.permission" />
+
+ <uses-feature android:name="android.hardware.wifi" />
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name" >
+ <uses-library android:name="com.example.helloworld" />
+ <activity
+ android:label="@string/app_name"
+ android:name=".Foo2Activity" >
+ <intent-filter >
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`res/values/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <!-- Home -->
+ <string name="home_title">Home Sample</string>
+ <string name="show_all_apps">All</string>
+
+ <!-- Home Menus -->
+ <string name="menu_wallpaper">Wallpaper</string>
+ <string name="menu_search">Search</string>
+ <string name="menu_settings">Settings</string>
+ <string name="sample" translatable="false">Ignore Me</string>
+
+ <!-- Wallpaper -->
+ <string name="wallpaper_instructions">Tap picture to set portrait wallpaper</string>
+</resources>
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/ManifestTypoDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `ManifestTypoDetector.testTypoUsesSdk`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="ManifestTypo"` on
+ the problematic XML element (or one of its enclosing elements). You
+ may also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="ManifestTypo" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'ManifestTypo'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore ManifestTypo ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/MatchingMenuId.md.html b/docs/checks/MatchingMenuId.md.html
new file mode 100644
index 00000000..b8297f04
--- /dev/null
+++ b/docs/checks/MatchingMenuId.md.html
@@ -0,0 +1,151 @@
+
+(#) Flags menu ids that don't match with the file name
+
+!!! WARNING: Flags menu ids that don't match with the file name
+ This is a warning.
+
+Id
+: `MatchingMenuId`
+Summary
+: Flags menu ids that don't match with the file name
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: vanniktech/lint-rules/
+Feedback
+: https://github.com/vanniktech/lint-rules/issues
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [com.vanniktech:lint-rules-android](com_vanniktech_lint-rules-android.md.html)
+Since
+: 0.6.0
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/main/kotlin/com/vanniktech/lintrules/android/MatchingMenuIdDetector.kt)
+Tests
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/test/kotlin/com/vanniktech/lintrules/android/MatchingMenuIdDetectorTest.kt)
+
+When the layout file is named menu_home all of the containing ids should
+be prefixed with menuHome to avoid ambiguity between different menu
+files across different menu items.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/menu/menu_main.xml:2:Warning: Id should start with: menuMain
+[MatchingMenuId]
+ <item android:id="@+id/something"/>
+ --------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/menu/menu_main.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/something"/>
+</menu>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/test/kotlin/com/vanniktech/lintrules/android/MatchingMenuIdDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `MatchingMenuIdDetector.idWithoutPrefix`.
+To report a problem with this extracted sample, visit
+https://github.com/vanniktech/lint-rules/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.vanniktech:lint-rules-android:0.25.0")
+
+// build.gradle
+lintChecks 'com.vanniktech:lint-rules-android:0.25.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.lint.rules.android)
+
+# libs.versions.toml
+[versions]
+lint-rules-android = "0.25.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+lint-rules-android = {
+ module = "com.vanniktech:lint-rules-android",
+ version.ref = "lint-rules-android"
+}
+```
+
+0.25.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.vanniktech:lint-rules-android](com_vanniktech_lint-rules-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="MatchingMenuId"` on
+ the problematic XML element (or one of its enclosing elements). You
+ may also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="MatchingMenuId" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'MatchingMenuId'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore MatchingMenuId ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/MatchingViewId.md.html b/docs/checks/MatchingViewId.md.html
new file mode 100644
index 00000000..dc177b76
--- /dev/null
+++ b/docs/checks/MatchingViewId.md.html
@@ -0,0 +1,149 @@
+
+(#) Flags view ids that don't match with the file name
+
+!!! WARNING: Flags view ids that don't match with the file name
+ This is a warning.
+
+Id
+: `MatchingViewId`
+Summary
+: Flags view ids that don't match with the file name
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Android
+Vendor
+: vanniktech/lint-rules/
+Feedback
+: https://github.com/vanniktech/lint-rules/issues
+Min
+: Lint 8.0 and 8.1
+Compiled
+: Lint 8.0 and 8.1
+Artifact
+: [com.vanniktech:lint-rules-android](com_vanniktech_lint-rules-android.md.html)
+Since
+: 0.6.0
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/main/kotlin/com/vanniktech/lintrules/android/MatchingViewIdDetector.kt)
+Tests
+: [Source Code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/test/kotlin/com/vanniktech/lintrules/android/MatchingViewIdDetectorTest.kt)
+
+When the layout file is named activity_home all of the containing ids
+should be prefixed with activityHome to avoid ambiguity between
+different layout files across different views.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/activity_main.xml:1:Warning: Id should start with:
+activityMain [MatchingViewId]
+<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/text"/>
+ ---------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/layout/activity_main.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/text"/>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](https://github.com/vanniktech/lint-rules/tree/master/lint-rules-android-lint/src/test/kotlin/com/vanniktech/lintrules/android/MatchingViewIdDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `MatchingViewIdDetector.idWithoutPrefix`.
+To report a problem with this extracted sample, visit
+https://github.com/vanniktech/lint-rules/issues.
+
+(##) Including
+
+!!!
+ This is not a built-in check. To include it, add the below dependency
+ to your project. This lint check is included in the lint documentation,
+ but the Android team may or may not agree with its recommendations.
+
+```
+// build.gradle.kts
+lintChecks("com.vanniktech:lint-rules-android:0.25.0")
+
+// build.gradle
+lintChecks 'com.vanniktech:lint-rules-android:0.25.0'
+
+// build.gradle.kts with version catalogs:
+lintChecks(libs.lint.rules.android)
+
+# libs.versions.toml
+[versions]
+lint-rules-android = "0.25.0"
+[libraries]
+# For clarity and text wrapping purposes the following declaration is
+# shown split up across lines, but in TOML it needs to be on a single
+# line (see https://github.com/toml-lang/toml/issues/516) so adjust
+# when pasting into libs.versions.toml:
+lint-rules-android = {
+ module = "com.vanniktech:lint-rules-android",
+ version.ref = "lint-rules-android"
+}
+```
+
+0.25.0 is the version this documentation was generated from;
+there may be newer versions available.
+
+[Additional details about com.vanniktech:lint-rules-android](com_vanniktech_lint-rules-android.md.html).
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="MatchingViewId"` on
+ the problematic XML element (or one of its enclosing elements). You
+ may also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="MatchingViewId" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'MatchingViewId'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore MatchingViewId ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/MediaCapabilities.md.html b/docs/checks/MediaCapabilities.md.html
new file mode 100644
index 00000000..c8bba4bd
--- /dev/null
+++ b/docs/checks/MediaCapabilities.md.html
@@ -0,0 +1,8 @@
+
+(#) MediaCapabilities
+
+The issue for this id has been deleted or marked obsolete and can now be
+ignored.
+
+(Additional metadata not available.)
+
\ No newline at end of file
diff --git a/docs/checks/MemberExtensionConflict.md.html b/docs/checks/MemberExtensionConflict.md.html
new file mode 100644
index 00000000..d140606c
--- /dev/null
+++ b/docs/checks/MemberExtensionConflict.md.html
@@ -0,0 +1,175 @@
+
+(#) Conflict applicable candidates of member and extension
+
+!!! WARNING: Conflict applicable candidates of member and extension
+ This is a warning.
+
+Id
+: `MemberExtensionConflict`
+Summary
+: Conflict applicable candidates of member and extension
+Note
+: **This issue is disabled by default**; use `--enable MemberExtensionConflict`
+Severity
+: Warning
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 8.11.0-alpha03 (March 2025)
+Affects
+: Kotlin and Java files
+Editing
+: This check runs on the fly in the IDE editor
+Implementation
+: [Source Code](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/MemberExtensionConflictDetector.kt)
+Tests
+: [Source Code](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/MemberExtensionConflictDetectorTest.kt)
+
+When both member and extension declarations are applicable, the
+resolution takes the member. This also implies that, if an extension
+existed first, but then a member is added later, the same call-site may
+end up with different call resolutions depending on target environment.
+This results in a potential runtime exception if the generated binary
+(library or app) targets earlier environment (i.e., without the new
+member, but only extension). More concrete example is found at:
+https://issuetracker.google.com/issues/350432371
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+src/ListWrapper.kt:10:Warning: `magicCount` is defined both as a member
+in class `ListWrapper` and an extension in package `users.own`. The
+defined behavior for this is to use the member, but since the extension
+is explicitly imported into this file, there's a chance that this was
+not expected. (One common way this happens is for members to be added to
+a class after code was already written to use an extension).
+[MemberExtensionConflict]
+ val x = l.magicCount // WARNING 1
+ ----------
+src/ListWrapper.kt:11:Warning: `removeMiddle` is defined both as a
+member in class `ListWrapper` and an extension in package `users.own`.
+The defined behavior for this is to use the member, but since the
+extension is explicitly imported into this file, there's a chance that
+this was not expected. (One common way this happens is for members to be
+added to a class after code was already written to use an extension).
+[MemberExtensionConflict]
+ l.removeMiddle() // WARNING 2
+ ----------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`src/my/cool/lib/MyList.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package my.cool.lib
+interface MyList {
+ val magicCount: Int
+ fun removeMiddle()
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/users/own/test.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+package users.own
+
+import my.cool.lib.MyList
+
+val MyList.magicCount: Int
+ get() = 42
+
+fun MyList.removeMiddle() {}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/ListWrapper.kt`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin linenumbers
+import my.cool.lib.MyList
+import users.own.magicCount
+import users.own.removeMiddle
+
+class ListWrapper(
+ private val base: MyList
+) : MyList by base
+
+fun test(l : ListWrapper) {
+ val x = l.magicCount // WARNING 1
+ l.removeMiddle() // WARNING 2
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/MemberExtensionConflictDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("MemberExtensionConflict")
+ fun method() {
+ problematicStatement()
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("MemberExtensionConflict")
+ void method() {
+ problematicStatement();
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection MemberExtensionConflict
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="MemberExtensionConflict" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'MemberExtensionConflict'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore MemberExtensionConflict ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/MenuTitle.md.html b/docs/checks/MenuTitle.md.html
new file mode 100644
index 00000000..6a3d8458
--- /dev/null
+++ b/docs/checks/MenuTitle.md.html
@@ -0,0 +1,148 @@
+
+(#) Missing menu title
+
+!!! ERROR: Missing menu title
+ This is an error.
+
+Id
+: `MenuTitle`
+Summary
+: Missing menu title
+Severity
+: Error
+Category
+: Usability
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Resource files
+Editing
+: This check runs on the fly in the IDE editor
+See
+: https://developer.android.com/training/appbar
+Implementation
+: [Source Code](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/TitleDetector.java)
+Tests
+: [Source Code](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/TitleDetectorTest.java)
+Copyright Year
+: 2012
+
+From the action bar documentation:
+"It's important that you always define android:title for each menu item
+— even if you don't declare that the title appear with the action item —
+for three reasons:
+
+* If there's not enough room in the action bar for the action item, the
+ menu item appears in the overflow menu and only the title appears.
+* Screen readers for sight-impaired users read the menu item's title.
+* If the action item appears with only the icon, a user can long-press
+ the item to reveal a tool-tip that displays the action item's
+ title.
+
+The android:icon is always optional, but recommended.
+
+!!! Tip
+ This lint check has an associated quickfix available in the IDE.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/menu/titles.xml:3:Error: Menu items should specify a title
+[MenuTitle]
+ <item android:id="@+id/action_bar_progress_spinner"
+ ----
+res/menu/titles.xml:12:Error: Menu items should specify a title
+[MenuTitle]
+ <item android:id="@+id/menu_plus_one"
+ ----
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/menu/titles.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/action_bar_progress_spinner"
+ android:showAsAction="always"
+ android:background="@null"
+ android:selectableItemBackground="@null"
+ android:actionLayout="@layout/action_bar_progress_spinner_layout"/>
+ <item android:id="@+id/refresh"
+ android:title="@string/menu_refresh"
+ android:showAsAction="always"
+ android:icon="@drawable/ic_menu_refresh"/>
+ <item android:id="@+id/menu_plus_one"
+ android:showAsAction="always"
+ android:icon="@drawable/ic_menu_plus1"/>
+</menu>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/TitleDetectorTest.java)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `TitleDetector.testBasic`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Adding the suppression attribute `tools:ignore="MenuTitle"` on the
+ problematic XML element (or one of its enclosing elements). You may
+ also need to add the following namespace declaration on the root
+ element in the XML file if it's not already there:
+ `xmlns:tools="http://schemas.android.com/tools"`.
+
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <item xmlns:tools="http://schemas.android.com/tools"
+ tools:ignore="MenuTitle" ...>
+ ...
+ </item>
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="MenuTitle" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'MenuTitle'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore MenuTitle ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/MergeMarker.md.html b/docs/checks/MergeMarker.md.html
new file mode 100644
index 00000000..1191ad0b
--- /dev/null
+++ b/docs/checks/MergeMarker.md.html
@@ -0,0 +1,114 @@
+
+(#) Code contains merge marker
+
+!!! ERROR: Code contains merge marker
+ This is an error.
+
+Id
+: `MergeMarker`
+Summary
+: Code contains merge marker
+Severity
+: Error
+Category
+: Correctness
+Platform
+: Any
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: 2.3.0 (March 2017)
+Editing
+: This check can *not* run live in the IDE editor
+Implementation
+: [Source Code](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/MergeMarkerDetector.java)
+Tests
+: [Source Code](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/MergeMarkerDetectorTest.kt)
+
+Many version control systems leave unmerged files with markers such as
+<<< in the source code. This check looks for these markers, which are
+sometimes accidentally left in, particularly in resource files where
+they don't break compilation.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/values/strings.xml:5:Error: Missing merge marker? [MergeMarker]
+<<<<<<< HEAD
+-------
+res/values/strings.xml:7:Error: Missing merge marker? [MergeMarker]
+=======
+-------
+res/values/strings.xml:9:Error: Missing merge marker? [MergeMarker]
+>>>>>>> branch-a
+-------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is the source file referenced above:
+
+`res/values/strings.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <string name="app_name">LibraryProject</string>
+<<<<<<< HEAD
+ <string name="string1">String 1</string>
+=======
+ <string name="string2">String 2</string>
+>>>>>>> branch-a
+ <string name="string3">String 3</string>
+
+</resources>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/MergeMarkerDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `MergeMarkerDetector.testMergeMarker`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="MergeMarker" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'MergeMarker'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore MergeMarker ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/MergeRootFrame.md.html b/docs/checks/MergeRootFrame.md.html
new file mode 100644
index 00000000..a06459ec
--- /dev/null
+++ b/docs/checks/MergeRootFrame.md.html
@@ -0,0 +1,151 @@
+
+(#) FrameLayout can be replaced with `` tag
+
+!!! WARNING: FrameLayout can be replaced with `` tag
+ This is a warning.
+
+Id
+: `MergeRootFrame`
+Summary
+: FrameLayout can be replaced with `` tag
+Severity
+: Warning
+Category
+: Performance
+Platform
+: Android
+Vendor
+: Android Open Source Project
+Feedback
+: https://issuetracker.google.com/issues/new?component=192708
+Since
+: Initial
+Affects
+: Kotlin and Java files and resource files
+Editing
+: This check can *not* run live in the IDE editor
+See
+: https://android-developers.googleblog.com/2009/03/android-layout-tricks-3-optimize-by.html
+Implementation
+: [Source Code](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/MergeRootFrameLayoutDetector.kt)
+Tests
+: [Source Code](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/MergeRootFrameLayoutDetectorTest.kt)
+Copyright Year
+: 2011
+
+If a `` is the root of a layout and does not provide
+background or padding etc, it can often be replaced with a `` tag
+which is slightly more efficient. Note that this depends on context, so
+make sure you understand how the `` tag works before proceeding.
+
+(##) Example
+
+Here is an example of lint warnings produced by this check:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
+res/layout/simple.xml:1:Warning: This can be replaced with
+a tag [MergeRootFrame]
+<FrameLayout
+^
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are the relevant source files:
+
+`res/layout/simple.xml`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~xml linenumbers
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`src/test/pkg/ImportFrameActivity.java`:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
+package test.pkg;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class ImportFrameActivity extends Activity {
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.simple);
+ }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also visit the
+[source code](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/MergeRootFrameLayoutDetectorTest.kt)
+for the unit tests for this check to see additional scenarios.
+
+The above example was automatically extracted from the first unit test
+found for this lint check, `MergeRootFrameLayoutDetector.testMergeRefFromJava`.
+To report a problem with this extracted sample, visit
+https://issuetracker.google.com/issues/new?component=192708.
+
+(##) Suppressing
+
+You can suppress false positives using one of the following mechanisms:
+
+* Using a suppression annotation like this on the enclosing
+ element:
+
+ ```kt
+ // Kotlin
+ @Suppress("MergeRootFrame")
+ fun method() {
+ setContentView(...)
+ }
+ ```
+
+ or
+
+ ```java
+ // Java
+ @SuppressWarnings("MergeRootFrame")
+ void method() {
+ setContentView(...);
+ }
+ ```
+
+* Using a suppression comment like this on the line above:
+
+ ```kt
+ //noinspection MergeRootFrame
+ problematicStatement()
+ ```
+
+* Using a special `lint.xml` file in the source tree which turns off
+ the check in that folder and any sub folder. A simple file might look
+ like this:
+ ```xml
+ <?xml version="1.0" encoding="UTF-8"?>
+ <lint>
+ <issue id="MergeRootFrame" severity="ignore" />
+ </lint>
+ ```
+ Instead of `ignore` you can also change the severity here, for
+ example from `error` to `warning`. You can find additional
+ documentation on how to filter issues by path, regular expression and
+ so on
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html).
+
+* In Gradle projects, using the DSL syntax to configure lint. For
+ example, you can use something like
+ ```gradle
+ lintOptions {
+ disable 'MergeRootFrame'
+ }
+ ```
+ In Android projects this should be nested inside an `android { }`
+ block.
+
+* For manual invocations of `lint`, using the `--ignore` flag:
+ ```
+ $ lint --ignore MergeRootFrame ...`
+ ```
+
+* Last, but not least, using baselines, as discussed
+ [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).
+
+
\ No newline at end of file
diff --git a/docs/checks/MinSdkTooLow.md.html b/docs/checks/MinSdkTooLow.md.html
new file mode 100644
index 00000000..b2934a13
--- /dev/null
+++ b/docs/checks/MinSdkTooLow.md.html
@@ -0,0 +1,147 @@
+