Skip to content

Commit

Permalink
Fix duplicated assertThisInitialized calls in constructors
Browse files Browse the repository at this point in the history
  • Loading branch information
rubennorte committed Feb 5, 2019
1 parent 65cbbc1 commit 9a9e428
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 61 deletions.
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
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ function (_Bar) {
var _this;

babelHelpers.classCallCheck(this, Foo);
Foo[babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this))];
Foo[babelHelpers.assertThisInitialized(_this)];
return babelHelpers.possibleConstructorReturn(_this);
}

Expand Down

0 comments on commit 9a9e428

Please sign in to comment.