Commit graph

16 commits

Author SHA1 Message Date
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
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
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
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
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
c0576faf80 fix(transformer/class-properties): use UID for args in created class constructor (#7866)
When creating class constructor for a class which has super class, use UID `_args` for temp var (rather than `args`). This avoids shadowing a var called `args` used in an instance property initializer.

This diverges from Babel. Babel uses `args` unless it finds a var called `args` in an instance property initializer. But searching the AST of initializers can be fairly expensive, so it's better to skip it. The overrides for test fixtures included in this PR are just to account for that difference.
2024-12-14 04:18:48 +00:00
Dunqing
b089e8b519 chore(tasks/transform-conformance): support override to replace takeover mode (#7771)
This PR does the following things.

1. Move the override output of the `snapshots` folder to the `overrides` folder.
2. Support `override` mode to replace `takeover` mode
3. The `update_fixtures.js` no longer uses `overrides`'s `output.js` to replace Babel's `output.js`.

### How does `override` mode work?

When running each test, it checks whether an output file for that test exists in the ⁠`overrides` directory. If it does, the output file will be used to compare with the transformed code.
2024-12-11 16:18:14 +00:00
overlookmotel
4f1ab49440 test(transformer/class-properties): add output.js files to override fixtures (#7777)
In two of the overridden text fixtures for class properties transform, there was no `output.js` file because what was overridden was just `options.json` and `update_fixtures.js` script then generated new output files using Babel with the new options.

That was fine, but doesn't work with #7771. So add `output.js` files to the these overrides too.
2024-12-10 15:25:39 +00:00
Dunqing
19a8aa5238 test(transformer/class-properties): overrides optional-chain-related tests (#7749)
These tests only variable names difference from Babel's output, which is caused by transforming order.
2024-12-10 10:35:06 +00:00
overlookmotel
2e69720ba0 feat(transformer/class-properties): support private_fields_as_properties assumption (#7717)
Support `private_fields_as_properties` assumption in class properties transform. This assumption is also enabled by the transform's `loose` option.

Optional chain (e.g. `this?.#prop`) is not yet implemented, but all other usages of private fields are supported. We'll handle optional chain in a follow-on PR.
2024-12-10 02:28:31 +00:00
overlookmotel
e010b6a7a0 feat(transformer/logical-assignment-operators): no temp vars for literals (#7759)
`TransformCtx::duplicate_expression` (introduced in #7754) don't create temp vars for literals. This produces more compact output for the logical assignment operators transform.

This diverges from Babel (it's better!) so add an override for one of Babel's fixtures. Also add further tests for all literal types.
2024-12-10 02:28:28 +00:00
overlookmotel
88a0b9c4af test(transformer/class-properties): override test output for _super in class constructor (#7729)
Our output for this test differs from Babel, because we handle `super()` in class constructors differently, but our output is valid.
2024-12-08 17:57:57 +00:00
overlookmotel
3bae741bb4 test(transformer/class-properties): override test output for _super in class constructor (#7726)
Our output for this test differs from Babel, because we handle `super()` in class constructors differently, but our output is valid.
2024-12-08 15:52:27 +00:00
overlookmotel
dd55b84399 refactor(transformer/class-properties): shorten output when _super function (#7710)
Produce more compact output when insert a `_super` function into class constructor.
2024-12-08 01:41:36 +00:00
overlookmotel
de5b0b63a9 fix(transformer/class-properties): make _super function outside class strict mode (#7708)
When create a `_super` function outside class, ensure it's always strict mode. The code it contains was previously inside the class, so was strict mode.
2024-12-08 01:41:34 +00:00
overlookmotel
5fd136139f test(transformer/class-properties): override fixtures (#7689)
Override some transform conformance test fixtures for class properties transform, where:

* Our output differs from Babel in cosmetic manner only.
* Our transform intentionally works differently from Babel.
* Babel's fixtures enable arrow functions transform, which malfunctions in our implementation. But we're not trying to test arrow functions transform here, so disable it.
2024-12-08 01:41:33 +00:00