add support for inheriting from statically inlined native constructors - closes #1172
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"blacklist": ["useStrict", "es6.blockScoping", "regenerator"],
|
||||
"blacklist": ["useStrict", "es6.blockScoping", "regenerator", "es6.spread"],
|
||||
"loose": ["es6.modules"]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
if (SUPER_NAME != null) {
|
||||
var NATIVE_REF = new SUPER_NAME(...arguments);
|
||||
NATIVE_REF.__proto__ = CLASS_NAME.prototype;
|
||||
return NATIVE_REF;
|
||||
}
|
||||
@@ -79,6 +79,10 @@ var verifyConstructorVisitor = traverse.explode({
|
||||
if (state.hasSuper && !state.hasBareSuper) {
|
||||
throw this.errorWithNode("'this' is not allowed before super()");
|
||||
}
|
||||
|
||||
if (state.isNativeSuper) {
|
||||
return state.nativeSuperRef;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -133,6 +137,15 @@ class ClassTransformer {
|
||||
|
||||
//
|
||||
|
||||
var superClass = this.node.superClass;
|
||||
this.isNativeSuper = superClass && t.isIdentifier(superClass) && t.NATIVE_TYPE_NAMES.indexOf(superClass.name) >= 0;
|
||||
|
||||
if (this.isNativeSuper) {
|
||||
this.nativeSuperRef = this.scope.generateUidIdentifier("this");
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
var body = this.body;
|
||||
|
||||
//
|
||||
@@ -203,6 +216,10 @@ class ClassTransformer {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.isNativeSuper) {
|
||||
constructorBody.body.push(t.returnStatement(this.nativeSuperRef));
|
||||
}
|
||||
|
||||
if (this.className) {
|
||||
// named class with only a constructor
|
||||
if (body.length === 1) return t.toExpression(body[0]);
|
||||
@@ -303,7 +320,9 @@ class ClassTransformer {
|
||||
if (!this.hasConstructor && this.hasSuper) {
|
||||
var helperName = "class-super-constructor-call";
|
||||
if (this.isLoose) helperName += "-loose";
|
||||
if (this.isNativeSuper) helperName = "class-super-native-constructor-call";
|
||||
constructorBody.body.push(util.template(helperName, {
|
||||
NATIVE_REF: this.nativeSuperRef,
|
||||
CLASS_NAME: className,
|
||||
SUPER_NAME: this.superName
|
||||
}, true));
|
||||
@@ -432,10 +451,12 @@ class ClassTransformer {
|
||||
|
||||
verifyConstructor(path: TraversalPath) {
|
||||
var state = {
|
||||
hasBareSuper: false,
|
||||
bareSuper: null,
|
||||
hasSuper: this.hasSuper,
|
||||
file: this.file
|
||||
nativeSuperRef: this.nativeSuperRef,
|
||||
isNativeSuper: this.isNativeSuper,
|
||||
hasBareSuper: false,
|
||||
bareSuper: null,
|
||||
hasSuper: this.hasSuper,
|
||||
file: this.file
|
||||
};
|
||||
|
||||
path.get("value").traverse(verifyConstructorVisitor, state);
|
||||
@@ -445,6 +466,21 @@ class ClassTransformer {
|
||||
if (!state.hasBareSuper && this.hasSuper) {
|
||||
throw path.errorWithNode("Derived constructor must call super()");
|
||||
}
|
||||
|
||||
if (this.isNativeSuper && this.bareSuper) {
|
||||
this.bareSuper.replaceWithMultiple([
|
||||
t.variableDeclaration("var", [
|
||||
t.variableDeclarator(this.nativeSuperRef, t.newExpression(this.superName, this.bareSuper.node.arguments))
|
||||
]),
|
||||
|
||||
t.expressionStatement(t.assignmentExpression(
|
||||
"=",
|
||||
t.memberExpression(this.nativeSuperRef, t.identifier("__proto__")),
|
||||
t.memberExpression(this.classRef, t.identifier("prototype"))
|
||||
)),
|
||||
t.expressionStatement(this.nativeSuperRef)
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user