Dart Lint 规则三大核心抽象从 LintCode 到 NodeLintRegistry 的 API 完全图解【免费下载链接】linterLinter for Dart.项目地址: https://gitcode.com/gh_mirrors/lint/linterDart 静态检查工具 LinterLinter for Dart是dart analyze背后的规则引擎内置 200 条 Lint 规则。本文带你快速看懂编写 Lint 规则时的三大核心抽象LintCode、LintRule、NodeLintRegistry——它们分别负责“报错内容”“规则本体”与“AST 节点订阅”是自定义 Lint 规则 API 参考中最关键的一环。⚡ 一图速览三大抽象各司其职抽象一句话职责典型用法LintCode规则的“报错名片”名称 问题消息 纠错建议每条规则声明一个静态常量LintRule规则的“大脑”封装描述、分组、节点处理器注册所有规则类继承它NodeLintRegistry规则的“订阅台”只订阅关心的 AST 节点类型形如registry.addMethodInvocation(this, visitor) 记忆口诀LintCode 定文案 → LintRule 写逻辑 → NodeLintRegistry 挑节点。三者协作才能产出一条 IDE 里可见的 Lint 诊断。️ 一、LintCode规则的诊断身份与报错文案LintCode 是每条规则的唯一诊断标识。规则触发时用户在终端或 IDE 里看到的问题消息与修复建议都来自这里。以avoid_print规则为例源码见lib/src/rules/avoid_print.dart第 61-63 行static const LintCode code LintCode( avoid_print, Dont invoke print in production code., correctionMessage: Try using a logging framework.);三个参数各有分工名称avoid_print与规则同名是analysis_options.yaml中启用规则时填写的 key问题消息诊断输出中显示给用户的核心描述correctionMessage纠错建议告诉用户“下一步该怎么改”是提升规则体验的关键。LintCode 通常定义为规则类内部的static const并通过lintCodegetter 暴露给引擎。 二、LintRule规则本体的元数据与注册入口每条规则都是一个继承自LintRule的类。构造函数负责把规则的“档案信息”交给引擎核心字段如下参考官方规则模板tool/rule.dart第 209-229 行字段作用name规则唯一名称与 LintCode 一致description简短描述用于控制台输出details详细说明含 GOOD / BAD 代码示例group规则分组如Group.style、Group.errors、Group.pub除了元数据规则类必须完成两件事重写lintCodegetter返回上文定义的 LintCode 常量重写registerNodeProcessors方法——这是接入 NodeLintRegistry 的入口下一节展开。所有规则最终都会汇入统一注册表 rules.dart由registerLintRules()一次性挂到引擎上该文件约 460 行 register 调用。 三、NodeLintRegistry基于 AST 的事件订阅机制NodeLintRegistry 是规则与语法树AST之间的桥梁。它的思想非常简单规则不去遍历整棵语法树而是向注册表声明“我只关心某类节点”引擎遍历时只把这些节点回调给你的访问者Visitor。以avoid_print为例avoid_print.dartoverride void registerNodeProcessors(NodeLintRegistry registry, LinterContext context) { var visitor _Visitor(this); registry.addMethodInvocation(this, visitor); }这里registry.addMethodInvocation(this, visitor)表示每当引擎遇到一个方法调用节点MethodInvocation就回调visitor.visitMethodInvocation规则逻辑在其中判断并决定是否调用rule.reportLint(node)上报诊断。⚡ 为什么推荐订阅节点官方文档 doc/writing-lints.md 明确指出出于性能考虑规则应优先实现节点级注册如registry.addXXX(this, visitor)避免自己全量遍历CompilationUnit——大项目下的性能差异非常明显。 三大抽象如何协作以 avoid_print 为例把lib/src/rules/avoid_print.dart拆成三步来看LintCode 定义诊断avoid_print 问题消息 纠错建议第 61-63 行LintRule 承载规则构造函数传入名称、描述、详细说明与Group.errors分组第 65-70 行NodeLintRegistry 订阅节点addMethodInvocation订阅方法调用第 79 行访问者触发上报visitMethodInvocation中判断该调用是dart:core的print且不在kDebugMode保护下即调用rule.reportLint第 89-95 行。至此一条完整的 Lint 诊断被产出用户运行dart analyze时即可看到。 动手速查5 步写出你的第一条 Lint 规则运行dart tool/rule.dart -n my_new_lint生成规则、测试与配置骨架在lib/src/rules/的新文件中填充 LintCode 文案与details说明选择合适的registry.addXXX订阅目标节点类型访问者逻辑中就地调用reportLint上报诊断在test/rules/补充测试用例测试数据位于test_data/rules/对应文件。生成器还会自动同步三处tool/since/sdk.yaml记录规则支持的 SDK 版本、CHANGELOG.md新增条目以及 example/all.yaml全量规则清单可直接粘贴到analysis_options.yaml按需裁剪。 规则的生命周期与官方资料规则并非“生而稳定”每条 Lint 都会经历Proposed提案→ Accepted接受→ Experimental实验→ Stable稳定→ Deprecated弃用→ Removed移除的状态流转详见官方文档 doc/lint-lifecycle.md。继续深入推荐这两份一手资料规则编写指南doc/writing-lints.md命名规范、DO / DONT / PREFER 分组原则完整规则清单与注册入口lib/src/rules.dart。掌握LintCode → LintRule → NodeLintRegistry这条主线你就能读懂仓库中任意一条规则的源码结构也能顺利为 Dart 生态贡献自己的第一条 Lint 规则。【免费下载链接】linterLinter for Dart.项目地址: https://gitcode.com/gh_mirrors/lint/linter创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考