Skip to content

Commit

Permalink
docs: various updates and fixes (#519)
Browse files Browse the repository at this point in the history
  • Loading branch information
ematipico authored Oct 13, 2023
1 parent 7bfb323 commit 5eb3f03
Show file tree
Hide file tree
Showing 12 changed files with 242 additions and 34 deletions.
9 changes: 9 additions & 0 deletions crates/biome_analyze/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,15 @@ _Biome_ follows a naming convention according to what the rule do:
When a rule's sole intention is to **mandate a single concept** - such as forcing the use of camel-casing - the rule should be named using the `use` prefix.
For example, the rule to mandating the use of camel-cased variable names is named `useCamelCase`.

### What a rule should say to the user

A rule should be informative to the user, and give as much explanation as possible.

When writing a rule, you must adhere to the following **pillars**:
1. Explain to the user the error. Generally, this is the message of the diagnostic.
2. Explain to the user **why** the error is triggered. Generally, this is implemented with an additional node.
3. Tell the user what they should do. Generally, this is implemented using a code action. If a code action is not applicable a note should tell the user what they should do to fix the error.

### Create and implement the rule

Let's say we want to create a new rule called `myRuleName`, which uses the semantic model.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,31 @@ use std::str::FromStr;
use schemars::JsonSchema;

declare_rule! {
/// Enforce all dependencies are correctly specified.
/// Enforce all dependencies are correctly specified in a React hook.
///
/// This rule is a port of the rule [react-hooks/exhaustive-deps](https://legacy.reactjs.org/docs/hooks-rules.html#eslint-plugin) is meant to target projects that uses React.
///
/// If your project _doesn't_ use React, **you're shouldn't use this rule**.
///
/// The rule will inspect the following **known** hooks:
///
/// - `useEffect`
/// - `useLayoutEffect`
/// - `useInsertionEffect`
/// - `useCallback`
/// - `useMemo`
/// - `useImperativeHandle`
/// - `useState`
/// - `useContext`
/// - `useReducer`
/// - `useRef`
/// - `useDebugValue`
/// - `useDeferredValue`
/// - `useTransition`
/// - `useId`
/// - `useSyncExternalStore`
///
/// If you want to add more hooks to the rule, check the [#options](options).
///
/// ## Examples
///
Expand Down
2 changes: 1 addition & 1 deletion crates/biome_service/src/configuration/linter/rules.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion editors/vscode/configuration_schema.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/@biomejs/backend-jsonrpc/src/workspace.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/@biomejs/biome/configuration_schema.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 8 additions & 5 deletions website/astro.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,6 @@ export default defineConfig({
{
label: "Use Biome in big projects",
link: "/guides/big-projects",
badge: {
text: "New",
variant: "note",
},
},
],
},
Expand Down Expand Up @@ -216,7 +212,14 @@ export default defineConfig({
items: [
{ label: "Philosophy", link: "/internals/philosophy" },
{ label: "Language support", link: "/internals/language-support" },
{ label: "Architecture", link: "/internals/architecture" },
{
label: "Architecture",
link: "/internals/architecture",
badge: {
text: "Updated",
variant: "note",
},
},
{ label: "Credits", link: "/internals/credits" },
{ label: "Versioning", link: "/internals/versioning" },
{ label: "Changelog", link: "/internals/changelog" },
Expand Down
152 changes: 147 additions & 5 deletions website/src/content/docs/internals/architecture.mdx
Original file line number Diff line number Diff line change
@@ -1,11 +1,153 @@
---
title: Architecture (WIP)
description: How Biome works.
title: Architecture
description: How Biome works under the hood.
---

Biome uses a server-client architecture to run its tasks.
This document covers some of the internals of Biome, and how they are used inside the project.

## Parser and CST

The architecture of the parser is bumped by an internal fork of [rowan], a library
that implements the [Green and Red tree] pattern.

The CST (Concrete Syntax Tree) is data structure very similar to AST (Abstract Syntax Tree) that keeps track of all the information of a program, trivia included.

**Trivia** are represented by all that information that are important to a program to run:
- spaces
- tabs
- comments

Trivia are attached to a node. A node can have leading trivia and trailing trivia. If you read code from left-to-right, leading trivia appear before a keyword, and trialing trivia appear after a keyword.

Leading trivia and trailing trivia are categorized as follows:
- Every trivia up to the token/keyword (including line breaks) will be the **leading trivia**;
- Everything until the next linebreak (but not including it) will be the **trailing trivia**;

Given the following JavaScript snippet, `// comment 1` is a trailing trivia of the token `;`, and `// comment 2` is a leading trivia to the keyword `const`. Below a minimized version of the CST represented by Biome: :

```js
const a = "foo"; // comment 1
// comment 2
const b = "bar";
```

```
0: [email protected]
...
1: [email protected] ";" [] [Whitespace(" "), Comments("// comment 1")]
1: [email protected]
...
1: [email protected] "const" [Newline("\n"), Comments("// comment 2"), Newline("\n")] [Whitespace(" ")]
3: [email protected] "" [] []
```

The CST is never directly accessible by design, a developer can read its information using the Red tree, using a number of APIs that are autogenerated from the grammar of the language.


#### Resilient and recoverable parser

In order to construct a CST, a parser needs to be error resilient and recoverable:
- resilient: a parser that is able to resume parsing after encountering syntax error that belong to the language;
- recoverable: a parser that is able to **understand** where an error occurred, and being able to resume the parsing by creating **correct** information;

The recoverable part of the parser is not a science, and there aren't any rules set on stone. This means that depending on what the parser was parsing and where an error occurred, the parser might be able to recover itself in an expected ways.

To protect the consumers from consuming incorrect syntax, the parser also uses `Bogus` nodes. These nodes are used decorate the broken code caused by an syntax error.

In the following example, the parenthesis in the `while` are missing, although parser is able to recover itself in a good manner, and it's able to represent the code with a decent CST. The parenthesis and condition of the loop are marked as missing, and the code block is correctly parsed:


```js
while {}
```

## Daemon
```
JsModule {
interpreter_token: missing (optional),
directives: JsDirectiveList [],
items: JsModuleItemList [
JsWhileStatement {
while_token: [email protected] "while" [] [Whitespace(" ")],
l_paren_token: missing (required),
test: missing (required),
r_paren_token: missing (required),
body: JsBlockStatement {
l_curly_token: [email protected] "{" [] [],
statements: JsStatementList [],
r_curly_token: [email protected] "}" [] [],
},
},
],
eof_token: [email protected] "" [] [],
}
```

A [daemon](<https://en.wikipedia.org/wiki/Daemon_(computing)>) is a long-running server
This is error emitted during parsing:

```
main.tsx:1:7 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ expected `(` but instead found `{`
> 1 │ while {}
│ ^
ℹ Remove {
```

The same can't be said for the following snippet. The parser can't properly understand the syntax during the recovery phase, so it needs to rely on the bogus nodes to mark some syntax as erroneous. Notice the `JsBogusStatement`:

```js
function}
```

```
JsModule {
interpreter_token: missing (optional),
directives: JsDirectiveList [],
items: JsModuleItemList [
TsDeclareFunctionDeclaration {
async_token: missing (optional),
function_token: FUNCTION_KW@0..8 "function" [] [],
id: missing (required),
type_parameters: missing (optional),
parameters: missing (required),
return_type_annotation: missing (optional),
semicolon_token: missing (optional),
},
JsBogusStatement {
items: [
R_CURLY@8..9 "}" [] [],
],
},
],
eof_token: EOF@9..9 "" [] [],
}
```

This is the error we get from the parsing phase:

```
main.tsx:1:9 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ expected a name for the function in a function declaration, but found none
> 1 │ function}
│ ^
```

## Formatter (WIP)

## Linter (WIP)

## Daemon (WIP)

Biome uses a server-client architecture to run its tasks.

A [daemon] is a long-running server
that Biome spawns in the background and uses to process requests from the editor and CLI.


[rowan]: https://github.com/rust-analyzer/rowan
[Green and Red tree]: https://learn.microsoft.com/en-us/archive/blogs/ericlippert/persistence-facades-and-roslyns-red-green-trees
[daemon]: https://en.wikipedia.org/wiki/Daemon_(computing)
34 changes: 19 additions & 15 deletions website/src/content/docs/linter/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ title: Linter
description: How to use the Biome linter.
---

import PackageManagerBiomeCommand from "@src/components/PackageManagerBiomeCommand.astro";
import NumberOfRules from "@src/components/generated/NumberOfRules.astro";
import RecommendedRules from "@src/components/generated/RecommendedRules.astro";
import RecommendedRulesMd from "@src/components/generated/RecommendedRules.md";
Expand All @@ -20,27 +19,22 @@ You can start by running the CLI to check for possible errors using the followin
biome lint ./src
```

To apply the **safe** fixes, run:

```shell
biome lint --apply ./src
```

For more information about all the available options, check the [CLI page](/reference/cli#biome-lint)

## Recommended rules
## Rule pillars

When the linter is enabled, it recommends a number of rules. Recommended rules will emit error diagnostics. Below the list of recommended rules:
<RecommendedRulesMd />
<RecommendedRules />
We believe that rules should be informative and explain to the user why a rule is triggered and tell the user what they should to do fix the error. A rule should follow these **pillars**:
1. Explain to the user the error. Generally, this is the message of the diagnostic.
2. Explain to the user **why** the error is triggered. Generally, this is implemented with an additional node.
3. Tell the user what they should do. Generally, this is implemented using a code action. If a code action is not applicable a note should tell the user what they should do to fix the error.

If you think a rule doesn't follow these pillars, please [file an issue](https://github.com/biomejs/biome/issues/new?assignees=&labels=S-To+triage&projects=&template=01_bug.yml&title=%F0%9F%90%9B+%3CTITLE%3E).

## Code fixes

Lint rules may provide automatic code fixes.
Biome distinguishes between two types of fixes:
Lint rules may provide automatic code fixes. Biome distinguishes between two types of fixes.

- safe fixes
- unsafe fixes
### Safe fixes

Safe fixes are guaranteed to not change the semantic of your code.
They can be applied without explicit review.
Expand All @@ -51,6 +45,8 @@ To apply _safe fixes_, use `--apply`:
biome check --apply ./src
```

### Unsafe fixes

Unsafe fixes may change the semantic of your program.
Therefore, it's advised to manually review the changes.

Expand All @@ -60,6 +56,14 @@ To apply _unsafe fixes_, use `--apply-unsafe`:
biome check --apply-unsafe ./src
```


## Recommended rules

When the linter is enabled, it recommends a number of rules. Recommended rules will emit error diagnostics. Below the list of recommended rules:
<RecommendedRulesMd />
<RecommendedRules />


## Ignoring Code

There are times when a developer wants to ignore a lint rule for a specific line of the code.
Expand Down
2 changes: 1 addition & 1 deletion website/src/content/docs/linter/rules/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ Rules that belong to this group <strong>are not subject to semantic version</str
| [useArrowFunction](/linter/rules/use-arrow-function) | Use arrow functions over function expressions. | <span aria-label="The rule has a safe fix" role="img" title="The rule has a safe fix">🔧 </span> |
| [useAsConstAssertion](/linter/rules/use-as-const-assertion) | Enforce the use of <code>as const</code> over literal type and type annotation. | <span aria-label="The rule has a safe fix" role="img" title="The rule has a safe fix">🔧 </span> |
| [useCollapsedElseIf](/linter/rules/use-collapsed-else-if) | Enforce using <code>else if</code> instead of nested <code>if</code> in <code>else</code> clauses. | <span aria-label="The rule has a safe fix" role="img" title="The rule has a safe fix">🔧 </span> |
| [useExhaustiveDependencies](/linter/rules/use-exhaustive-dependencies) | Enforce all dependencies are correctly specified. | |
| [useExhaustiveDependencies](/linter/rules/use-exhaustive-dependencies) | Enforce all dependencies are correctly specified in a React hook. | |
| [useGroupedTypeImport](/linter/rules/use-grouped-type-import) | Enforce the use of <code>import type</code> when an <code>import</code> only has specifiers with <code>type</code> qualifier. | <span aria-label="The rule has an unsafe fix" role="img" title="The rule has an unsafe fix">⚠️ </span> |
| [useHookAtTopLevel](/linter/rules/use-hook-at-top-level) | Enforce that all React hooks are being called from the Top Level component functions. | |
| [useImportRestrictions](/linter/rules/use-import-restrictions) | Disallows package private imports. | |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,31 @@ title: useExhaustiveDependencies (since v1.0.0)
This rule is part of the [nursery](/linter/rules/#nursery) group.
:::

Enforce all dependencies are correctly specified.
Enforce all dependencies are correctly specified in a React hook.

This rule is a port of the rule [react-hooks/exhaustive-deps](https://legacy.reactjs.org/docs/hooks-rules.html#eslint-plugin) is meant to target projects that uses React.

If your project _doesn't_ use React, **you're shouldn't use this rule**.

The rule will inspect the following **known** hooks:

- `useEffect`
- `useLayoutEffect`
- `useInsertionEffect`
- `useCallback`
- `useMemo`
- `useImperativeHandle`
- `useState`
- `useContext`
- `useReducer`
- `useRef`
- `useDebugValue`
- `useDeferredValue`
- `useTransition`
- `useId`
- `useSyncExternalStore`

If you want to add more hooks to the rule, check the [#options](options).

## Examples

Expand Down
Loading

0 comments on commit 5eb3f03

Please sign in to comment.