Commit graph

7656 commits

Author SHA1 Message Date
Yuji Sugiura
8e3eed7562
refactor(prettier): Update tasks/prettier to correctly handle snapshots (#8337)
I refactored the code in `tasks/prettier_conformance` primarily to make
the output more readable when using `--filter`.

But I also discovered that our previous implementation did not correctly
handle Prettier's behavior of adding a blank line at the EOF.

In addition, I resolved a problem where test specs that used patterns
like `runFormatTest(_, parsers)` were unable to locate the correct
snapshot output.

As a result, compatibility has also improved slightly. 😉

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-01-08 17:10:30 +08:00
Boshen
6220e05f38 feat(minifier): remove empty if statment if (test) {} -> test (#8336) 2025-01-08 08:50:10 +00:00
Boshen
a76dfae8e3 feat(minifier): remove label statement with empty body (#8333) 2025-01-08 07:38:39 +00:00
Boshen
e88a6bdd94 feat(minifier): minimize !0 + null !== 1 -> !0 + null != 1 (#8332) 2025-01-08 04:36:42 +00:00
Boshen
98f2b1ccd5 refactor(minifier): clean up peephole_substitute_alternate_syntax (#8327) 2025-01-08 03:44:19 +00:00
overlookmotel
ce6c4457c2 refactor(transformer/arrow-functions): add TODO comments (#8328)
Add some TODO comments for this transform.
2025-01-08 01:52:46 +00:00
overlookmotel
73d0025a75 refactor(transformer/arrow-functions): reduce repeated code (#8323)
Follow-on after #8024. Pure refactor. Make `self.visit_statement(stmt)` only get called in one place, rather than 2.
2025-01-08 01:52:45 +00:00
overlookmotel
62e3f7e525 perf(transformer/arrow-functions): reduce size of inlined visitor (#8322)
Follow-on after #8024.

Move code out of `visit_expression`.

`visit_expression` is marked `#[inline]`, which is a good idea because it's a hot path and most of the time the `Expression` is not `super()` and the function does nothing.

But this means we want `visit_expression` to be as small as possible to reduce the cost of inlining it. So only retain the fast path for "Is it `super()`? No it's not, so just continue traversal." and move everything else out into a separate function.
2025-01-08 01:52:45 +00:00
overlookmotel
3dd08e9786 refactor(transformer/arrow-functions): do not inline non-trivial visitor method (#8321)
Follow-on after #8024. Don't inline `visit_statements` visitor method. This visitor is not so small, and always executes unconditionally. The compiler can decide whether to inline it or not. Where `#[inline]` is really valuable is:

1. Where the function is tiny so the cost of moving it into the caller is small. and
2. The function gets called a lot e.g. `visit_expression`, `visit_statement`, `visit_identifier_reference`.
3. Most commonly the function checks something and exits "nothing to do here". e.g. `visit_expression` where you only need to transform a particular type of `Expression`.
2025-01-08 01:52:44 +00:00
overlookmotel
ea9cefb5c3 refactor(transformer/arrow-functions): reorder visitor methods (#8320)
Follow-on after #8024. Pure refactor.

Re-order the methods of the `ConstructorBodyThisAfterSuperInserter` visitor. Intent is that the call path flows from top to bottom, so the "story" makes sense when you read the code starting from the top.
2025-01-08 01:52:43 +00:00
overlookmotel
37199a4cd6 refactor(transformer/arrow-functions): rename lifetime (#8319)
Follow-on after #8024. Pure refactor. Rename lifetime to `'v` ("v" for visitor).
2025-01-08 01:52:43 +00:00
1zumii
45eb35434d
chore(linter): add vscode debugger launch config (#8271)
refer to this
[reply](https://discord.com/channels/1079625926024900739/1080101477672046712/1265758176754794598),
add CodeLLDB launch config for debugging oxlint.

usage for real dev like:
```json
{
  "type": "lldb",
  "request": "launch",
  "name": "Debug Oxlint",
  "cargo": {
    "env": {
      "RUSTFLAGS": "-g"
    },
    "args": ["build", "--bin=oxlint", "--package=oxlint"],
    "filter": {
      "name": "oxlint",
      "kind": "bin"
    }
  },
  "args": ["--ignore-pattern=./ignore/**"],
  "cwd": "/home/xxx/temp/oxlint-7102"
}
```

besides, i tired add config in `args` to override `Cargo.toml`
`[profile.dev] debug = false`, but cargo in CodeLLDB throw error.
```json
"args": [
  "build", "--bin=oxlint", "--package=oxlint", 
  "--config profile.dev.debug=true"
]
```

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-01-08 09:51:47 +08:00
overlookmotel
aebe0ea46d perf(transformer/arrow-functions): use NonEmptyStack instead of Stack (#8318)
Follow-on after #8024.

Use `NonEmptyStack` instead of `Stack`.

`NonEmptyStack` is cheaper as `last` / `last_mut` always returns `T`, rather than `Option<T>`, so there's no need to branch on whether it's `Some` or not.

The only downside of `NonEmptyStack` is that it always contains 1 dummy entry at the start (so that it's never empty). This means that it always allocates, unlike `Stack` which doesn't allocate unless you push something into it.

So `NonEmptyStack` is always the better choice unless either:

1. The stack will likely never have anything pushed to it. or
2. The type the stack holds is large or expensive to construct, so there's a high cost in having to create an initial dummy value.

In this case:

* The type is `bool` - very small and cheap to construct.
* The stack will be pushed to when entering a function. Very few JS files contain no functions at all, so the stack will always need to allocate, even if we used `Stack`.

So this case doesn't satisfy either of the circumstances in which `Stack` is the better choice.
2025-01-08 01:32:56 +00:00
overlookmotel
57e9dcf046 refactor(transformer/arrow-functions): shorten AstBuilder call (#8317)
Follow-on after #8024. Pure refactor, just shorten code.
2025-01-08 01:32:55 +00:00
sapphi-red
ec88c68c28
feat(minifier): compress a || (a = b) to a ||= b (#8315)
Compress `a || (a = b)` to `a ||= b` and for other logical operators that are possible to.

I didn't find other minifiers doing this, but this is safe for identifiers. [Quoting MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_OR_assignment#description):

> Logical OR assignment short-circuits, meaning that `x ||= y` is equivalent to `x || (x = y)`, except that the expression x is only evaluated once.

I actually checked the spec and the only difference was that `Let lRef be ? Evaluation of LeftHandSideExpression` was done twice. Evaluating an IdentifierReference is idempotent so it should be safe to do this compression.

References:

- [Spec of `&&=`](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-assignment-operators:~:text=Return%20r.-,AssignmentExpression,7.%20Return%20rVal.,-AssignmentExpression)
- [Spec of `=`](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#prod-AssignmentExpression:~:text=Runtime%20Semantics%3A%20Evaluation-,AssignmentExpression,6.%20Return%20rVal.,-AssignmentExpression)
- [Spec of `&&`](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-binary-logical-operators:~:text=Runtime%20Semantics%3A%20Evaluation-,LogicalANDExpression,5.%20Return%20%3F%C2%A0GetValue(rRef).,-LogicalORExpression)

I think this is safe for `a.b || (a.b = foo)` as well because the number of `GetValue` and `SetValue` does not change, but I didn't include that in this PR.
2025-01-07 23:19:52 +00:00
sapphi-red
e6fe84d674
feat(minifier): compress a = a + b to a += b (#8314)
Compress `a = a + b` to `a += b` and for other binary operators that are possible to.
2025-01-07 23:19:50 +00:00
sapphi-red
9ea4e31ba3
feat(minifier): remove new from new Error/new Function/new RegExp (#8313)
Remove `new` from some cases:

- `new Error(...)` -> `Error(...)`: `new` can be removed unconditionally, [spec](https://tc39.es/ecma262/multipage/fundamental-objects.html#sec-error-constructor:~:text=Thus%20the%20function%20call%20Error(%E2%80%A6)%20is%20equivalent%20to%20the%20object%20creation%20expression%20new%20Error(%E2%80%A6)%20with%20the%20same%20arguments.)
- `new Function(...)` -> `Function(...)`: `new` can be removed unconditionally, [spec](https://tc39.es/ecma262/multipage/fundamental-objects.html#sec-function-constructor:~:text=Thus%20the%20function%20call%20Function(%E2%80%A6)%20is%20equivalent%20to%20the%20object%20creation%20expression%20new%20Function(%E2%80%A6)%20with%20the%20same%20arguments.)
- `new RegExp(nonRegexp)` -> `RegExp(nonRegexp)`: `new` can be removed if there's no argument or the first argument is not regex object, [mdn](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/RegExp#return_value), [spec](https://tc39.es/ecma262/multipage/text-processing.html#sec-regexp-constructor:~:text=when%20called%20as%20a%20function%20rather%20than%20as%20a%20constructor%2C%20returns%20either%20a%20new%20RegExp%20object%2C%20or%20the%20argument%20itself%20if%20the%20only%20argument%20is%20a%20RegExp%20object.). I made this to happen if the first argument is not an object.
2025-01-07 14:48:56 +00:00
Boshen
fc662b7896 refactor(minifier): handle big int values later (#8324) 2025-01-07 14:25:22 +00:00
Dunqing
775a289a55 fix(transformer/arrow-functions): _this = this should be inserted after super call expression (#8024)
related: #7792

This PR doesn't contain fixing the async arrow function in `super()`, which is difficult for our architecture. I just found that `esbuild`'s implementation is quite simpler! https://esbuild.github.io/try/#dAAwLjI0LjAALS10YXJnZXQ9ZXMyMDE2AGNsYXNzIEMgZXh0ZW5kcyBTIHsKICBjb25zdHJ1Y3RvcigpIHsKICAgIHN1cGVyKGFzeW5jICgpID0+IHRoaXMpOwogICAgYXN5bmMoKSA9PiB7fQogIH0KfQ
2025-01-07 13:53:44 +00:00
Boshen
051fbb6909 feat(minifier): minimize x["0"] -> x[0] (#8316) 2025-01-07 13:12:35 +00:00
Boshen
a542013773 feat(minifier): minimize do{}while(true) -> do;while(true) (#8311) 2025-01-07 12:55:03 +00:00
Boshen
e3ff81ef82 feat(minifier): minimize (x = 1) === 1 -> (x = 1) == 1 (#8310) 2025-01-07 07:48:35 +00:00
Boshen
4b68cc0972 feat(minifier): minimize empty try statement (#8309) 2025-01-07 07:16:01 +00:00
overlookmotel
e1f8ea41ad fix(lexer): Source is not Clone (#8294)
It's an invariant of `Source` that only a single instance of `Source` can exist at any time. `Source` was erroneously implementing `Clone`, which makes it trivial to break this invariant. `Clone` is unnecessary, so remove it.
2025-01-07 06:58:26 +00:00
overlookmotel
64bfdfe223 refactor(lexer): tighten safety of lexer by always including lifetime on SourcePosition (#8293)
Always use `SourcePosition<'a>` not `SourcePosition`, to ensure not reading from a `Source` with a `SourcePosition` which is from *another* `Source`. This doesn't definitively guard against UB - that is the job of `UniquePromise` - but it adds another level of defence.
2025-01-07 06:58:24 +00:00
overlookmotel
16dcdaf6cd test(lexer): assert size of Token in 32-bit WASM (#8292)
`Token` should be 16 bytes in WASM too. Enable this test on 32-bit platforms.
2025-01-07 06:58:23 +00:00
overlookmotel
0344e98c99 refactor(lexer): make handle_byte a method of Lexer (#8291)
Pure refactor. `handle_byte` was a free function. Make it a method of `Lexer` instead - more idiomatic.
2025-01-07 06:58:22 +00:00
Boshen
922c5147b5 feat(minifier): fold .toString() (#8308) 2025-01-07 06:33:58 +00:00
Yuji Sugiura
30cee0e47e
feat(prettier): Print tagged template literal (#8307)
Part of #5068 

First steps for template literals... 🗻

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-01-07 14:25:14 +08:00
Boshen
d16e598678 refactor(minifier): clean up peephole_replace_known_methods (#8306) 2025-01-07 02:29:49 +00:00
camc314
66a24437ac feat(minifier): minify sequence expressions (#8305) 2025-01-06 23:42:30 +00:00
camc314
af65c3670f feat(minifier): minimize double negated binary expressions (#8304) 2025-01-06 23:26:20 +00:00
camc314
76c778b03f feat(minifier): remove logical nots when arg is a delete expression (#8303) 2025-01-06 23:26:20 +00:00
camc314
5ed439bcaf feat(minifier): minify typeof in binary expressions (#8302) 2025-01-06 23:26:19 +00:00
camc314
6afc590db8 feat(minifier): compress typeof addition string (#8301) 2025-01-06 23:26:18 +00:00
overlookmotel
4d2888d6fc style(lexer): reorder imports (#8290)
Re-order imports in lexer.
2025-01-06 19:57:59 +00:00
overlookmotel
fabf116f4b refactor(lexer): replace #[allow] with #[expect] (#8289)
Pure refactor. Replace `#[allow]` with `#[expect]` in lexer, and remove various `#[allow]`s which were unnecessary.
2025-01-06 18:01:16 +00:00
overlookmotel
0462edbe7e refactor(lexer): rename function param (#8288)
Pure refactor. Rename unused function param. This results in better param name hint in IDE.
2025-01-06 17:33:09 +00:00
overlookmotel
d8b27afc35 refactor(ast)!: no unneccesary trailing underscores on AstBuilder method names (#8283)
`AstBuilder` method names have an `_` added on end if method name is not a valid identifier (e.g. `super`). But no need for trailing underscore on `alloc_super`.

Currently this only applies to `super`. But future-proof by checking against all Rust's reserved words.

This is a breaking change, because `alloc_super` method was previously called `alloc_super_`. But probably no-one uses that method anyway - usually you'd use `expression_super` method to get an `Expression::Super`.
2025-01-06 15:09:05 +00:00
overlookmotel
0db2a22e48 refactor(ast): AstBuilder enum builder methods use alloc_* methods (#8281)
Pure refactor. `AstBuilder` methods can use `alloc_*` methods directly, instead of calling `alloc`. Probably this makes no difference to performance as all these methods are marked `#[inline]` anyway. But in general it's better to use methods which don't return large objects on the stack.
2025-01-06 15:09:04 +00:00
overlookmotel
5106088b88 refactor(ast)!: remove FromIn<Expression> for Statement (#8280)
All node creation is meant to go via `AstBuilder`. This is necessary to support Node IDs. Remove this method which breaks that rule. It's not used anyway.
2025-01-06 15:02:58 +00:00
overlookmotel
a5e35282ac refactor(transformer/async-to-generator): pass TraverseCtx to function not AstBuilder (#8279)
Pure refactor. Our convention in transformer is to pass `TraverseCtx` around, and not deal with `AstBuilder` directly. This will make it easier to make changes to `AstBuilder` to support Node IDs later on.
2025-01-06 14:56:54 +00:00
overlookmotel
109b8fc047 refactor(transformer): elide lifetimes where possible (#8285)
Pure refactor. Enable `clippy::needless_lifetimes` lint rule in `oxc_transformer`, and fix what the rule flags - remove unnecessary lifetimes which can be elided.

Also rename a few lifetimes `'b` and `'c` to more descriptive `'ctx`.
2025-01-06 14:52:03 +00:00
overlookmotel
e81f34f2f6 style(span): reformat code (#8296) 2025-01-06 13:57:58 +00:00
overlookmotel
cd0c2dc6f7 test(transformer): remove repeated code from fixtures updating script (#8287)
Pure refactor / tidy up. These 2 lines are repeated twice.
2025-01-06 11:55:00 +00:00
overlookmotel
c8e48434c6 docs(ast): fix doc comment (#8286)
Docs only. Fix an erroneous doc comment.
2025-01-06 11:48:56 +00:00
overlookmotel
1835687b75 refactor(ecmascript): remove unnecessary use statement (#8284)
Tiny refactor. Unnecessary `use core::f64` snuck in in #8252. Probably auto-added by IDE.
2025-01-06 11:42:26 +00:00
Boshen
b8d26eab17 refactor(minifier): move optional catch param to peephole_substitute_alternate_syntax (#8282) 2025-01-06 10:47:56 +00:00
underfin
2e7207f11c
fix(transformer/typescript): should strip import specifiers type with only_remove_type_imports (#8141)
close: https://github.com/oxc-project/oxc/issues/8140
close: https://github.com/rolldown/rolldown/issues/3244

---------

Co-authored-by: Dunqing <dengqing0821@gmail.com>
2025-01-06 18:20:16 +08:00
Boshen
f87da160df fix(minifier): do not fold literals in -0 != +0 (#8278) 2025-01-06 10:08:57 +00:00