Skip to content

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.

Cargo.toml Configuration

Here, it parses arguments and then runs the LintRunner.

Lint Execution Flow

crates/oxc_diagnostics ​

The LintService passes the mpsc::channel Sender to oxc_diagnostics to receive lint results.

Receiving Lint Results

It formats and displays the received messages. The formatting is done by the miette crate.

miette Crate Reference

crates/oxc_linter ​

Starting with the LintService:

  • Holds self.runtime as Arc<Runtime>
  • Runtime holds paths for linting
  • Upon running, it iterates over Runtime paths in parallel using rayon
  • It sends a None to finish

LintService Implementation

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 for script blocks
  • Processes JavaScript and TypeScript sources
  • Executes linting and sends results to DiagnosticService

Runtime Path Processing

Runtime: process_source() ​

  • Processes the source with a parser into an AST
  • Creates a LintContext from SemanticBuilder and runs it through Linter

Runtime Source Processing

crates/oxc_semantic: SemanticBuilder ​

SemanticBuilder builds semantic information extracted from the source.

SemanticBuilder Source

  • source_text: Source code
  • nodes: AST nodes
  • classes: Classes
  • scopes: Scopes
  • trivias: Comments
  • jsdoc: JSDoc
  • etc.

When SemanticBuilder builds, it generates SemanticBuilderReturn, but only Semantic is passed to LintContext.

SemanticBuilder Return

crates/oxc_linter: LintContext ​

LintContext Source

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 ​

Linter Source

The run() function of this Linter is the core of the linting process.

  • Linter holds rules to execute on the target source in self.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.

Implemented Rules

For adding new rules, remember to update this list.

Linter Example ​

The repository provides the minimum code configuration for creating a linter.

Minimal Linter Code

Released under the MIT License.