Wrapping a function expression in parentheses is unnecessary. Codegen already adds parentheses when printing a function expression as a statement expression. i.e. `(function() {});`.
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.
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.
## 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.
- 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.)
`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.
> 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

----

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>
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.
The last failed test is only because of the comments. the oxc prettier
output is:
```
enum Direction {
Up = 1,
Down,
Left,
Right,
}
enum FileAccess {
None,
Read = // constant members
1 << 1,
Write = 1 << 2,
ReadWrite = Read | Write,
G = // computed member
"123".length,
}
enum Empty {}
const enum Enum {
A = 1,
B = A * 2,
}
```
Expected output:
aa3853b776/tests/format/typescript/enum/__snapshots__/format.test.js.snap (L91-L99)
Hope you can tell more why this happens :)
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
…t_function_return_type rule
This PR fixes an issue where the Bitwise AND (&) operator was mistakenly
used in a conditional statement, instead of the Logical AND (&&)
operator.
Add `SemanticBuilder::with_excess_capacity` method to request that `SemanticBuilder` over-allocate space in `Semantic`'s `Vec`s.
Use this method to reserve 200% extra capacity for transformer to create more scopes, symbols and references.
200% is an unscientific guess of how much extra capacity is required. Obviously it depends on what transforms are enabled and content of the source code.
### Difference
In `enter_expression`: Recursive transform JSX
In `exit_expression`: Deep first transform
After the change, `transform_jsx` still has a lot of room for improvement.