自定义静态分析
静态分析允许您在执行任何代码之前发现问题。它是一个强大的工具,用于防止错误并确保代码符合样式指南。
借助分析器,您可以找到简单的拼写错误。例如,一个意外的分号可能出现在 if
语句中:
dartvoid increment() { if (count < 10) ; count++; }
如果配置正确,分析器会指向分号并产生以下警告:
info - example.dart:9:19 - Unnecessary empty statement. Try removing the empty statement or restructuring the code. - empty_statements
分析器还可以帮助您找到更细微的问题。例如,您可能忘记关闭 sink 方法:
dartvar controller = StreamController<String>();
info - Unclosed instance of 'Sink'. Try invoking 'close' in the function in which the 'Sink' was created. - close_sinks
在 Dart 生态系统中,Dart 分析服务器和其他工具使用 analyzer 包 执行静态分析。
您可以自定义静态分析以查找各种潜在问题,包括 Dart 语言规范 中指定的错误和警告。您还可以配置 linter 规则,以确保您的代码符合 Dart 样式指南 以及 Effective Dart 中的其他建议指南。诸如 dart analyze
、 flutter analyze
和 IDE 和编辑器 之类的工具使用 analyzer 包来评估您的代码。
本文档说明如何使用分析选项文件或 Dart 源代码中的注释来自定义分析器的行为。如果您想将静态分析添加到您的工具中,请参阅 analyzer 包 文档和 分析服务器 API 规范 。
分析选项文件
#将分析选项文件 analysis_options.yaml
放在包的根目录下,与 pubspec 文件位于同一目录中。
这是一个示例分析选项文件:
include: package:lints/recommended.yaml
analyzer:
exclude: [build/**]
language:
strict-casts: true
strict-raw-types: true
linter:
rules:
- cancel_subscriptions
该示例说明了最常见的顶级条目:
- 使用
include: url
从指定的 URL 引入选项,在本例中是从lints
包中的文件引入。由于 YAML 不允许重复键,因此您最多可以包含一个文件。 - 使用
analyzer:
条目自定义静态分析: 启用更严格的类型检查 、 排除文件 、 忽略特定规则 、 更改规则的严重性 或 启用实验 。 - 使用
linter:
条目配置 linter 规则 。
如果分析器找不到包根目录下的分析选项文件,它会向上遍历目录树,查找该文件。如果没有可用文件,分析器将默认为标准检查。
考虑大型项目的以下目录结构:
分析器使用文件 #1 来分析 my_other_package
和 my_other_other_package
中的代码,并使用文件 #2 来分析 my_package
中的代码。
启用更严格的类型检查
#如果您想要比 Dart 类型系统 所要求的更严格的静态检查, 请考虑启用 strict-casts
、 strict-inference
和 strict-raw-types
语言模式:
analyzer:
language:
strict-casts: true
strict-inference: true
strict-raw-types: true
您可以一起或单独使用这些模式;所有模式都默认为 false
。
strict-casts: <bool>
true
值确保类型推断引擎绝不会隐式地从dynamic
类型转换为更具体的类型。以下有效的 Dart 代码包含从jsonDecode
返回的dynamic
值到List<String>
的隐式向下转换,这在运行时可能会失败。此模式会报告潜在的错误,要求您添加显式转换或以其他方式调整代码。
void foo(List<String> lines) {
...
}
void bar(String jsonText) {
foo(jsonDecode(jsonText)); // 隐式转换
}
error - The argument type 'dynamic' can't be assigned to the parameter type 'List<String>'. - argument_type_not_assignable
strict-inference: <bool>
true
值确保类型推断引擎绝不会在无法确定静态类型时选择dynamic
类型。以下有效的 Dart 代码创建一个其类型参数无法推断的Map
,此模式会提示推断失败:
final lines = {}; // 推断失败
lines['Dart'] = 10000;
lines['C++'] = 'one thousand';
lines['Go'] = 2000;
print('Lines: ${lines.values.reduce((a, b) => a + b)}'); // 运行时错误
warning - The type argument(s) of 'Map' can't be inferred - inference_failure_on_collection_literal
strict-raw-types: <bool>
true
值确保类型推断引擎绝不会在由于省略类型参数而无法确定静态类型时选择dynamic
类型。以下有效的 Dart 代码具有一个原始类型的List
变量,此模式会提示原始类型:
List numbers = [1, 2, 3]; // 原始类型的 List
for (final n in numbers) {
print(n.length); // 运行时错误
}
warning - The generic type 'List<dynamic>' should have explicit type arguments but doesn't - strict_raw_type
启用和禁用 linter 规则
#analyzer 包还提供了一个代码 linter。有各种各样的 linter 规则 可用。Linter 往往是非教派的——规则不必相互一致。例如,某些规则更适合常规 Dart 包,而其他规则则专为 Flutter 应用而设计。请注意,与静态分析不同,linter 规则可能会出现误报。
启用 Dart 团队推荐的 linter 规则
#Dart 团队在 lints 包 中提供了两套推荐的 linter 规则:
- 核心规则
- 帮助识别可能在运行或使用 Dart 代码时导致问题的关键问题。所有代码都应该通过这些 linter 规则。上传到 pub.dev 的包具有一个 包评分 ,该评分部分基于通过这些规则。
- 推荐规则
- 帮助识别可能在运行或使用 Dart 代码时导致问题的其他问题,并强制执行单一、惯用的样式和格式。我们建议所有 Dart 代码都使用这些规则,这些规则是核心规则的超集。
要启用任一套 lint,请将 lints 包 添加为开发依赖项:
$ dart pub add --dev lints
然后编辑您的 analysis_options.yaml
文件以包含您首选的规则集:
include: package:lints/<RULE_SET>.yaml
例如,您可以这样包含推荐的规则集:
include: package:lints/recommended.yaml
启用单个规则
#要启用单个 linter 规则,请将 linter:
添加到分析选项文件作为顶级键,然后将 rules:
添加为二级键。在后续行中,指定要应用的规则,前面加上短划线(YAML 列表的语法)。例如:
linter:
rules:
- always_declare_return_types
- cancel_subscriptions
- close_sinks
- combinators_ordering
- comment_references
- invalid_case_patterns
- one_member_abstracts
- only_throw_errors
- prefer_single_quotes
禁用单个规则
#如果您包含像 lints
中的那个分析选项文件,
您可能希望禁用某些包含的规则。禁用单个规则类似于启用它们,但是需要使用映射而不是列表作为 rules:
条目的值,因此每一行都应该包含规则名称后跟 : false
或 : true
。
这是一个分析选项文件的示例,它使用 lints
中的所有推荐规则,除了 avoid_shadowing_type_parameters
。它还启用了 lint await_only_futures
:
include: package:lints/recommended.yaml
linter:
rules:
avoid_shadowing_type_parameters: false
await_only_futures: true
启用分析器插件(实验性)
#分析器对插件具有实验性支持。这些插件与分析器集成,以添加功能,例如新的诊断信息、快速修复和自定义代码补全。您每个 analysis_options.yaml
文件只能启用一个插件。启用分析器插件会增加分析器使用的内存量。
如果您的情况符合以下任一条件,请不要使用分析器插件:
- 您使用的开发机器内存少于 16 GB。
- 您使用的是包含 10 个以上
pubspec.yaml
和analysis_options.yaml
文件的单体仓库。
您可以在 pub.dev 上找到一些分析器插件。
要启用插件:
将包含插件的包添加为开发依赖项。
$ dart pub add --dev <your_favorite_analyzer_plugin_package>
编辑您的
analysis_options.yaml
文件以启用插件。yamlanalyzer: plugins: - your_favorite_analyzer_plugin_package
要指示要启用的特定插件功能,例如新的诊断信息,可能需要额外的设置。
从分析中排除代码
#有时,某些代码无法通过分析是可以的。例如,您可能依赖于您不拥有的包生成的代码——生成的代码有效,但在静态分析期间会产生警告。或者 linter 规则可能会导致您想要抑制的误报。
您可以通过几种方法从分析中排除代码:
- 从分析中排除整个文件。
- 阻止将特定非错误规则应用于单个文件。
- 阻止将特定非错误规则应用于代码的单个行。
您还可以 禁用特定规则 用于所有文件或 更改规则的严重性 。
排除文件
#要从静态分析中排除文件,请使用 exclude:
分析器选项。您可以列出单个文件,或使用 glob 模式语法。所有 glob 模式的用法都应相对于包含 analysis_options.yaml
文件的目录。
analyzer:
exclude:
- lib/client.dart
- lib/server/*.g.dart
- test/_data/**
抑制文件的诊断信息
#要忽略特定文件的特定非错误诊断信息,请向该文件添加 ignore_for_file
注释:
// ignore_for_file: unused_local_variable
这会作用于整个文件,在注释之前或之后,对于生成的代码特别有用。
要抑制多个诊断信息,请使用逗号分隔的列表:
// ignore_for_file: unused_local_variable, duplicate_ignore, dead_code
要抑制所有 linter 规则,请添加 type=lint
说明符:
// ignore_for_file: type=lint
抑制代码行的诊断信息
#要抑制 Dart 代码特定行上的特定非错误诊断信息,请在代码行上方放置 ignore
注释。这是一个忽略导致运行时错误的代码的示例,就像您在语言测试中可能做的那样:
// ignore: invalid_assignment
int x = '';
要抑制多个诊断信息,请提供逗号分隔的列表:
// ignore: invalid_assignment, const_initialized_with_non_constant_value
const x = y;
或者,将 ignore 注释附加到它适用的行:
int x = ''; // ignore: invalid_assignment
在 pubspec 文件中抑制诊断信息
#如果您需要从 pubspec.yaml
文件中的分析器中抑制非错误诊断信息,请在受影响的行上方添加 ignore
注释。
以下示例忽略了 sort_pub_dependencies
lint,因为它希望首先放置 flutter
依赖项:
dependencies:
flutter:
sdk: flutter
# ignore: sort_pub_dependencies
collection: ^1.19.0
自定义分析规则
#每个 分析器诊断信息 和 linter 规则 都有默认严重性。您可以使用分析选项文件来更改单个规则的严重性,或始终忽略某些规则。
分析器支持三个严重性级别:
info
- 一条不会导致分析失败的信息消息。 示例:
dead_code
warning
- 一条警告,除非分析器配置为将警告视为错误,否则不会导致分析失败。 示例:
invalid_null_aware_operator
error
- 一个导致分析失败的错误。 示例:
invalid_assignment
忽略规则
#您可以使用 errors:
字段忽略特定的 分析器诊断信息 和 linter 规则 。列出规则,后跟 : ignore
。例如,以下分析选项文件指示分析工具忽略 TODO 规则:
analyzer:
errors:
todo: ignore
更改规则的严重性
#您可以全局更改特定规则的严重性。此技术适用于常规分析问题以及 lint。例如,以下分析选项文件指示分析工具将无效赋值视为警告,将缺少返回值视为错误,并提供有关死代码的信息(而不是警告或错误):
analyzer:
errors:
invalid_assignment: warning
missing_return: error
dead_code: info
资源
#使用以下资源来了解有关 Dart 中静态分析的更多信息:
除非另有说明,否则本网站上的文档反映的是 Dart 3.6.0。页面最后更新于 2025-02-05。 查看源代码 或 报告问题.