Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/RDambrosio016/RSLint

A (WIP) Extremely fast JavaScript and TypeScript linter and Rust crate
https://github.com/RDambrosio016/RSLint

javascript javascript-linter linter parallel parser rust typescript

Last synced: 3 months ago
JSON representation

A (WIP) Extremely fast JavaScript and TypeScript linter and Rust crate

Awesome Lists containing this project

README

        


RSLint


A fast, customizable, and easy to use
JavaScript and
TypeScript linter


build status
Documentation Status


Guide
|
Contributing
|
Website
|
Linter Rules

⚠️ RSLint is in early development and should not be used in production, expect bugs! 🐛

## Installation

### Through Cargo

```sh
$ cargo install rslint_cli
$ rslint --help
```

### Prebuilt Binaries

We publish prebuilt binaries for Windows, Linux, and MacOS for every release which you can find [here](https://github.com/rslint/rslint/releases).

### Build From Source

```sh
$ git clone https://github.com/rslint/rslint.git
$ cd rslint
$ cargo run --release -- --help
```

## Usage

To use the linter simply pass files to lint to the CLI:

```sh
$ echo "let a = foo.hasOwnProperty('bar');" > foo.js
$ rslint ./foo.js
error[no-prototype-builtins]: do not access the object property `hasOwnProperty` directly from `foo`
┌─ ./foo.js:1:9

1 │ let a = foo.hasOwnProperty('bar');
│ ^^^^^^^^^^^^^^^^^^^^^^^^^

help: get the function from the prototype of `Object` and call it

1 │ let a = Object.prototype.hasOwnProperty.call(foo, 'bar');
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

╧ note: the method may be shadowed and cause random bugs and denial of service vulnerabilities

Outcome: 1 fail, 0 warn, 0 success

help: for more information about the errors try the explain command: `rslint explain `
```

The RSLint CLI works without a configuration file and will select recommended non-stylistic rules to run.

## Features

**Speed**. RSLint uses parallelism to utilize multiple threads to speed up linting on top of being compiled to
native code.

**Low memory footprint**. RSLint's syntax tree utilizes interning and other ways of drastically reducing memory usage
while linting.

**Sensible defaults**. The CLI assumes recommended non-stylistic rules if no configuration file is specified and ignores directories such as
`node_modules`.

**Error recovery**. RSLint's custom parser can recover from syntax errors and produce a usable syntax tree even when whole parts of
a statement are missing. Allowing accurate on-the-fly linting as you type.

**No confusing options**. ECMAScript version for the parser does not have to be configured, the parser assumes latest syntax and
assumes scripts for `*.js` and modules for `*.mjs`.

**Native TypeScript support**. `*.ts` files are automatically linted, no configuration for different parsers or rules is required.

**Rule groups**. Rules are grouped by scope for ease of configuration, understanding, and a cleaner file structure for the project.

**Understandable errors**. Each error emitted by the linter points out the area in the source code in an understandable and clean manner as well as contains labels, notes, and suggestions to explain how to fix each issue. There is also an alternative formatter similar to ESLint's formatter available using the `-F` flag or the `formatter` key in the config.

**Strongly typed rule configuration**. RSLint ships a JSON schema and links it for `rslintrc.json` to provide autocompletion for the config file in Visual Studio Code. The JSON Schema describes rule config options in full, allowing easy configuration. Moreover, RSLint's language server protocol implementation provides autocompletion for `rslintrc.toml` files too.

**Powerful directives**. Directives (commands through comments) use a parser based around the internal JavaScript lexer with instructions, allowing us to provide:

- Autocompletion for directives such as `// rslint-ignore no-empty` in the language server protocol.
- Hover support for directives to offer information on a command on hover.
- Understandable errors for incorrect directives.

**Standalone**. RSLint is compiled to a single standalone binary, it does not require Node, v8, or any other runtime. RSLint can run on any platform which can be targeted by LLVM.

**Powerful autofix**. Automatic fixes for some errors are provided and can be applied through the `--fix` flag or actions in the IDE. Fixes can even be applied if the file contains syntax errors through the `--dirty` flag.

**Built-in documentation**. RSLint contains rule documentation in its binary, allowing it to show documentation in the terminal through the explain subcommand, e.g. `rslint explain no-empty, for-direction`.

## Internal Features

**Clean and clear project layout**. The RSLint project is laid out in a monorepo and each crate has a distinct job, each crate can be used in other Rust projects and each crate has good documentation and a good API.

**Easy rule declaration**. Rules are declared using a `declare_lint!` macro. The macro accepts doc comments, a struct name, the group name, a rule code, and configuration options. The macro generates a struct definition and a `Rule` implementation and processes the doc comments into the documentation for the struct as well as into a static string used in the `docs()` method on each rule. Everything is concise and kept in one place.

**Full fidelity syntax tree**. Unlike ESTree, RSLint's custom syntax tree retains:

- All whitespace
- All comments
- All tokens

Allowing it to have powerful analysis without having to rely on separate structures such as ESLint's `SourceCode`.

**Untyped Syntax Tree**. RSLint's syntax tree is made of untyped nodes and untyped tokens at the low level, this allows for powerful, efficient traversal through the tree, e.g. `if_stmt.cons()?.child_with_ast::()`.

**Easy APIs**. RSLint uses easy to use builders for its complex errors, as well as builders for autofix. Everything is laid out to minimize the effort required to implement rules.

## Performance

The benchmarks can be found in the `benchmarks` directory. You can run them on your machine using `deno run -A --quiet benchmarks/bench.ts`.
They are also run on CI and you can see the latest results if you click on the latest GitHub Actions run.

| Project | RSLint | eslint |
|---------------------------------|--------|--------|
| engine262 (~42k LOC JavaScript) | 414ms | 46.9s |
| Oak (~11k LOC TypeScript) | 53ms | 399ms |

(These benchmarks are run on AMD Ryzen 7 2700x, 8 Cores at 3.9MHz)

## License

This project is Licensed under the [MIT license](http://opensource.org/licenses/MIT).