Skip to content

Commit

Permalink
Fix duplicated assertThisInitialized calls in constructors (#9458)
Browse files Browse the repository at this point in the history
  • Loading branch information
rubennorte authored and nicolo-ribaudo committed Feb 7, 2019
1 parent d1514f5 commit 045d019
Show file tree
Hide file tree
Showing 25 changed files with 69 additions and 87 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ function (_Bar) {

if (condition) {
_this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this));
Object.defineProperty(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this))), _bar, {
Object.defineProperty(babelHelpers.assertThisInitialized(_this), _bar, {
writable: true,
value: "foo"
});
} else {
_this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this));
Object.defineProperty(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this))), _bar, {
Object.defineProperty(babelHelpers.assertThisInitialized(_this), _bar, {
writable: true,
value: "foo"
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ function (_Foo) {

babelHelpers.classCallCheck(this, Bar);
_this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Bar).call(this, ...args));
Object.defineProperty(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this)), _prop2, {
Object.defineProperty(babelHelpers.assertThisInitialized(_this), _prop2, {
writable: true,
value: "bar"
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ function (_Parent) {

babelHelpers.classCallCheck(this, Child);
_this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Child).call(this));
Object.defineProperty(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this)), _scopedFunctionWithThis, {
Object.defineProperty(babelHelpers.assertThisInitialized(_this), _scopedFunctionWithThis, {
writable: true,
value: function value() {
_this.name = {};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ function (_Bar) {
var _temp, _this;

babelHelpers.classCallCheck(this, Foo);
foo((_temp = _this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this)), Object.defineProperty(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this)), _bar, {
foo((_temp = _this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this)), Object.defineProperty(babelHelpers.assertThisInitialized(_this), _bar, {
writable: true,
value: "foo"
}), _temp));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ function (_Bar) {

babelHelpers.classCallCheck(this, Foo);
_this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this));
Object.defineProperty(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this)), _bar, {
Object.defineProperty(babelHelpers.assertThisInitialized(_this), _bar, {
writable: true,
value: "foo"
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ function (_Bar) {
if (condition) {
_this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this));

_bar.set(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this))), {
_bar.set(babelHelpers.assertThisInitialized(_this), {
writable: true,
value: "foo"
});
} else {
_this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this));

_bar.set(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this))), {
_bar.set(babelHelpers.assertThisInitialized(_this), {
writable: true,
value: "foo"
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ function (_Foo) {
babelHelpers.classCallCheck(this, Bar);
_this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Bar).call(this, ...args));

_prop2.set(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this)), {
_prop2.set(babelHelpers.assertThisInitialized(_this), {
writable: true,
value: "bar"
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ function (_Parent) {
babelHelpers.classCallCheck(this, Child);
_this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Child).call(this));

_scopedFunctionWithThis.set(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this)), {
_scopedFunctionWithThis.set(babelHelpers.assertThisInitialized(_this), {
writable: true,
value: () => {
_this.name = {};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ function (_A) {
babelHelpers.classCallCheck(this, B);
_this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(B).call(this, ...args));

_foo.set(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this)), {
_foo.set(babelHelpers.assertThisInitialized(_this), {
writable: true,
value: babelHelpers.get(babelHelpers.getPrototypeOf(B.prototype), "foo", babelHelpers.assertThisInitialized(_this)).call(babelHelpers.assertThisInitialized(_this))
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ function (_Bar) {
var _temp, _this;

babelHelpers.classCallCheck(this, Foo);
foo((_temp = _this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this)), _bar.set(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this)), {
foo((_temp = _this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this)), _bar.set(babelHelpers.assertThisInitialized(_this), {
writable: true,
value: "foo"
}), _temp));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ function (_Bar) {
babelHelpers.classCallCheck(this, Foo);
_this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this));

_bar.set(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this)), {
_bar.set(babelHelpers.assertThisInitialized(_this), {
writable: true,
value: "foo"
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ function (_Bar) {

if (condition) {
_this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this));
babelHelpers.defineProperty(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this))), "bar", "foo");
babelHelpers.defineProperty(babelHelpers.assertThisInitialized(_this), "bar", "foo");
} else {
_this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this));
babelHelpers.defineProperty(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this))), "bar", "foo");
babelHelpers.defineProperty(babelHelpers.assertThisInitialized(_this), "bar", "foo");
}

return babelHelpers.possibleConstructorReturn(_this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ function (_Bar) {

babelHelpers.classCallCheck(this, Foo);
_this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this, ...args));
babelHelpers.defineProperty(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this)), "bar", "foo");
babelHelpers.defineProperty(babelHelpers.assertThisInitialized(_this), "bar", "foo");
return _this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ function (_Parent) {

babelHelpers.classCallCheck(this, Child);
_this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Child).call(this));
babelHelpers.defineProperty(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this)), "scopedFunctionWithThis", function () {
babelHelpers.defineProperty(babelHelpers.assertThisInitialized(_this), "scopedFunctionWithThis", function () {
_this.name = {};
});
return _this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ function (_A) {

babelHelpers.classCallCheck(this, B);
_this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(B).call(this, ...args));
babelHelpers.defineProperty(babelHelpers.assertThisInitialized(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(babelHelpers.getPrototypeOf(B.prototype), "foo", babelHelpers.assertThisInitialized(_this)).call(babelHelpers.assertThisInitialized(_this)));
return _this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ function (_Bar) {
var _temp, _this;

babelHelpers.classCallCheck(this, Foo);
foo((_temp = _this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this)), babelHelpers.defineProperty(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this)), "bar", "foo"), _temp));
foo((_temp = _this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this)), babelHelpers.defineProperty(babelHelpers.assertThisInitialized(_this), "bar", "foo"), _temp));
return _this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ function (_Bar) {

babelHelpers.classCallCheck(this, Foo);
_this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this));
babelHelpers.defineProperty(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this)), "bar", "foo");
babelHelpers.defineProperty(babelHelpers.assertThisInitialized(_this), "bar", "foo");
return _this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat

