Commit graph

5625 commits

Author SHA1 Message Date
overlookmotel
ef8dcc9d4d test(transformer): more tests for arrow function transform (#5849) 2024-09-18 09:46:58 +00:00
overlookmotel
49ee1dcff2 fix(transformer): arrow function transform handle this in arrow function in class static block (#5848)
Class static blocks also hold a `this` binding.
2024-09-18 09:46:57 +00:00
Boshen
bcdbba3981 feat(codegen): print jsdoc comments that are attached to statements and class elements (#5845)
I am unable to print all comments correctly. Comments have way too much semantic meaning in JavaScript.

This PR reduces the scope to only print jsdoc comments that are attached to statements and class elements, in order to get isolated declarations shipped.
2024-09-18 07:58:22 +00:00
DonIsaac
3120c6c5ba docs(parser): add module and struct level documentation (#5831) 2024-09-18 06:27:24 +00:00
Boshen
42dcadfccf fix(parser): hashbang comment should not keep the end newline char (#5844)
Previously it included a newline in the value

```
  "hashbang": {
    "type": "Hashbang",
    "start": 0,
    "end": 16,
    "value": "/usr/bin/node\n"
  },
```

This change will also make the lexer emit a `\n` token, which will make comment position detection correct.
2024-09-18 05:41:44 +00:00
oxc-bot
65a17346cd
release(oxlint): v0.9.6 (#5843)
## [0.9.6] - 2024-09-18

### Features

- 3bf7b24 linter: Make `typescript/no-duplicate-enum-values` a
`correctness` rule (#5810) (DonIsaac)
- 7799c06 linter/react: Implement `no-danger-with-children` rule (#5420)
(Cam McHenry)

### Bug Fixes

- f942485 linter: Remove all* remaining "Disallow <foo>" messages
(#5812) (DonIsaac)
- b5ad518 linter: Improve diagnostic messages for various lint rules
(#5808) (DonIsaac)
- 858f7af linter: Plugin prefix name for eslint-plugin-node (#5807)
(DonIsaac)
- 737ba1d linter: Fix some cases on ```AssignmentExpression``` for
```unicorn/consistent-function-scoping``` (#5675) (Arian94)
- 148c7a8 linter: Replace bitwise AND (&) with logical AND (&&) in
explici… (#5780) (kaykdm)
- b4ed564 linter/no-unused-vars: Writes to members triggering false
positive (#5744) (Dunqing)
- e9c084a linter/no-unused-vars: False positive when a variable used as
a computed member property (#5722) (Dunqing)

### Performance

- 3725d5d linter: Make all rules share a diagnostics vec (#5806)
(DonIsaac)
- e978567 linter: Shrink size of `DisableDirectives` (#5798) (DonIsaac)
- 1bfa515 linter: Remove redundant clone of diagnostics in context
(#5797) (DonIsaac)
- e413cad linter: Move shared context info to `ContextHost` (#5795)
(DonIsaac)

### Refactor

- 6dd6f7c ast: Change `Comment` struct (#5783) (Boshen)
- 7caae5b codegen: Add `GetSpan` requirement to `Gen` trait (#5772)
(Boshen)
- 026ee6a linter: Decouple module resolution from import plugin (#5829)
(dalaoshu)
- 50834bc linter: Move `override_rule` to `OxlintRules` (#5708)
(DonIsaac)
- a438743 linter: Move `OxlintConfig` to `Oxlintrc` (#5707) (DonIsaac)
- f61e8b5 linter: Impl serde and schemars traits for `LintPlugins`
(#5706) (DonIsaac)
- 20a7861 linter: Shorten `Option` syntax (#5735) (overlookmotel)
- d8b612c oxc_linter: Prefer pass Enum instead of str `no_plus_plus`
(#5730) (IWANABETHATGUY)
- cc0408b semantic: S/AstNodeId/NodeId (#5740) (Boshen)

---------

Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2024-09-18 12:02:09 +08:00
DonIsaac
26386da01e feat(codegen): have with_source_text reserve memory for code buffer (#5823)
`Codegen::with_source_text` gives us enough information to use `Codegen::with_capacity`. This change makes the API cleaner as users have to provide less redundant information.
2024-09-18 03:27:43 +00:00
Alexander S.
31da9bce3f
feat(prettier): class improvements part 2 (#5838) 2024-09-18 11:07:51 +08:00
overlookmotel
fd70c4b885 perf(transformer): arrow function transform more efficient scope search (#5842)
Micro-optimization. Match scopes with a single comparison, instead of 2.
2024-09-18 02:23:37 +00:00
overlookmotel
03e02a0eac refactor(transformer): comment about potential improvement to arrow function transform (#5841) 2024-09-18 02:23:36 +00:00
overlookmotel
635e9187d3 feat(traverse): generate_uid_name method (#5839)
Rename `find_uid_name` to `generate_uid_name` and make it a public method.
2024-09-18 02:23:36 +00:00
overlookmotel
40cdad572c refactor(transformer): remove repeat code in arrow function transform (#5837)
Pure refactor. Move repeated code into a function.
2024-09-18 02:23:35 +00:00
overlookmotel
3dd188c139 refactor(transformer): deref SymbolId immediately (#5836)
Tiny refactor. Deref `&SymbolId` to `SymbolId` as early as possible.
2024-09-18 02:23:35 +00:00
overlookmotel
56703a3a59 perf(transformer): make branch more predictable in arrow function transform (#5833)
Micro-optimization. Rather than `inside_arrow_function_stack` sometimes being run down to empty, initialize it with a single entry which is never popped off. This means that `self.inside_arrow_function_stack.last()` *always* returns `Some` - so the branch is completely predictable.
2024-09-18 02:23:35 +00:00
overlookmotel
03a9e1ad5d refactor(transformer): reorder methods in arrow function transform (#5830)
Pure refactor. Just move methods which push/pop to stacks to the top, so they're all together.
2024-09-18 02:23:34 +00:00
overlookmotel
172fa0361f fix(transformer): fix stacks in arrow function transform (#5828)
Push/pop to stacks in matching `enter_*` / `exit_*` visitors.

The reason why there was a bug here is a little bit subtle.

Between `enter_expression` and `exit_expression`, another transform can replace the `Expression` with something else. Ditto `enter_declaration` + `exit_declaration`.

So pushing+popping from stacks in `enter_expression` + `exit_expression` can make the stack get out of sync. e.g.:

```rs
impl<'a> Traverse for TransformerWithStack {
    fn enter_expression(&mut self, expr: &mut Expression<'a>, ctx: TraverseCtx<'a>) {
        if let Expression::FunctionExpression(_) = expr {
            self.stack.push(true);
        }
    }

    fn exit_expression(&mut self, expr: &mut Expression<'a>, ctx: TraverseCtx<'a>) {
        if let Expression::FunctionExpression(_) = expr {
            self.stack.pop();
        }
    }
}

// Transformer that replaces `null` with a function expression (!)
impl<'a> Traverse for SomeOtherTransformer {
    fn enter_expression(&mut self, expr: &mut Expression<'a>, ctx: TraverseCtx<'a>) {
        if let Expression::NullLiteral(_) = expr {
            *expr = ctx.ast.expression_function( /* ... */ );
        }
    }
}
```

`TransformerWithStack` is assuming in `exit_expression` that it previously saw a `FunctionExpression` in `enter_expression`. But `SomeOtherTransformer` has created a *new* `FunctionExpression` after `TransformerWithStack::enter_expression` ran. So in `TransformerWithStack`, `exit_expression` is called 1 more time than `enter_expression`. When `exit_expression` calls `self.stack.pop()`, `self.stack` is empty, and it panics.

This example is silly, but real cases of this do exist. e.g. TS transformer creates a new functions when transforming `enum`s.

`enter_function` + `exit_function` / `enter_arrow_function_expression` + `exit_arrow_function_expression` not have this problem. As we cannot mutate upwards, there are always the same number of calls to `enter_*` and `exit_*` (same for all `enter_*` / `exit_*` pairs which operate on a struct, *not an enum*).
2024-09-18 02:23:34 +00:00
overlookmotel
4d97184239 refactor(transformer): rename vars in arrow function transform (#5827)
Pure refactor. Rename properties to be more descriptive.
2024-09-18 02:23:33 +00:00
overlookmotel
01c5b7cb4b refactor(transformer): shorten code in arrow functions transform (#5826)
Use `unwrap()` on `scope_id` field of `ArrowFunctionExpression`. Previously we had errors in other transforms which did not set `scope_id` correctly, but this appears to now be fixed.
2024-09-18 02:23:33 +00:00
overlookmotel
d74c7fa0c9 fix(transformer): remove AstBuilder::copy from arrow functions transform (#5825)
Remove `AstBuilder::copy` calls by taking ownership of the `ArrowFunctionExpression` at start of transform.
2024-09-18 02:23:33 +00:00
Alexander S.
c6d97e9366
feat(prettier): improve ts class output (#5835)
please look first at  #5834 :)
2024-09-17 17:33:35 -04:00
Alexander S.
6d9ccdda92
feat(prettier): support TSMappedType (#5834) 2024-09-17 16:25:51 -04:00
dalaoshu
026ee6a7e8
refactor(linter): decouple module resolution from import plugin (#5829)
closes #5815
2024-09-17 15:48:03 -04:00
overlookmotel
85ac3f749a refactor(transformer): arrow functions transform do not wrap function expressions in parentheses (#5824)
Wrapping a function expression in parentheses is unnecessary. Codegen already adds parentheses when printing a function expression as a statement expression. i.e. `(function() {});`.
2024-09-17 14:11:05 +00:00
Boshen
5901d2a0f1 fix(codegen): various spacing issues (#5820) 2024-09-17 09:03:28 +00:00
Alexander S.
18e4ac22ad
feat(prettier): improve TSInterfaceDeclaration (#5817)
last one for today :)

---------

Co-authored-by: Don Isaac <donald.isaac@gmail.com>
2024-09-17 14:41:33 +08:00
DonIsaac
f9424857df fix(linter): remove all* remaining "Disallow <foo>" messages (#5812)
Cleans diagnostic messages and help texts for (almost) all remaining rules.
There were two rules I couldn' find good replacements for.

I also made some logical improvements to a few rules, and added `pending` fixers
to others.
2024-09-17 05:46:16 +00:00
DonIsaac
3bf7b24621 feat(linter): make typescript/no-duplicate-enum-values a correctness rule (#5810)
This rule is enabled by default in typescript-eslint's recommended config, so we
should enable it by default too. I checked this change with `oxlint-ecosystem-ci` locally and saw no problems.

This PR also improves diagnostic messages for this rule.
2024-09-17 05:46:16 +00:00
DonIsaac
a5f2e9ac04 feat(span): impl From<Atom<'a>> for Atom (#5809) 2024-09-17 05:46:16 +00:00
DonIsaac
b5ad518621 fix(linter): improve diagnostic messages for various lint rules (#5808)
This is the first of a few PRs to remove "Disallow <x>" from all diagnostic
messages. More to come.
2024-09-17 05:46:15 +00:00
DonIsaac
858f7af2b5 fix(linter): plugin prefix name for eslint-plugin-node (#5807) 2024-09-17 05:46:15 +00:00
DonIsaac
3725d5d44e perf(linter): make all rules share a diagnostics vec (#5806)
## What This PR Does

Each time a lint rule is run on a file, it will now store diagnostics in a
shared vec instead of having its own list. This is done by moving `diagnostics`
from `LintContext` to `ContextHost`.

The motivating line of code can be found in `Linter::run` in
`oxc_linter/src/lib.rs#145`

```rust
rules.into_iter().flat_map(|(_, ctx)| ctx.into_message()).collect::<Vec<_>>()
```

Each `LintContext` allocates a new vec, and pushes diagnostics into it. After
all run-related methods have been run, a new vec is created and those
diagnostics are copied into it. This is `O(n+1)` allocations and `O(n)` copies,
not to mention that allocations for the original vecs cannot be re-used since
those vecs aren't dropped until after the new one is created.
2024-09-17 05:46:15 +00:00
DonIsaac
e04841c6a1 docs(syntax): add ModuleRecord documentation (#5818) 2024-09-17 05:22:01 +00:00
DonIsaac
50834bc6d2 refactor(linter): move override_rule to OxlintRules (#5708) 2024-09-17 05:15:38 +00:00
DonIsaac
a438743191 refactor(linter): move OxlintConfig to Oxlintrc (#5707) 2024-09-17 05:15:37 +00:00
Alexander S.
b5ac5a6bf0
feat(prettier): support TSModuleDeclaration (#5813)
Goal of this PR is to resolve this test:
aa3853b776/tests/format/typescript/interface/separator.ts
2024-09-16 16:39:42 -04:00
Cam McHenry
7799c06c1b
feat(linter/react): Implement no-danger-with-children rule (#5420)
- Part of https://github.com/oxc-project/oxc/issues/1022

This implements the [recommended rule
`no-danger-with-children`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-danger-with-children.md)
from the `eslint-plugin-react` package.

This rule proved to be a little bit trickier to implement than I
anticipated, as it required searching up through all of the scopes
recursively in order to resolve object properties. This would be easier
with something like a type-check system, but this will work for now.

(Sidenote: this is my first real attempt at Rust programming in ~5
years, so any feedback on making this more idiomatic is welcome.)
2024-09-16 13:33:00 -04:00
Alexander S.
8b1485bb00
feat(prettier): improve ClassMemberish with print_class_property (#5811) 2024-09-16 13:32:20 -04:00
Alexander S.
01f8c1bca8
feat(prettier): support TSIntersectionType and TSUnionType (#5794) 2024-09-16 13:09:30 -04:00
Boshen
8e7556f842 feat(parser): calculate leading and trailing position for comments (#5785) 2024-09-16 16:37:35 +00:00
overlookmotel
31e9db442d refactor(parser): shorten UniquePromise code (#5805)
Pure refactor. Shorten code a little.
2024-09-16 15:37:01 +00:00
overlookmotel
2322b8b713 refactor(parser): remove dead code warning when running tests (#5804)
`UniquePromise::new_for_tests` is not used in tests, so produces a dead code warning when running tests. Prevent that.

Also, rename it to `new_for_benchmarks`, since that's where it's used.
2024-09-16 15:37:00 +00:00
overlookmotel
47d9ad8cbf refactor(semantic): remove unused vars warning in release mode (#5803)
Avoid an `unused_variables` warning in release mode for a variable which is only used in debug mode.
2024-09-16 15:32:36 +00:00
Boshen
bb95306efd refactor(codegen): change annotation comment tests to snapshot (#5800) 2024-09-16 05:03:43 +00:00
DonIsaac
e978567659 perf(linter): shrink size of DisableDirectives (#5798)
Use boxed slices instead of vecs, shrinking `DisableDirectives` from 136 to 120
bytes.
2024-09-16 04:22:08 +00:00
DonIsaac
1bfa515088 perf(linter): remove redundant clone of diagnostics in context (#5797) 2024-09-16 04:22:07 +00:00
DonIsaac
e413cad0d7 perf(linter): move shared context info to ContextHost (#5795)
> Related to #5770

## What This PR Does

Moves state that is constant over a linted file out of `LintContext` and into a shared `ContextHost` struct, turning `LintContext` into a [flyweight](https://en.wikipedia.org/wiki/Flyweight_pattern).

This brings `LintContext` from 144 bytes down to 96. `Linter::run` iterates over `(rule, ctx)` pairs in a very tight loop, and each rule instance gets its own clone of `ctx`. A smaller `LintContext` means better cache locality and a smaller heap allocation for this vec. I'm hoping to eventually get it small enough to fit in a single cache line.

I made a PR a while ago that did something similar to this one, but instead of using an `Rc`, each `LintContext` stored a read-only reference. This added an extra lifetime parameter, making it slightly unwieldy, but I saw up to 15%/25% perf improvements on local benchmarks. I'll dig around for it and add a link shortly.

### Architecture
![image](https://github.com/user-attachments/assets/9e8352ae-a581-46a3-a578-9eb855d4ebaf)
----
![image](https://github.com/user-attachments/assets/49213cd9-3c31-40dc-97ad-ddf010705ab6)
2024-09-16 04:22:07 +00:00
overlookmotel
17cd9038b7 refactor(ast): move functions to top level in ast macro (#5793)
Pure refactor. Convert nested functions to top level, to make it easier to read.
2024-09-16 04:10:31 +00:00
overlookmotel
cf97f6d1ad refactor(ast): import syn types in ast macro (#5792)
Pure refactor. Import `syn` types with a use statement. This allows shortening the rest of the code, which, in my opinion, makes it easier to read.
2024-09-16 04:10:30 +00:00
Arian94
737ba1d9d8
fix(linter): fix some cases on ``AssignmentExpression` for `unicorn/consistent-function-scoping`` (#5675)
This is to fix the cases mentioned in the comment section of #5365.

In short, it will report these as PASS test cases:

```js
let inner;

function foo1() {
  inner = function() {}
}
function foo2() {
  inner = function() {}
}
```

```js
let inner;

function outer() {
  inner = function() {}
}
```

And report these below as FAIL test cases:

```js
let inner;

function foo1() {
  inner = function smth() {}
}
function foo2() {
  inner = function bar() {}
}
```

```js
let inner;

function outer() {
  inner = function inner() {}
}
```

The case below was already done in #5312 but mentioned in #5365. It is a
FAIL case as well:
```js
function outer() {
  const inner = function inner() {}
}
```

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Don Isaac <donald.isaac@gmail.com>
2024-09-16 00:09:59 -04:00
overlookmotel
dc10eaf047 refactor(ast): split ast macro into multiple files (#5791)
Pure refactor. Split implementation of `#[ast]` macro into multiple files. This means each file works with a single version of `TokenStream`, rather than having `proc_macro::TokenStream` and `proc_macro2::TokenStream` both in use in a single file.
2024-09-16 04:03:49 +00:00