內容

自訂靜態分析

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

在分析器的協助下,您可以找出簡單的拼字錯誤。例如,意外的セミコロン可能出現在 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 分析伺服器和其他工具使用 analyzer 套件 來執行靜態分析。

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

此文件說明如何使用分析選項檔案或 Dart 原始碼中的註解自訂分析器的行為。如果您想要將靜態分析新增到您的工具,請參閱 analyzer 套件 文件和 分析伺服器 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 規則

#

analyzer 套件也提供程式碼 linter。有各種各樣的 linter 規則 可用。linter 往往是非宗派的,規則彼此之間不必一致。例如,有些規則較適合一般 Dart 套件,而其他規則則設計用於 Flutter 應用程式。請注意,與靜態分析不同,linter 規則可能會產生誤報。

啟用 Dart 團隊建議的 Linter 規則

#

Dart 團隊在 lints 套件 中提供兩組建議的 linter 規則

核心規則
協助識別在執行或使用 Dart 程式碼時可能會導致問題的重大問題。所有程式碼都應該通過這些 linter 規則。上傳到 pub.dev 的套件有一個 套件評分,部分根據通過這些規則來評分。
建議的規則
協助識別在執行或使用 Dart 程式碼時可能會導致問題的其他問題,並強制使用單一的慣用樣式和格式。我們建議所有 Dart 程式碼都使用這些規則,這些規則是核心規則的超集。

若要啟用任一組 lints,請將 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
    - library_annotations
    - one_member_abstracts
    - only_throw_errors

停用個別規則

#

如果您包含 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;

或者,將忽略註解附加到它適用的行

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.18.0

自訂分析規則

#

每個 分析器診斷linter 規則 都有預設嚴重性。您可以使用分析選項檔案變更個別規則的嚴重性,或永遠忽略某些規則。

分析器支援三個嚴重性等級

資訊
不會導致分析失敗的資訊訊息。範例:dead_code
警告
除非分析器設定將警告視為錯誤,否則不會導致分析失敗的警告。範例:invalid_null_aware_operator
錯誤
導致分析失敗的錯誤。範例: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 中的靜態分析