diff --git a/pkgs/lints/.github/ISSUE_TEMPLATE/config.yml b/pkgs/lints/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..040ffa6b --- /dev/null +++ b/pkgs/lints/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,9 @@ +blank_issues_enabled: true +contact_links: + - name: Propose a new lint + url: https://github.com/dart-lang/linter/issues/new?assignees=&labels=enhancement%2C+lint+request&template=lint-request.md&title= + about: Request a new lint rule. + - name: Report an issue with a lint + url: https://github.com/dart-lang/linter/issues/new?assignees=&labels=&template=issue-report.md&title= + about: Create an issue report for an existing lint. + diff --git a/pkgs/lints/.github/ISSUE_TEMPLATE/lint-propoposal.md b/pkgs/lints/.github/ISSUE_TEMPLATE/lint-propoposal.md new file mode 100644 index 00000000..25571ac0 --- /dev/null +++ b/pkgs/lints/.github/ISSUE_TEMPLATE/lint-propoposal.md @@ -0,0 +1,14 @@ +--- +name: Add an existing lint to the `core` or `recommended` rule set +about: Propose adding an existing lint rule to the `core` or `recommended` rule set. +title: '' +labels: type-lint +assignees: '' + +--- + +**Describe the rule you'd like to see added and to what rule set** +Include as much detail as you can. + +**Additional context** +Add any other considerations or context here. diff --git a/pkgs/lints/.github/dependabot.yaml b/pkgs/lints/.github/dependabot.yaml new file mode 100644 index 00000000..439e796b --- /dev/null +++ b/pkgs/lints/.github/dependabot.yaml @@ -0,0 +1,10 @@ +# Dependabot configuration file. +version: 2 + +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: monthly + labels: + - autosubmit diff --git a/pkgs/lints/.github/workflows/publish.yaml b/pkgs/lints/.github/workflows/publish.yaml new file mode 100644 index 00000000..f4163209 --- /dev/null +++ b/pkgs/lints/.github/workflows/publish.yaml @@ -0,0 +1,14 @@ +# A CI configuration to auto-publish pub packages. + +name: Publish + +on: + pull_request: + branches: [ main ] + push: + tags: [ 'v[0-9]+.[0-9]+.[0-9]+*' ] + +jobs: + publish: + if: ${{ github.repository_owner == 'dart-lang' }} + uses: dart-lang/ecosystem/.github/workflows/publish.yaml@main diff --git a/pkgs/lints/.github/workflows/validate.yml b/pkgs/lints/.github/workflows/validate.yml new file mode 100644 index 00000000..bb82fbc4 --- /dev/null +++ b/pkgs/lints/.github/workflows/validate.yml @@ -0,0 +1,32 @@ +name: validate + +# Controls when the action will run. +on: + # Triggers the workflow on push or pull request events but only for the main branch + push: + branches: [ main ] + pull_request: + branches: [ main ] + # Run weekly + schedule: + - cron: "0 0 * * 0" + +jobs: + build: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + sdk: [beta] # todo: re-add stable + + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + - uses: dart-lang/setup-dart@e630b99d28a3b71860378cafdc2a067c71107f94 + with: + sdk: ${{ matrix.sdk }} + + - run: dart pub get + - run: dart format --output=none --set-exit-if-changed . + - run: dart analyze --fatal-infos + - run: dart tool/validate_lib.dart + - run: dart tool/gen_docs.dart --verify diff --git a/pkgs/lints/.gitignore b/pkgs/lints/.gitignore new file mode 100644 index 00000000..ec2434a7 --- /dev/null +++ b/pkgs/lints/.gitignore @@ -0,0 +1,10 @@ +# Files and directories created by pub +.dart_tool/ +.packages + +# Omit commiting pubspec.lock for library packages: +# https://dart.dev/guides/libraries/private-files#pubspeclock +pubspec.lock + +# Directory created by dartdoc +doc/api/ diff --git a/pkgs/lints/CHANGELOG.md b/pkgs/lints/CHANGELOG.md new file mode 100644 index 00000000..be12b329 --- /dev/null +++ b/pkgs/lints/CHANGELOG.md @@ -0,0 +1,96 @@ +## 5.1.1 + +- Updated the SDK lower bound to 3.6. + +## 5.1.0 + +- `core`: + - added [unintended_html_in_doc_comment] (https://github.com/dart-lang/lints/issues/192) +- Updated the SDK lower bound to 3.6 (dev). + +[unintended_html_in_doc_comment]: https://dart.dev/lints/unintended_html_in_doc_comment + +## 5.0.0 + +- `recommended`: + - added [invalid_runtime_check_with_js_interop_types] (https://github.com/dart-lang/lints/issues/188) + - added [unnecessary_library_name] (https://github.com/dart-lang/lints/issues/181) + - removed [avoid_null_checks_in_equality_operators] (https://github.com/dart-lang/lints/issues/200) +- Updated the SDK lower-bound to 3.5. + +[invalid_runtime_check_with_js_interop_types]: https://dart.dev/tools/linter-rules/invalid_runtime_check_with_js_interop_types +[unnecessary_library_name]: https://dart.dev/lints/unnecessary_library_name +[avoid_null_checks_in_equality_operators]: https://dart.dev/tools/linter-rules/avoid_null_checks_in_equality_operators + +## 4.0.0 + +- `core`: + - added `library_annotations` (https://github.com/dart-lang/lints/issues/177) + - added `no_wildcard_variable_uses` (https://github.com/dart-lang/lints/issues/139) + - removed `package_prefixed_library_names` (https://github.com/dart-lang/lints/issues/172) +- `recommended`: + - removed `library_names` (https://github.com/dart-lang/lints/issues/181) +- Updated the SDK lower-bound to 3.1. +- Add a section on upgrading to the latest lint set to the readme. + +## 3.0.0 + +- `core`: + - added `collection_methods_unrelated_type` + - added `dangling_library_doc_comments` + - added `implicit_call_tearoffs` + - added `secure_pubspec_urls` + - added `type_literal_in_constant_pattern` + - added `use_string_in_part_of_directives` + - removed `iterable_contains_unrelated_type` + - removed `list_remove_unrelated_type` +- `recommended`: + - added `unnecessary_to_list_in_spreads` + - added `use_super_parameters` + - removed `prefer_equal_for_default_values` + - removed `prefer_void_to_null` +- Add info about which lints have quick fixes to the package's readme. +- Move the list of lint rules from the readme to a separate + [rules.md](https://github.com/dart-lang/lints/blob/main/rules.md) file. + +## 2.1.1 + +- Added the `analysis` and `lints` topics to the pubspec file. +- Update the package's readme to include the list of lint rules that + `package:lints/core.yaml` and `package:lints/recommended.yaml` include. + +## 2.1.0 + +- Updated the SDK lower-bound to 3.0. +- Removed `always_require_non_null_named_parameters` from `recommended.yaml` + as it is only relevant in Dart pre 2.12 and with Dart 3.0, libraries can + no longer be opted back that far. + +## 2.0.1 + +- Updated documentation for the `lib/core.yaml` and `lib/recommended.yaml` + analysis configurations. + +## 2.0.0 + +- Added the following lints to core.yaml: + - `depend_on_referenced_packages` + - `null_check_on_nullable_type_parameter` +- Added the following lints to recommended.yaml: + - `library_private_types_in_public_api` + - `no_leading_underscores_for_library_prefixes` + - `no_leading_underscores_for_local_identifiers` + - `prefer_interpolation_to_compose_strings` + - `unnecessary_constructor_name` + - `unnecessary_late` + - `unnecessary_null_aware_assignments` + - `unnecessary_nullable_for_final_variable_declarations` +- Bumped the minimum required Dart SDK version to 2.17 + +## 1.0.1 + +- Documentation updates + +## 1.0.0 + +- Initial stable version diff --git a/pkgs/lints/LICENSE b/pkgs/lints/LICENSE new file mode 100644 index 00000000..a2178151 --- /dev/null +++ b/pkgs/lints/LICENSE @@ -0,0 +1,27 @@ +Copyright 2021, the Dart project authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/pkgs/lints/README.md b/pkgs/lints/README.md new file mode 100644 index 00000000..751a72b5 --- /dev/null +++ b/pkgs/lints/README.md @@ -0,0 +1,115 @@ +[![Build Status](https://github.com/dart-lang/lints/workflows/validate/badge.svg)](https://github.com/dart-lang/lints/actions?query=branch%3Amain) +[![pub package](https://img.shields.io/pub/v/lints.svg)](https://pub.dev/packages/lints) +[![package publisher](https://img.shields.io/pub/publisher/lints.svg)](https://pub.dev/packages/lints/publisher) + +# Official Dart lint rules + +The Dart linter is a static analyzer for identifying possible problems in your +Dart source code. More than a hundred [linter rules][rules] are available, +checking anything from potential typing issues, coding style, and formatting. +This package - `package:lints` - contains the lint settings recommended by the +Dart team. + +## Lint sets + +This package includes two sets of lints: + +* **Core lints**: Lints that help identify critical issues that are likely to +lead to problems when running or consuming Dart code. All code should pass these +lints. + +* **Recommended lints**: Lints that help identify additional issues that may +lead to problems when running or consuming Dart code, and lints that enforce +writing Dart using a single, idiomatic style and format. All code is encouraged +to pass these lints. The recommended lints include all the core lints. + +Additionally, a third lint set - +[`package:flutter_lints`](https://pub.dev/packages/flutter_lints) - extends the +recommended set with additional recommended Flutter-specific lints. + +The Dart team will likely not provide recommendations past the `core` and +`recommended` sets (e.g., a `strict` rule set). However, there are many such rule +sets in the ecosystem (available at [pub.dev](https://pub.dev/)). + +Rule set authors: consider adding the `lints` topic to your pubspec to allow +easier discovery (e.g., +[pub.dev/packages?q=topic:lints](https://pub.dev/packages?q=topic%3Alints)). +For more information about topics, visit +[dart.dev/tools/pub/pubspec#topics](https://dart.dev/tools/pub/pubspec#topics). + +## Where these lints are used + +When creating a new Dart project using the [`dart create`][dart create] command, +the `recommended` set of lints from `package:lints` is enabled by default. + +When uploading a package to the [pub.dev] package repository, packages are +[awarded pub points][scoring] based on how many of the 'core' lints pass. + +## Enabling the lints + +For new apps created with `dart create` the `recommended` set of lints are +enabled by default. + +For existing apps or packages, you can enable these lints via: + +1. In a terminal, located at the root of your package, run this command: + + ```terminal + dart pub add dev:lints + ``` + +2. Create a new `analysis_options.yaml` file, next to the pubspec, that + includes the lints package: + + ```yaml + include: package:lints/recommended.yaml + ``` + + or: + + ```yaml + include: package:lints/core.yaml + ``` + +## Upgrading to the latest lints + +To upgrade to the latest version of the lint set, run: + +``` +dart pub add dev:lints +``` + +## Customizing the predefined lint sets + +For details on customizing static analysis above and beyond the predefined +lint sets, check out [Customizing static analysis]. + +## Evolving the lint sets + +The Dart language changes and the ecosystem continues to develop new best +practices, so the lint sets must be periodically updated to reflect the best way +we know to write Dart code. The process we use is: + +1. Anyone can file an [issue] to discuss a potential change to a lint set + (i.e., adding or removing a lint from one or both sets; if you're proposing + an entirely new lint, the place to suggest that is at the [linter repo]). + Feedback is welcome from any Dart user. + +2. Periodically, a group of Dart and Flutter team members meet to review the + suggestions and decide what to adopt. + +3. The lists are updated and a new version of the package is published. + +## Lint set contents + +See [rules.md](https://github.com/dart-lang/lints/blob/main/rules.md) for a list +of rules that make up the core and recommended rule sets. + +[dart create]: https://dart.dev/tools/dart-create +[scoring]: https://pub.dev/help/scoring +[customizing static analysis]: https://dart.dev/tools/analysis +[rules]: https://dart.dev/tools/linter-rules +[pub.dev]: https://pub.dev +[issue]: https://github.com/dart-lang/lints/issues +[linter repo]: https://github.com/dart-lang/linter +[`package:flutter_lints`]: https://pub.dev/packages/flutter_lints diff --git a/pkgs/lints/example/README.md b/pkgs/lints/example/README.md new file mode 100644 index 00000000..63d13e1b --- /dev/null +++ b/pkgs/lints/example/README.md @@ -0,0 +1 @@ +An example project that uses Dart recommended lints. diff --git a/pkgs/lints/example/analysis_options.yaml b/pkgs/lints/example/analysis_options.yaml new file mode 100644 index 00000000..dee8927a --- /dev/null +++ b/pkgs/lints/example/analysis_options.yaml @@ -0,0 +1,30 @@ +# This file configures the static analysis results for your project (errors, +# warnings, and lints). +# +# This enables the 'recommended' set of lints from `package:lints`. +# This set helps identify many issues that may lead to problems when running +# or consuming Dart code, and enforces writing Dart using a single, idiomatic +# style and format. +# +# If you want a smaller set of lints you can change this to specify +# 'package:lints/core.yaml'. These are just the most critical lints +# (the recommended set includes the core lints). +# The core lints are also what is used by pub.dev for scoring packages. + +include: package:lints/recommended.yaml + +# Uncomment the following section to specify additional rules. + +# linter: +# rules: +# - camel_case_types + +# analyzer: +# exclude: +# - path/to/excluded/files/** + +# For more information about the core and recommended set of lints, see +# https://dart.dev/go/core-lints + +# For additional information about configuring this file, see +# https://dart.dev/guides/language/analysis-options diff --git a/pkgs/lints/example/pubspec.yaml b/pkgs/lints/example/pubspec.yaml new file mode 100644 index 00000000..7f3ec2b8 --- /dev/null +++ b/pkgs/lints/example/pubspec.yaml @@ -0,0 +1,10 @@ +name: example +description: An example project that uses Dart recommended lints. +version: 0.1.0 +publish_to: none + +environment: + sdk: ^3.0.0 + +dev_dependencies: + lints: ^2.1.0 diff --git a/pkgs/lints/lib/core.yaml b/pkgs/lints/lib/core.yaml new file mode 100644 index 00000000..ca8a8ca1 --- /dev/null +++ b/pkgs/lints/lib/core.yaml @@ -0,0 +1,42 @@ +# This is a set of core lints used to identify critical issues. +# Check out https://github.com/dart-lang/lints for more information. +# +# To learn more about customizing static analysis for your package or app, +# visit https://dart.dev/tools/analysis. + +linter: + rules: + - avoid_empty_else + - avoid_relative_lib_imports + - avoid_shadowing_type_parameters + - avoid_types_as_parameter_names + - await_only_futures + - camel_case_extensions + - camel_case_types + - collection_methods_unrelated_type + - curly_braces_in_flow_control_structures + - dangling_library_doc_comments + - depend_on_referenced_packages + - empty_catches + - file_names + - hash_and_equals + - implicit_call_tearoffs + - library_annotations + - no_duplicate_case_values + - no_wildcard_variable_uses + - non_constant_identifier_names + - null_check_on_nullable_type_parameter + - prefer_generic_function_type_aliases + - prefer_is_empty + - prefer_is_not_empty + - prefer_iterable_whereType + - prefer_typing_uninitialized_variables + - provide_deprecation_message + - secure_pubspec_urls + - type_literal_in_constant_pattern + - unintended_html_in_doc_comment + - unnecessary_overrides + - unrelated_type_equality_checks + - use_string_in_part_of_directives + - valid_regexps + - void_checks diff --git a/pkgs/lints/lib/recommended.yaml b/pkgs/lints/lib/recommended.yaml new file mode 100644 index 00000000..5b762ff7 --- /dev/null +++ b/pkgs/lints/lib/recommended.yaml @@ -0,0 +1,68 @@ +# This set of lints builds on top of `package:lints/core.yaml`. +# It includes lints that help identify additional issues that might lead to +# problems when running or consuming Dart code, as well as lints +# that enforce writing Dart using a single, idiomatic style. +# Check out https://github.com/dart-lang/lints for more information. +# +# To learn more about customizing static analysis for your package or app, +# visit https://dart.dev/tools/analysis. + +include: package:lints/core.yaml + +linter: + rules: + - annotate_overrides + - avoid_function_literals_in_foreach_calls + - avoid_init_to_null + - avoid_renaming_method_parameters + - avoid_return_types_on_setters + - avoid_returning_null_for_void + - avoid_single_cascade_in_expression_statements + - constant_identifier_names + - control_flow_in_finally + - empty_constructor_bodies + - empty_statements + - exhaustive_cases + - implementation_imports + - invalid_runtime_check_with_js_interop_types + - library_prefixes + - library_private_types_in_public_api + - no_leading_underscores_for_library_prefixes + - no_leading_underscores_for_local_identifiers + - null_closures + - overridden_fields + - package_names + - prefer_adjacent_string_concatenation + - prefer_collection_literals + - prefer_conditional_assignment + - prefer_contains + - prefer_final_fields + - prefer_for_elements_to_map_fromIterable + - prefer_function_declarations_over_variables + - prefer_if_null_operators + - prefer_initializing_formals + - prefer_inlined_adds + - prefer_interpolation_to_compose_strings + - prefer_is_not_operator + - prefer_null_aware_operators + - prefer_spread_collections + - recursive_getters + - slash_for_doc_comments + - type_init_formals + - unnecessary_brace_in_string_interps + - unnecessary_const + - unnecessary_constructor_name + - unnecessary_getters_setters + - unnecessary_late + - unnecessary_library_name + - unnecessary_new + - unnecessary_null_aware_assignments + - unnecessary_null_in_if_null_operators + - unnecessary_nullable_for_final_variable_declarations + - unnecessary_string_escapes + - unnecessary_string_interpolations + - unnecessary_this + - unnecessary_to_list_in_spreads + - use_function_type_syntax_for_parameters + - use_rethrow_when_possible + - use_super_parameters diff --git a/pkgs/lints/pubspec.yaml b/pkgs/lints/pubspec.yaml new file mode 100644 index 00000000..e157af3d --- /dev/null +++ b/pkgs/lints/pubspec.yaml @@ -0,0 +1,21 @@ +name: lints +version: 5.1.1 +description: > + Official Dart lint rules. Defines the 'core' and 'recommended' set of lints + suggested by the Dart team. +repository: https://github.com/dart-lang/lints + +topics: + - analysis + - lints + +environment: + sdk: ^3.6.0 + +# NOTE: Code is not allowed in this package - do not add dependencies. +# dependencies: + +dev_dependencies: + http: ^1.0.0 + path: ^1.8.0 + yaml: ^3.1.0 diff --git a/pkgs/lints/rules.md b/pkgs/lints/rules.md new file mode 100644 index 00000000..e4dd15e4 --- /dev/null +++ b/pkgs/lints/rules.md @@ -0,0 +1,106 @@ +## Lint set contents + +### Core lint rules + + +| Lint Rules | Description | [Fix][] | +| :--------- | :---------- | ------- | +| [`avoid_empty_else`](https://dart.dev/lints/avoid_empty_else) | Avoid empty statements in else clauses. | ✅ | +| [`avoid_relative_lib_imports`](https://dart.dev/lints/avoid_relative_lib_imports) | Avoid relative imports for files in `lib/`. | ✅ | +| [`avoid_shadowing_type_parameters`](https://dart.dev/lints/avoid_shadowing_type_parameters) | Avoid shadowing type parameters. | | +| [`avoid_types_as_parameter_names`](https://dart.dev/lints/avoid_types_as_parameter_names) | Avoid types as parameter names. | ✅ | +| [`await_only_futures`](https://dart.dev/lints/await_only_futures) | Await only futures. | ✅ | +| [`camel_case_extensions`](https://dart.dev/lints/camel_case_extensions) | Name extensions using UpperCamelCase. | | +| [`camel_case_types`](https://dart.dev/lints/camel_case_types) | Name types using UpperCamelCase. | | +| [`collection_methods_unrelated_type`](https://dart.dev/lints/collection_methods_unrelated_type) | Invocation of various collection methods with arguments of unrelated types. | | +| [`curly_braces_in_flow_control_structures`](https://dart.dev/lints/curly_braces_in_flow_control_structures) | DO use curly braces for all flow control structures. | ✅ | +| [`dangling_library_doc_comments`](https://dart.dev/lints/dangling_library_doc_comments) | Attach library doc comments to library directives. | ✅ | +| [`depend_on_referenced_packages`](https://dart.dev/lints/depend_on_referenced_packages) | Depend on referenced packages. | | +| [`empty_catches`](https://dart.dev/lints/empty_catches) | Avoid empty catch blocks. | ✅ | +| [`file_names`](https://dart.dev/lints/file_names) | Name source files using `lowercase_with_underscores`. | | +| [`hash_and_equals`](https://dart.dev/lints/hash_and_equals) | Always override `hashCode` if overriding `==`. | ✅ | +| [`implicit_call_tearoffs`](https://dart.dev/lints/implicit_call_tearoffs) | Explicitly tear-off `call` methods when using an object as a Function. | ✅ | +| [`library_annotations`](https://dart.dev/lints/library_annotations) | Attach library annotations to library directives. | ✅ | +| [`no_duplicate_case_values`](https://dart.dev/lints/no_duplicate_case_values) | Don't use more than one case with same value. | ✅ | +| [`no_wildcard_variable_uses`](https://dart.dev/lints/no_wildcard_variable_uses) | Don't use wildcard parameters or variables. | | +| [`non_constant_identifier_names`](https://dart.dev/lints/non_constant_identifier_names) | Name non-constant identifiers using lowerCamelCase. | ✅ | +| [`null_check_on_nullable_type_parameter`](https://dart.dev/lints/null_check_on_nullable_type_parameter) | Don't use `null` check on a potentially nullable type parameter. | ✅ | +| [`prefer_generic_function_type_aliases`](https://dart.dev/lints/prefer_generic_function_type_aliases) | Prefer generic function type aliases. | ✅ | +| [`prefer_is_empty`](https://dart.dev/lints/prefer_is_empty) | Use `isEmpty` for `Iterable`s and `Map`s. | ✅ | +| [`prefer_is_not_empty`](https://dart.dev/lints/prefer_is_not_empty) | Use `isNotEmpty` for `Iterable`s and `Map`s. | ✅ | +| [`prefer_iterable_whereType`](https://dart.dev/lints/prefer_iterable_whereType) | Prefer to use `whereType` on iterable. | ✅ | +| [`prefer_typing_uninitialized_variables`](https://dart.dev/lints/prefer_typing_uninitialized_variables) | Prefer typing uninitialized variables and fields. | ✅ | +| [`provide_deprecation_message`](https://dart.dev/lints/provide_deprecation_message) | Provide a deprecation message, via `@Deprecated("message")`. | | +| [`secure_pubspec_urls`](https://dart.dev/lints/secure_pubspec_urls) | Use secure urls in `pubspec.yaml`. | | +| [`type_literal_in_constant_pattern`](https://dart.dev/lints/type_literal_in_constant_pattern) | Don't use constant patterns with type literals. | ✅ | +| [`unintended_html_in_doc_comment`](https://dart.dev/lints/unintended_html_in_doc_comment) | Use of angle brackets in a doc comment is treated as HTML by Markdown. | | +| [`unnecessary_overrides`](https://dart.dev/lints/unnecessary_overrides) | Don't override a method to do a super method invocation with the same parameters. | ✅ | +| [`unrelated_type_equality_checks`](https://dart.dev/lints/unrelated_type_equality_checks) | Equality operator `==` invocation with references of unrelated types. | | +| [`use_string_in_part_of_directives`](https://dart.dev/lints/use_string_in_part_of_directives) | Use string in part of directives. | ✅ | +| [`valid_regexps`](https://dart.dev/lints/valid_regexps) | Use valid regular expression syntax. | | +| [`void_checks`](https://dart.dev/lints/void_checks) | Don't assign to `void`. | | + + +### Recommended lint rules + + +| Lint Rules | Description | [Fix][] | +| :--------- | :---------- | ------- | +| [`annotate_overrides`](https://dart.dev/lints/annotate_overrides) | Annotate overridden members. | ✅ | +| [`avoid_function_literals_in_foreach_calls`](https://dart.dev/lints/avoid_function_literals_in_foreach_calls) | Avoid using `forEach` with a function literal. | ✅ | +| [`avoid_init_to_null`](https://dart.dev/lints/avoid_init_to_null) | Don't explicitly initialize variables to `null`. | ✅ | +| [`avoid_renaming_method_parameters`](https://dart.dev/lints/avoid_renaming_method_parameters) | Don't rename parameters of overridden methods. | ✅ | +| [`avoid_return_types_on_setters`](https://dart.dev/lints/avoid_return_types_on_setters) | Avoid return types on setters. | ✅ | +| [`avoid_returning_null_for_void`](https://dart.dev/lints/avoid_returning_null_for_void) | Avoid returning `null` for `void`. | ✅ | +| [`avoid_single_cascade_in_expression_statements`](https://dart.dev/lints/avoid_single_cascade_in_expression_statements) | Avoid single cascade in expression statements. | ✅ | +| [`constant_identifier_names`](https://dart.dev/lints/constant_identifier_names) | Prefer using lowerCamelCase for constant names. | ✅ | +| [`control_flow_in_finally`](https://dart.dev/lints/control_flow_in_finally) | Avoid control flow in `finally` blocks. | | +| [`empty_constructor_bodies`](https://dart.dev/lints/empty_constructor_bodies) | Use `;` instead of `{}` for empty constructor bodies. | ✅ | +| [`empty_statements`](https://dart.dev/lints/empty_statements) | Avoid empty statements. | ✅ | +| [`exhaustive_cases`](https://dart.dev/lints/exhaustive_cases) | Define case clauses for all constants in enum-like classes. | ✅ | +| [`implementation_imports`](https://dart.dev/lints/implementation_imports) | Don't import implementation files from another package. | | +| [`invalid_runtime_check_with_js_interop_types`](https://dart.dev/lints/invalid_runtime_check_with_js_interop_types) | Avoid runtime type tests with JS interop types where the result may not be platform-consistent. | | +| [`library_prefixes`](https://dart.dev/lints/library_prefixes) | Use `lowercase_with_underscores` when specifying a library prefix. | | +| [`library_private_types_in_public_api`](https://dart.dev/lints/library_private_types_in_public_api) | Avoid using private types in public APIs. | | +| [`no_leading_underscores_for_library_prefixes`](https://dart.dev/lints/no_leading_underscores_for_library_prefixes) | Avoid leading underscores for library prefixes. | ✅ | +| [`no_leading_underscores_for_local_identifiers`](https://dart.dev/lints/no_leading_underscores_for_local_identifiers) | Avoid leading underscores for local identifiers. | ✅ | +| [`null_closures`](https://dart.dev/lints/null_closures) | Do not pass `null` as an argument where a closure is expected. | ✅ | +| [`overridden_fields`](https://dart.dev/lints/overridden_fields) | Don't override fields. | | +| [`package_names`](https://dart.dev/lints/package_names) | Use `lowercase_with_underscores` for package names. | | +| [`prefer_adjacent_string_concatenation`](https://dart.dev/lints/prefer_adjacent_string_concatenation) | Use adjacent strings to concatenate string literals. | ✅ | +| [`prefer_collection_literals`](https://dart.dev/lints/prefer_collection_literals) | Use collection literals when possible. | ✅ | +| [`prefer_conditional_assignment`](https://dart.dev/lints/prefer_conditional_assignment) | Prefer using `??=` over testing for `null`. | ✅ | +| [`prefer_contains`](https://dart.dev/lints/prefer_contains) | Use contains for `List` and `String` instances. | ✅ | +| [`prefer_final_fields`](https://dart.dev/lints/prefer_final_fields) | Private field could be `final`. | ✅ | +| [`prefer_for_elements_to_map_fromIterable`](https://dart.dev/lints/prefer_for_elements_to_map_fromIterable) | Prefer `for` elements when building maps from iterables. | ✅ | +| [`prefer_function_declarations_over_variables`](https://dart.dev/lints/prefer_function_declarations_over_variables) | Use a function declaration to bind a function to a name. | ✅ | +| [`prefer_if_null_operators`](https://dart.dev/lints/prefer_if_null_operators) | Prefer using `??` operators. | ✅ | +| [`prefer_initializing_formals`](https://dart.dev/lints/prefer_initializing_formals) | Use initializing formals when possible. | ✅ | +| [`prefer_inlined_adds`](https://dart.dev/lints/prefer_inlined_adds) | Inline list item declarations where possible. | ✅ | +| [`prefer_interpolation_to_compose_strings`](https://dart.dev/lints/prefer_interpolation_to_compose_strings) | Use interpolation to compose strings and values. | ✅ | +| [`prefer_is_not_operator`](https://dart.dev/lints/prefer_is_not_operator) | Prefer is! operator. | ✅ | +| [`prefer_null_aware_operators`](https://dart.dev/lints/prefer_null_aware_operators) | Prefer using `null`-aware operators. | ✅ | +| [`prefer_spread_collections`](https://dart.dev/lints/prefer_spread_collections) | Use spread collections when possible. | ✅ | +| [`recursive_getters`](https://dart.dev/lints/recursive_getters) | Property getter recursively returns itself. | | +| [`slash_for_doc_comments`](https://dart.dev/lints/slash_for_doc_comments) | Prefer using `///` for doc comments. | ✅ | +| [`type_init_formals`](https://dart.dev/lints/type_init_formals) | Don't type annotate initializing formals. | ✅ | +| [`unnecessary_brace_in_string_interps`](https://dart.dev/lints/unnecessary_brace_in_string_interps) | Avoid using braces in interpolation when not needed. | ✅ | +| [`unnecessary_const`](https://dart.dev/lints/unnecessary_const) | Avoid `const` keyword. | ✅ | +| [`unnecessary_constructor_name`](https://dart.dev/lints/unnecessary_constructor_name) | Unnecessary `.new` constructor name. | ✅ | +| [`unnecessary_getters_setters`](https://dart.dev/lints/unnecessary_getters_setters) | Avoid wrapping fields in getters and setters just to be "safe". | ✅ | +| [`unnecessary_late`](https://dart.dev/lints/unnecessary_late) | Don't specify the `late` modifier when it is not needed. | ✅ | +| [`unnecessary_library_name`](https://dart.dev/lints/unnecessary_library_name) | Don't have a library name in a `library` declaration. | ✅ | +| [`unnecessary_new`](https://dart.dev/lints/unnecessary_new) | Unnecessary new keyword. | ✅ | +| [`unnecessary_null_aware_assignments`](https://dart.dev/lints/unnecessary_null_aware_assignments) | Avoid `null` in `null`-aware assignment. | ✅ | +| [`unnecessary_null_in_if_null_operators`](https://dart.dev/lints/unnecessary_null_in_if_null_operators) | Avoid using `null` in `??` operators. | ✅ | +| [`unnecessary_nullable_for_final_variable_declarations`](https://dart.dev/lints/unnecessary_nullable_for_final_variable_declarations) | Use a non-nullable type for a final variable initialized with a non-nullable value. | ✅ | +| [`unnecessary_string_escapes`](https://dart.dev/lints/unnecessary_string_escapes) | Remove unnecessary backslashes in strings. | ✅ | +| [`unnecessary_string_interpolations`](https://dart.dev/lints/unnecessary_string_interpolations) | Unnecessary string interpolation. | ✅ | +| [`unnecessary_this`](https://dart.dev/lints/unnecessary_this) | Don't access members with `this` unless avoiding shadowing. | ✅ | +| [`unnecessary_to_list_in_spreads`](https://dart.dev/lints/unnecessary_to_list_in_spreads) | Unnecessary `toList()` in spreads. | ✅ | +| [`use_function_type_syntax_for_parameters`](https://dart.dev/lints/use_function_type_syntax_for_parameters) | Use generic function type syntax for parameters. | ✅ | +| [`use_rethrow_when_possible`](https://dart.dev/lints/use_rethrow_when_possible) | Use rethrow to rethrow a caught exception. | ✅ | +| [`use_super_parameters`](https://dart.dev/lints/use_super_parameters) | Use super-initializer parameters where possible. | ✅ | + + +[Fix]: https://dart.dev/tools/dart-fix diff --git a/pkgs/lints/tool/README.md b/pkgs/lints/tool/README.md new file mode 100644 index 00000000..e1f4a99c --- /dev/null +++ b/pkgs/lints/tool/README.md @@ -0,0 +1,25 @@ + +## `tool/validate_lib.dart` + +This tool ensures that we don't commit `.dart` source files into the `lib/` +directory; it's automatically run by the CI. To run manually: + +```shell +dart run tool/validate_lib.dart +``` + +## `tool/gen_docs.dart` + +This tool regenerates the lists of core and recommended lints into the package's +`README.md` file. To use it, run: + +```shell +dart run tool/gen_docs.dart +``` + +It can also validate that the readme file is up-to-date. It's automatically +run by the CI; to run it manually: + +```shell +dart run tool/gen_docs.dart --verify +``` diff --git a/pkgs/lints/tool/analysis_options.yaml b/pkgs/lints/tool/analysis_options.yaml new file mode 100644 index 00000000..505a0b7f --- /dev/null +++ b/pkgs/lints/tool/analysis_options.yaml @@ -0,0 +1 @@ +include: ../lib/recommended.yaml diff --git a/pkgs/lints/tool/gen_docs.dart b/pkgs/lints/tool/gen_docs.dart new file mode 100644 index 00000000..2ecea386 --- /dev/null +++ b/pkgs/lints/tool/gen_docs.dart @@ -0,0 +1,215 @@ +// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:convert'; +import 'dart:io'; + +import 'package:path/path.dart' as p; +import 'package:yaml/yaml.dart' as yaml; +import 'package:http/http.dart' as http; + +/// Source of truth for linter rules. +const rulesUrl = + 'https://raw.githubusercontent.com/dart-lang/site-www/main/src/_data/linter_rules.json'; + +/// Local cache of linter rules from [rulesUrl]. +/// +/// Relative to package root. +const rulesCacheFilePath = 'tool/rules.json'; + +/// Generated rules documentation markdown file. +/// +/// Relative to package root. +const rulesMarkdownFilePath = 'rules.md'; + +/// Fetches the [rulesUrl] JSON description of all lints, saves a cached +/// summary of the relevant fields in [rulesCacheFilePath], and +/// updates [rulesMarkdownFilePath] to +/// +/// Passing any command line argument disables generating documentation, +/// and makes this tool just verify that the doc is up-to-date with the +/// [rulesCacheFilePath]. (Which it always should be, since the two +/// are saved at the same time.) +void main(List args) async { + final verifyOnly = args.isNotEmpty; + + // Read lint rules. + final rulesJson = await _fetchRulesJson(verifyOnly: verifyOnly); + + // Read existing generated Markdown documentation. + final rulesMarkdownFile = _packageRelativeFile(rulesMarkdownFilePath); + final rulesMarkdownContent = rulesMarkdownFile.readAsStringSync(); + + if (verifyOnly) { + print('Validating that ${rulesMarkdownFile.path} is up-to-date ...'); + } else { + print('Regenerating ${rulesMarkdownFile.path} ...'); + } + + // Generate new documentation. + var newRulesMarkdownContent = + _updateMarkdown(rulesMarkdownContent, rulesJson); + + // If no documentation change, all is up-to-date. + if (newRulesMarkdownContent == rulesMarkdownContent) { + print('${rulesMarkdownFile.path} is up-to-date.'); + return; + } + + /// Documentation has changed. + if (verifyOnly) { + print('${rulesMarkdownFile.path} is not up-to-date (lint tables need to be ' + 'regenerated).'); + print(''); + print("Run 'dart tool/gen_docs.dart' to re-generate."); + exit(1); + } else { + // Save [rulesMarkdownFilePath]. + rulesMarkdownFile.writeAsStringSync(newRulesMarkdownContent); + print('Wrote ${rulesMarkdownFile.path}.'); + } +} + +/// Fetches or load the JSON lint rules. +/// +/// If [verifyOnly] is `false`, fetches JSON from [rulesUrl], +/// extracts the needed information, and writes a summary to +/// [rulesCacheFilePath]. +/// +/// If [verifyOnly] is `true`, only reads the cached data back from +/// [rulesCacheFilePath]. +Future>> _fetchRulesJson( + {required bool verifyOnly}) async { + final rulesJsonFile = _packageRelativeFile(rulesCacheFilePath); + if (verifyOnly) { + final rulesJsonText = rulesJsonFile.readAsStringSync(); + return _readJson(rulesJsonText); + } + final rulesJsonText = (await http.get(Uri.parse(rulesUrl))).body; + final rulesJson = _readJson(rulesJsonText); + + // Re-save [rulesJsonFile] file. + var newRulesJson = [...rulesJson.values]; + rulesJsonFile + .writeAsStringSync(JsonEncoder.withIndent(' ').convert(newRulesJson)); + + return rulesJson; +} + +/// Extracts relevant information from a list of JSON objects. +/// +/// For each JSON object, includes only the relevant (string-typed) properties, +/// then creates a map indexed by the `'name'` property of the objects. +Map> _readJson(String rulesJsonText) { + /// Relevant keys in the JSON information about lints. + const relevantKeys = {'name', 'description', 'fixStatus'}; + final rulesJson = jsonDecode(rulesJsonText) as List; + return { + for (Map rule in rulesJson) + rule['name'] as String: { + for (var key in relevantKeys) key: rule[key] as String + } + }; +} + +/// Inserts new Markdown content for both rule sets into [content]. +/// +/// For both "core" and "recommended" rule sets, +/// replaces the table between the two `` and the two +/// `` markers with a new table generated from +/// [rulesJson], based on the list of rules in `lib/core.yaml` and +/// `lib/recommended.yaml`. +String _updateMarkdown( + String content, Map> rulesJson) { + for (var ruleSetName in ['core', 'recommended']) { + var ruleFile = _packageRelativeFile(p.join('lib', '$ruleSetName.yaml')); + var ruleSet = _parseRules(ruleFile); + + final rangeDelimiter = '\n'; + var rangeStart = content.indexOf(rangeDelimiter) + rangeDelimiter.length; + var rangeEnd = content.indexOf(rangeDelimiter, rangeStart); + if (rangeEnd < 0) { + stderr.writeln('Missing "$rangeDelimiter" in $rulesMarkdownFilePath.'); + continue; + } + content = content.replaceRange( + rangeStart, rangeEnd, _createRuleTable(ruleSet, rulesJson)); + } + return content; +} + +/// Parses analysis options YAML file, and extracts linter rules. +List _parseRules(File yamlFile) { + var yamlData = yaml.loadYaml(yamlFile.readAsStringSync()) as Map; + var linterEntry = yamlData['linter'] as Map; + return List.from(linterEntry['rules'] as List); +} + +/// Creates markdown source for a table of lint rules. +String _createRuleTable( + List rules, Map> lintMeta) { + rules.sort(); + + final lines = [ + '| Lint Rules | Description | [Fix][] |', + '| :--------- | :---------- | ------- |', + for (var rule in rules) _createRuleTableRow(rule, lintMeta), + ]; + + return '${lines.join('\n')}\n'; +} + +/// Creates a line containing the markdown table row for a single lint rule. +/// +/// Used by [_createRuleTable] for each row in the generated table. +/// The row should have the same number of entires as the table format, +/// and should be on a single line with no newline at the end. +String _createRuleTableRow( + String rule, Map> lintMeta) { + final ruleMeta = lintMeta[rule]; + if (ruleMeta == null) { + stderr.writeln("WARNING: Missing rule information for rule: $rule"); + } + final description = (ruleMeta?['description'] ?? '') + .replaceAll('\n', ' ') + .replaceAll(RegExp(r'\s+'), ' ') + .trim(); + final hasFix = ruleMeta?['fixStatus'] == 'hasFix'; + final fixDesc = hasFix ? '✅' : ''; + + return '| [`$rule`](https://dart.dev/lints/$rule) | ' + '$description | $fixDesc |'; +} + +/// A path relative to the root of this package. +/// +/// Works independently of the current working directory. +/// Is based on the location of this script, through [Platform.script]. +File _packageRelativeFile(String packagePath) => + File(p.join(_packageRoot, packagePath)); + +/// Cached package root used by [_packageRelative]. +final String _packageRoot = _relativePackageRoot(); + +/// A path to the package root from the current directory. +/// +/// If the current directory is inside the package, the returned path is +/// a relative path of a number of `..` segments. +/// If the current directory is outside of the package, the returned path +/// may be absolute. +String _relativePackageRoot() { + var rootPath = p.dirname(p.dirname(Platform.script.path)); + if (p.isRelative(rootPath)) return rootPath; + var baseDir = p.current; + if (rootPath == baseDir) return ''; + if (baseDir.startsWith(rootPath)) { + var backSteps = []; + do { + backSteps.add('..'); + baseDir = p.dirname(baseDir); + } while (baseDir != rootPath); + return p.joinAll(backSteps); + } + return rootPath; +} diff --git a/pkgs/lints/tool/rules.json b/pkgs/lints/tool/rules.json new file mode 100644 index 00000000..5dff4a90 --- /dev/null +++ b/pkgs/lints/tool/rules.json @@ -0,0 +1,1207 @@ +[ + { + "name": "always_declare_return_types", + "description": "Declare method return types.", + "fixStatus": "hasFix" + }, + { + "name": "always_put_control_body_on_new_line", + "description": "Separate the control structure expression from its statement.", + "fixStatus": "hasFix" + }, + { + "name": "always_put_required_named_parameters_first", + "description": "Put required named parameters first.", + "fixStatus": "hasFix" + }, + { + "name": "always_require_non_null_named_parameters", + "description": "Specify `@required` on named parameters without defaults.", + "fixStatus": "noFix" + }, + { + "name": "always_specify_types", + "description": "Specify type annotations.", + "fixStatus": "hasFix" + }, + { + "name": "always_use_package_imports", + "description": "Avoid relative imports for files in `lib/`.", + "fixStatus": "hasFix" + }, + { + "name": "annotate_overrides", + "description": "Annotate overridden members.", + "fixStatus": "hasFix" + }, + { + "name": "annotate_redeclares", + "description": "Annotate redeclared members.", + "fixStatus": "hasFix" + }, + { + "name": "avoid_annotating_with_dynamic", + "description": "Avoid annotating with `dynamic` when not required.", + "fixStatus": "hasFix" + }, + { + "name": "avoid_as", + "description": "Avoid using `as`.", + "fixStatus": "noFix" + }, + { + "name": "avoid_bool_literals_in_conditional_expressions", + "description": "Avoid `bool` literals in conditional expressions.", + "fixStatus": "needsFix" + }, + { + "name": "avoid_catches_without_on_clauses", + "description": "Avoid catches without on clauses.", + "fixStatus": "noFix" + }, + { + "name": "avoid_catching_errors", + "description": "Don't explicitly catch `Error` or types that implement it.", + "fixStatus": "noFix" + }, + { + "name": "avoid_classes_with_only_static_members", + "description": "Avoid defining a class that contains only static members.", + "fixStatus": "noFix" + }, + { + "name": "avoid_double_and_int_checks", + "description": "Avoid `double` and `int` checks.", + "fixStatus": "needsFix" + }, + { + "name": "avoid_dynamic_calls", + "description": "Avoid method calls or property accesses on a `dynamic` target.", + "fixStatus": "noFix" + }, + { + "name": "avoid_empty_else", + "description": "Avoid empty statements in else clauses.", + "fixStatus": "hasFix" + }, + { + "name": "avoid_equals_and_hash_code_on_mutable_classes", + "description": "Avoid overloading operator == and hashCode on classes not marked `@immutable`.", + "fixStatus": "noFix" + }, + { + "name": "avoid_escaping_inner_quotes", + "description": "Avoid escaping inner quotes by converting surrounding quotes.", + "fixStatus": "hasFix" + }, + { + "name": "avoid_field_initializers_in_const_classes", + "description": "Avoid field initializers in const classes.", + "fixStatus": "noFix" + }, + { + "name": "avoid_final_parameters", + "description": "Avoid `final` for parameter declarations.", + "fixStatus": "needsFix" + }, + { + "name": "avoid_function_literals_in_foreach_calls", + "description": "Avoid using `forEach` with a function literal.", + "fixStatus": "hasFix" + }, + { + "name": "avoid_futureor_void", + "description": "Avoid using 'FutureOr' as the type of a result.", + "fixStatus": "noFix" + }, + { + "name": "avoid_implementing_value_types", + "description": "Don't implement classes that override `==`.", + "fixStatus": "noFix" + }, + { + "name": "avoid_init_to_null", + "description": "Don't explicitly initialize variables to `null`.", + "fixStatus": "hasFix" + }, + { + "name": "avoid_js_rounded_ints", + "description": "Avoid JavaScript rounded ints.", + "fixStatus": "noFix" + }, + { + "name": "avoid_multiple_declarations_per_line", + "description": "Don't declare multiple variables on a single line.", + "fixStatus": "hasFix" + }, + { + "name": "avoid_null_checks_in_equality_operators", + "description": "Don't check for `null` in custom `==` operators.", + "fixStatus": "hasFix" + }, + { + "name": "avoid_positional_boolean_parameters", + "description": "Avoid positional boolean parameters.", + "fixStatus": "noFix" + }, + { + "name": "avoid_print", + "description": "Avoid `print` calls in production code.", + "fixStatus": "hasFix" + }, + { + "name": "avoid_private_typedef_functions", + "description": "Avoid private typedef functions.", + "fixStatus": "hasFix" + }, + { + "name": "avoid_redundant_argument_values", + "description": "Avoid redundant argument values.", + "fixStatus": "hasFix" + }, + { + "name": "avoid_relative_lib_imports", + "description": "Avoid relative imports for files in `lib/`.", + "fixStatus": "hasFix" + }, + { + "name": "avoid_renaming_method_parameters", + "description": "Don't rename parameters of overridden methods.", + "fixStatus": "hasFix" + }, + { + "name": "avoid_return_types_on_setters", + "description": "Avoid return types on setters.", + "fixStatus": "hasFix" + }, + { + "name": "avoid_returning_null", + "description": "Avoid returning null from members whose return type is bool, double, int, or num.", + "fixStatus": "noFix" + }, + { + "name": "avoid_returning_null_for_future", + "description": "Avoid returning null for Future.", + "fixStatus": "noFix" + }, + { + "name": "avoid_returning_null_for_void", + "description": "Avoid returning `null` for `void`.", + "fixStatus": "hasFix" + }, + { + "name": "avoid_returning_this", + "description": "Avoid returning this from methods just to enable a fluent interface.", + "fixStatus": "noFix" + }, + { + "name": "avoid_setters_without_getters", + "description": "Avoid setters without getters.", + "fixStatus": "needsFix" + }, + { + "name": "avoid_shadowing_type_parameters", + "description": "Avoid shadowing type parameters.", + "fixStatus": "noFix" + }, + { + "name": "avoid_single_cascade_in_expression_statements", + "description": "Avoid single cascade in expression statements.", + "fixStatus": "hasFix" + }, + { + "name": "avoid_slow_async_io", + "description": "Avoid slow asynchronous `dart:io` methods.", + "fixStatus": "needsFix" + }, + { + "name": "avoid_type_to_string", + "description": "Avoid .toString() in production code since results may be minified.", + "fixStatus": "noFix" + }, + { + "name": "avoid_types_as_parameter_names", + "description": "Avoid types as parameter names.", + "fixStatus": "hasFix" + }, + { + "name": "avoid_types_on_closure_parameters", + "description": "Avoid annotating types for function expression parameters.", + "fixStatus": "hasFix" + }, + { + "name": "avoid_unnecessary_containers", + "description": "Avoid unnecessary containers.", + "fixStatus": "hasFix" + }, + { + "name": "avoid_unstable_final_fields", + "description": "Avoid overriding a final field to return different values if called multiple times.", + "fixStatus": "noFix" + }, + { + "name": "avoid_unused_constructor_parameters", + "description": "Avoid defining unused parameters in constructors.", + "fixStatus": "hasFix" + }, + { + "name": "avoid_void_async", + "description": "Avoid `async` functions that return `void`.", + "fixStatus": "hasFix" + }, + { + "name": "avoid_web_libraries_in_flutter", + "description": "Avoid using web-only libraries outside Flutter web plugin packages.", + "fixStatus": "noFix" + }, + { + "name": "await_only_futures", + "description": "Await only futures.", + "fixStatus": "hasFix" + }, + { + "name": "camel_case_extensions", + "description": "Name extensions using UpperCamelCase.", + "fixStatus": "noFix" + }, + { + "name": "camel_case_types", + "description": "Name types using UpperCamelCase.", + "fixStatus": "noFix" + }, + { + "name": "cancel_subscriptions", + "description": "Cancel instances of `dart:async` `StreamSubscription`.", + "fixStatus": "noFix" + }, + { + "name": "cascade_invocations", + "description": "Cascade consecutive method invocations on the same reference.", + "fixStatus": "hasFix" + }, + { + "name": "cast_nullable_to_non_nullable", + "description": "Don't cast a nullable value to a non nullable type.", + "fixStatus": "hasFix" + }, + { + "name": "close_sinks", + "description": "Close instances of `dart:core` `Sink`.", + "fixStatus": "noFix" + }, + { + "name": "collection_methods_unrelated_type", + "description": "Invocation of various collection methods with arguments of unrelated types.", + "fixStatus": "noFix" + }, + { + "name": "combinators_ordering", + "description": "Sort combinator names alphabetically.", + "fixStatus": "hasFix" + }, + { + "name": "comment_references", + "description": "Only reference in-scope identifiers in doc comments.", + "fixStatus": "hasFix" + }, + { + "name": "conditional_uri_does_not_exist", + "description": "Missing conditional import.", + "fixStatus": "noFix" + }, + { + "name": "constant_identifier_names", + "description": "Prefer using lowerCamelCase for constant names.", + "fixStatus": "hasFix" + }, + { + "name": "control_flow_in_finally", + "description": "Avoid control flow in `finally` blocks.", + "fixStatus": "noFix" + }, + { + "name": "curly_braces_in_flow_control_structures", + "description": "DO use curly braces for all flow control structures.", + "fixStatus": "hasFix" + }, + { + "name": "dangling_library_doc_comments", + "description": "Attach library doc comments to library directives.", + "fixStatus": "hasFix" + }, + { + "name": "depend_on_referenced_packages", + "description": "Depend on referenced packages.", + "fixStatus": "needsFix" + }, + { + "name": "deprecated_consistency", + "description": "Missing deprecated annotation.", + "fixStatus": "needsFix" + }, + { + "name": "deprecated_member_use_from_same_package", + "description": "Avoid using deprecated elements from within the package in which they are declared.", + "fixStatus": "hasFix" + }, + { + "name": "diagnostic_describe_all_properties", + "description": "DO reference all public properties in debug methods.", + "fixStatus": "hasFix" + }, + { + "name": "directives_ordering", + "description": "Adhere to Effective Dart Guide directives sorting conventions.", + "fixStatus": "hasFix" + }, + { + "name": "discarded_futures", + "description": "Don't invoke asynchronous functions in non-`async` blocks.", + "fixStatus": "hasFix" + }, + { + "name": "do_not_use_environment", + "description": "Do not use environment declared variables.", + "fixStatus": "noFix" + }, + { + "name": "document_ignores", + "description": "Document ignore comments.", + "fixStatus": "needsFix" + }, + { + "name": "empty_catches", + "description": "Avoid empty catch blocks.", + "fixStatus": "hasFix" + }, + { + "name": "empty_constructor_bodies", + "description": "Use `;` instead of `{}` for empty constructor bodies.", + "fixStatus": "hasFix" + }, + { + "name": "empty_statements", + "description": "Avoid empty statements.", + "fixStatus": "hasFix" + }, + { + "name": "enable_null_safety", + "description": "Do use sound null safety.", + "fixStatus": "noFix" + }, + { + "name": "eol_at_end_of_file", + "description": "Put a single newline at end of file.", + "fixStatus": "hasFix" + }, + { + "name": "exhaustive_cases", + "description": "Define case clauses for all constants in enum-like classes.", + "fixStatus": "hasFix" + }, + { + "name": "file_names", + "description": "Name source files using `lowercase_with_underscores`.", + "fixStatus": "noFix" + }, + { + "name": "flutter_style_todos", + "description": "Use Flutter TODO format: // TODO(username): message, https://URL-to-issue.", + "fixStatus": "hasFix" + }, + { + "name": "hash_and_equals", + "description": "Always override `hashCode` if overriding `==`.", + "fixStatus": "hasFix" + }, + { + "name": "implementation_imports", + "description": "Don't import implementation files from another package.", + "fixStatus": "noFix" + }, + { + "name": "implicit_call_tearoffs", + "description": "Explicitly tear-off `call` methods when using an object as a Function.", + "fixStatus": "hasFix" + }, + { + "name": "implicit_reopen", + "description": "Don't implicitly reopen classes.", + "fixStatus": "hasFix" + }, + { + "name": "invalid_case_patterns", + "description": "Use case expressions that are valid in Dart 3.0.", + "fixStatus": "hasFix" + }, + { + "name": "invalid_runtime_check_with_js_interop_types", + "description": "Avoid runtime type tests with JS interop types where the result may not\n be platform-consistent.", + "fixStatus": "needsEvaluation" + }, + { + "name": "invariant_booleans", + "description": "Conditions should not unconditionally evaluate to `true` or to `false`.", + "fixStatus": "noFix" + }, + { + "name": "iterable_contains_unrelated_type", + "description": "Invocation of `Iterable.contains` with references of unrelated types.", + "fixStatus": "noFix" + }, + { + "name": "join_return_with_assignment", + "description": "Join return statement with assignment when possible.", + "fixStatus": "needsFix" + }, + { + "name": "leading_newlines_in_multiline_strings", + "description": "Start multiline strings with a newline.", + "fixStatus": "hasFix" + }, + { + "name": "library_annotations", + "description": "Attach library annotations to library directives.", + "fixStatus": "hasFix" + }, + { + "name": "library_names", + "description": "Name libraries using `lowercase_with_underscores`.", + "fixStatus": "noFix" + }, + { + "name": "library_prefixes", + "description": "Use `lowercase_with_underscores` when specifying a library prefix.", + "fixStatus": "noFix" + }, + { + "name": "library_private_types_in_public_api", + "description": "Avoid using private types in public APIs.", + "fixStatus": "noFix" + }, + { + "name": "lines_longer_than_80_chars", + "description": "Avoid lines longer than 80 characters.", + "fixStatus": "noFix" + }, + { + "name": "list_remove_unrelated_type", + "description": "Invocation of `remove` with references of unrelated types.", + "fixStatus": "noFix" + }, + { + "name": "literal_only_boolean_expressions", + "description": "Boolean expression composed only with literals.", + "fixStatus": "noFix" + }, + { + "name": "matching_super_parameters", + "description": "Use matching super parameter names.", + "fixStatus": "needsFix" + }, + { + "name": "missing_code_block_language_in_doc_comment", + "description": "A code block is missing a specified language.", + "fixStatus": "needsEvaluation" + }, + { + "name": "missing_whitespace_between_adjacent_strings", + "description": "Missing whitespace between adjacent strings.", + "fixStatus": "needsFix" + }, + { + "name": "no_adjacent_strings_in_list", + "description": "Don't use adjacent strings in list.", + "fixStatus": "needsFix" + }, + { + "name": "no_default_cases", + "description": "No default cases.", + "fixStatus": "needsFix" + }, + { + "name": "no_duplicate_case_values", + "description": "Don't use more than one case with same value.", + "fixStatus": "hasFix" + }, + { + "name": "no_leading_underscores_for_library_prefixes", + "description": "Avoid leading underscores for library prefixes.", + "fixStatus": "hasFix" + }, + { + "name": "no_leading_underscores_for_local_identifiers", + "description": "Avoid leading underscores for local identifiers.", + "fixStatus": "hasFix" + }, + { + "name": "no_literal_bool_comparisons", + "description": "Don't compare boolean expressions to boolean literals.", + "fixStatus": "hasFix" + }, + { + "name": "no_logic_in_create_state", + "description": "Don't put any logic in createState.", + "fixStatus": "noFix" + }, + { + "name": "no_runtimeType_toString", + "description": "Avoid calling `toString()` on `runtimeType`.", + "fixStatus": "noFix" + }, + { + "name": "no_self_assignments", + "description": "Don't assign a variable to itself.", + "fixStatus": "needsEvaluation" + }, + { + "name": "no_wildcard_variable_uses", + "description": "Don't use wildcard parameters or variables.", + "fixStatus": "needsEvaluation" + }, + { + "name": "non_constant_identifier_names", + "description": "Name non-constant identifiers using lowerCamelCase.", + "fixStatus": "hasFix" + }, + { + "name": "noop_primitive_operations", + "description": "Noop primitive operations.", + "fixStatus": "hasFix" + }, + { + "name": "null_check_on_nullable_type_parameter", + "description": "Don't use `null` check on a potentially nullable type parameter.", + "fixStatus": "hasFix" + }, + { + "name": "null_closures", + "description": "Do not pass `null` as an argument where a closure is expected.", + "fixStatus": "hasFix" + }, + { + "name": "omit_local_variable_types", + "description": "Omit type annotations for local variables.", + "fixStatus": "hasFix" + }, + { + "name": "omit_obvious_local_variable_types", + "description": "Omit obvious type annotations for local variables.", + "fixStatus": "hasFix" + }, + { + "name": "omit_obvious_property_types", + "description": "Omit obvious type annotations for top-level and static variables.", + "fixStatus": "hasFix" + }, + { + "name": "one_member_abstracts", + "description": "Avoid defining a one-member abstract class when a simple function will do.", + "fixStatus": "noFix" + }, + { + "name": "only_throw_errors", + "description": "Only throw instances of classes extending either Exception or Error.", + "fixStatus": "noFix" + }, + { + "name": "overridden_fields", + "description": "Don't override fields.", + "fixStatus": "noFix" + }, + { + "name": "package_api_docs", + "description": "Provide doc comments for all public APIs.", + "fixStatus": "noFix" + }, + { + "name": "package_names", + "description": "Use `lowercase_with_underscores` for package names.", + "fixStatus": "noFix" + }, + { + "name": "package_prefixed_library_names", + "description": "Prefix library names with the package name and a dot-separated path.", + "fixStatus": "noFix" + }, + { + "name": "parameter_assignments", + "description": "Don't reassign references to parameters of functions or methods.", + "fixStatus": "noFix" + }, + { + "name": "prefer_adjacent_string_concatenation", + "description": "Use adjacent strings to concatenate string literals.", + "fixStatus": "hasFix" + }, + { + "name": "prefer_asserts_in_initializer_lists", + "description": "Prefer putting asserts in initializer lists.", + "fixStatus": "needsFix" + }, + { + "name": "prefer_asserts_with_message", + "description": "Prefer asserts with message.", + "fixStatus": "noFix" + }, + { + "name": "prefer_bool_in_asserts", + "description": "Prefer using a boolean as the assert condition.", + "fixStatus": "noFix" + }, + { + "name": "prefer_collection_literals", + "description": "Use collection literals when possible.", + "fixStatus": "hasFix" + }, + { + "name": "prefer_conditional_assignment", + "description": "Prefer using `??=` over testing for `null`.", + "fixStatus": "hasFix" + }, + { + "name": "prefer_const_constructors", + "description": "Prefer `const` with constant constructors.", + "fixStatus": "hasFix" + }, + { + "name": "prefer_const_constructors_in_immutables", + "description": "Prefer declaring `const` constructors on `@immutable` classes.", + "fixStatus": "hasFix" + }, + { + "name": "prefer_const_declarations", + "description": "Prefer `const` over `final` for declarations.", + "fixStatus": "hasFix" + }, + { + "name": "prefer_const_literals_to_create_immutables", + "description": "Prefer const literals as parameters of constructors on @immutable classes.", + "fixStatus": "hasFix" + }, + { + "name": "prefer_constructors_over_static_methods", + "description": "Prefer defining constructors instead of static methods to create instances.", + "fixStatus": "needsFix" + }, + { + "name": "prefer_contains", + "description": "Use contains for `List` and `String` instances.", + "fixStatus": "hasFix" + }, + { + "name": "prefer_double_quotes", + "description": "Prefer double quotes where they won't require escape sequences.", + "fixStatus": "hasFix" + }, + { + "name": "prefer_equal_for_default_values", + "description": "Use `=` to separate a named parameter from its default value.", + "fixStatus": "noFix" + }, + { + "name": "prefer_expression_function_bodies", + "description": "Use => for short members whose body is a single return statement.", + "fixStatus": "hasFix" + }, + { + "name": "prefer_final_fields", + "description": "Private field could be `final`.", + "fixStatus": "hasFix" + }, + { + "name": "prefer_final_in_for_each", + "description": "Prefer final in for-each loop variable if reference is not reassigned.", + "fixStatus": "hasFix" + }, + { + "name": "prefer_final_locals", + "description": "Prefer final for variable declarations if they are not reassigned.", + "fixStatus": "hasFix" + }, + { + "name": "prefer_final_parameters", + "description": "Prefer final for parameter declarations if they are not reassigned.", + "fixStatus": "hasFix" + }, + { + "name": "prefer_for_elements_to_map_fromIterable", + "description": "Prefer `for` elements when building maps from iterables.", + "fixStatus": "hasFix" + }, + { + "name": "prefer_foreach", + "description": "Use `forEach` to only apply a function to all the elements.", + "fixStatus": "needsFix" + }, + { + "name": "prefer_function_declarations_over_variables", + "description": "Use a function declaration to bind a function to a name.", + "fixStatus": "hasFix" + }, + { + "name": "prefer_generic_function_type_aliases", + "description": "Prefer generic function type aliases.", + "fixStatus": "hasFix" + }, + { + "name": "prefer_if_elements_to_conditional_expressions", + "description": "Prefer if elements to conditional expressions where possible.", + "fixStatus": "hasFix" + }, + { + "name": "prefer_if_null_operators", + "description": "Prefer using `??` operators.", + "fixStatus": "hasFix" + }, + { + "name": "prefer_initializing_formals", + "description": "Use initializing formals when possible.", + "fixStatus": "hasFix" + }, + { + "name": "prefer_inlined_adds", + "description": "Inline list item declarations where possible.", + "fixStatus": "hasFix" + }, + { + "name": "prefer_int_literals", + "description": "Prefer int literals over double literals.", + "fixStatus": "hasFix" + }, + { + "name": "prefer_interpolation_to_compose_strings", + "description": "Use interpolation to compose strings and values.", + "fixStatus": "hasFix" + }, + { + "name": "prefer_is_empty", + "description": "Use `isEmpty` for `Iterable`s and `Map`s.", + "fixStatus": "hasFix" + }, + { + "name": "prefer_is_not_empty", + "description": "Use `isNotEmpty` for `Iterable`s and `Map`s.", + "fixStatus": "hasFix" + }, + { + "name": "prefer_is_not_operator", + "description": "Prefer is! operator.", + "fixStatus": "hasFix" + }, + { + "name": "prefer_iterable_whereType", + "description": "Prefer to use `whereType` on iterable.", + "fixStatus": "hasFix" + }, + { + "name": "prefer_mixin", + "description": "Prefer using mixins.", + "fixStatus": "needsFix" + }, + { + "name": "prefer_null_aware_method_calls", + "description": "Prefer `null`-aware method calls.", + "fixStatus": "needsFix" + }, + { + "name": "prefer_null_aware_operators", + "description": "Prefer using `null`-aware operators.", + "fixStatus": "hasFix" + }, + { + "name": "prefer_relative_imports", + "description": "Prefer relative imports for files in `lib/`.", + "fixStatus": "hasFix" + }, + { + "name": "prefer_single_quotes", + "description": "Only use double quotes for strings containing single quotes.", + "fixStatus": "hasFix" + }, + { + "name": "prefer_spread_collections", + "description": "Use spread collections when possible.", + "fixStatus": "hasFix" + }, + { + "name": "prefer_typing_uninitialized_variables", + "description": "Prefer typing uninitialized variables and fields.", + "fixStatus": "hasFix" + }, + { + "name": "prefer_void_to_null", + "description": "Don't use the Null type, unless you are positive that you don't want void.", + "fixStatus": "hasFix" + }, + { + "name": "provide_deprecation_message", + "description": "Provide a deprecation message, via `@Deprecated(\"message\")`.", + "fixStatus": "noFix" + }, + { + "name": "public_member_api_docs", + "description": "Document all public members.", + "fixStatus": "noFix" + }, + { + "name": "recursive_getters", + "description": "Property getter recursively returns itself.", + "fixStatus": "noFix" + }, + { + "name": "require_trailing_commas", + "description": "Use trailing commas for all parameter lists and argument lists.", + "fixStatus": "hasFix" + }, + { + "name": "secure_pubspec_urls", + "description": "Use secure urls in `pubspec.yaml`.", + "fixStatus": "noFix" + }, + { + "name": "sized_box_for_whitespace", + "description": "`SizedBox` for whitespace.", + "fixStatus": "hasFix" + }, + { + "name": "sized_box_shrink_expand", + "description": "Use SizedBox shrink and expand named constructors.", + "fixStatus": "needsFix" + }, + { + "name": "slash_for_doc_comments", + "description": "Prefer using `///` for doc comments.", + "fixStatus": "hasFix" + }, + { + "name": "sort_child_properties_last", + "description": "Sort child properties last in widget instance creations.", + "fixStatus": "hasFix" + }, + { + "name": "sort_constructors_first", + "description": "Sort constructor declarations before other members.", + "fixStatus": "hasFix" + }, + { + "name": "sort_pub_dependencies", + "description": "Sort pub dependencies alphabetically.", + "fixStatus": "needsFix" + }, + { + "name": "sort_unnamed_constructors_first", + "description": "Sort unnamed constructor declarations first.", + "fixStatus": "hasFix" + }, + { + "name": "specify_nonobvious_local_variable_types", + "description": "Specify non-obvious type annotations for local variables.", + "fixStatus": "hasFix" + }, + { + "name": "specify_nonobvious_property_types", + "description": "Specify non-obvious type annotations for top-level and static variables.", + "fixStatus": "hasFix" + }, + { + "name": "super_goes_last", + "description": "Place the `super` call last in a constructor initialization list.", + "fixStatus": "noFix" + }, + { + "name": "test_types_in_equals", + "description": "Test type of argument in `operator ==(Object other)`.", + "fixStatus": "noFix" + }, + { + "name": "throw_in_finally", + "description": "Avoid `throw` in `finally` block.", + "fixStatus": "noFix" + }, + { + "name": "tighten_type_of_initializing_formals", + "description": "Tighten type of initializing formal.", + "fixStatus": "needsFix" + }, + { + "name": "type_annotate_public_apis", + "description": "Type annotate public APIs.", + "fixStatus": "hasFix" + }, + { + "name": "type_init_formals", + "description": "Don't type annotate initializing formals.", + "fixStatus": "hasFix" + }, + { + "name": "type_literal_in_constant_pattern", + "description": "Don't use constant patterns with type literals.", + "fixStatus": "hasFix" + }, + { + "name": "unawaited_futures", + "description": "`Future` results in `async` function bodies must be `await`ed or marked `unawaited` using `dart:async`.", + "fixStatus": "hasFix" + }, + { + "name": "unintended_html_in_doc_comment", + "description": "Use of angle brackets in a doc comment is treated as HTML by Markdown.", + "fixStatus": "needsFix" + }, + { + "name": "unnecessary_await_in_return", + "description": "Unnecessary `await` keyword in return.", + "fixStatus": "hasFix" + }, + { + "name": "unnecessary_brace_in_string_interps", + "description": "Avoid using braces in interpolation when not needed.", + "fixStatus": "hasFix" + }, + { + "name": "unnecessary_breaks", + "description": "Don't use explicit `break`s when a break is implied.", + "fixStatus": "hasFix" + }, + { + "name": "unnecessary_const", + "description": "Avoid `const` keyword.", + "fixStatus": "hasFix" + }, + { + "name": "unnecessary_constructor_name", + "description": "Unnecessary `.new` constructor name.", + "fixStatus": "hasFix" + }, + { + "name": "unnecessary_final", + "description": "Don't use `final` for local variables.", + "fixStatus": "hasFix" + }, + { + "name": "unnecessary_getters_setters", + "description": "Avoid wrapping fields in getters and setters just to be \"safe\".", + "fixStatus": "hasFix" + }, + { + "name": "unnecessary_lambdas", + "description": "Don't create a lambda when a tear-off will do.", + "fixStatus": "hasFix" + }, + { + "name": "unnecessary_late", + "description": "Don't specify the `late` modifier when it is not needed.", + "fixStatus": "hasFix" + }, + { + "name": "unnecessary_library_directive", + "description": "Avoid library directives unless they have documentation comments or annotations.", + "fixStatus": "hasFix" + }, + { + "name": "unnecessary_library_name", + "description": "Don't have a library name in a `library` declaration.", + "fixStatus": "hasFix" + }, + { + "name": "unnecessary_new", + "description": "Unnecessary new keyword.", + "fixStatus": "hasFix" + }, + { + "name": "unnecessary_null_aware_assignments", + "description": "Avoid `null` in `null`-aware assignment.", + "fixStatus": "hasFix" + }, + { + "name": "unnecessary_null_aware_operator_on_extension_on_nullable", + "description": "Unnecessary null aware operator on extension on a nullable type.", + "fixStatus": "needsFix" + }, + { + "name": "unnecessary_null_checks", + "description": "Unnecessary `null` checks.", + "fixStatus": "hasFix" + }, + { + "name": "unnecessary_null_in_if_null_operators", + "description": "Avoid using `null` in `??` operators.", + "fixStatus": "hasFix" + }, + { + "name": "unnecessary_nullable_for_final_variable_declarations", + "description": "Use a non-nullable type for a final variable initialized with a non-nullable value.", + "fixStatus": "hasFix" + }, + { + "name": "unnecessary_overrides", + "description": "Don't override a method to do a super method invocation with the same parameters.", + "fixStatus": "hasFix" + }, + { + "name": "unnecessary_parenthesis", + "description": "Unnecessary parentheses can be removed.", + "fixStatus": "hasFix" + }, + { + "name": "unnecessary_raw_strings", + "description": "Unnecessary raw string.", + "fixStatus": "hasFix" + }, + { + "name": "unnecessary_statements", + "description": "Avoid using unnecessary statements.", + "fixStatus": "noFix" + }, + { + "name": "unnecessary_string_escapes", + "description": "Remove unnecessary backslashes in strings.", + "fixStatus": "hasFix" + }, + { + "name": "unnecessary_string_interpolations", + "description": "Unnecessary string interpolation.", + "fixStatus": "hasFix" + }, + { + "name": "unnecessary_this", + "description": "Don't access members with `this` unless avoiding shadowing.", + "fixStatus": "hasFix" + }, + { + "name": "unnecessary_to_list_in_spreads", + "description": "Unnecessary `toList()` in spreads.", + "fixStatus": "hasFix" + }, + { + "name": "unreachable_from_main", + "description": "Unreachable top-level members in executable libraries.", + "fixStatus": "hasFix" + }, + { + "name": "unrelated_type_equality_checks", + "description": "Equality operator `==` invocation with references of unrelated types.", + "fixStatus": "needsEvaluation" + }, + { + "name": "unsafe_html", + "description": "Avoid unsafe HTML APIs.", + "fixStatus": "noFix" + }, + { + "name": "unsafe_variance", + "description": "Unsafe type: Has a type variable in a non-covariant position.", + "fixStatus": "noFix" + }, + { + "name": "use_build_context_synchronously", + "description": "Do not use `BuildContext` across asynchronous gaps.", + "fixStatus": "noFix" + }, + { + "name": "use_colored_box", + "description": "Use `ColoredBox`.", + "fixStatus": "hasFix" + }, + { + "name": "use_decorated_box", + "description": "Use `DecoratedBox`.", + "fixStatus": "hasFix" + }, + { + "name": "use_enums", + "description": "Use enums rather than classes that behave like enums.", + "fixStatus": "hasFix" + }, + { + "name": "use_full_hex_values_for_flutter_colors", + "description": "Prefer an 8-digit hexadecimal integer (for example, 0xFFFFFFFF) to instantiate a Color.", + "fixStatus": "hasFix" + }, + { + "name": "use_function_type_syntax_for_parameters", + "description": "Use generic function type syntax for parameters.", + "fixStatus": "hasFix" + }, + { + "name": "use_if_null_to_convert_nulls_to_bools", + "description": "Use `??` operators to convert `null`s to `bool`s.", + "fixStatus": "needsFix" + }, + { + "name": "use_is_even_rather_than_modulo", + "description": "Prefer intValue.isOdd/isEven instead of checking the result of % 2.", + "fixStatus": "needsFix" + }, + { + "name": "use_key_in_widget_constructors", + "description": "Use key in widget constructors.", + "fixStatus": "hasFix" + }, + { + "name": "use_late_for_private_fields_and_variables", + "description": "Use late for private members with a non-nullable type.", + "fixStatus": "needsFix" + }, + { + "name": "use_named_constants", + "description": "Use predefined named constants.", + "fixStatus": "hasFix" + }, + { + "name": "use_raw_strings", + "description": "Use raw string to avoid escapes.", + "fixStatus": "hasFix" + }, + { + "name": "use_rethrow_when_possible", + "description": "Use rethrow to rethrow a caught exception.", + "fixStatus": "hasFix" + }, + { + "name": "use_setters_to_change_properties", + "description": "Use a setter for operations that conceptually change a property.", + "fixStatus": "noFix" + }, + { + "name": "use_string_buffers", + "description": "Use string buffers to compose strings.", + "fixStatus": "needsFix" + }, + { + "name": "use_string_in_part_of_directives", + "description": "Use string in part of directives.", + "fixStatus": "hasFix" + }, + { + "name": "use_super_parameters", + "description": "Use super-initializer parameters where possible.", + "fixStatus": "hasFix" + }, + { + "name": "use_test_throws_matchers", + "description": "Use throwsA matcher instead of fail().", + "fixStatus": "needsFix" + }, + { + "name": "use_to_and_as_if_applicable", + "description": "Start the name of the method with to/_to or as/_as if applicable.", + "fixStatus": "noFix" + }, + { + "name": "use_truncating_division", + "description": "Use truncating division.", + "fixStatus": "hasFix" + }, + { + "name": "valid_regexps", + "description": "Use valid regular expression syntax.", + "fixStatus": "noFix" + }, + { + "name": "void_checks", + "description": "Don't assign to `void`.", + "fixStatus": "noFix" + } +] \ No newline at end of file diff --git a/pkgs/lints/tool/validate_lib.dart b/pkgs/lints/tool/validate_lib.dart new file mode 100644 index 00000000..38b1ce80 --- /dev/null +++ b/pkgs/lints/tool/validate_lib.dart @@ -0,0 +1,26 @@ +// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:io'; + +import 'package:path/path.dart' as p; + +void main(List args) { + print('Validating that there are no .dart source files in lib/ ...'); + + final dartSourceFiles = Directory('lib') + .listSync(recursive: true) + .whereType() + .where((file) => p.extension(file.path) == '.dart') + .toList(); + + if (dartSourceFiles.isEmpty) { + print('No Dart files found.'); + } else { + for (var file in dartSourceFiles) { + print(' error: found ${file.path}'); + } + exit(1); + } +}