# High level flow
RSLint's linting flow can be categoried into several distinct steps as shown below:
CLI args -> Load Config -> Load Files -> Call Runner -> Parse File -> Run Rules -> Maybe Autofix -> Report Diagnostics rslint_cli rslint_config rslint_cli rslint_core rslint_parser rslint_core ----------- rslint_cli ------------
Each step is roughly separated to allow us to reuse some of the concepts from each crate to avoid code duplication.
# Project structure
RSLint is laid out as a monorepo, a structure you may be familiar with, Rust monorepos are more specifically refered to as workspaces. RSLint separates distinct steps into separate crates (e.g. CLI, parsing, lexing, and the core), this allows us to reuse and distibute individual parts of the linter for use outside of RSLint. Let's briefly go through what each crate is responsible for.
rslint_cli: This crate contains all of the logic used in the rslint CLI and is one of the only crates which is rslint-specific.
rslint_config: This crate houses all of the logic for
rslintrc.toml, it is used by both
rslint_core: This is where all of the linting takes place and where all of the rules are, the core runner contains no
rslint_clispecific logic, therefore you could use it as a crate and embed it into your rust programs easily.
rslint_errors: This crate contains all of the error (diagnostic) logic shared across every crate, it has a single
Diagnostictype which is used everywhere in RSLint. It also has multiple formatters which you may have read about here.
rslint_lexer: This is an extremely fast ECMAScript lexer which produces tokens from source code. It also contains logic for syntax highlighting code with ANSI coloring which is used for the
rslint_lsp: This is the (unfinished) language server protocol implementation, it will be used for the VSC, Vim, Emacs, and Atom extensions.
rslint_macros: A simple crate for proc macros (procedural macros) used by
rslint_parser: This is the heart of the linter, it is an ECMAScript 2021 parser which produces a lossless syntax tree and can produce an AST from any source code using error recovery. It is unconventional in the techniques it uses, but we will cover that later on.
rslint_syntax: This houses the
SyntaxKindenum which is used by both
rslint_parser(and consumed by other crates through
rslint_text_edit: This houses simple structs and methods to represent and apply text edits to strings. It is shared between
rslint_lsp(for fix commands), and soon
rslint_parser(for incremental reparsing).
RSLint employs a high level of parallelism to achieve high speeds. This includes:
- Loading files in parallel
- Linting files in parallel
- Running rules in parallel
This means each rule must be able to be shared across threads as well as be able to be sent across threads. Or in rust terms,
it must be
Send + Sync. This is not the end of the line for more "contextual" rules however! RSLint (soon) defines a different rule type which
can act on the linted files as a whole.