Customize Static Analysis
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 an analysis options file. 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:
analyzer: strong-mode: implicit-casts: false implicit-dynamic: false errors: todo: ignore exclude: - flutter/** - lib/api/*.dart linter: rules: - avoid_empty_else - cancel_subscriptions - close_sinks
YAML is sensitive to whitespace—don’t use tabs in a YAML file, and use 2 spaces to denote each level of indentation.
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 will use file #1 to analyze the code in
my_other_other_package, and file #2 to analyze the code in
Specifying strong mode
The Dart 1.x language spec supports dynamic typing, allowing you to write code that has no type annotations at all. Strong mode applies more restrictive rules to the type system and, as a result, finds more errors during static analysis and at runtime. Another benefit of strong mode is faster compilation. Some tools, such as dartdevc, require strong mode compliance.
The simplest way to enable strong mode is to specify
strong-mode: true in the analysis-options file:
analyzer: strong-mode: true
Strong mode is disabled by default. Instead of specifying
you can use the following flags to look for specific types
of implicit casting, on top of the standard strong mode checks.
The presence of either flag, regardless of value, enables strong mode.
- 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);
This flag defaults to
- A value of
falseensures that the type inference engine never chooses the
dynamictype when it can’t determine a static type. This flag defaults to
To disallow both implicit downcasts and implicit dynamic types in the analysis options file:
analyzer: strong-mode: implicit-casts: false implicit-dynamic: false
Enabling linter rules
The analyzer package also provides a code linter. A wide variety of linter rules are available. Linters tend to be non denominational—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 some of the linter rules don’t play well with strong mode, and linter rules can have false positives, unlike static analysis.
To enable a 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:
analyzer: strong-mode: true 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_interp
Perhaps you rely on code generated from a package that
you don’t own—the generated code works,
but produces errors during static analysis.
You can exclude files from static analysis using the
analyzer: strong-mode: true exclude: - lib/client/piratesapi.dart
You can specify a group of files using glob syntax:
analyzer: strong-mode: true exclude: - src/test/_data/** - test/*_example.dart
Excluding lines within a file
Perhaps one of the linter rules causes a false positive and you want to suppress that warning. To suppress a specific rule on a specific line of code, preceed that line with a comment using the following format:
// ignore: <linter rule>
// ignore: invalid_assignment int x = '';
If you want to suppress more than one rule, supply a comma-separated list. For example:
// ignore: invalid_assignment, const_initialized_with_non_constant_value const x = y;
Ignoring specific analysis rules
Sometimes your code doesn’t fit perfectly within the standard
analysis guidelines, or violates a rule here or there, for
reasons you’d rather not get into. You can ignore specific
rules during analysis using the
errors: field. List the
rule, followed by
: ignore. For example:
analyzer: errors: todo: ignore
This analysis options file instructs the analysis tools to ignore the TODO rule.
Alternatively, as of Dart 1.24 you can ignore a specific rule for a
specific file using an
// ignore_for_file: unused_import
This acts for the whole file, before or after the comment, and is particularly useful for generated code. A comma-separated list may be used to suppress more than one rule:
// ignore_for_file: unused_import, invalid_assignment
Changing the severity of analysis rules
Using the same mechanism, you can also globally change the severity
of a particular rule using one of the following values:
info. This works for regular analysis issues as well as
for lints. For example:
analyzer: errors: invalid_assignment: warning missing_return: error dead_code: info
This analysis options file instructs the analysis tools to ignore unused local variables, treat invalid assignments as warnings and missing returns as errors, and only provide information about dead code.
Use the following resources to learn more about static analysis in Dart: