fix decorator interop - fixes #1277

This commit is contained in:
Sebastian McKenzie
2015-04-25 18:18:30 +01:00
parent 00c0a958db
commit deed48a3db
22 changed files with 124 additions and 81 deletions

View File

@@ -60,6 +60,7 @@ export default class File {
"create-class",
"create-decorated-class",
"create-decorated-object",
"define-decorated-property-descriptor",
"tagged-template-literal",
"tagged-template-literal-loose",
"to-array",

View File

@@ -1 +0,0 @@
this.KEY = INITIALIZERS.KEY.call(this);

View File

@@ -1 +0,0 @@
CONSTRUCTOR.KEY = INITIALIZERS.KEY.call(CONSTRUCTOR);

View File

@@ -23,7 +23,11 @@
throw new TypeError("The decorator for method " + descriptor.key + " is of the invalid type " + typeof decorator);
}
}
if (initializers) initializers[key] = descriptor.initializer;
if (descriptor.initializer) {
initializers[key] = descriptor;
continue;
}
}
Object.defineProperty(target, key, descriptor);

View File

@@ -13,7 +13,7 @@
descriptor.enumerable = true;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
descriptor.writable = true;
if (decorators) {
for (var f = 0; f < decorators.length; f++) {
@@ -26,6 +26,8 @@
}
}
descriptor.value = descriptor.initializer();
Object.defineProperty(target, key, descriptor);
}

View File

@@ -0,0 +1,12 @@
(function (target, key, descriptors) {
var _descriptor = descriptors[key];
// clone it
var descriptor = {};
for (var _key in _descriptor) descriptor[_key] = _descriptor[_key];
// initialize it
descriptor.value = descriptor.initializer();
Object.defineProperty(target, key, descriptor);
})

View File

@@ -554,35 +554,39 @@ class ClassTransformer {
node.value = t.functionExpression(null, [], t.blockStatement(body));
this.pushToMap(node, true, "initializer");
var initializers;
var body;
var target;
if (node.static) {
this.staticPropBody.push(util.template("call-static-decorator", {
INITIALIZERS: this.staticInitializersId ||= this.scope.generateUidIdentifier("staticInitializers"),
CONSTRUCTOR: this.classRef,
KEY: node.key,
}, true));
initializers = this.staticInitializersId ||= this.scope.generateUidIdentifier("staticInitializers");
body = this.staticPropBody;
target = this.classRef;
} else {
this.instancePropBody.push(util.template("call-instance-decorator", {
INITIALIZERS: this.instanceInitializersId ||= this.scope.generateUidIdentifier("instanceInitializers"),
KEY: node.key
}, true));
initializers = this.instanceInitializersId ||= this.scope.generateUidIdentifier("instanceInitializers");
body = this.instancePropBody;
target = t.thisExpression();
}
body.push(t.expressionStatement(
t.callExpression(this.file.addHelper("define-decorated-property-descriptor"), [
target,
t.literal(node.key.name),
initializers
])
));
} else {
if (!node.static && node.value) {
node.value ||= t.identifier("undefined");
if (node.static) {
// can just be added to the static map
this.pushToMap(node, true);
} else if (node.value) {
// add this to the instancePropBody which will be added after the super call in a derived constructor
// or at the start of a constructor for a non-derived constructor
this.instancePropBody.push(t.expressionStatement(
t.assignmentExpression("=", t.memberExpression(t.thisExpression(), node.key), node.value)
));
node.value = null;
}
if (!node.value) {
node.value = t.identifier("undefined");
}
// can just be added to the static map
this.pushToMap(node, true);
}
}

View File

@@ -27,7 +27,16 @@ export function ObjectExpression(node, parent, scope, file) {
for (var i = 0; i < node.properties.length; i++) {
var prop = node.properties[i];
if (prop.decorators) memoiseDecorators(prop.decorators, scope);
defineMap.push(mutatorMap, prop, null, file);
if (prop.kind === "init") {
prop.kind = "";
prop.value = t.functionExpression(null, [], t.blockStatement([
t.returnStatement(prop.value)
]));
}
defineMap.push(mutatorMap, prop, "initializer", file);
}
var obj = defineMap.toClassObject(mutatorMap);