function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }

function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }

function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }

function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
Expand Down Expand Up @@ -43,7 +43,7 @@ var Test = function Test() {

_this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(Other)).call.apply(_getPrototypeOf2, [this].concat(args)));

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

Expand Down
92 changes: 37 additions & 55 deletions packages/babel-plugin-transform-classes/src/transformClass.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,25 +32,6 @@ const verifyConstructorVisitor = traverse.visitors.merge([
);
}
},

ThisExpression(path, state) {
if (!state.isDerived) return;

const { node, parentPath } = path;
if (parentPath.isMemberExpression({ object: node })) {
// In cases like this.foo or this[foo], there is no need to add
// assertThisInitialized, since they already throw if this is
// undefined.
return;
}

const assertion = t.callExpression(
state.file.addHelper("assertThisInitialized"),
[node],
);
path.replaceWith(assertion);
path.skip();
},
},
]);

Expand Down Expand Up @@ -84,7 +65,6 @@ export default function transformClass(
instancePropRefs: {},
staticPropBody: [],
body: [],
bareSupers: new Set(),
superThises: [],
pushedConstructor: false,
pushedInherits: false,
Expand Down Expand Up @@ -217,34 +197,22 @@ export default function transformClass(

replaceSupers.replace();

// TODO this needs to be cleaned up. But, one step at a time.
const state = {
returns: [],
bareSupers: new Set(),
};
const superReturns = [];
path.traverse(
traverse.visitors.merge([
environmentVisitor,
{
ReturnStatement(path, state) {
ReturnStatement(path) {
if (!path.getFunctionParent().isArrowFunctionExpression()) {
state.returns.push(path);
}
},

Super(path, state) {
const { node, parentPath } = path;
if (parentPath.isCallExpression({ callee: node })) {
state.bareSupers.add(parentPath);
superReturns.push(path);
}
},
},
]),
state,
);

if (isConstructor) {
pushConstructor(state, node, path);
pushConstructor(superReturns, node, path);
} else {
pushMethod(node, path);
}
Expand Down Expand Up @@ -378,15 +346,43 @@ export default function transformClass(

path.traverse(findThisesVisitor);

let guaranteedSuperBeforeFinish = !!classState.bareSupers.size;

let thisRef = function() {
const ref = path.scope.generateDeclaredUidIdentifier("this");
thisRef = () => t.cloneNode(ref);
return ref;
};

for (const bareSuper of classState.bareSupers) {
for (const thisPath of classState.superThises) {
const { node, parentPath } = thisPath;
if (parentPath.isMemberExpression({ object: node })) {
thisPath.replaceWith(thisRef());
continue;
}
thisPath.replaceWith(
t.callExpression(classState.file.addHelper("assertThisInitialized"), [
thisRef(),
]),
);
}

const bareSupers = new Set();
path.traverse(
traverse.visitors.merge([
environmentVisitor,
{
Super(path) {
const { node, parentPath } = path;
if (parentPath.isCallExpression({ callee: node })) {
bareSupers.add(parentPath);
}
},
},
]),
);

let guaranteedSuperBeforeFinish = !!bareSupers.size;

for (const bareSuper of bareSupers) {
wrapSuperCall(bareSuper, classState.superName, thisRef, body);

if (guaranteedSuperBeforeFinish) {
Expand All @@ -408,19 +404,6 @@ export default function transformClass(
}
}

for (const thisPath of classState.superThises) {
const { node, parentPath } = thisPath;
if (parentPath.isMemberExpression({ object: node })) {
thisPath.replaceWith(thisRef());
continue;
}
thisPath.replaceWith(
t.callExpression(classState.file.addHelper("assertThisInitialized"), [
thisRef(),
]),
);
}

let wrapReturn;

if (classState.isLoose) {
Expand Down Expand Up @@ -535,7 +518,7 @@ export default function transformClass(
* Replace the constructor body of our class.
*/
function pushConstructor(
replaceSupers,
superReturns,
method: { type: "ClassMethod" },
path: NodePath,
) {
Expand All @@ -548,8 +531,7 @@ export default function transformClass(
userConstructorPath: path,
userConstructor: method,
hasConstructor: true,
bareSupers: replaceSupers.bareSupers,
superReturns: replaceSupers.returns,
superReturns,
});

const { construct } = classState;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function (_b) {
_this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(a1).call(this));

_this.x = function () {
return babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this));
return babelHelpers.assertThisInitialized(_this);
};

return _this;
Expand All @@ -42,7 +42,7 @@ function (_b2) {
_this2 = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(a2).call(this));

_this2.x = function () {
return babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this2));
return babelHelpers.assertThisInitialized(_this2);
};

return _this2;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ function (_Bar) {
var _this;

babelHelpers.classCallCheck(this, Foo);
return _this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this, babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this))));
return _this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this, babelHelpers.assertThisInitialized(_this)));
}

return Foo;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ function (_Bar) {

babelHelpers.classCallCheck(this, Foo);

var fn = () => babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this));
var fn = () => babelHelpers.assertThisInitialized(_this);

fn();
return _this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ function (_Bar) {

babelHelpers.classCallCheck(this, Foo);

var fn = () => babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this));
var fn = () => babelHelpers.assertThisInitialized(_this);

_this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this));
fn();
Expand Down
Loading

0 comments on commit 045d019

Please sign in to comment.