Commit graph

573 commits

Author SHA1 Message Date
Boshen
3bc05faf27 feat(transformer): implement jsx spread child (#8763)
closes #8690
2025-01-31 15:20:54 +00:00
Yuji Sugiura
b3a57696a1
feat(tasks/prettier): Show total match ratio with updating snapshot format (#8788)
Previously, #8634 visualized each spec result, but this was not enough.

If the implementation has been updated but the spec still fails, there
is no way to know if there is an improvement or not.

This time, finally, all progress is visualized! 🤩 


![image](https://github.com/user-attachments/assets/df5b4658-450a-4b0c-8348-ffc9b977c50c)

e.g. here `arrow_function_expression` is mostly passing, except for
comment handling.
2025-01-30 22:27:34 +08:00
renovate[bot]
40362dfc01
chore(deps): update npm packages (#8740) 2025-01-27 12:10:20 +08:00
branchseer
3e509e1c9b
fix(transformer/typescript): enum merging when same name declared in outer scope (#8691)
```typescript
var x = 10;
enum Merge { x = Math.random() }
enum Merge {
    y = x // <-- refers to Merge.x
}
```

This case wasn't covered in #8543 and by the [babel test
case](e568916ef3/packages/babel-plugin-transform-typescript/test/fixtures/enum/non-constant-member-reference/input.ts).
To handle it we still have to go through the scope ancestors.

---------

Co-authored-by: Dunqing <dengqing0821@gmail.com>
2025-01-26 09:18:00 +08:00
Dunqing
e7ab96cbb6 fix(transformer/jsx): incorrect isStaticChildren argument for Fragment with multiple children (#8713)
close: #8650
2025-01-25 16:11:28 +00:00
branchseer
7421a52f7c
fix(transformer/typescript): correctly resolve references to non-constant enum members (#8543)
fixes #8342

---------

Co-authored-by: overlookmotel <theoverlookmotel@gmail.com>
Co-authored-by: Dunqing <dengqing0821@gmail.com>
2025-01-18 17:02:50 +08:00
Boshen
7f4b302508
chore: vitest 3.0.0 (#8578) 2025-01-18 12:10:01 +08:00
Dunqing
f413bb5c64 feat(transformer/optional-chaining): change parent scope for expression when it wrapped with an arrow function (#8511) 2025-01-16 12:21:44 +00:00
Dunqing
06ccb51fae fix(transformer/async-to-generator): move parameters to the inner generator function when they could throw errors (#8500)
The new implementation port from [esbuild](df815ac27b/internal/js_parser/js_parser_lower.go (L355-L467)), before from `Babel`.

Babel's transform implementation for the async method is incorrect because the async method should return a rejecting promise when it throws an error. Everything is good if the errors are thrown in the async method body, but the following case will throw an error in the parameters which causes the whole program crushed not a rejecting promise. So we should move the parameters to the inner generator function when the parameters could throw an error.

Input:
```js
class Cls {
  // ReferenceError: Cannot access 'b' before initialization
  async method(a = b, b = 0) {}
}
```

Before output
```js
class Cls {
  method(a = b, b = 0) {
    return babelHelpers.asyncToGenerator(function* () {})();
  }
}
```

After output:
```js
class Cls {
  method() {
     // ReferenceError: Cannot access 'b' before initialization
    return babelHelpers.asyncToGenerator(function* (a = b, b = 0) {}).apply(this, arguments);
  }
}
```

No override tests because Babel doesn't cover this case.
2025-01-16 00:18:05 +00:00
overlookmotel
356f0c1a6a fix(transformer/class-properties): handle nested super() calls (#8506)
Similar to #8494. Handle nested `super()` calls in class constructor e.g. `super(self = super())`. Very weird code, but legal!
2025-01-15 15:09:00 +00:00
overlookmotel
cfd783aa19
chore(coverage): bump babel submodule (#8508)
Update babel submodule for conformance tests to latest HEAD.

The test fixtures include a new one for a bug fix which @branchseer
intends to also apply to Oxc - https://github.com/babel/babel/pull/17050
(see #8342).
2025-01-15 22:58:15 +08:00
overlookmotel
99635330c7 fix(transformer/arrow-functions): visit arguments to super() call (#8494)
Follow-on after #8482.

Fix an edge case in arrow functions transform when inserting `_this = this` after `super()`. It is possible (though bizarre) for `super()` to contain another `super()` call. This will throw an error when evaluating the outer `super()`, but it can still be observable in some cases.

```js
let f;
class S {}
class C extends S {
  constructor(x) {
    super(super(), this.x = x, f = async () => this);
  }
}

try { new C(123) } catch {}

const c = await f();
assert(c.x === 123);
```

So, before bailing out from searching for more `super()`s in class constructor, visit the `super()` call's arguments.
2025-01-15 02:07:05 +00:00
overlookmotel
ca02c16f8f test(transformer): handle more exec tests (#8493)
Some of Babel's exec tests contain a return statement at top level, in order to return a Promise.

e.g. ad572fd1a1/packages/babel-plugin-transform-private-methods/test/fixtures/private-method-loose/async/exec.js

These test files could not be parsed due to illegal position of `return`, and the tests were silently excluded.

This PR:

1. Includes those tests by passing `allow_return_outside_function: true` option to parser for exec tests.
2. Includes a "transform error" message in snapshot for any exec tests which produce errors in parser/transformer.
2025-01-15 02:07:04 +00:00
Dunqing
270245fd6e fix(transformer/typescript): correct the semantic for TSImportEqualsDeclaration transformation (#8463) 2025-01-14 11:26:50 +00:00
Dunqing
2a400d66d4
fix(transformer/typescript): retain TSImportEqualsDeclaration when it is exported 2025-01-14 19:12:23 +08:00
Dunqing
c83ce5c6cf refactor(transformer/typescript): improve transforming namespace (#8459)
I did a few things in this PR,

1. Remove `names` which store the declarations name used for checking re-declaration. (We can use SymbolTable to do it now.)
2. Correct semantic data for namespace transform
3. Simplify code
2025-01-14 09:42:31 +00:00
Dunqing
c444de8be1 fix(transformer/arrow-functions): transform this and super incorrectly in async arrow function (#8435)
close: #8385

This PR is to solve the missing `super` transform in the async arrow function, and `_this = this` inserts to an incorrect place. These problems are all about the async arrow function, which is a part of the init of class property. Learn more at #8387.

The output matches Babel's output except for static prop as Babel transforms incorrectly.
2025-01-14 08:38:55 +00:00
overlookmotel
0358c6f6c3 test(transformer/async-to-generator): failing test for async arrow function in class static block (#8387)
It's arguable whether we should support this, because async functions is ES2018 and class static blocks is ES2022. So there should not be any browser which needs async-to-generator transform, and not the static block transform too. And when class-static-block transform is enabled, this works fine.

But personally, I think we should support it, because:

1. We allow user to enable/disable arbitrary transforms via `TransformOptions`.
2. We support `this` in async arrow functions in class static blocks, so it makes sense to complete that support.
3. I don't think it should be too hard, as the framework for it is already there in the async-to-generator transform.

[Babel REPL](https://babeljs.io/repl#?browsers=defaults%2C%20not%20ie%2011%2C%20not%20ie_mob%2011&build=&builtIns=false&corejs=3.21&spec=false&loose=false&code_lz=MYGwhgzhAEDC0FMAeAXBA7AJjAytA3gFDTQQpgoCWwBxJ0KAFpRAHQBm60AvNJAJ7oaACgCUPAHykArgAcEAJw4B7ZQG46AX0LagA&debug=false&forceAllTransforms=false&modules=false&shippedProposals=false&evaluate=false&fileSize=false&timeTravel=false&sourceType=module&lineWrap=true&presets=&prettier=true&targets=&version=7.26.4&externalPlugins=%40babel%2Fplugin-transform-async-to-generator%407.25.9%2C%40babel%2Fplugin-external-helpers%407.25.9&assumptions=%7B%7D)
2025-01-14 08:38:54 +00:00
Dunqing
ab694b064a fix(transformer/typescript): retain TSImportEqualsDeclaration in namespace when its binding has been referenced or onlyRemoveTypeImports is true (#8458)
close: #8384
2025-01-13 05:57:30 +00:00
Dunqing
9a03bd23b9 fix(transformer/typescript): remove type-only import = when only_remove_type_imports is true (#8275)
close: https://github.com/oxc-project/oxc/issues/8230
close: https://github.com/rolldown/rolldown/issues/3287

Related PR in Babel: https://github.com/oxc-project/oxc/issues/8230

I have compared our output with TypeScript, and it is the same as `TypeScript`, Babel's implementation currently hasn't removed imports referenced by type-only `TSImportEqualsDeclaration`
2025-01-11 08:42:51 +00:00
overlookmotel
8d2176e2e1 test(transformer/arrow-functions): add decorators to test (#8393)
Follow-on after #8382. Add decorators to the test fixture.
2025-01-10 03:27:46 +00:00
Dunqing
3feac2711b fix(transformer/arrow-functions): outer super() in nested class (#8382) 2025-01-09 17:54:06 +00:00
overlookmotel
0df18667ea fix(transformer/typescript): create Reference for require (#8355)
Create a `Reference` when generating new `IdentifierReference` for `require`.
2025-01-09 16:50:46 +00:00
Dunqing
335065d8c8 fix(transformer/arrow-functions): do not transform super that inside nested non-async method (#8335)
This `super.value` belongs to the nested class, we shouldn't transform it.
```js
class Outer {
    async method() {
      class Inner extends Outer {
        normal() {
          // `super.value` should not be transformed, because it is not in an async method
          super.value
        }
      }
    }
 }
```
2025-01-09 11:41:20 +00:00
overlookmotel
ab6142503f fix(transformer/private-methods): no temp var for class when unused private methods (#8360)
No temp var is required for class if it contains static private method which is not referenced within class. e.g.:

```js
let C = class {
  static #method() {}
};
```

->

```js
let C = class {};
function _method() {}
```
2025-01-09 03:17:37 +00:00
overlookmotel
78d7c97357 fix(transformer/typescript): create Reference for Infinity (#8354)
Create a `Reference` when generating new `IdentifierReference` for `Infinity`.
2025-01-09 02:26:33 +00:00
Dunqing
e4d66e4636 fix(transformer/arrow-functions): store super_methods on a Stack to fix nested async methods (#8331)
In the following case, async methods can be nested in another async method. The implementation is changing to store `super_methods` on a stack, and then we can store super method information in the correct `super_methods` map.

```js
const outer = {
  value: 0,
  async method() {
    () => super.value;

    const inner = {
      value: 0,
      async method() {
        () => super.value;
      }
    };

    () => super.value;
  }
};
```
2025-01-08 21:00:45 +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
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
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
Dunqing
0592a8b43f feat(transformer/class-properties): transform private in expression (#8202)
This PR support transforms `#prop in object` in class-properties to cover https://www.npmjs.com/package/@babel/plugin-transform-private-property-in-object  plugin does
2024-12-31 12:30:58 +00:00
Dunqing
80c16526fb chore(transformer): enable Babel's private-property-in-property plugin tests (#8201) 2024-12-31 12:30:57 +00:00
Dunqing
3c77ed1af1 feat(transform-conformance): support enabling all class-related plugins when any of them are enabled in update_fixtures (#8200)
The `class-properties` plugin supports all class-related plugins, so we need to ensure that once any of them are enabled, we also enable all class-related plugins.
2024-12-31 12:30:57 +00:00
Dunqing
ad77ad5c12 feat(transformer/class-properties): transform static/instance accessor methods (#8132)
This PR supports transforming private `getter` or `setter` methods, and the output is a little different from Babel's output, For example:

Input:
```js
class Cls {
  #prop = 0;

  get #accessor() {
    return this.#prop;
  }
  set #accessor(v) {
    console.log(arguments);
    this.#prop = v;
  }

  constructor() {
    console.log(this.#accessor)
    [this.#accessor] = [1];
  }
}
```

[Babel's output](https://babeljs.io/repl#?browsers=defaults%2C%20not%20ie%2011%2C%20not%20ie_mob%2011&build=&builtIns=false&corejs=3.21&spec=false&loose=false&code_lz=MYGwhgzhAEDCIwN4ChrQMQAcBOB7T0AvNAAwDcyq0A5gKYAuGYwwtUu2AFAJTQpppsDAK7YAdtHoALAJYQAdFjyYKaAL5UIDJizYQOnAG69-A4LjH6QteSFzVOYbNWEBbWmPoRuqgdLmKOPhE0Ia-GlTmlvTYwsD0BiZUaFFWNnYO_grozKzs2NzJ0ADaWYq5ehwAuiHFAIxV4cgaQA&debug=false&forceAllTransforms=false&modules=false&shippedProposals=false&evaluate=false&fileSize=false&timeTravel=false&sourceType=script&lineWrap=true&presets=&prettier=false&targets=&version=7.26.4&externalPlugins=%40babel%2Fplugin-transform-class-properties%407.25.9%2C%40babel%2Fplugin-transform-private-methods%407.25.9%2C%40babel%2Fplugin-external-helpers%407.25.9&assumptions=%7B%7D):
```js
var _prop = new WeakMap();
var _Cls_brand = new WeakSet();
class Cls {
  constructor() {
    babelHelpers.classPrivateMethodInitSpec(this, _Cls_brand);
    babelHelpers.classPrivateFieldInitSpec(this, _prop, 0);
    console.log(babelHelpers.classPrivateGetter(_Cls_brand, this, _get_accessor));
    [babelHelpers.classPrivateGetter(_Cls_brand, this, _get_accessor)] = [1];
  }
}
function _get_accessor(_this) {
  return babelHelpers.classPrivateFieldGet(_prop, _this);
}
function _set_accessor(_this2, v) {
  var _arguments = [].slice.call(arguments, 1);
  console.log(_arguments);
  babelHelpers.classPrivateFieldSet(_prop, _this2, v);
}
```

Oxc's output:
```js
var _prop = new WeakMap();
var _Cls_brand = new WeakSet();
class Cls {
        constructor() {
                babelHelpers.classPrivateMethodInitSpec(this, _Cls_brand);
                babelHelpers.classPrivateFieldInitSpec(this, _prop, 0);
                console.log(_get_accessor.call(babelHelpers.assertClassBrand(_Cls_brand, this)));
                [babelHelpers.toSetter(_set_accessor.bind(babelHelpers.assertClassBrand(_Cls_brand, this)), [])._] = [1];
        }
}
function _get_accessor() {
        return babelHelpers.classPrivateFieldGet2(_prop, this);
}
function _set_accessor(v) {
        console.log(arguments);
        babelHelpers.classPrivateFieldSet2(_prop, this, v);
}
```

### Main difference
```diff
// Babel
+ console.log(babelHelpers.classPrivateGetter(_Cls_brand, this, _get_accessor));
+ [babelHelpers.classPrivateGetter(_Cls_brand, this, _get_accessor)] = [1];

+ function _get_accessor(_this) {
+   return babelHelpers.classPrivateFieldGet(_prop, _this);
+ }

+ function _set_accessor(_this2, v) {
+   var _arguments = [].slice.call(arguments, 1);
+   console.log(_arguments);
+   babelHelpers.classPrivateFieldSet(_prop, _this2, v);
+ }

// Oxc
-  console.log(_get_accessor.call(babelHelpers.assertClassBrand(_Cls_brand, this)));- -
-  [babelHelpers.toSetter(_set_accessor.bind(babelHelpers.assertClassBrand(_Cls_brand, this)), [])._] = [1];

- function _get_accessor() {
-   return babelHelpers.classPrivateFieldGet2(_prop, this);
- }

- function _set_accessor(v) {
-   console.log(arguments);
-   babelHelpers.classPrivateFieldSet2(_prop, this, v);
- }
```

From the main differences, we can see that Babel handles `getter` and `setter` methods using `classPrivateGetter` and `classPrivateSetter` helper functions, which causes all use `this` and `arguments` needs to rewrite to use a temp var instead in `getter` and `setter` methods. This is unnecessary and is not an efficient transformation for us.

Instead, I adapt binding a `this` instead of passing in `this`, this way we don't need to rewrite anything. We can't control the `helper` library for now, so I just transformed the AST to bind `this`, in the future, we can create a helper function to do the same thing.
2024-12-31 12:30:56 +00:00
Dunqing
e405f79577 feat(transformer/class-properties): transform static private method invoking (#8117) 2024-12-31 12:30:56 +00:00
Dunqing
3303e9986b feat(transformer/class-properties): insert statements after statement of class expression (#8116) 2024-12-31 12:30:55 +00:00
Dunqing
0cc71cf5e3 feat(transformer/class-properties): transform super expressions and identifiers that refers to class binding in private method (#8106)
All private methods will be moved out of class, so we need to transform all `super` expressions in private methods and transform identifiers that refer to class binding.
2024-12-31 12:30:55 +00:00
Dunqing
58ed83242a feat(transformer/class-properties): transform private field expression which invokes private method (#8102) 2024-12-31 12:30:53 +00:00
Dunqing
f14567a658 feat(transformer/class-properties): transform callee which invokes private method (#8100)
transform call expression's callee if it invokes a private method
2024-12-31 12:30:52 +00:00
Dunqing
13349ef1b8 feat(transformer/class-properties): transform private methods (#8099)
This PR support transforms private methods in a class, moving all of them to after the `class`
2024-12-31 12:30:52 +00:00
Dunqing
6af5870a7d chore(transformer): enable Babel's private-methods plugin tests (#8098)
part of #8052
2024-12-31 12:30:51 +00:00
Boshen
e632a7b158 feat(transformer): remove typescript symbols after transform (#8069)
part of #7460
2024-12-23 08:24:54 +00:00
overlookmotel
6b08c6e6c4 fix(transformer/class-properties): correctly resolve private fields pointing to private methods (#8042)
We don't transform private methods yet, but in class properties transform, still need to record private methods that classes have, so can correctly resolve private fields.

```js
class Outer {
  #foo = 123;
  method() {
    class Inner {
      #foo() {}
      // Refers to `Inner`'s `#foo` method, not `Outer`'s `#foo` property
      prop = this.#foo;
    }
  }
}
```
2024-12-23 03:44:08 +00:00
camc314
274f117d4e fix(transformer/nullish-coalescing): use correct scope id for binding (#8053) 2024-12-21 07:08:29 +00:00
overlookmotel
3d83396f0b test(transformer/nullish-coalescing): failing test (#8051)
Add failing test for nullish coalescing operator. The output is correct, but temp var is created in wrong scope.

My guess is that it needs to use `current_hoist_scope_id`, not `current_scope_id`.

This test from class properties also shows the same problem: ac097e9160/tasks/transform_conformance/snapshots/oxc.snap.md (L20-L35)
2024-12-21 07:08:29 +00:00
overlookmotel
043252dcd1 fix(transformer/class-properties): replace this and class name in static blocks (#8035)
Transform `this`, class name, and `super` in static blocks.
2024-12-20 10:07:23 +00:00
overlookmotel
273795d471 fix(transformer/class-properties): run other transforms on static properties, static blocks, and computed keys (#7982)
Large re-architecting of class properties transform. Split transform into 3 phases:

1. Transform instance properties when entering class.
2. Transform private fields during traversal of class body.
3. Transform static properties and static blocks when exiting class.

This ensures that code which has to be moved outside of the class (static property initializers, static blocks, computed keys) can get transformed by other transforms before they're moved out.

Also fixes a problem where we previously registered private properties too early - on entering the class, rather than the class *body*, so private fields in `extends` clause of a nested class were misinterpretted.
2024-12-20 10:07:23 +00:00
overlookmotel
897a1a8946 feat(transformer/class-properties): exit faster from super replacement visitor (#8028)
When inserting instance property initializers into class constructor, need to search for and transform `super()`. Exit that visit earlier in some cases, for better performance and smaller output.
2024-12-20 03:10:22 +00:00
overlookmotel
0a38eea95c refactor(transformer/class-properties): use temp_var_name_base to generate temp var names for super transform (#8004)
Follow-on after #7997.

Generate "base name" for temp var using `temp_var_name_base` and then create the 2 temp bindings from it.

This is a bit more efficient than creating 2nd temp binding from name of the first temp binding, because the first binding's name has `_` added to start, and may have digits on the end, which have to be trimmed off again. Whereas the "base name" is ready to go.

Incidentally, changing the timing of when temp bindings are created also aligns output with Babel.
2024-12-19 02:24:58 +00:00
overlookmotel
87ea928e17 test(transformer/class-properties): failing test for super.prop as assignment target (#8005)
Add failing test for syntax we can't support yet.
2024-12-18 19:07:24 +00:00