Skip to content

Commit

Permalink
Super property eval order (#11480)
Browse files Browse the repository at this point in the history
  • Loading branch information
jridgewell committed Apr 25, 2020
1 parent 2e4f18a commit 0bbf2da
Show file tree
Hide file tree
Showing 19 changed files with 93 additions and 63 deletions.
62 changes: 47 additions & 15 deletions packages/babel-helper-replace-supers/src/index.js
Expand Up @@ -101,29 +101,47 @@ const specHandlers = {
},

get(superMember) {
return this._get(superMember, this._getThisRefs());
},

_get(superMember, thisRefs) {
const proto = getPrototypeOfExpression(
this.getObjectRef(),
this.isStatic,
this.file,
this.isPrivateMethod,
);
return t.callExpression(this.file.addHelper("get"), [
getPrototypeOfExpression(
this.getObjectRef(),
this.isStatic,
this.file,
this.isPrivateMethod,
),
thisRefs.memo ? t.sequenceExpression([thisRefs.memo, proto]) : proto,
this.prop(superMember),
t.thisExpression(),
thisRefs.this,
]);
},

_getThisRefs() {
if (!this.isDerivedConstructor) {
return { this: t.thisExpression() };
}
const thisRef = this.scope.generateDeclaredUidIdentifier("thisSuper");
return {
memo: t.assignmentExpression("=", thisRef, t.thisExpression()),
this: t.cloneNode(thisRef),
};
},

set(superMember, value) {
const thisRefs = this._getThisRefs();
const proto = getPrototypeOfExpression(
this.getObjectRef(),
this.isStatic,
this.file,
this.isPrivateMethod,
);
return t.callExpression(this.file.addHelper("set"), [
getPrototypeOfExpression(
this.getObjectRef(),
this.isStatic,
this.file,
this.isPrivateMethod,
),
thisRefs.memo ? t.sequenceExpression([thisRefs.memo, proto]) : proto,
this.prop(superMember),
value,
t.thisExpression(),
thisRefs.this,
t.booleanLiteral(superMember.isInStrictMode()),
]);
},
Expand All @@ -135,7 +153,12 @@ const specHandlers = {
},

call(superMember, args) {
return optimiseCall(this.get(superMember), t.thisExpression(), args);
const thisRefs = this._getThisRefs();
return optimiseCall(
this._get(superMember, thisRefs),
t.cloneNode(thisRefs.this),
args,
);
},
};

Expand Down Expand Up @@ -190,6 +213,10 @@ const looseHandlers = {

return t.memberExpression(t.thisExpression(), prop, computed);
},

call(superMember, args) {
return optimiseCall(this.get(superMember), t.thisExpression(), args);
},
};

