mcpField
D
dart-fix-runtime-errors

dart-fix-runtime-errors

github.com/dart-lang开发53218.9k 次安装2 周前更新
代码仓库

关于 dart-fix-runtime-errors

为 Dart 开发者提供静态分析错误排查与修复指导,重点涉及类型安全、空安全和异常处理。流程结合自动修复、手动调整及分析和测试验证。

主要功能

  1. 01处理类型与泛型问题
  2. 02修复空安全相关错误
  3. 03区分异常与不可恢复错误
  4. 04预览并应用自动修复
  5. 05通过分析和测试验证改动

适用场景

  1. 01排查 Dart 静态分析错误
  2. 02修复类型不匹配
  3. 03处理可空值及初始化问题
  4. 04检查修复后是否引入运行时错误

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/dart-lang/skills --skill dart-fix-runtime-errors

安装后在 Claude Code 中输入/dart-fix-runtime-errors确认已加载。

详细介绍

解决 Dart 静态分析错误

目录

核心概念与指南

类型系统与健全性

遵循 Dart 的健全类型系统,防止出现无效的运行时状态。

  • 方法重写: 保持健全的返回类型(协变)和参数类型(逆变)。除非显式标记 covariant 关键字,否则绝不要在子类中收紧参数类型。
  • 泛型与集合: 为泛型类添加显式类型注解(例如,List<T>、Map<K, V>)。绝不要将 List<dynamic> 赋给带类型的列表(例如,List<Cat>)。
  • 向下转型: 避免从 dynamic 隐式向下转型。必要时使用显式转换(例如,as List<Cat>),但要确保底层运行时类型匹配,以防止出现 TypeError 异常。
  • 严格转换: 在 analysis_options.yaml 的 analyzer: language: 下启用 strict-casts: true,强制进行显式转换,并在编译时捕获隐式向下转型错误。
空安全

通过正确管理变量初始化和可空性,消除与空安全相关的静态错误。

  • 修饰符: 可空类型使用 ?,空断言使用 !,无法为 null 的命名参数使用 required。
  • 延迟初始化: 对保证在使用前初始化的非空变量使用 late 关键字。具体而言,在 Dart 的控制流分析无法明确证明已初始化的顶层变量或实例变量上使用它。
  • 通配符: 对不绑定值的局部变量或参数使用 _ 通配符变量(Dart 3.7+),以避免未使用变量警告。
错误处理

区分可恢复异常与不可恢复错误。

  • 捕获: 捕获可恢复故障的 Exception 子类型。
  • 错误: 绝不要显式捕获 Error 或其子类型(例如,TypeError、ArgumentError)。错误表明存在必须修复、而非捕获的编程缺陷。启用 avoid_catching_errors lint 规则来强制执行这一点。
  • 重新抛出: 在 catch 块中使用 rethrow 传播异常,同时保留其原始堆栈跟踪。

工作流

工作流:静态分析问题修复

使用此顺序工作流,在 Dart 项目中识别、修复并验证静态分析错误。复制此检查清单以跟踪进度。

任务进度:

  • 1. 运行静态分析器。
  • 2. 应用自动修复。
  • 3. 手动解决剩余错误。
  • 4. 验证修复(反馈循环)。

1. 运行静态分析器 运行 Dart 分析器,找出目标目录或文件中的所有静态错误。

dart analyze . --fatal-infos

2. 应用自动修复 使用 dart fix 工具自动解决常见的 lint 和分析问题。

# Preview changes
dart fix --dry-run
# Apply changes
dart fix --apply

3. 手动解决剩余错误 查看分析器剩余的输出,并根据错误类型应用相应的处理逻辑:

  • 如果错误是空安全问题(例如:“无法通过可空接收器访问属性”):
    • 确认该变量在逻辑上是否可能为 null。
    • 如果可能,请使用可选链式调用(?.)或提供备用值(??)。
    • 如果不可能,且能保证该变量会在其他位置初始化,请在声明中添加 late。
  • 如果错误是类型不匹配(例如:“参数类型 'List' 无法赋给……”):
    • 追踪变量的初始化过程。
    • 在实例化时添加显式泛型类型注释(例如,使用 <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 = []; // Inferred as List<dynamic>
  list.add(1);
  list.add(2);
  printInts(list); // Error: List<dynamic> can't be assigned to List<int>
}

输出(静态分析通过):

void printInts(List<int> a) => print(a);

void main() {
  final list = <int>[]; // Explicitly typed
  list.add(1);
  list.add(2);
  printInts(list);
}
示例:修复方法重写(逆变)

输入(静态分析失败):

class Animal {
  void chase(Animal a) {}
}

class Cat extends Animal {
  @override
  void chase(Mouse a) {} // Error: Tightening parameter type
}

输出(静态分析通过):

class Animal {
  void chase(Animal a) {}
}

class Cat extends Animal {
  @override
  void chase(covariant Mouse a) {} // Explicitly marked covariant
}
示例:使用 late 修复空安全问题

输入(静态分析失败):

class Thermometer {
  String temperature; // Error: Non-nullable instance field must be initialized

  void read() {
    temperature = '20C';
  }
}

输出(静态分析通过):

class Thermometer {
  late String temperature; // Defers initialization check to runtime

  void read() {
    temperature = '20C';
  }
}

评论

支持 Markdown