Commit graph

92 commits

Author SHA1 Message Date
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
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
Dunqing
3ea4109d14 feat(transformer/class-properties): transform super update expressions within static prop initializer (#7997) 2024-12-18 18:29:05 +00:00
overlookmotel
5cf253c216 test(transformer/class-properties): more testing for assignment to super[prop] (#7992)
Amend test added in #7991 to test transform of `super[prop] = value` where `prop` is not bound.

We should ideally have the `_unbound` temp vars *inside* the arrow function rather than outside, as Babel does, but that's not possible with our double-visitor scheme at present, and I think current output will operate correctly anyway.

Probably these temp vars could be hoisted even higher up - to very top level of the file, even if the class and `super[prop]` were deeply nested in many functions - and it'd still be correct. That'd be good for transformer performance as less `var` statements to insert, and also slightly smaller output size - less `var`s in code. But I don't know if that would be worse for runtime performance, as it makes the arrow function more impure. 🤔
2024-12-18 12:49:42 +00:00
Dunqing
cc57db38e1 feat(transformer/class-properties): transform super assignment expressions within static prop initializer (#7991)
Alternative of #7956 and #7959. Unlike the previous method, adapting duplicating the same logic rather than making the same logic transform function to be generic
2024-12-18 11:28:39 +00:00
Dunqing
e3d0889009 test(transformer/class-properties): add static super tagged template test (#7964)
I just found that we don't need to transform `TaggedTemplateExpression` because its `tag` can be transformed by `transform_static_member_expression` and `transform_computed_member_expression`
2024-12-18 10:25:21 +00:00
overlookmotel
bb3806554f fix(transformer/class-properties): do not transform super.prop in nested method within static prop initializer (#7978)
Don't transform `super` in static property initializers if it's nested in another method, so is a *different* `super`.

```js
class C {
  static prop = () => {
    const object = {
      method() {
        // `super` here refers to prototype of `object`, not class `C`
        return super.foo;
      }
    };
  };
}
```
2024-12-18 03:00:04 +00:00
overlookmotel
80d0b3e10f perf(transformer/class-properties): fast path for instance prop initializer scope re-parenting (#7901)
Add a fast path for inserting instance property initializers into constructor, when no existing constructor or constructor has no bindings. This should be reasonably common.

The `Scope flags mismatch` errors are due to #7900.
2024-12-15 01:53:13 +00:00
overlookmotel
feac02e65b feat(transformer/class-properties): only rename symbols if necessary (#7896)
#7872 implements renaming symbols in constructor which shadow references in instance property initializers. But we don't need to rename where the reference in initializer references a symbol which is bound within the initializer itself.

Input:

```js
class C {
  double = n => n * 2;
  constructor(n) {
    console.log(n);
  }
}
```

Output:

```js
class C {
  constructor(n) { // <-- not renamed
    this.double = n => n * 2; // <-- moved into constructor
    console.log(n); // <-- not renamed
  }
}
```

This produces better output, and avoids a traversal of constructor's AST renaming symbols.
2024-12-15 01:53:13 +00:00
Dunqing
6bc530d2e2 feat(transformer/class-properties): transform super call expression that is inside static prop initializer (#7831) 2024-12-13 13:47:38 +00:00
Yunfei He
9479e2b0a2
fix(semantic): missing references when export {} references a type-only binding and a normal (#7812)
https://playground.oxc.rs/#eNpdTzEOgzAM/AryzFAqdUHq2rlD1YklUIMihTiyTQGh/L0BBEMn31l35/MCDZTQkBfNXmRE3xbHQKzZPSsqX3mcNrZkOgfcJU+mIPmfPEIOBOUCPPh1yOzVTFAqD5iDs14PLA0FPMnc1+QOpmy8tMT9vog5BMOCnAITXkMOfCq3BajhDtMFQLleihskRUMf7HDtkkhvvW3tYU7vKpN7OBpX8xe5JkmVWuMEY4w/P71iMw==

Current:

<img width="876" alt="image"
src="https://github.com/user-attachments/assets/58327920-44ef-469d-8c7c-a2d7b17da717"
/>


Expected:


https://babeljs.io/repl#?browsers=&build=&builtIns=false&corejs=false&spec=false&loose=false&code_lz=MYewdgzgLgBAKiAhtAagSwKYHcAOIBOsAvDAIwBQ5UAnjhvEtAAr4g4QwkXkYAeehGAG8YNOg2RQWbCABoJqTLgKwAvkA&debug=false&forceAllTransforms=false&modules=false&shippedProposals=false&evaluate=false&fileSize=false&timeTravel=false&sourceType=module&lineWrap=true&presets=env%2Ctypescript&prettier=false&targets=&version=7.26.4&externalPlugins=&assumptions=%7B%7D

<img width="877" alt="image"
src="https://github.com/user-attachments/assets/9b847baa-5b5a-43be-b77d-d529fb3f8026"
/>

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Dunqing <dengqing0821@gmail.com>
2024-12-13 12:00:58 +08:00
Dunqing
2964a61546 fix(transformer/class-properties): unwrap failed when private field expression doesn't contain optional expression in ChainExpression (#7798)
The root cause is due to transform wrongly a PrivateFieldExpression that doesn't contain any optional expression, so call `to_member_expression_mut` causes unwrap to fail.  I have fixed the incorrect transform and changed `to_member_expression_mut` to `as_member_expression_mut`.
2024-12-11 11:32:21 +00:00
Dunqing
6fa6785d0d fix(transformer/class-properties): panic when the callee or member is ParenthesisExpression or TS-syntax expressions. (#7795)
We need to call `get_inner_expression_mut` to get actual expressions that we need to deal with
2024-12-11 11:15:20 +00:00
overlookmotel
caa57f1649 fix(transformer/class-properties): fix scope flags in static prop initializers (#7786)
Code in static property initializers moves from inside the class to outside. If environment outside the class is not strict mode, then scopes within the initializer become sloppy mode. Update `ScopeFlags` for scopes in static prop initializers accordingly.

We're following Babel for now, but this isn't actually correct. The initializers should be wrapped in a strict mode IIFE to maintain their strict mode behavior. But at least semantic data is now correct for the output.
2024-12-10 23:57:43 +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
e48769a45d fix(transformer/logic-assignment-operator): always create IdentifierReferences with ReferenceId (#7745)
Use `TransformCtx::duplicate_expression` (introduced in #7754) to decide when to create temp vars for member expression object and computed property.

This fixes a bug where `IdentifierReference`s created when transforming `key` in `object[key] &&= value` were created without a `ReferenceId` (due to `clone_in`).

We didn't catch this before because Babel's test fixtures only cover `object[key++] &&= value` not the simpler `object[key] &&= value`. Add tests for this.
2024-12-10 02:28:26 +00:00
overlookmotel
97acd88793 test(transformer/class-properties): add more tests (#7743)
Babel's tests only cover transforming `this.#prop &&= value` with logical assignment operators transform also enabled. Add tests for just class properties transform alone.
2024-12-09 14:17:12 +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
da63e873d9 test(transformer/class-properties): exec test for this in computed key (#7687)
Add an exec test for #7686.
2024-12-08 01:41:31 +00:00
overlookmotel
72b5d58560 fix(transformer/class-properties): create temp var for this in computed key (#7686)
`this` in computed key needs a temp var, otherwise once moved into constructor it refers to the wrong `this`.
2024-12-06 02:20:57 +00:00
IWANABETHATGUY
6af8659624 fix(oxc_transformer): correct generate ThisExpr and import.meta in jsx pragma (#7553) 2024-12-03 13:54:15 +00:00
IWANABETHATGUY
a784a82f4f feat(oxc_transformer): support jsx pragma that are long member expressions (#7538)
related tests:

d34e79e2a9/internal/bundler_tests/bundler_default_test.go (L6188-L6236)
2024-12-02 14:02:38 +00:00
overlookmotel
488029ea24 test(transformer/async-to-generator): failing test for nested supers (#7314)
Failing test for async-to-generator transform.

When exiting a function which has `super` bindings, need to restore previous state of `super_methods`. It probably needs to be a stack. But not sure if `renamed_arguments_symbol_ids` needs to be a stack too? I don't really understand this transform, so am not attempting to fix myself.

[Babel REPL](https://babeljs.io/repl#?browsers=ie%2011&build=&builtIns=false&corejs=3.21&spec=false&loose=false&code_lz=MYewdgzgLgBCCuUCmAnGBeGBvAUDGAbgIYA28SAXDAAwA0eMREAnmMDALZJQAWIAJgAoAlNgb4RGAHwwI8AA6oAdMTJIA3DnExQkWAEswYVBjH5zhUuSp1t-Jq3ZdeAybgsXJ6GXMUoVVhp2MAC-2iGa2l4-Csqq5Jr4YRE4QA&debug=false&forceAllTransforms=false&modules=commonjs&shippedProposals=false&evaluate=false&fileSize=false&timeTravel=false&sourceType=module&lineWrap=true&presets=&prettier=true&targets=&version=7.26.2&externalPlugins=%40babel%2Fplugin-external-helpers%407.25.9%2C%40babel%2Fplugin-transform-async-to-generator%407.25.9&assumptions=%7B%7D)
2024-11-26 15:54:07 +00:00
Boshen
224775c056 feat(transformer): transform object rest spread (#7003)
https://babel.dev/docs/babel-plugin-transform-object-rest-spread
2024-11-21 11:33:26 +00:00
overlookmotel
5d853869eb refactor(transformer/arrow-functions): use IndexMap for super getter/setters (#7317)
Generate getter/setter declarations in same order as Babel by using `IndexMap` instead of `HashMap` to store `super` getter/setter method details.
2024-11-17 10:07:34 +00:00
Dunqing
7d75130865 fix(transformer/async-to-generator): arguments isn't correct after transformation (#7234)
Fix due to this plugin transforming the async method and async arrow function, it caused arguments no longer point the original function.

For example:

Before

```js
class Cls {
  async method() {
    () => {
    	console.log(arguments)
    }
  }
}
```

After:

```js
class Cls {
  method() {
    var _arguments = arguments;
    return babelHelpers.asyncToGenerator(function* () {
      () => {
        console.log(_arguments);
      };
    })();
  }
}
```

In this way, the `_arguments` is its original function's arguments

### For performance regression

It seems we need to check the IdentifierReference and BindingIdentifier if it's an `arguments`, that causes a significant regression, we may need a cheap way to do checking
2024-11-17 05:01:44 +00:00
Song Gao
cf3415b0e4
chore(doc): replace main/master to tag/commit to make the url always accessible (#7298) 2024-11-16 21:00:30 +08:00
Dunqing
ede10dc030 fix(transformer/async-to-generator): incorrect transform when super expression is inside async method (#7171)
After transformation, super expressions have moved to unexpected places. This PR replaces super expression to call expression, and then inserts the super methods to the top of the method body.

For example:

Before:
```js
class G {
  async method() {
    super.foo()
  }
}
```

After:
```js
class G {
  method() {
    var _superprop_getFoo = () => super.foo,
      _this = this;
    return _asyncToGenerator(function* () {
      _superprop_getFoo().call(_this);
    })();
  }
}```
2024-11-08 08:18:45 +00:00
Dunqing
1910227590 feat(transformer/async-to-generator): support inferring the function name from the ObjectPropertyValue's key (#7201)
Support for inferring function name from ObjectPropertyValue's key

For example:
```js
({ foo: async function() {} })
```

After this, we will able to infer `foo` for the object method
2024-11-08 08:18:44 +00:00
Dunqing
293d072e77 fix(transformer/async-to-generator): only transform object method in exit_function (#7199)
part of #7175
2024-11-08 03:03:27 +00:00
Dunqing
b2a888df0d fix(transformer/async-generator-functions): incorrect transformation for for await if it's not placed in a block (#7148)
Found in https://github.com/oxc-project/monitor-oxc/actions/runs/11681867380/job/32527898715
2024-11-06 05:51:01 +00:00
Dunqing
19892ede40 fix(transformer/async-generator-functions): transform incorrectly for for await if it's in LabeledStatement (#7147)
Found in https://github.com/oxc-project/monitor-oxc/actions/runs/11681867380/job/32527898715
2024-11-06 03:27:14 +00:00
Dunqing
cd1006fec1 refactor(transformer/async-generator-functions): do not transform yield expression where inside generator function (#7134) 2024-11-06 03:27:13 +00:00
Dunqing
a2244ff089 fix(transformer/async-to-generator): output is incorrect when arrow function without params (#7052) 2024-11-01 15:35:57 +00:00
Dunqing
1ca8cd2fd9 refactor(transformer/react-refresh): avoid panic for init of VariableDeclarator isn't a BindingIdentifier (#6937)
related: https://github.com/oxc-project/oxc/pull/6881#discussion_r1816597462
2024-10-28 01:19:53 +00:00
Dunqing
5f153aca0c refactor(transformer/react-refresh): use VarDeclarations to insert declarators (#6884) 2024-10-27 07:05:24 +00:00
Dunqing
142da1d2ff chore(transform_conformance): reorganize react-refresh related tests (#6918)
Move all tests that are copied from [react-refresh](https://github.com/facebook/react/blob/main/packages/react-refresh/src/__tests__/ReactFreshBabelPlugin-test.js) to the `react-refresh` directory, and add a README to describe the source of these tests. This way we can better stay in sync with upstream.

related: https://github.com/oxc-project/oxc/pull/6884#discussion_r1816888813
2024-10-26 13:07:10 +00:00
Dunqing
0d0bb17ad9 feat(transformer): complete the async-to-generator plugin (#6658)
In this PR, most of the async functions have transformed correctly. But the async arrow functions don't fully transform correctly yet, it is related to we need to transform the arrow function to the generator function. For example:

Input:
```js
function declaration() {
  const asy = async () => {
  console.log(this.name)
 }
}
```

Output:
```js
function declaration() {
  const asy = babelHelpers.asyncToGenerator(function* () {
     console.log(this.name);
  });
}
```

Expected Output:

```js
function declaration() {
  var _this = this;
  const asy = /*#__PURE__*/function () {
    var _ref = babelHelpers.asyncToGenerator(function* () {
      console.log(_this.name);
    });
    return function asy() {
      return _ref.apply(this, arguments);
    };
  }();
}
```

From the expected output, we haven't handled `this` correctly, which means even if the `arrow-function` plugin doesn't enable, we still need to handle this correctly as the `arrow-function` plugin does, and further question if `arrow-function` plugin is enabled, how to avoid these making conflict?

I thought we may move out the implementation of `arrow-function` and as a common helper, this way every plugin can handle this well
2024-10-25 03:23:31 +00:00
Dunqing
076f5c39f4 fix(transformer/typescript): retain ExportNamedDeclaration without specifiers and declaration (#6848)
close: #6825
2024-10-24 07:59:07 +00:00
overlookmotel
10484cdeeb feat(transformer): class static block transform (#6733)
Add ES2022 class static block transform.
2024-10-22 03:40:02 +00:00
magic-akari
1d3d256db3 fix(transformer): Correctly trim JSX (#6639)
- Closes: #6638
2024-10-17 14:41:02 +00:00
overlookmotel
4fd89e8eed test(transformer): fix indentation in transformer test fixtures (#6346)
Unimportant nit. Fix whitespace in the transformer test fixtures.
2024-10-08 01:32:07 +00:00
overlookmotel
cf20f3a89d feat(transformer): exponentiation transform: support private fields (#6345)
Babel doesn't support private fields in this transform, but there's no reason not to. So we can.
2024-10-08 01:32:06 +00:00
overlookmotel
4aa4e6bec0 refactor(transformer): exponentiation transform: do not wrap in SequenceExpression if not needed (#6343)
`left **= right` is transformed to `left = Math.pow(left, right)`. There is no need to wrap it in a `SequenceExpression`.
2024-10-08 01:32:05 +00:00