Customizing static analysis
- The analysis options file
- Enabling stricter type checks
- Enabling and disabling linter rules
- Excluding code from analysis
- Customizing analysis rules
Static analysis allows you to find problems before executing a single line of code. It’s a powerful tool used to prevent bugs and ensure that code conforms to style guidelines.
With the help of the analyzer, you can find
simple typos. For example, perhaps an accidental semicolon
made its way into an
The analyzer can also help you find more subtle problems. For example, perhaps you’ve forgotten to close a sink method:
In the Dart ecosystem, the Dart Analysis Server and other tools use the analyzer package to perform static analysis.
You can customize static analysis to look for a variety of potential
problems, including errors and warnings specified in the
Dart language spec.
You can also configure the linter, one of the analyzer’s plugins,
to ensure that your code complies with the
Dart Style Guide
and other suggested guidelines in
Effective Dart. Dart tools such as the
Dart dev compiler (dartdevc),
and JetBrains IDEs
use the analyzer package to evaluate your code.
This document explains how to customize the behavior of the analyzer using either an analysis options file or comments in Dart source code. If you want to add static analysis to your tool, see the analyzer package docs and the Analysis Server API Specification.
The analysis options file
Place the analysis options file,
at the root of the package, in the same directory as the pubspec file.
Here’s a sample analysis options file:
include: package:pedantic/analysis_options.yaml linter: rules: - camel_case_types analyzer: # exclude: # - path/to/excluded/files/**
include: url entry
brings in YAML code from the specified URL — in this case,
from a file in the
linter: entry enables linter rules.
You can use the
analyzer: entry to customize static analysis —
enabling stricter type checks,
ignoring specific rules, or
changing the severity of rules.
Another tag you might see is
which is used for experimental language features.
If the analyzer can’t find an analysis options file at the package root, it walks up the directory tree, looking for one. If no file is available, the analyzer defaults to standard checks.
Consider the following directory structure for a large project:
The analyzer uses file #1 to analyze the code in
my_other_other_package, and file #2 to analyze the code in
Enabling stricter type checks
If you want stricter static checks than
the Dart type system requires,
consider using the
analyzer: strong-mode: implicit-casts: false implicit-dynamic: false
You can use the flags together or separately;
both default to
- A value of
falseensures that the type inference engine never implicitly casts to a more specific type. The following valid Dart code includes an implicit downcast that would be caught by this flag:
Object o = ...; String s = o; // Implicit downcast String s2 = s.substring(1);
- A value of
falseensures that the type inference engine never chooses the
dynamictype when it can’t determine a static type.
Enabling and disabling linter rules
The analyzer package also provides a code linter. A wide variety of linter rules are available. Linters tend to be nondenominational—rules don’t have to agree with each other. For example, some rules are more appropriate for library packages and others are designed for Flutter apps. Note that linter rules can have false positives, unlike static analysis.
Enabling default Google rules: pedantic
To enable the list of linter rules that Google uses in its own Dart code,
depend on the pedantic package
and include its
Unless you need to use the
pedantic API, declare a dev dependency on
dev_dependencies: pedantic: ^1.0.0
pub get, and then
add the following line to your
Enabling individual rules
To enable a single linter rule, add
linter: to the analysis options file,
On subsequent lines, specify the rules that you want to apply,
prefixed with dashes. For example:
linter: rules: - always_declare_return_types - camel_case_types - empty_constructor_bodies - annotate_overrides - avoid_init_to_null - constant_identifier_names - one_member_abstracts - slash_for_doc_comments - sort_constructors_first - unnecessary_brace_in_string_interps
Disabling individual rules
If you include an analysis options file such as the one in
you might want to disable some of the included rules.
Disabling individual rules is similar enabling them,
but with two differences:
- Omit the dash (
-) before the rule name.
: falseafter the rule name.
Here’s an example of an analysis options file
that uses all pedantic rules except
It also adds the lint
include: package:pedantic/analysis_options.yaml linter: rules: avoid_shadowing_type_parameters: false await_only_futures: true
<aside class=”alert alert-warning” markdown=”1”>
If you disable any rules, then use key-value syntax to enable rules.
For example, the preceding example can’t use
instead, it must use
The reason it can’t use the dash shortcut (
-) to enable
is that YAML doesn’t support mixing list and key-value syntaxes.
Excluding code from analysis
Sometimes it’s OK for some code to fail analysis. For example, you might rely on code generated by a package that you don’t own—the generated code works, but produces errors during static analysis. Or a linter rule might cause a false positive that you want to suppress.
You have several ways to exclude code from analysis:
- Exclude entire files from analysis.
- Stop specific rules from being applied to individual files.
- Stop specific rules from being applied to individual lines of code.
- Ignore specific rules or errors.
You can also change the severity of rules.
To exclude files from static analysis,
exclude: in the analysis options file:
analyzer: exclude: - lib/client/piratesapi.dart
You can specify a group of files using glob syntax:
analyzer: exclude: - src/test/_data/** - test/*_example.dart
Suppressing rules for a file
To ignore a specific rule for a specific file,
ignore_for_file comment to the file:
// ignore_for_file: unused_import
This acts for the whole file, before or after the comment, and is particularly useful for generated code.
To suppress more than one rule, use a comma-separated list:
// ignore_for_file: unused_import, invalid_assignment
Suppressing rules for a line of code
To suppress a specific rule on a specific line of code,
preceed that line with an
// ignore: <linter rule>
Here’s example of ignoring code that causes a runtime error, as you might do in a language test:
// ignore: invalid_assignment int x = '';
To suppress more than one rule, supply a comma-separated list:
// ignore: invalid_assignment, const_initialized_with_non_constant_value const x = y;
Alternatively, append the ignore rule to the line that it applies to:
int x = ''; // ignore: invalid_assignment
Customizing analysis rules
The analyzer supports three severity levels:
- An informational message that doesn’t cause analysis to fail.
- A warning that doesn’t cause analysis to fail unless
the analyzer is configured to treat warnings as errors.
- An error that causes analysis to fail.
You can ignore specific analyzer error codes and linter rules
by using the
List the rule, followed by
: ignore. For example, the following
analysis options file instructs the analysis tools to ignore the TODO rule:
analyzer: errors: todo: ignore
Changing the severity of rules
You can globally change the severity of a particular rule. This technique works for regular analysis issues as well as for lints. For example, the following analysis options file instructs the analysis tools to treat invalid assignments as warnings and missing returns as errors, and to provide information (but not a warning or error) about dead code:
analyzer: errors: invalid_assignment: warning missing_return: error dead_code: info
Use the following resources to learn more about static analysis in Dart: