follow-up: https://github.com/oxc-project/oxc/pull/4587#issue-2440174935
The `CalculateSignatureKey`is used to collect signature keys, but since it requires a double visit, it doesn't perform very well. Now I use ScopeId to store the signature key that is generated in `CallExpression`. This way we can then determine which ArrowFunction/Function the `CallExpression` belongs to.
Follow-on after #5223. We're trying to ignore JSX identifiers, so there's no point walking downwards from `JSXElementName`, as all we'll find is JSX identifiers that we want to ignore.
Follow-on after #5223.
Now that we are getting an `IdentifierReference` with a `reference_id`, we can use that ID for a faster lookup of whether the reference is bound or not.
Outside of the parser, a `JSXIdentifier` in a `JSXElementName::Identifier` will never be a identifier reference. So move the code for deciding if a `JSXElementName` is `JSXElementName::Identifier` or `JSXElementName::IdentifierReference`, and the code for converting from one to the other, into the parser - which is only place it should be used.
#5223 added a new variant `JSXElementName::IdentifierReference` for JSX identifiers which are treated as references (e.g. `<Foo>`) as opposed to `JSXElementName::Identifier` which is for lowercase (e.g. `<div>`).
But we were incorrectly categorizing identifiers beginning with `_` or `$` - these should also be treated as references.
(as discussed in https://github.com/oxc-project/oxc/pull/5339#issuecomment-2321037779)
Follow-on after #5223.
#5223 introduced the line `let span = jsx_el.opening_element.name.span();`. But the span is only needed when creating a diagnostic when the rule fails (cold path). Avoid the work of getting the span for the common case where the rule passes.
Follow-on after #5223.
JSX identifiers which start with a capital letter are now `JSXElementName::IdentifierReference`s, so no need to check for capitalized `JSXElementName::Identifier`s.
Box `TSThisParameter` in `Function`, `TSMethodSignature` and `TSFunctionType`. I assume `function(this: Whatever) {}` is a fairly rare syntax in TS code, and obviously never occurs in JS code, so it takes up a lot of space in `Function` for this uncommon case.
This change reduces `Function` from 136 bytes to 104.
VSCode has a couple violations. examples:
```
x oxc(no-accumulating-spread): Do not spread accumulators in loops
,-[src/vs/workbench/services/textMate/common/TMGrammarFactory.ts:65:5]
64 | let injections: string[] = [];
65 | for (let i = 1; i <= scopeParts.length; i++) {
: ^|^
: `-- For this loop
66 | const subScopeName = scopeParts.slice(0, i).join('.');
67 | injections = [...injections, ...(this._injections[subScopeName] || [])];
: ^^^^^^|^^^^^^
: `-- From this spread
68 | }
`----
help: Consider using `Object.assign()` or `Array.prototype.push()` to mutate the accumulator instead.
Using spreads within accumulators leads to `O(n^2)` time complexity.
x oxc(no-accumulating-spread): Do not spread accumulators in loops
,-[src/vs/base/common/actions.ts:205:3]
204 | let out: IAction[] = [];
205 | for (const list of actionLists) {
: ^|^
: `-- For this loop
206 | if (!list.length) {
207 | // skip
208 | } else if (out.length) {
209 | out = [...out, new Separator(), ...list];
: ^^^|^^
: `-- From this spread
210 | } else {
`----
help: Consider using `Object.assign()` or `Array.prototype.push()` to mutate the accumulator instead.
Using spreads within accumulators leads to `O(n^2)` time complexity.
help: It looks like you're spreading an `Array`. Consider using the `Array.push` or `Array.concat` methods to mutate the accumulator instead.
Using spreads within accumulators leads to `O(n^2)` time complexity.
x oxc(no-accumulating-spread): Do not spread accumulators in loops
,-[src/vs/workbench/contrib/extensions/browser/extensionsActions.ts:302:3]
301 | let actions: IAction[] = [];
302 | for (const visibleActions of actionsGroups) {
: ^|^
: `-- For this loop
303 | if (visibleActions.length) {
304 | actions = [...actions, ...visibleActions, new Separator()];
: ^^^^^|^^^^
: `-- From this spread
305 | }
`----
help: Consider using `Object.assign()` or `Array.prototype.push()` to mutate the accumulator instead.
Using spreads within accumulators leads to `O(n^2)` time complexity.
x oxc(no-accumulating-spread): Do not spread accumulators in loops
,-[src/vs/workbench/contrib/extensions/browser/extensionsActions.ts:1141:3]
1140 | let actions: IAction[] = [];
1141 | for (const menuActions of menuActionGroups) {
: ^|^
: `-- For this loop
1142 | actions = [...actions, ...menuActions, new Separator()];
: ^^^^^|^^^^
: `-- From this spread
1143 | }
`----
help: Consider using `Object.assign()` or `Array.prototype.push()` to mutate the accumulator instead.
Using spreads within accumulators leads to `O(n^2)` time complexity.
x oxc(no-accumulating-spread): Do not spread accumulators in loops
,-[src/vs/workbench/contrib/extensions/browser/extensionsViews.ts:334:4]
333 | let actions: IAction[] = [];
334 | for (const menuActions of groups) {
: ^|^
: `-- For this loop
335 | actions = [...actions, ...menuActions, new Separator()];
: ^^^^^|^^^^
: `-- From this spread
336 | }
`----
help: Consider using `Object.assign()` or `Array.prototype.push()` to mutate the accumulator instead.
Using spreads within accumulators leads to `O(n^2)` time complexity.
```
`TraverseCtx::ancestors` iterator would previously yield `Some(Ancestor::None)` before finally yielding `None`. Skip `Ancestor::None` as it's pointless.
Change meaning of `level` passed to `TraverseCtx` from "levels above current" to "levels above parent". `ctx.parent()`'s equivalent was `ctx.ancestor(1)`, now it's `ctx.ancestor(0)`.
This prevents out of bounds read on `ctx.ancestor(0)` (UB), which was made possible by #5286.
Preparation for upstack PRs. Graphical reporter diagnostics look exactly the same. This does, however, change `to_string()` to only show diagnostic messages, and not error codes + messages.
This pr is for jest/vitest compat and add another jest rule condition
---------
Co-authored-by: Don Isaac <donald.isaac@gmail.com>
Co-authored-by: Wang Wenzhe <mysteryven@gmail.com>
changes from using `without_parenthesis` to using `get_inner_expression` to ignore type casts, non null assertions ect.
this helps catch more error cases
Fixing code is an important part of linter logic. We want to make sure fixers for each rule, and the code responsible for applying those fixes, are included in benchmarks.
As it currently stands, fixer closures are applied regardless of whether the user wants fixers to be applied. However, this is an implementation detail and is subject to change. I also want to bench the performance of `Fixer`.