Commit Graph

26 Commits

Author SHA1 Message Date
Dunqing e6090e7ccc fix(transformer): keep enum IIFE when a non-inlinable value reference remains (#22501)
Refs vitejs/vite#22452 (comment).

The optimize pass dropped the enum declaration whenever the members were all evaluable — regardless of whether some non-inlinable value reference still named the enum at runtime. The result referenced a binding that no longer existed:

```ts
const enum Phase { one = 'one' }
export default Phase;
// -> export default Phase;  // ReferenceError at runtime

enum Direction { Up }
Direction.Up.toString();
// -> Direction.Up.toString();  // ReferenceError at runtime
```

## Fix

Decide based on the remaining resolved references: drop only when none of them is a value reference (`Read`/`Write`). Type references (`as E`, `: E`) are kept here and stripped later by `annotations.rs`, so they don't block removal. `typeof E` in JS expression position is `Read` and correctly keeps the IIFE; `typeof E` in TS type position is `ValueAsType` (not in `Value`) and doesn't.

Unifies the rule for regular and const enums — the previous asymmetry (const always dropped, regular dropped only when no refs at all) had no principled basis.

## Compatibility

Diverges from Babel on two `optimize-const-enums/*` fixtures where the input has a bare value reference to the enum that we can't inline. Three engines disagree on what to do:

| Engine | Inline `E.X` member accesses | Preserve `E` binding (IIFE) | Result for `E.unknown` / bare `E` |
|---|---|---|---|
| Babel `transform-typescript` (optimize-const-enums) | yes | **no** | runtime ReferenceError / TypeError |
| tsc `--isolatedModules` | no | yes | `undefined` / resolves |
| oxc after this PR | yes | yes | `undefined` / resolves |

We now hybridize: inline what's inlinable (Babel) **and** keep the binding (tsc). Local overrides under `tasks/transform_conformance/overrides/` record the new expected output for the two affected Babel fixtures.

### `optimize-const-enums/local`

Input:

```ts
const enum A {
  x, y
}

A.x;
A["y"];
A.z;
A;
```

Babel (and oxc before this PR):

```js
0;
1;
A.z;
A;
```

`A.z` is `TypeError: cannot read properties of undefined`; `A;` is `ReferenceError`.

tsc (`--isolatedModules`):

```js
var A;
(function (A) {
    A[A["x"] = 0] = "x";
    A[A["y"] = 1] = "y";
})(A || (A = {}));
A.x;
A["y"];
A.z;
A;
```

Keeps the IIFE binding, no member-access inlining. `A.z` evaluates to `undefined`; `A;` is a no-op.

oxc after this PR (`overrides/.../optimize-const-enums/local/output.mjs`):

```js
var A = /* @__PURE__ */ function(A) {
  A[A["x"] = 0] = "x";
  A[A["y"] = 1] = "y";
  return A;
}(A || {});
0;
1;
A.z;
A;
```

Hybrid: inlines `A.x` / `A["y"]` like Babel, **and** keeps the IIFE binding like tsc — so `A.z` evaluates to `undefined` (not crash) and `A;` resolves.

### `optimize-const-enums/merged`

Input:

```ts
const enum A {
  x, y
}

const enum A {
  z
}

A.x;
A["y"];
A.z;
A.w;
A;
```

Babel (and oxc before this PR):

```js
0;
1;
0;
A.w;
A;
```

`A.w` is `TypeError: cannot read properties of undefined`; `A;` is `ReferenceError`.

tsc (`--isolatedModules`):

```js
var A;
(function (A) {
    A[A["x"] = 0] = "x";
    A[A["y"] = 1] = "y";
})(A || (A = {}));
(function (A) {
    A[A["z"] = 0] = "z";
})(A || (A = {}));
A.x;
A["y"];
A.z;
A.w;
A;
```

Both IIFEs emitted, no inlining. `A.w` is `undefined`; `A;` resolves.

oxc after this PR (`overrides/.../optimize-const-enums/merged/output.mjs`):

```js
var A = /* @__PURE__ */ function(A) {
  A[A["x"] = 0] = "x";
  A[A["y"] = 1] = "y";
  return A;
}(A || {});
A = /* @__PURE__ */ function(A) {
  A[A["z"] = 0] = "z";
  return A;
}(A || {});
0;
1;
0;
A.w;
A;
```

Hybrid: both enum bodies lower (the second reuses the first's binding via `A = (function(A) { … })(A || {})` — assignment, not `var`) **and** members are inlined like Babel. `A.w` evaluates to `undefined`; `A;` resolves.

## Verification

New fixtures cover the bug shapes:
- `babel-plugin-transform-typescript/const-enum-value-ref-kept/` — `export default Phase`
- `babel-plugin-transform-typescript/const-enum-mixed-refs/` — member access + bare ref combined

Existing `optimize-enums/type-cast` updated to drop the IIFE for the all-type-refs case (the regular-enum side of the unified rule).
2026-05-18 02:19:11 +00:00
camc314 4e880de872 fix(transformer/object-rest-spread): declare temp vars for computed keys (#22284)
Given some code like
```js
const {
  [({ ...rest }) => {
    let { ...b } = {};
  }]: a,
  [({ ...d } = {})]: c,
} = {};

export {}; // necessary so we are in strict mode
```
It would previously be transformed to:
```js
const { [(_ref) => {
	let rest = _extends({}, (_objectDestructuringEmpty(_ref), _ref));
	let _ref2 = {}, b = _extends({}, (_objectDestructuringEmpty(_ref2), _ref2));
}]: a, [(_ref3 = {}, {} = _ref3, d = _extends({}, (_objectDestructuringEmpty(_ref3), _ref3)), _ref3)]: c } = {};
export {};
```

This is a problem because there was no declaration to `_ref3`

This causes runtime errors.

After this PR, we now emit:

This new code includes `var _ref3`, fixing the unresolved reference issue.

```js
var _ref3;
const {
  [_ref => {
    let rest = babelHelpers.extends({}, (babelHelpers.objectDestructuringEmpty(_ref), _ref));
    let _ref2 = {},
      b = babelHelpers.extends({}, (babelHelpers.objectDestructuringEmpty(_ref2), _ref2));
  }]: a,
  [(_ref3 = {}, {} = _ref3, d = babelHelpers.extends({}, (babelHelpers.objectDestructuringEmpty(_ref3), _ref3)), _ref3)]: c
} = {};

```

This aligns with Babel.

----

This has been fixed by walking up to find the containing statement, and inserting the var declaration before it.

Previously, the `var` declaration would only be inserted if we were inside `ExpressionStatementExpression` which was not guaranteed.
2026-05-11 09:14:25 +00:00
Dunqing c59c1990bc fix(transformer/typescript): emit class fields for parameter properties (#21831)
## Summary

Fixes a long-standing inconsistency in the TypeScript transformer's handling of constructor parameter properties under the documented default (`useDefineForClassFields: true` per [`compiler_assumptions.rs:137-139`](https://github.com/oxc-project/oxc/blob/main/crates/oxc_transformer/src/compiler_assumptions.rs#L137-L139)).

The transformer already emitted TS-true-aligned output for **declared** fields (kept `boom: number;` as `boom;`) but silently dropped the field declaration for **parameter properties**, so downstream tools that re-analyze the transformed AST saw the property only as a `this.*` write, not as a declared class field.

```ts
// input
class Foo {
  boom: number;                  // declared field
  constructor(public foo) {}     // parameter property
}
```

```js
// before — inconsistent
class Foo {
  boom;                          // ✅ kept (TS-true)
  constructor(foo) {             // ❌ missing `foo;` (TS-false-style for params only)
    this.foo = foo;
  }
}

// after — consistent
class Foo {
  foo;                           // ✅ now matches `boom;`
  boom;
  constructor(foo) {
    this.foo = foo;
  }
}
```

This is **not a policy change** — the documented default has always been `useDefineForClassFields: true` (set both `set_public_class_fields` and `remove_class_fields_without_initializer` to `true` to opt into `false` semantics). The fix just closes the missing case for parameter properties.

## Implementation

- Add `add_parameter_property_fields` to the `enter_class` path that runs when `set_public_class_fields` is `false`, mirroring the existing branch that calls `transform_class_fields` when it is `true`.
- Skip parameter properties whose name matches an existing instance field on the same class (matches tsc's dedup). Static, private, and `declare`-only fields are different bindings, so they don't suppress the new field.
- Early-bail before allocating the dedup set when the class has no parameter properties — keeps the transformer-allocations snapshot at baseline.

No new option is added; the existing `set_public_class_fields` assumption already maps cleanly to `useDefineForClassFields` (the playground's `useDefineForClassFields: true` already toggles `set_public_class_fields = false`).

Closes #21600
Closes #21831
2026-04-30 00:39:25 +00:00
Boshen deed3d851b fix(transformer): remove unnecessary trailing expression in object rest spread assignment (#19259)
## Summary

- Skip the trailing reference (e.g. `_c`) in the generated sequence expression when the destructuring assignment is directly inside an `ExpressionStatement`, since the expression result is not consumed
- Before: `_c = c2, {a2} = _c, b2 = objectWithoutProperties(_c, ["a2"]), _c;`
- After: `_c = c2, {a2} = _c, b2 = objectWithoutProperties(_c, ["a2"]);`
- The trailing reference is still kept when the result is consumed, e.g. `console.log((..., _c))`

Closes #7389 (issue 1)

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-02-11 11:43:24 +00:00
Dunqing 7c2d2c664e fix(transformer/top-level-statements): should not inject statements after non-import statement (#12463)
* close https://github.com/oxc-project/oxc/issues/12460

Injecting top-level statements after the last import statement is unsound because once there is an import statement in the last line, it would be broken if other code relies on the injected statements. Learn more to see the following example.

I suppose the reason we did this is that we had a test case that misled us. I overrode that test with the expected output.

For example:

Input:

```js
import { observer } from 'mobx-react-lite'
import { useFoo } from './useFoo'

export const BazComponent = observer(function BazComponent_() {
  const foo = useFoo()
  return (
    <>
      {foo}
      {bar}
    </>
  )
})

import { bar } from './bar'
```

Before output:
```js
import { observer } from "mobx-react-lite";
import { useFoo } from "./useFoo";
export const BazComponent = _s(observer(_c = _s(function BazComponent_() {
        _s();
        const foo = useFoo();
        return /* @__PURE__ */ _jsxs(_Fragment, { children: [foo, bar] });
}, "useFoo{foo}", false, function() {
        return [useFoo];
})), "useFoo{foo}", false, function() {
        return [useFoo];
});
_c2 = BazComponent;
import { bar } from "./bar";
import { Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
var _s = $RefreshSig$();
var _c, _c2;
$RefreshReg$(_c, "BazComponent$observer");
$RefreshReg$(_c2, "BazComponent");

```

After output:

```js
import { observer } from "mobx-react-lite";
import { useFoo } from "./useFoo";
import { Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
var _s = $RefreshSig$();
export const BazComponent = _s(observer(_c = _s(function BazComponent_() {
        _s();
        const foo = useFoo();
        return /* @__PURE__ */ _jsxs(_Fragment, { children: [foo, bar] });
}, "useFoo{foo}", false, function() {
        return [useFoo];
})), "useFoo{foo}", false, function() {
        return [useFoo];
});
_c2 = BazComponent;
import { bar } from "./bar";
var _c, _c2;
$RefreshReg$(_c, "BazComponent$observer");
$RefreshReg$(_c2, "BazComponent");
```

The difference is that `import { Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime"; var _s = $RefreshSig$();` has injected after `import { useFoo } from "./useFoo";`
2025-07-24 00:58:59 +00:00
overlookmotel 79e462dac1 perf(transformer): faster UID generation (#10759)
Alter the algorithm for generating UIDs, to improve its performance.

Previously we stored all existing symbol names which start with `_` in an `FxHashSet`. When creating a UID based on `foo`, it would first see if `_foo` is available, then try `_foo2`, then `_foo3`, then `_foo4` etc.

When creating a lot of UIDs from the same base name (`foo` in example above), this has poor performance as each attempt requires a separate hashset lookup.

Instead, use an `FxHashMap` mapping base name to:

1. Largest number of underscores at start.
2. Largest numeric prefix on end.

i.e. if there are existing symbols `_foo`, `_bar3`, `_bar8`, `_qux`, `___qux2`, this produces a map:

```
{
    "foo": { postfix: 1, underscore_count: 1 },
    "bar": { postfix: 8, underscore_count: 1 },
    "qux": { postfix: 2, underscore_count: 3 },
}
```

When generating a UID, `postfix` is incremented and UID is constructed as `<underscores><base><postfix>`.

This requires a maximum of 1 x hashmap lookup and 1 x hashmap insert for each UID. It also reduces the size of the hashmap where many UIDs are created for same base name.

This new algorithm produces almost same UIDs as Babel, but not quite. 3 tests require their outputs to be changed due to UIDs being different.
2025-05-02 01:15:47 +00:00
Dunqing 032377d75c refactor(transformer/typescript): do not need to go through TSModuleDeclaration if is a NamespaceModule (#10366)
Benefits from https://github.com/oxc-project/oxc/pull/10350. `NamespaceModule` means this `TSModuleDeclaration` is a type-only declaration, so that we can get rid of it early without going through its block.
2025-04-14 02:49:00 +00:00
Dunqing c25eab0036 test(transformer/typescript): override namespace/empty-removed test (#10365)
Just override the test without any changes to prepare for #10366.
2025-04-12 13:39:48 +00:00
hi-ogawa cead38d647 fix(transformer/optional-chaining): fix context of optional chain call (#9526)
- closes https://github.com/oxc-project/oxc/issues/9498

`this.f?.()` is handled by https://github.com/oxc-project/oxc/pull/9505, but it looks like the same needs to be applied for member expressions in general, such as `repro.x.f?.()`.

Here is an output of esbuild
https://esbuild.github.io/try/#dAAwLjI1LjAALS10YXJnZXQ9ZXMyMDE1AGNvbnN0IHJlcHJvID0ge30KcmVwcm8uZj8uKCk7CnJlcHJvLnguZj8uKCk7CnJlcHJvLnhbImYiXT8uKCk7

---

This PR fixes following case:

- Not only member expressions but also arbitrary expressions can be a call context, such as:

```js
(0, repro).f?.();
```

- same logic is required for `transform_and_join_expression`, which is used in cases, such as

```js
repro.x?.y.f?.()
```
2025-03-04 12:15:47 +00:00
Dunqing 45ace4419b feat(transformer): add /* @_PURE__ */ annotation for pure calls (#9424)
close: #6072

Many tests outputs are updated because we need to print `/* @_PURE__ */` for the pure calls.
2025-03-04 06:13:21 +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
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