type ReplaceSupersOptionsBase = {|
Expand All @@ -214,6 +241,8 @@ export default class ReplaceSupers {
const path = opts.methodPath;

this.methodPath = path;
this.isDerivedConstructor =
path.isClassMethod({ kind: "constructor" }) && !!opts.superRef;
this.isStatic = path.isObjectMethod() || path.node.static;
this.isPrivateMethod = path.isPrivate() && path.isMethod();

Expand All @@ -224,6 +253,7 @@ export default class ReplaceSupers {
}

file: HubInterface;
isDerivedConstructor: boolean;
isLoose: boolean;
isPrivateMethod: boolean;
isStatic: boolean;
Expand All @@ -240,6 +270,8 @@ export default class ReplaceSupers {

memberExpressionToFunctions(this.methodPath, visitor, {
file: this.file,
scope: this.methodPath.scope,
isDerivedConstructor: this.isDerivedConstructor,
isStatic: this.isStatic,
isPrivateMethod: this.isPrivateMethod,
getObjectRef: this.getObjectRef.bind(this),
Expand Down
Expand Up @@ -22,11 +22,11 @@ let Outer = /*#__PURE__*/function (_Hello) {
function Outer() {
let _babelHelpers$get$cal;

var _this;
var _thisSuper, _this;

babelHelpers.classCallCheck(this, Outer);
_this = _super.call(this);
_babelHelpers$get$cal = babelHelpers.get(babelHelpers.getPrototypeOf(Outer.prototype), "toString", babelHelpers.assertThisInitialized(_this)).call(babelHelpers.assertThisInitialized(_this));
_babelHelpers$get$cal = babelHelpers.get((_thisSuper = babelHelpers.assertThisInitialized(_this), babelHelpers.getPrototypeOf(Outer.prototype)), "toString", _thisSuper).call(_thisSuper);

let Inner = function Inner() {
babelHelpers.classCallCheck(this, Inner);
Expand Down
Expand Up @@ -22,14 +22,14 @@ var B = /*#__PURE__*/function (_A) {
var _super = babelHelpers.createSuper(B);

function B(...args) {
var _this;
var _thisSuper, _this;

babelHelpers.classCallCheck(this, B);
_this = _super.call(this, ...args);

_foo.set(babelHelpers.assertThisInitialized(_this), {
writable: true,
value: babelHelpers.get(babelHelpers.getPrototypeOf(B.prototype), "foo", babelHelpers.assertThisInitialized(_this)).call(babelHelpers.assertThisInitialized(_this))
value: babelHelpers.get((_thisSuper = babelHelpers.assertThisInitialized(_this), babelHelpers.getPrototypeOf(B.prototype)), "foo", _thisSuper).call(_thisSuper)
});

return _this;
Expand Down
Expand Up @@ -22,11 +22,11 @@ var B = /*#__PURE__*/function (_A) {
var _super = babelHelpers.createSuper(B);

function B(...args) {
var _this;
var _thisSuper, _this;

babelHelpers.classCallCheck(this, B);
_this = _super.call(this, ...args);
_this.foo = babelHelpers.get(babelHelpers.getPrototypeOf(B.prototype), "foo", babelHelpers.assertThisInitialized(_this)).call(babelHelpers.assertThisInitialized(_this));
_this.foo = babelHelpers.get((_thisSuper = babelHelpers.assertThisInitialized(_this), babelHelpers.getPrototypeOf(B.prototype)), "foo", _thisSuper).call(_thisSuper);
return _this;
}

Expand Down
Expand Up @@ -22,11 +22,11 @@ var B = /*#__PURE__*/function (_A) {
var _super = babelHelpers.createSuper(B);

function B(...args) {
var _this;
var _thisSuper, _this;

babelHelpers.classCallCheck(this, B);
_this = _super.call(this, ...args);
babelHelpers.defineProperty(babelHelpers.assertThisInitialized(_this), "foo", babelHelpers.get(babelHelpers.getPrototypeOf(B.prototype), "foo", babelHelpers.assertThisInitialized(_this)).call(babelHelpers.assertThisInitialized(_this)));
babelHelpers.defineProperty(babelHelpers.assertThisInitialized(_this), "foo", babelHelpers.get((_thisSuper = babelHelpers.assertThisInitialized(_this), babelHelpers.getPrototypeOf(B.prototype)), "foo", _thisSuper).call(_thisSuper));
return _this;
}

Expand Down
Expand Up @@ -33,7 +33,7 @@ var Test = function Test() {
var _super = _createSuper(Other);

function Other() {
var _this;
var _thisSuper, _this;

_classCallCheck(this, Other);

Expand All @@ -44,7 +44,7 @@ var Test = function Test() {
_this = _super.call.apply(_super, [this].concat(args));

_defineProperty(_assertThisInitialized(_this), "a", function () {
return _get(_getPrototypeOf(Other.prototype), "test", _assertThisInitialized(_this));
return _get((_thisSuper = _assertThisInitialized(_this), _getPrototypeOf(Other.prototype)), "test", _thisSuper);
});

return _this;
Expand Down
Expand Up @@ -26,15 +26,15 @@ var ColorPoint = /*#__PURE__*/function (_Point) {
var _super = _createSuper(ColorPoint);

function ColorPoint() {
var _this;
var _thisSuper, _thisSuper2, _this;

babelHelpers.classCallCheck(this, ColorPoint);
_this = _super.call(this);
_this.x = 2;
babelHelpers.set(babelHelpers.getPrototypeOf(ColorPoint.prototype), "x", 3, babelHelpers.assertThisInitialized(_this), true);
babelHelpers.set((_thisSuper = babelHelpers.assertThisInitialized(_this), babelHelpers.getPrototypeOf(ColorPoint.prototype)), "x", 3, _thisSuper, true);
expect(_this.x).toBe(3); // A

expect(babelHelpers.get(babelHelpers.getPrototypeOf(ColorPoint.prototype), "x", babelHelpers.assertThisInitialized(_this))).toBeUndefined(); // B
expect(babelHelpers.get((_thisSuper2 = babelHelpers.assertThisInitialized(_this), babelHelpers.getPrototypeOf(ColorPoint.prototype)), "x", _thisSuper2)).toBeUndefined(); // B

return _this;
}
Expand Down
Expand Up @@ -8,17 +8,17 @@ var Test = /*#__PURE__*/function (_Foo) {
function Test() {
var _babelHelpers$get;

var _this;
var _thisSuper, _thisSuper2, _thisSuper3, _this;

babelHelpers.classCallCheck(this, Test);
woops.super.test();
_this = _super.call(this);
babelHelpers.get(babelHelpers.getPrototypeOf(Test.prototype), "test", babelHelpers.assertThisInitialized(_this)).call(babelHelpers.assertThisInitialized(_this));
babelHelpers.get((_thisSuper = babelHelpers.assertThisInitialized(_this), babelHelpers.getPrototypeOf(Test.prototype)), "test", _thisSuper).call(_thisSuper);
_this = _super.apply(this, arguments);
_this = _super.call.apply(_super, [this, "test"].concat(Array.prototype.slice.call(arguments)));
babelHelpers.get(babelHelpers.getPrototypeOf(Test.prototype), "test", babelHelpers.assertThisInitialized(_this)).apply(babelHelpers.assertThisInitialized(_this), arguments);
babelHelpers.get((_thisSuper2 = babelHelpers.assertThisInitialized(_this), babelHelpers.getPrototypeOf(Test.prototype)), "test", _thisSuper2).apply(_thisSuper2, arguments);

(_babelHelpers$get = babelHelpers.get(babelHelpers.getPrototypeOf(Test.prototype), "test", babelHelpers.assertThisInitialized(_this))).call.apply(_babelHelpers$get, [babelHelpers.assertThisInitialized(_this), "test"].concat(Array.prototype.slice.call(arguments)));
(_babelHelpers$get = babelHelpers.get((_thisSuper3 = babelHelpers.assertThisInitialized(_this), babelHelpers.getPrototypeOf(Test.prototype)), "test", _thisSuper3)).call.apply(_babelHelpers$get, [_thisSuper3, "test"].concat(Array.prototype.slice.call(arguments)));

return _this;
}
Expand Down
Expand Up @@ -6,12 +6,12 @@ var Test = /*#__PURE__*/function (_Foo) {
var _super = babelHelpers.createSuper(Test);

function Test() {
var _this;
var _thisSuper, _thisSuper2, _this;

babelHelpers.classCallCheck(this, Test);
_this = _super.call(this);
babelHelpers.get(babelHelpers.getPrototypeOf(Test.prototype), "test", babelHelpers.assertThisInitialized(_this));
babelHelpers.get(babelHelpers.getPrototypeOf(Test.prototype), "test", babelHelpers.assertThisInitialized(_this)).whatever;
babelHelpers.get((_thisSuper = babelHelpers.assertThisInitialized(_this), babelHelpers.getPrototypeOf(Test.prototype)), "test", _thisSuper);
babelHelpers.get((_thisSuper2 = babelHelpers.assertThisInitialized(_this), babelHelpers.getPrototypeOf(Test.prototype)), "test", _thisSuper2).whatever;
return _this;
}

Expand Down
Expand Up @@ -6,12 +6,12 @@ var Test = /*#__PURE__*/function (_Foo) {
var _super = babelHelpers.createSuper(Test);

function Test() {
var _this;
var _thisSuper, _thisSuper2, _this;

babelHelpers.classCallCheck(this, Test);
_this = _super.call(this);
babelHelpers.get(babelHelpers.getPrototypeOf(Test.prototype), "test", babelHelpers.assertThisInitialized(_this)).whatever();
babelHelpers.get(babelHelpers.getPrototypeOf(Test.prototype), "test", babelHelpers.assertThisInitialized(_this)).call(babelHelpers.assertThisInitialized(_this));
babelHelpers.get((_thisSuper = babelHelpers.assertThisInitialized(_this), babelHelpers.getPrototypeOf(Test.prototype)), "test", _thisSuper).whatever();
babelHelpers.get((_thisSuper2 = babelHelpers.assertThisInitialized(_this), babelHelpers.getPrototypeOf(Test.prototype)), "test", _thisSuper2).call(_thisSuper2);
return _this;
}

Expand Down
Expand Up @@ -20,7 +20,7 @@ var Outer = /*#__PURE__*/function (_Hello) {
var _super = babelHelpers.createSuper(Outer);

function Outer() {
var _this;
var _thisSuper, _this;

babelHelpers.classCallCheck(this, Outer);
_this = _super.call(this);
Expand All @@ -31,7 +31,7 @@ var Outer = /*#__PURE__*/function (_Hello) {
}

babelHelpers.createClass(Inner, [{
key: babelHelpers.get(babelHelpers.getPrototypeOf(Outer.prototype), "toString", babelHelpers.assertThisInitialized(_this)).call(babelHelpers.assertThisInitialized(_this)),
key: babelHelpers.get((_thisSuper = babelHelpers.assertThisInitialized(_this), babelHelpers.getPrototypeOf(Outer.prototype)), "toString", _thisSuper).call(_thisSuper),
value: function value() {
return 'hello';
}
Expand Down
Expand Up @@ -20,12 +20,12 @@ var Outer = /*#__PURE__*/function (_Hello) {
var _super = babelHelpers.createSuper(Outer);

function Outer() {
var _this;
var _thisSuper, _this;

babelHelpers.classCallCheck(this, Outer);
_this = _super.call(this);
var Inner = {
[babelHelpers.get(babelHelpers.getPrototypeOf(Outer.prototype), "toString", babelHelpers.assertThisInitialized(_this)).call(babelHelpers.assertThisInitialized(_this))]() {
[babelHelpers.get((_thisSuper = babelHelpers.assertThisInitialized(_this), babelHelpers.getPrototypeOf(Outer.prototype)), "toString", _thisSuper).call(_thisSuper)]() {
return 'hello';
}

Expand Down
Expand Up @@ -26,11 +26,11 @@ var Foo = /*#__PURE__*/function (_Bar) {
var _super = _createSuper(Foo);

function Foo() {
var _this;
var _thisSuper, _this;

_classCallCheck(this, Foo);

_get(_getPrototypeOf(Foo.prototype), "foo", _assertThisInitialized(_this)).call(_assertThisInitialized(_this), _this = _super.call(this));
_get((_thisSuper = _assertThisInitialized(_this), _getPrototypeOf(Foo.prototype)), "foo", _thisSuper).call(_thisSuper, _this = _super.call(this));

return _this;
}
Expand Down
Expand Up @@ -26,11 +26,11 @@ var Foo = /*#__PURE__*/function (_Bar) {
var _super = _createSuper(Foo);

function Foo() {
var _this;
var _thisSuper, _this;

_classCallCheck(this, Foo);

_get(_getPrototypeOf(Foo.prototype), "foo", _assertThisInitialized(_this)).call(_assertThisInitialized(_this));
_get((_thisSuper = _assertThisInitialized(_this), _getPrototypeOf(Foo.prototype)), "foo", _thisSuper).call(_thisSuper);

return _this = _super.call(this);
}
Expand Down
Expand Up @@ -6,13 +6,13 @@ var Foo = /*#__PURE__*/function (_Bar) {
var _super = babelHelpers.createSuper(Foo);

function Foo() {
var _this;
var _thisSuper, _thisSuper2, _this;

babelHelpers.classCallCheck(this, Foo);

var t = () => babelHelpers.get(babelHelpers.getPrototypeOf(Foo.prototype), "test", babelHelpers.assertThisInitialized(_this)).call(babelHelpers.assertThisInitialized(_this));
var t = () => babelHelpers.get((_thisSuper = babelHelpers.assertThisInitialized(_this), babelHelpers.getPrototypeOf(Foo.prototype)), "test", _thisSuper).call(_thisSuper);

babelHelpers.get(babelHelpers.getPrototypeOf(Foo.prototype), "foo", babelHelpers.assertThisInitialized(_this)).call(babelHelpers.assertThisInitialized(_this));
babelHelpers.get((_thisSuper2 = babelHelpers.assertThisInitialized(_this), babelHelpers.getPrototypeOf(Foo.prototype)), "foo", _thisSuper2).call(_thisSuper2);
return _this = _super.call(this);
}

Expand Down
Expand Up @@ -6,11 +6,11 @@ var Foo = /*#__PURE__*/function (_Bar) {
var _super = babelHelpers.createSuper(Foo);

function Foo() {
var _this;
var _thisSuper, _this;

babelHelpers.classCallCheck(this, Foo);

var t = () => babelHelpers.get(babelHelpers.getPrototypeOf(Foo.prototype), "test", babelHelpers.assertThisInitialized(_this)).call(babelHelpers.assertThisInitialized(_this));
var t = () => babelHelpers.get((_thisSuper = babelHelpers.assertThisInitialized(_this), babelHelpers.getPrototypeOf(Foo.prototype)), "test", _thisSuper).call(_thisSuper);

_this = _super.call(this);
t();
Expand Down
Expand Up @@ -6,11 +6,11 @@ var Foo = /*#__PURE__*/function (_Bar) {
var _super = babelHelpers.createSuper(Foo);

function Foo() {
var _this;
var _thisSuper, _this;

babelHelpers.classCallCheck(this, Foo);

var t = () => babelHelpers.get(babelHelpers.getPrototypeOf(Foo.prototype), "test", babelHelpers.assertThisInitialized(_this)).call(babelHelpers.assertThisInitialized(_this));
var t = () => babelHelpers.get((_thisSuper = babelHelpers.assertThisInitialized(_this), babelHelpers.getPrototypeOf(Foo.prototype)), "test", _thisSuper).call(_thisSuper);

return _this = _super.call(this);
}
Expand Down
@@ -1,20 +1,18 @@
let called = false;

class A {
method() {
get prop() {
called = true;
}

get methodName() {
return "method";
}
}

class B extends A {
constructor() {
super[super().methodName]()
super[super().prop]
}
}

new B();
expect(called).toBe(true);
expect(() => {
new B();
}).toThrow();
expect(called).toBe(false);

0 comments on commit 0bbf2da

Please sign in to comment.