目錄

自訂靜態分析

靜態分析可讓您在執行任何程式碼之前找出問題。這是一個強大的工具,用於防止錯誤並確保程式碼符合樣式指南。

在分析器的協助下,您可以找到簡單的錯字。例如,可能有一個意外的分號進入 if 陳述式

dart
void 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 方法

dart
var controller = StreamController<String>();
info - Unclosed instance of 'Sink'. Try invoking 'close' in the function in which the 'Sink' was created. - close_sinks

在 Dart 生態系統中,Dart 分析伺服器和其他工具會使用 分析器套件來執行靜態分析。

您可以自訂靜態分析,以尋找各種潛在問題,包括Dart 語言規格中指定的錯誤和警告。您也可以設定 linter 規則,以確保您的程式碼符合Dart 樣式指南以及有效的 Dart中的其他建議準則。諸如dart analyzeflutter analyzeIDE 和編輯器等工具會使用分析器套件來評估您的程式碼。

本文件說明如何使用分析選項檔案或 Dart 原始程式碼中的註解來自訂分析器的行為。如果您想將靜態分析新增至您的工具,請參閱 分析器套件文件和 分析伺服器 API 規格

分析選項檔案

#

將分析選項檔案 analysis_options.yaml 放在套件的根目錄中,與 pubspec 檔案放在同一個目錄中。

以下是分析選項檔案的範例

analysis_options.yaml
yaml
include: package:lints/recommended.yaml

