SKILL.md
readonlyread-only
name
dart-fix-runtime-errors
description
Uses get_runtime_errors and lsp to fetch an active stack trace, locate the failing line, apply a fix, and verify resolution via hot_reload.
解決 Dart 靜態分析錯誤
目錄
核心概念與指南
型別系統與健全性
強制執行 Dart 的健全型別系統,以防止執行時期無效狀態。
- 方法覆寫: 維持健全的回傳型別(covariant)與參數型別(contravariant)。除非明確標記
covariant關鍵字,否則切勿在子類別中縮小參數型別。 - 泛型與集合: 為泛型類別(例如
List<T>、Map<K, V>)加入明確的型別註解。切勿將List<dynamic>指派給有型別的列表(例如List<Cat>)。 - 向下轉型: 避免從
dynamic隱含向下轉型。必要時使用明確轉型(例如as List<Cat>),但需確保底層執行時期型別相符,以防止TypeError例外。 - 嚴格轉型: 在
analysis_options.yaml的analyzer: language:下啟用strict-casts: true,以強制明確轉型並在編譯時期捕捉隱含向下轉型錯誤。
空值安全
透過正確管理變數初始化與可空性,消除與空值安全相關的靜態錯誤。
- 修飾詞: 對可空型別使用
?,對空值斷言使用!,對不可為空的具名參數使用required。 - 延遲初始化: 對保證在使用前初始化的非可空變數使用
late關鍵字。特別適用於 Dart 的控制流程分析無法明確證明初始化的頂層或實例變數。 - 萬用字元: 使用
_萬用字元變數(Dart 3.7+)表示非綁定的區域變數或參數,以避免未使用變數的警告。
錯誤處理
區分可復原的例外與不可復原的錯誤。
- 捕捉: 對可復原的失敗捕捉
Exception子型別。 - 錯誤: 切勿明確捕捉
Error或其子型別(例如TypeError、ArgumentError)。錯誤表示程式設計錯誤,必須修復而非捕捉。透過啟用avoid_catching_errors檢查規則來強制執行。 - 重新拋出: 在
catch區塊內使用rethrow傳播例外,同時保留其原始堆疊追蹤。
工作流程
工作流程:靜態分析解析
使用此順序性工作流程來識別、修復並驗證 Dart 專案中的靜態分析錯誤。複製檢查清單以追蹤進度。
任務進度:
- [ ] 1. 執行靜態分析器。
- [ ] 2. 套用自動修復。
- [ ] 3. 手動解決其餘錯誤。
- [ ] 4. 驗證修復(回饋迴圈)。
1. 執行靜態分析器
執行 Dart 分析器以識別目標目錄或檔案中的所有靜態錯誤。
dart analyze . --fatal-infos
2. 套用自動修復
使用 dart fix 工具自動解決標準的 lint 與分析問題。
# 預覽變更
dart fix --dry-run
# 套用變更
dart fix --apply
3. 手動解決其餘錯誤
檢視其餘的分析器輸出,並根據錯誤型別套用條件邏輯:
- 如果錯誤是空值安全問題(例如「無法在可空接收器上存取屬性」):
- 確認變數邏輯上是否可為 null。
- 如果是,使用可選鏈接(
?.)或提供預設值(??)。 - 如果否,且初始化已在其他地方保證,則將宣告標記為
late。
- 如果錯誤是型別不符(例如「引數型別 'List<dynamic>' 無法指派...」):
- 追蹤變數的初始化。
- 在實例化中加入明確的泛型型別註解(例如使用
<int>[]而非[])。
- 如果錯誤是無效覆寫(例如「參數型別與被覆寫的方法不符」):
- 放寬參數型別以符合父類別,或者
- 如果領域邏輯需要縮小型別,則在參數中加入
covariant關鍵字。
4. 驗證修復(回饋迴圈)
執行驗證器。檢視錯誤。修復。
dart analyze .
dart test
- 如果
dart analyze回報錯誤: 返回步驟 3。 - 如果
dart test因TypeError失敗: 您引入了無效的明確轉型(as T)或存取了未初始化的late變數。找出執行時期失敗並修正型別階層或初始化順序。
範例
範例:修正動態列表指派
輸入(靜態分析失敗):
void printInts(List<int> a) => print(a);
void main() {
final list = []; // 推斷為 List<dynamic>
list.add(1);
list.add(2);
printInts(list); // 錯誤:List<dynamic> 無法指派給 List<int>
}
輸出(靜態分析通過):
void printInts(List<int> a) => print(a);
void main() {
final list = <int>[]; // 明確指定型別
list.add(1);
list.add(2);
printInts(list);
}
範例:修正方法覆寫(反變性)
輸入(靜態分析失敗):
class Animal {
void chase(Animal a) {}
}
class Cat extends Animal {
@override
void chase(Mouse a) {} // 錯誤:縮小參數型別
}
輸出(靜態分析通過):
class Animal {
void chase(Animal a) {}
}
class Cat extends Animal {
@override
void chase(covariant Mouse a) {} // 明確標記 covariant
}
範例:使用 late 修正空值安全
輸入(靜態分析失敗):
class Thermometer {
String temperature; // 錯誤:非可空實例欄位必須初始化
void read() {
temperature = '20C';
}
}
輸出(靜態分析通過):
class Thermometer {
late String temperature; // 將初始化檢查延遲到執行時期
void read() {
temperature = '20C';
}
}






