Linter 架构
本文最初发布于 leaysgur.github.io/posts,作者为 @leaysgur。
apps/oxlint
oxlint 二进制文件是构建 apps/oxlint crate 中的 main.rs 的结果。
在这里,它解析参数然后运行 LintRunner。
crates/oxc_diagnostics
LintService 将 mpsc::channel Sender 传递给 oxc_diagnostics 以接收 lint 结果。
它格式化并显示接收到的消息。格式化由 miette crate 完成。
crates/oxc_linter
从 LintService 开始:
- 持有
self.runtime作为Arc<Runtime> Runtime持有用于 lint 的路径- 运行时,它使用
rayon并行遍历Runtime路径 - 它发送一个
None来完成
Runtime: process_path()
- 从路径推断扩展名和内容
- 支持
.[m|c]?[j|t]s或.[j|t]sx扩展名 .vue、.astro和.svelte例外,部分支持script块- 处理 JavaScript 和 TypeScript 源文件
- 执行 linting 并将结果发送到
DiagnosticService
Runtime: process_source()
- 使用解析器将源代码处理为 AST
- 从
SemanticBuilder创建LintContext并通过Linter运行
crates/oxc_semantic: SemanticBuilder
SemanticBuilder 构建从源代码中提取的语义信息。
source_text: 源代码nodes: AST 节点classes: 类scopes: 作用域trivias: 注释jsdoc: JSDoc- 等等。
当 SemanticBuilder 构建时,它生成 SemanticBuilderReturn,但只有 Semantic 被传递给 LintContext。
crates/oxc_linter: LintContext
表示上下文,以 Semantic 为主体。它包含每条信息的 getter 以及像 diagnostic() 这样用于通知 lint 问题的方法。
crates/oxc_linter: Linter
此 Linter 的 run() 函数是 lint 过程的核心。
Linter在self.rules中持有要在目标源上执行的规则- 每个规则可以根据 trait 实现三种类型的处理
- 它按顺序执行这三种模式
对于当前已实现的规则,请参考此列表。
对于添加新规则,记得更新此列表。
Linter 示例
仓库提供了创建 linter 的最小代码配置。
