use a different helper if a class contains class methods to avoid non-enumerability and delegation to es6.properties.computed transformer - fixes #984, closes #986
This commit is contained in:
@@ -50,6 +50,7 @@ export default class File {
|
||||
"inherits",
|
||||
"defaults",
|
||||
"create-class",
|
||||
"create-computed-class",
|
||||
"apply-constructor",
|
||||
"tagged-template-literal",
|
||||
"tagged-template-literal-loose",
|
||||
|
||||
@@ -5,33 +5,40 @@ import has from "lodash/object/has";
|
||||
import t from "../../types";
|
||||
|
||||
export function push(mutatorMap, key, kind, computed, value) {
|
||||
var alias;
|
||||
var alias = t.toKeyAlias({ computed }, key);
|
||||
|
||||
if (t.isIdentifier(key)) {
|
||||
alias = key.name;
|
||||
if (computed) alias = `computed:${alias}`;
|
||||
} else if (t.isLiteral(key)) {
|
||||
alias = String(key.value);
|
||||
} else {
|
||||
alias = JSON.stringify(traverse.removeProperties(t.cloneDeep(key)));
|
||||
}
|
||||
|
||||
var map;
|
||||
if (has(mutatorMap, alias)) {
|
||||
map = mutatorMap[alias];
|
||||
} else {
|
||||
map = {};
|
||||
}
|
||||
var map = {};
|
||||
if (has(mutatorMap, alias)) map = mutatorMap[alias];
|
||||
mutatorMap[alias] = map;
|
||||
|
||||
map._key = key;
|
||||
if (computed) {
|
||||
map._computed = true;
|
||||
}
|
||||
if (computed) map._computed = true;
|
||||
|
||||
map[kind] = value;
|
||||
}
|
||||
|
||||
export function hasComputed(mutatorMap) {
|
||||
for (var key in mutatorMap) {
|
||||
if (mutatorMap[key]._computed) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function toComputedObjectFromClass(obj) {
|
||||
var objExpr = t.arrayExpression([]);
|
||||
|
||||
for (var i = 0; i < obj.properties.length; i++) {
|
||||
var prop = obj.properties[i];
|
||||
var val = prop.value;
|
||||
val.properties.unshift(t.property("init", t.identifier("key"), t.toComputedKey(prop)));
|
||||
objExpr.elements.push(val);
|
||||
}
|
||||
|
||||
return objExpr;
|
||||
}
|
||||
|
||||
export function toClassObject(mutatorMap) {
|
||||
var objExpr = t.objectExpression([]);
|
||||
|
||||
@@ -49,6 +56,7 @@ export function toClassObject(mutatorMap) {
|
||||
var prop = t.property("init", t.identifier(key), node);
|
||||
t.inheritsComments(prop, inheritNode);
|
||||
t.removeComments(inheritNode);
|
||||
|
||||
mapNode.properties.push(prop);
|
||||
});
|
||||
|
||||
@@ -59,35 +67,11 @@ export function toClassObject(mutatorMap) {
|
||||
}
|
||||
|
||||
export function toDefineObject(mutatorMap) {
|
||||
var objExpr = t.objectExpression([]);
|
||||
|
||||
each(mutatorMap, function (map) {
|
||||
var mapNode = t.objectExpression([]);
|
||||
|
||||
var propNode = t.property("init", map._key, mapNode, map._computed);
|
||||
|
||||
if (map.value) {
|
||||
map.writable = t.literal(true);
|
||||
}
|
||||
|
||||
if (map.value) map.writable = t.literal(true);
|
||||
map.configurable = t.literal(true);
|
||||
map.enumerable = t.literal(true);
|
||||
|
||||
each(map, function (node, key) {
|
||||
if (key[0] === "_") return;
|
||||
|
||||
node = t.clone(node);
|
||||
var inheritNode = node;
|
||||
if (t.isMethodDefinition(node)) node = node.value;
|
||||
|
||||
var prop = t.property("init", t.identifier(key), node);
|
||||
t.inheritsComments(prop, inheritNode);
|
||||
t.removeComments(inheritNode);
|
||||
mapNode.properties.push(prop);
|
||||
});
|
||||
|
||||
objExpr.properties.push(propNode);
|
||||
});
|
||||
|
||||
return objExpr;
|
||||
return toClassObject(mutatorMap);
|
||||
}
|
||||
|
||||
18
src/babel/transformation/templates/create-computed-class.js
Normal file
18
src/babel/transformation/templates/create-computed-class.js
Normal file
@@ -0,0 +1,18 @@
|
||||
(function() {
|
||||
function defineProperties(target, rawProps) {
|
||||
var props = {};
|
||||
for (var i = 0; i < rawProps.length; i ++) {
|
||||
var prop = rawProps[i];
|
||||
prop.configurable = true;
|
||||
if (prop.value) prop.writable = true;
|
||||
props[prop.key] = prop;
|
||||
}
|
||||
Object.defineProperties(target, props);
|
||||
}
|
||||
|
||||
return function (Constructor, protoProps, staticProps) {
|
||||
if (protoProps) defineProperties(Constructor.prototype, protoProps);
|
||||
if (staticProps) defineProperties(Constructor, staticProps);
|
||||
return Constructor;
|
||||
};
|
||||
})()
|
||||
@@ -217,6 +217,7 @@ class ClassTransformer {
|
||||
|
||||
var instanceProps;
|
||||
var staticProps;
|
||||
var classHelper = "create-class";
|
||||
|
||||
if (this.hasInstanceMutators) {
|
||||
instanceProps = defineMap.toClassObject(this.instanceMutatorMap);
|
||||
@@ -227,13 +228,19 @@ class ClassTransformer {
|
||||
}
|
||||
|
||||
if (instanceProps || staticProps) {
|
||||
if (defineMap.hasComputed(this.instanceMutatorMap) || defineMap.hasComputed(this.staticMutatorMap)) {
|
||||
if (instanceProps) instanceProps = defineMap.toComputedObjectFromClass(instanceProps);
|
||||
if (staticProps) staticProps = defineMap.toComputedObjectFromClass(staticProps);
|
||||
classHelper = "create-computed-class";
|
||||
}
|
||||
|
||||
instanceProps ||= t.literal(null);
|
||||
|
||||
var args = [this.classRef, instanceProps];
|
||||
if (staticProps) args.push(staticProps);
|
||||
|
||||
body.push(t.expressionStatement(
|
||||
t.callExpression(this.file.addHelper("create-class"), args)
|
||||
t.callExpression(this.file.addHelper(classHelper), args)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ each(t.BUILDER_KEYS, function (keys, type) {
|
||||
* Description
|
||||
*/
|
||||
|
||||
t.toComputedKey = function (node: Object, key: Object): Object {
|
||||
t.toComputedKey = function (node: Object, key: Object = node.key): Object {
|
||||
if (!node.computed) {
|
||||
if (t.isIdentifier(key)) key = t.literal(key.name);
|
||||
}
|
||||
@@ -701,6 +701,23 @@ t.getLastStatements = function (node: Object): Array<Object> {
|
||||
return nodes;
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
|
||||
t.toKeyAlias = function (node: Object, key: Object = node.key) {
|
||||
var alias;
|
||||
if (t.isIdentifier(key)) {
|
||||
alias = key.name;
|
||||
} else if (t.isLiteral(key)) {
|
||||
alias = JSON.stringify(key.value);
|
||||
} else {
|
||||
alias = JSON.stringify(traverse.removeProperties(t.cloneDeep(key)));
|
||||
}
|
||||
if (node.computed) alias = `[${alias}]`;
|
||||
return alias;
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user