delay this assignment when referencing this inside an arrow function pre-bare super in derived class constructors - fixes #1920

This commit is contained in:
Sebastian McKenzie 2015-07-04 23:32:11 +02:00
parent cda2bfce38
commit 1fd0b1f741
5 changed files with 53 additions and 8 deletions

View File

@ -52,7 +52,20 @@ var verifyConstructorVisitor = {
ThisExpression(node, parent, scope, state) { ThisExpression(node, parent, scope, state) {
if (state.isDerived && !state.hasBareSuper) { if (state.isDerived && !state.hasBareSuper) {
throw this.errorWithNode("'this' is not allowed before super()"); if (this.inShadow()) {
var thisAlias = state.constructorPath.getData("this");
if (!thisAlias) {
thisAlias = state.constructorPath.setData(
"this",
state.constructorPath.scope.generateUidIdentifier("this")
);
}
return thisAlias;
} else {
throw this.errorWithNode("'this' is not allowed before super()");
}
} }
}, },
@ -429,13 +442,21 @@ export default class ClassTransformer {
verifyConstructor(path: NodePath) { verifyConstructor(path: NodePath) {
var state = { var state = {
hasBareSuper: false, constructorPath: path.get("value"),
bareSuper: null, hasBareSuper: false,
isDerived: this.isDerived, bareSuper: null,
file: this.file isDerived: this.isDerived,
file: this.file,
}; };
path.get("value").traverse(verifyConstructorVisitor, state); state.constructorPath.traverse(verifyConstructorVisitor, state);
var thisAlias = state.constructorPath.getData("this");
if (thisAlias && state.bareSuper) {
state.bareSuper.insertAfter(t.variableDeclaration("var", [
t.variableDeclarator(thisAlias, t.thisExpression())
]));
}
this.bareSuper = state.bareSuper; this.bareSuper = state.bareSuper;

View File

@ -6,7 +6,8 @@ export var metadata = {
function remap(path, key, create) { function remap(path, key, create) {
// ensure that we're shadowed // ensure that we're shadowed
if (!path.inShadow()) return; var shadowPath = path.inShadow();
if (!shadowPath || shadowPath.isArrowFunctionExpression()) return;
var shadowFunction = path.node._shadowedFunctionLiteral; var shadowFunction = path.node._shadowedFunctionLiteral;
var currentFunction; var currentFunction;

View File

@ -178,7 +178,7 @@ export function inShadow() {
var path = this; var path = this;
while (path) { while (path) {
if (path.isFunction()) { if (path.isFunction()) {
if (path.node.shadow) { if (path.node.shadow || path.isArrowFunctionExpression()) {
return path; return path;
} else { } else {
return null; return null;

View File

@ -0,0 +1,7 @@
class Foo extends Bar {
constructor() {
super(() => {
this.test;
});
}
}

View File

@ -0,0 +1,16 @@
"use strict";
var Foo = (function (_Bar) {
function Foo() {
babelHelpers.classCallCheck(this, Foo);
babelHelpers.get(Object.getPrototypeOf(Foo.prototype), "constructor", this).call(this, function () {
_this.test;
});
var _this = this;
}
babelHelpers.inherits(Foo, _Bar);
return Foo;
})(Bar);