03-定义 Lint
3 分钟阅读
译文 · 基于 Clippy Documentation
定义 Lint
原文链接: https://doc.rust-lang.org/nightly/clippy/development/defining_lints.html
新 lint 旅程的第一步,是在 Clippy 代码库中定义并注册该 lint。 由于涉及一些样板代码,可使用 Clippy 开发工具完成这一步。
Lint 类型
lint 类型指你的 lint 所关注的项与表达式的类别。
截至本文更新时,除 clippy_lints/src/ 下众多独立 lint 外,还有 11 种 类型:
cargocastsfunctionsloopsmatchesmethodsmisc_earlyoperatorstransmutetypesunit_types
这些类型将具有共同行为的 lint 分组。例如 functions 包含处理 Rust 函数某些方面的 lint,如定义、签名与属性。
更多信息可对比任一类别下的 lint 文件与全部 Clippy lint,或询问维护者。
Lint 名称
好的 lint 名称很重要,请务必查看 lint 命名指南。若名称不合适,Clippy 团队成员会在 PR 流程中提醒你。
我们的示例 lint 检测名为 “foo” 的函数,命名为 foo_functions。
可查看 lint 命名指南 了解该名称为何合理。
添加并注册 Lint
名称确定后,将 foo_functions 注册到代码库。有两种注册方式。
独立 lint
若你认为新 lint 是独立 lint(不属于 functions、loops 等特定类型),可在 Clippy 项目中运行:
| |
注意两点:
--pass:本例使用--pass=late做 late lint pass。另一种是earlylint pass。区别见 [Lint 遍历] 一章。--category:若未提供,新 lint 的category默认为nursery。
cargo dev new_lint 会创建新文件 clippy_lints/src/foo_functions.rs,并注册 lint。
总体上,你会看到以下文件被修改或创建:
| |
特定类型
注意:lint 类型列在 “Lint 类型” 一节。
若你认为新 lint 属于某类 lint,可对 cargo dev new_lint 使用 --type 选项。
由于 foo_functions 与函数调用相关,可将其放入检测函数行为的 lint 组,例如 functions 组。
在 Clippy 项目中运行:
| |
该命令会创建新文件 clippy_lints/src/{type}/foo_functions.rs。
本例路径为 clippy_lints/src/functions/foo_functions.rs。
注意该命令使用 --type 而非 --pass。与独立定义不同,该 lint 不会以传统方式注册,而需在类型对应的 lint pass 中调用,位于 clippy_lints/src/{type}/mod.rs。
类型 就是 clippy_lints/src 下的目录名,如示例中的 functions。Clippy 将具有共同行为的 lint 分组,若你的 lint 属于某一类,最好加入该类型。
总体上,你会看到以下文件被修改或创建:
| |
declare_clippy_lint 宏
运行 cargo dev new_lint 后,应能看到名为 declare_clippy_lint 的宏。若为独立 lint,宏在同一文件中;若为类型特定 lint,则在 mod.rs 中。
宏大致如下:
| |
Lint 注册
若为新 lint 运行 cargo dev new_lint,lint 会自动注册,无需额外操作。
但有时需要手动声明新 lint,此时应随后运行 cargo dev update_lints。
手动声明 lint 时,可能需在 clippy_lints/src/lib.rs 的 late_lint_methods! 宏调用中、// add late passes here 标记处手动注册 lint pass:
| |
顾名思义,有 late 就有 early:Clippy 也有 early_lint_methods! 宏。early 与 late pass 的更多说明见 [Lint 遍历] 一章。
若未在 early_lint_methods! 或 late_lint_methods! 之一中登记,对应的 lint pass 不会运行。