analyzer:
  exclude: [build/**]
  language:
    strict-casts: true
    strict-raw-types: true

linter:
  rules:
    - cancel_subscriptions

此範例說明最常見的頂層項目

如果分析器在套件根目錄找不到分析選項檔案,則會向上走訪目錄樹,尋找該檔案。如果沒有可用的檔案,分析器會預設為標準檢查。

請考慮大型專案的以下目錄結構

project root contains analysis_options.yaml (#1) and 3 packages, one of which (my_package) contains an analysis_options.yaml file (#2).

分析器會使用檔案 #1 來分析 my_other_packagemy_other_other_package 中的程式碼,並使用檔案 #2 來分析 my_package 中的程式碼。

啟用更嚴格的類型檢查

#

如果您想要比Dart 類型系統要求更嚴格的靜態檢查,請考慮啟用 strict-castsstrict-inferencestrict-raw-types 語言模式

analysis_options.yaml
yaml
analyzer:
  language:
    strict-casts: true
    strict-inference: true
    strict-raw-types: true

您可以一起或分開使用這些模式;所有模式的預設值都是 false

strict-casts: <bool>
值為 true 可確保類型推斷引擎絕不會從 dynamic 隱含轉換為更明確的類型。以下有效的 Dart 程式碼包含從 jsonDecode 傳回的 dynamic 值到 List<String> 的隱含向下轉型,這可能會在執行階段失敗。此模式會報告潛在錯誤,要求您新增明確轉換或以其他方式調整程式碼。
✗ 靜態分析:失敗dart
void foo(List<String> lines) {
  ...
}

void bar(String jsonText) {
  foo(jsonDecode(jsonText)); // Implicit cast
}
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,導致此模式產生推斷失敗提示
✗ 靜態分析:失敗dart
final lines = {}; // Inference failure
lines['Dart'] = 10000;
lines['C++'] = 'one thousand';
lines['Go'] = 2000;
print('Lines: ${lines.values.reduce((a, b) => a + b)}'); // Runtime error

warning - The type argument(s) of 'Map' can't be inferred - inference_failure_on_collection_literal
strict-raw-types: <bool>
值為 true 可確保類型推斷引擎在因為省略類型引數而無法判斷靜態類型時,絕不會選擇 dynamic 類型。以下有效的 Dart 程式碼具有一個原始類型的 List 變數,導致此模式產生原始類型提示
✗ 靜態分析:失敗dart
List numbers = [1, 2, 3]; // List with raw type
for (final n in numbers) {
  print(n.length); // Runtime error
}
warning - The generic type 'List<dynamic>' should have explicit type arguments but doesn't - strict_raw_type

啟用和停用 linter 規則

#

分析器套件也提供程式碼 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 檔案,以包含您偏好的規則集

yaml
include: package:lints/<RULE_SET>.yaml

例如,您可以像這樣包含建議的規則集

yaml
include: package:lints/recommended.yaml

啟用個別規則

#

要啟用單個 linter 規則,請將 linter: 作為頂層鍵加入分析選項檔案,然後將 rules: 作為第二層鍵。在後續的行中,指定您要套用的規則,並以破折號作為前綴(YAML 清單的語法)。例如

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

analysis_options.yaml
yaml
include: package:lints/recommended.yaml

linter:
  rules:
    avoid_shadowing_type_parameters: false
    await_only_futures: true

啟用分析器外掛程式 (實驗性)

#

分析器對外掛程式有實驗性的支援。這些外掛程式與分析器整合,以新增診斷、快速修復和自訂程式碼完成等功能。您每個 analysis_options.yaml 檔案只能啟用一個外掛程式。啟用分析器外掛程式會增加分析器使用的記憶體量。

如果您的情況符合以下任一條件,請不要使用分析器外掛程式

  • 您使用的開發機器記憶體小於 16 GB。
  • 您使用單一儲存庫,其中包含超過 10 個 pubspec.yamlanalysis_options.yaml 檔案。

您可以在 pub.dev 上找到一些分析器外掛程式。

要啟用外掛程式

  1. 將包含外掛程式的套件新增為開發相依性。

    $ dart pub add --dev <your_favorite_analyzer_plugin_package>
  2. 編輯您的 analysis_options.yaml 檔案以啟用外掛程式。

    yaml
    analyzer:
      plugins:
        - your_favorite_analyzer_plugin_package

    若要指示要啟用的特定外掛程式功能,例如新的診斷,可能需要額外的設定。

從分析中排除程式碼

#

有時,某些程式碼分析失敗是可以接受的。例如,您可能依賴於您不擁有的套件所產生的程式碼 — 產生的程式碼可以運作,但在靜態分析期間會產生警告。或者,linter 規則可能會產生您想要抑制的誤判。

您有幾種方法可以將程式碼排除在分析之外

  • 將整個檔案排除在分析之外。
  • 停止將特定的非錯誤規則套用到個別檔案。
  • 停止將特定的非錯誤規則套用到個別程式碼行。

您也可以停用所有檔案的特定規則變更規則的嚴重性

排除檔案

#

若要將檔案排除在靜態分析之外,請使用 exclude: 分析器選項。您可以列出個別檔案,或使用 glob 模式語法。所有 glob 模式的使用都應相對於包含 analysis_options.yaml 檔案的目錄。

yaml
analyzer:
  exclude:
    - lib/client.dart
    - lib/server/*.g.dart
    - test/_data/**

隱藏檔案的診斷訊息

#

若要忽略特定檔案的特定非錯誤診斷,請將 ignore_for_file 註解新增到檔案中

dart
// ignore_for_file: unused_local_variable

這適用於整個檔案,無論註解之前或之後,並且對於產生的程式碼特別有用。

若要抑制多個診斷,請使用逗號分隔的清單

dart
// ignore_for_file: unused_local_variable, duplicate_ignore, dead_code

若要抑制所有 linter 規則,請新增 type=lint 指定符

dart
// ignore_for_file: type=lint

隱藏程式碼行的診斷訊息

#

若要抑制特定 Dart 程式碼行上的特定非錯誤診斷,請在程式碼行上方放置一個 ignore 註解。以下是一個忽略導致執行階段錯誤的程式碼的範例,您可能會在語言測試中這樣做

dart
// ignore: invalid_assignment
int x = '';

若要抑制多個診斷,請提供逗號分隔的清單

dart
// ignore: invalid_assignment, const_initialized_with_non_constant_value
const x = y;

或者,將 ignore 註解附加到它所適用的行

dart
int x = ''; // ignore: invalid_assignment

隱藏 pubspec 檔案中的診斷訊息

#

如果您需要抑制 pubspec.yaml 檔案中分析器發出的非錯誤診斷,請在受影響的行上方新增一個 ignore 註解。

以下範例忽略了 sort_pub_dependencies lint,因為它想要將 flutter 相依性放在第一位

pubspec.yaml
yaml
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 規則

yaml
analyzer:
  errors:
    todo: ignore

變更規則的嚴重性

#

您可以全域變更特定規則的嚴重性。此技術適用於常規分析問題以及 lints。例如,以下分析選項檔案指示分析工具將無效的指派視為警告,將遺失的返回視為錯誤,並提供有關無用程式碼的資訊(但不是警告或錯誤)

yaml
analyzer:
  errors:
    invalid_assignment: warning
    missing_return: error
    dead_code: info

資源

#

使用以下資源來了解有關 Dart 中靜態分析的更多資訊