Skip to content

Commit

Permalink
fix(transformer/class-properties): make _super function outside cla…
Browse files Browse the repository at this point in the history
…ss 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.
  • Loading branch information
overlookmotel committed Dec 8, 2024
1 parent 5fd1361 commit de5b0b6
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 14 deletions.
19 changes: 16 additions & 3 deletions crates/oxc_transformer/src/es2022/class_properties/constructor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
//! Oxc output:
//! ```js
//! let _super = function() {
//! "use strict";
//! this.prop = foo();
//! return this;
//! };
Expand All @@ -95,7 +96,7 @@
//! }
//! ```
//!
//! ESBuild does not `super()` in constructor params correctly:
//! ESBuild does not handle `super()` in constructor params correctly:
//! [ESBuild REPL](https://esbuild.github.io/try/#dAAwLjI0LjAALS10YXJnZXQ9ZXMyMDIwAGNsYXNzIEMgZXh0ZW5kcyBTIHsKICBwcm9wID0gZm9vKCk7CiAgY29uc3RydWN0b3IoeCA9IHN1cGVyKCksIHkgPSBzdXBlcigpKSB7fQp9Cg)
use oxc_allocator::Vec as ArenaVec;
Expand Down Expand Up @@ -407,8 +408,20 @@ impl<'a, 'c> ConstructorParamsSuperReplacer<'a, 'c> {
let super_func_scope_id = ctx.scopes_mut().add_scope(
Some(outer_scope_id),
NodeId::DUMMY,
ScopeFlags::Function | ScopeFlags::Arrow | ScopeFlags::StrictMode,
ScopeFlags::Function | ScopeFlags::StrictMode,
);

// Add `"use strict"` directive if outer scope is not strict mode
let directives = if ctx.scopes().get_flags(outer_scope_id).is_strict_mode() {
ctx.ast.vec()
} else {
ctx.ast.vec1(ctx.ast.directive(
SPAN,
ctx.ast.string_literal(SPAN, Atom::from("use strict"), None),
Atom::from("use strict"),
))
};

// `return this;`
let return_stmt = ctx.ast.statement_return(SPAN, Some(ctx.ast.expression_this(SPAN)));
// `<inits>; return this;`
Expand All @@ -430,7 +443,7 @@ impl<'a, 'c> ConstructorParamsSuperReplacer<'a, 'c> {
NONE,
),
NONE,
Some(ctx.ast.alloc_function_body(SPAN, ctx.ast.vec(), body_stmts)),
Some(ctx.ast.alloc_function_body(SPAN, directives, body_stmts)),
super_func_scope_id,
))
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
let _super = function() {
"use strict";
babelHelpers.defineProperty(this, "bar", "foo");
return this;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
let _super = function() {
"use strict";
babelHelpers.defineProperty(this, "bar", "foo");
return this;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
let _super = function() {
"use strict";
babelHelpers.defineProperty(this, "bar", "foo");
return this;
};
Expand Down
9 changes: 0 additions & 9 deletions tasks/transform_conformance/snapshots/babel.snap.md
Original file line number Diff line number Diff line change
Expand Up @@ -822,25 +822,16 @@ x Output mismatch
x Output mismatch

* public/derived-super-in-default-params/input.js
Scope flags mismatch:
after transform: ScopeId(3): ScopeFlags(StrictMode | Function | Arrow)
rebuilt : ScopeId(1): ScopeFlags(Function)
Symbol flags mismatch for "_super":
after transform: SymbolId(2): SymbolFlags(FunctionScopedVariable)
rebuilt : SymbolId(0): SymbolFlags(BlockScopedVariable)

* public/derived-super-in-default-params-complex/input.js
Scope flags mismatch:
after transform: ScopeId(3): ScopeFlags(StrictMode | Function | Arrow)
rebuilt : ScopeId(1): ScopeFlags(Function)
Symbol flags mismatch for "_super":
after transform: SymbolId(2): SymbolFlags(FunctionScopedVariable)
rebuilt : SymbolId(0): SymbolFlags(BlockScopedVariable)

* public/derived-super-in-default-params-in-arrow/input.js
Scope flags mismatch:
after transform: ScopeId(4): ScopeFlags(StrictMode | Function | Arrow)
rebuilt : ScopeId(1): ScopeFlags(Function)
Symbol flags mismatch for "_super":
after transform: SymbolId(2): SymbolFlags(FunctionScopedVariable)
rebuilt : SymbolId(0): SymbolFlags(BlockScopedVariable)
Expand Down
13 changes: 11 additions & 2 deletions tasks/transform_conformance/snapshots/oxc.snap.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
commit: 54a8389f

Passed: 94/105
Passed: 94/106

# All Passed:
* babel-plugin-transform-class-properties
* babel-plugin-transform-class-static-block
* babel-plugin-transform-nullish-coalescing-operator
* babel-plugin-transform-optional-catch-binding
Expand All @@ -16,6 +15,16 @@ Passed: 94/105
* regexp


# babel-plugin-transform-class-properties (1/2)
* super-in-constructor-strict/input.js
Symbol flags mismatch for "_super":
after transform: SymbolId(6): SymbolFlags(FunctionScopedVariable)
rebuilt : SymbolId(1): SymbolFlags(BlockScopedVariable)
Symbol flags mismatch for "_super2":
after transform: SymbolId(7): SymbolFlags(FunctionScopedVariable)
rebuilt : SymbolId(5): SymbolFlags(BlockScopedVariable)


# babel-plugin-transform-async-to-generator (14/15)
* super/nested/input.js
x Output mismatch
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
function sloppy() {
class C extends S {
prop = 1;
constructor(x = super()) {}
}
}

function strict() {
"use strict";
class C extends S {
prop = 1;
constructor(x = super()) {}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
function sloppy() {
let _super = function() {
"use strict";
babelHelpers.defineProperty(this, "prop", 1);
return this;
};
class C extends S {
constructor(x = _super.call(super())) {}
}
}

function strict() {
"use strict";
let _super2 = function() {
babelHelpers.defineProperty(this, "prop", 1);
return this;
};
class C extends S {
constructor(x = _super2.call(super())) {}
}
}

0 comments on commit de5b0b6

Please sign in to comment.