| # pedantic |
| |
| [](https://pub.dev/packages/pedantic) |
| |
| This package serves three purposes: |
| |
| - It documents how Dart static analysis is used internally at Google, |
| including best practices for the code we write. The documentation is |
| this `README.md`. |
| - It contains a corresponding sample `analysis_options.yaml`. |
| - It contains occasional small snippets of Dart code that are used in |
| implementing those best practices. |
| |
| Note that everything here fits within the guidelines set out in |
| [Effective Dart](https://www.dartlang.org/guides/language/effective-dart). |
| You could think of that document as the _design_ and this package as one |
| possible partial _implementation_. |
| |
| See |
| [this Medium article](https://medium.com/dartlang/pedantic-dart-1c7d365510de) |
| for more background. |
| |
| |
| ## Using Static Analysis |
| |
| Here is how static analysis is used internally at Google: |
| |
| - By default we disallow checking in code with any errors, warnings, or hints. |
| - The `TODO` hint is a permanent exception. |
| - Deprecation hints are a permanent exception. Deprecations are handled |
| separately on a case by case basis. |
| - `unused_element`, `unused_field` and `unused_local_variable` are allowed. |
| - When a new SDK version adds new errors, warnings or hints, we either clean |
| up everything before switching SDK version or maintain a whitelist of |
| allowed violations so it can be gradually cleaned up. |
| - Lints are considered and enabled on a case by case basis. When enabling a |
| lint we first clean up all pre-existing violations. After it's enabled, any |
| attempt to check in a further violation will be blocked. |
| |
| ## Enabled Lints |
| |
| The currently enabled lints can be found in |
| [analysis_options.1.9.0.yaml](https://github.com/dart-lang/pedantic/blob/master/lib/analysis_options.1.9.0.yaml). |
| |
| ## Using the Lints |
| |
| To use the lints add a dependency in your `pubspec.yaml`: |
| |
| ```yaml |
| # If you use `package:pedantic/pedantic.dart`, add a normal dependency. |
| dependencies: |
| pedantic: ^1.9.0 |
| |
| # Or, if you just want `analysis_options.yaml`, it can be a dev dependency. |
| dev_dependencies: |
| pedantic: ^1.9.0 |
| ``` |
| |
| then, add an include in your `analysis_options.yaml`. If you want to always |
| use the latest version of the lints, add a dependency on the main |
| `analysis_options` file: |
| |
| |
| ```yaml |
| include: package:pedantic/analysis_options.yaml |
| ``` |
| |
| If your continuous build and/or presubmit check lints then they will likely |
| fail whenever a new version of `package:pedantic` is released. To avoid this, |
| specify a specific version of `analysis_options.yaml` instead: |
| |
| ```yaml |
| include: package:pedantic/analysis_options.1.9.0.yaml |
| ``` |
| |
| ## Unused Lints |
| |
| The following lints have been considered and will _not_ be enforced: |
| |
| `always_put_control_body_on_new_line` |
| violates Effective Dart "DO format your code using dartfmt". See note about |
| Flutter SDK style below. |
| |
| `always_put_required_named_parameters_first` |
| does not allow for other logical orderings of parameters, such as matching the |
| class field order or alphabetical. |
| |
| `always_specify_types` |
| violates Effective Dart "AVOID type annotating initialized local variables" |
| and others. See note about Flutter SDK style below. |
| |
| `avoid_annotating_with_dynamic` |
| violates Effective Dart "PREFER annotating with `dynamic` instead of letting |
| inference fail". |
| |
| `avoid_as` |
| does not reflect common usage. See note about Flutter SDK style below. |
| |
| `avoid_catches_without_on_clauses` |
| is too strict, catching anything is useful and common even if not always the |
| most correct thing to do. |
| |
| `avoid_catching_errors` |
| is too strict, the distinction between `Error` and `Exception` is followed |
| closely in the SDK but is impractical to follow everywhere. |
| |
| `avoid_classes_with_only_static_members` |
| is too strict, Effective Dart explicitly calls out some cases (constants, |
| enum-like types) where it makes sense to violate this lint. |
| |
| `avoid_double_and_int_checks` |
| only applies to web, but there is currently no mechanism for enabling a lint |
| on web code only. |
| |
| `avoid_equals_and_hashcode_on_mutable_classes` |
| would require the `@immutable` annotation to be consistently and correctly |
| used everywhere. |
| |
| `avoid_field_initializers_in_const_classes` |
| does not offer a clear readability benefit. |
| |
| `avoid_js_rounded_ints` |
| only applies to web, but there is currently no mechanism for enabling a lint |
| on web code only. |
| |
| `avoid_print` |
| is too strict, it's okay to `print` in some code. |
| |
| `avoid_returning_null` |
| will be obsoleted by NNBD. |
| |
| `avoid_returning_this` |
| has occasional false positives, and adds little value as the cascade operator |
| for fluent interfaces in Dart is already very popular. |
| |
| `avoid_slow_async_io` |
| gives wrong advice if the underlying filesystem has unusual properties, for |
| example a network mount. |
| |
| `avoid_void_async` |
| prevents a valid style where an asynchronous method has a `void` return type |
| to indicate that nobody should `await` for the result. |
| |
| `cancel_subscriptions` |
| has false positives when you use a utility method or class to call `cancel`. |
| |
| `close_sinks` |
| has false positives when you use a utility method or class to call `close`. |
| |
| `constant_identifier_names` |
| is too strict as it does not support the exceptions allowed in Effective Dart |
| for use of ALL_CAPS. |
| |
| `control_flow_in_finally` |
| does not offer enough value: people are unlikely to do this by accident, |
| and there are occasional valid uses. |
| |
| `directives_ordering` |
| would enforce a slightly different ordering to that used by IntelliJ and other |
| tools using the analyzer. |
| |
| `empty_statements` |
| is superfluous, enforcing use of `dartfmt` is sufficient to make empty |
| statements obvious. |
| |
| `flutter_style_todos` |
| is for Flutter SDK internal use, see note about Flutter SDK style below. |
| |
| `invariant_booleans` |
| is experimental. |
| |
| `join_return_with_assignment` |
| does not reflect common usage. |
| |
| `one_member_abstracts` |
| is too strict, classes might implement more than one such abstract class and |
| there is no equivalent way to do this using functions. |
| |
| `parameter_assignments` |
| does not reflect common usage, and will cause particular problems with NNBD |
| code. |
| |
| `prefer_asserts_in_initializer_lists` |
| does not reflect common usage. |
| |
| `prefer_asserts_with_message` |
| is too strict; some asserts do not benefit from documentation. |
| |
| `prefer_bool_in_asserts` |
| is obsolete in Dart 2; bool is required in asserts. |
| |
| `prefer_const_constructors` |
| would add a lot of noise to code now that `new` is optional. |
| |
| `prefer_const_constructors_in_immutables` |
| does not often apply as `@immutable` is not widely used. |
| |
| `prefer_const_literals_to_create_immutables` |
| is too strict, requiring `const` everywhere adds noise. |
| |
| `prefer_constructors_over_static_methods` |
| is too strict, in some cases static methods are better. |
| |
| `prefer_double_quotes` |
| does not reflect common usage. |
| |
| `prefer_expression_function_bodies` |
| is too strict, braces look better for long expressions. |
| |
| `prefer_final_in_for_each` |
| does not reflect common usage. |
| |
| `prefer_final_locals` |
| does not reflect common usage. |
| |
| `prefer_foreach` |
| is too strict; `forEach` is not always an improvement. |
| |
| `prefer_int_literals` |
| does not reflect common usage. |
| |
| `prefer_typing_uninitialized_variables` |
| will be obsoleted by NNBD, which comes with type inference for uninitialized |
| variables. |
| |
| `literal_only_boolean_expressions` |
| does not offer enough value: such expressions are easily spotted and so hard |
| to add by accident. |
| |
| `no_adjacent_strings_in_list` |
| does not offer enough value: adjacent strings in lists are easily spotted |
| when the code is formatted with `dartfmt`. |
| |
| `sort_constructors_first` |
| does not reflect common usage. |
| |
| `sort_unnamed_constructors_first` |
| is too strict, people are free to choose the best constructor ordering. |
| |
| `test_types_in_equals` |
| does not offer enough value: there are plenty of other mistakes possible in |
| `operator ==` implementations. It's better to use codegen. |
| |
| `unnecessary_null_aware_assignments` |
| does not offer enough value: this is hard to do by mistake, and harmless. |
| |
| `use_setters_to_change_properties` |
| is too strict: it can't detect when something is conceptually a property. |
| |
| `use_to_and_if_as_applicable` |
| is too strict: it can't detect when the style rule actually applies. |
| |
| `throw_in_finally` |
| does not offer enough value: people are unlikely to do this by accident, |
| and there are occasional valid uses. |
| |
| Note on Flutter SDK Style: some lints were created specifically to support |
| Flutter SDK development. Flutter app developers should instead use standard |
| Dart style as described in Effective Dart, and should not use these lints. |
| |
| ## Features and bugs |
| |
| Please file feature requests and bugs at the [issue tracker][tracker]. |
| |
| [tracker]: https://github.com/dart-lang/pedantic/issues |