Linter Architecture
This article is originally posted on leaysgur.github.io/posts by @leaysgur.
apps/oxlint
The oxlint
binary is the result of building main.rs
from the apps/oxlint
crate.
Here, it parses arguments and then runs the LintRunner
.
crates/oxc_diagnostics
The LintService
passes the mpsc::channel
Sender to oxc_diagnostics
to receive lint results.
It formats and displays the received messages. The formatting is done by the miette
crate.
crates/oxc_linter
Starting with the LintService
:
- Holds
self.runtime
asArc<Runtime>
Runtime
holds paths for linting- Upon running, it iterates over
Runtime
paths in parallel usingrayon
- It sends a
None
to finish
Runtime
: process_path()
- Infers extension and content from the path
- Supports
.[m|c]?[j|t]s
or.[j|t]sx
extensions - Exceptions for
.vue
,.astro
, and.svelte
with partial support forscript
blocks - Processes JavaScript and TypeScript sources
- Executes linting and sends results to
DiagnosticService
Runtime
: process_source()
- Processes the source with a parser into an AST
- Creates a
LintContext
fromSemanticBuilder
and runs it throughLinter
crates/oxc_semantic: SemanticBuilder
SemanticBuilder
builds semantic information extracted from the source.
source_text
: Source codenodes
: AST nodesclasses
: Classesscopes
: Scopestrivias
: Commentsjsdoc
: JSDoc- etc.
When SemanticBuilder
builds, it generates SemanticBuilderReturn
, but only Semantic
is passed to LintContext
.
crates/oxc_linter: LintContext
Represents the context, with Semantic
as the main body. It includes getters for each piece of information and methods like diagnostic()
to notify of linting issues.
crates/oxc_linter: Linter
The run()
function of this Linter
is the core of the linting process.
Linter
holds rules to execute on the target source inself.rules
- Each rule can implement three types of processing as per the trait
- It sequentially executes these three patterns
For the currently implemented rules, refer to this list.
For adding new rules, remember to update this list.
Linter Example
The repository provides the minimum code configuration for creating a linter.