use Object.defineProperty on computed properties - fixes #357
This commit is contained in:
parent
7b5b8ab6ed
commit
800c350db6
@ -26,7 +26,8 @@ File.declarations = [
|
||||
"sliced-to-array",
|
||||
"object-without-properties",
|
||||
"has-own",
|
||||
"slice"
|
||||
"slice",
|
||||
"define-property"
|
||||
];
|
||||
|
||||
File.normaliseOptions = function (opts) {
|
||||
|
||||
8
lib/6to5/transformation/templates/define-property.js
Normal file
8
lib/6to5/transformation/templates/define-property.js
Normal file
@ -0,0 +1,8 @@
|
||||
(function (obj, key, value) {
|
||||
return Object.defineProperty(obj, key, {
|
||||
value: value,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true
|
||||
});
|
||||
});
|
||||
@ -1,3 +0,0 @@
|
||||
(function (KEY) {
|
||||
return KEY;
|
||||
})(OBJECT)
|
||||
@ -1,4 +0,0 @@
|
||||
(function (KEY) {
|
||||
CONTENT;
|
||||
return KEY;
|
||||
})(OBJECT);
|
||||
@ -1,6 +0,0 @@
|
||||
Object.defineProperty(this, KEY, {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: VALUE
|
||||
})
|
||||
@ -4,44 +4,91 @@ var t = require("../../types");
|
||||
exports.ObjectExpression = function (node, parent, file) {
|
||||
var hasComputed = false;
|
||||
|
||||
var computed = [];
|
||||
|
||||
node.properties = node.properties.filter(function (prop) {
|
||||
if (prop.computed) {
|
||||
hasComputed = true;
|
||||
computed.unshift(prop);
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
for (var i in node.properties) {
|
||||
hasComputed = t.isProperty(node.properties[i], { computed: true });
|
||||
if (hasComputed) break;
|
||||
}
|
||||
|
||||
if (!hasComputed) return;
|
||||
|
||||
var objId = util.getUid(parent, file);
|
||||
|
||||
var container = util.template("function-return-obj", {
|
||||
KEY: objId,
|
||||
OBJECT: node
|
||||
});
|
||||
var body = [];
|
||||
var container = t.functionExpression(null, [], t.blockStatement(body));
|
||||
container._aliasFunction = true;
|
||||
|
||||
var containerCallee = container.callee;
|
||||
var containerBody = containerCallee.body.body;
|
||||
var props = node.properties;
|
||||
|
||||
containerCallee._aliasFunction = true;
|
||||
// normalise key
|
||||
|
||||
for (var i in computed) {
|
||||
var prop = computed[i];
|
||||
containerBody.unshift(
|
||||
t.expressionStatement(
|
||||
t.assignmentExpression(
|
||||
"=",
|
||||
t.memberExpression(objId, prop.key, true),
|
||||
prop.value
|
||||
)
|
||||
)
|
||||
);
|
||||
for (i in props) {
|
||||
var prop = props[i];
|
||||
var key = prop.key;
|
||||
|
||||
if (!prop.computed && t.isIdentifier(key)) {
|
||||
prop.key = t.literal(key.name);
|
||||
}
|
||||
}
|
||||
|
||||
return container;
|
||||
// add all non-computed properties and `__proto__` properties to the initializer
|
||||
|
||||
var initProps = [];
|
||||
var broken = false;
|
||||
|
||||
for (i in props) {
|
||||
var prop = props[i];
|
||||
|
||||
if (prop.computed) {
|
||||
broken = true;
|
||||
}
|
||||
|
||||
if (!broken || t.isLiteral(prop.key, { value: "__proto__" })) {
|
||||
initProps.push(prop);
|
||||
props[i] = null;
|
||||
}
|
||||
}
|
||||
|
||||
// add a simple assignment for all Symbol member expressions due to symbol polyfill limitations
|
||||
// otherwise use Object.defineProperty
|
||||
|
||||
for (i in props) {
|
||||
var prop = props[i];
|
||||
if (!prop) continue;
|
||||
|
||||
var key = prop.key;
|
||||
var bodyNode;
|
||||
|
||||
if (prop.computed && t.isMemberExpression(key) && t.isIdentifier(key.object, { name: "Symbol" })) {
|
||||
bodyNode = t.assignmentExpression(
|
||||
"=",
|
||||
t.memberExpression(objId, key, true),
|
||||
prop.value
|
||||
);
|
||||
} else {
|
||||
bodyNode = t.callExpression(file.addDeclaration("define-property"), [objId, key, prop.value]);
|
||||
}
|
||||
|
||||
body.push(t.expressionStatement(bodyNode));
|
||||
}
|
||||
|
||||
// only one node and it's a Object.defineProperty that returns the object
|
||||
|
||||
if (body.length === 1) {
|
||||
var first = body[0].expression;
|
||||
|
||||
if (t.isCallExpression(first)) {
|
||||
first.arguments[0] = t.objectExpression([]);
|
||||
return first;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
body.unshift(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(objId, t.objectExpression(initProps))
|
||||
]));
|
||||
|
||||
body.push(t.returnStatement(objId));
|
||||
|
||||
return t.callExpression(container, []);
|
||||
};
|
||||
|
||||
@ -1,6 +1,12 @@
|
||||
"use strict";
|
||||
|
||||
foo((function (_ref) {
|
||||
_ref[bar] = "foobar";
|
||||
return _ref;
|
||||
})({}));
|
||||
var _defineProperty = function (obj, key, value) {
|
||||
return Object.defineProperty(obj, key, {
|
||||
value: value,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true
|
||||
});
|
||||
};
|
||||
|
||||
foo(_defineProperty({}, bar, "foobar"));
|
||||
|
||||
@ -1,6 +1,12 @@
|
||||
"use strict";
|
||||
|
||||
foo = (function (_foo) {
|
||||
_foo[bar] = "foobar";
|
||||
return _foo;
|
||||
})({});
|
||||
var _defineProperty = function (obj, key, value) {
|
||||
return Object.defineProperty(obj, key, {
|
||||
value: value,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true
|
||||
});
|
||||
};
|
||||
|
||||
foo = _defineProperty({}, bar, "foobar");
|
||||
|
||||
3
test/fixtures/transformation/es6-computed-property-names/ignore-symbol/actual.js
vendored
Normal file
3
test/fixtures/transformation/es6-computed-property-names/ignore-symbol/actual.js
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
var foo = {
|
||||
[Symbol.iterator]: "foobar"
|
||||
};
|
||||
8
test/fixtures/transformation/es6-computed-property-names/ignore-symbol/expected.js
vendored
Normal file
8
test/fixtures/transformation/es6-computed-property-names/ignore-symbol/expected.js
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
"use strict";
|
||||
|
||||
var foo = (function () {
|
||||
var _foo = {};
|
||||
|
||||
_foo[Symbol.iterator] = "foobar";
|
||||
return _foo;
|
||||
})();
|
||||
@ -1,9 +1,14 @@
|
||||
"use strict";
|
||||
|
||||
var obj = (function (_obj) {
|
||||
_obj[foobar] = function () {
|
||||
return "foobar";
|
||||
};
|
||||
var _defineProperty = function (obj, key, value) {
|
||||
return Object.defineProperty(obj, key, {
|
||||
value: value,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true
|
||||
});
|
||||
};
|
||||
|
||||
return _obj;
|
||||
})({});
|
||||
var obj = _defineProperty({}, foobar, function () {
|
||||
return "foobar";
|
||||
});
|
||||
|
||||
@ -1,10 +1,24 @@
|
||||
"use strict";
|
||||
|
||||
var obj = (function (_obj) {
|
||||
_obj["x" + foo] = "heh";
|
||||
_obj["y" + bar] = "noo";
|
||||
var _defineProperty = function (obj, key, value) {
|
||||
return Object.defineProperty(obj, key, {
|
||||
value: value,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true
|
||||
});
|
||||
};
|
||||
|
||||
var obj = (function () {
|
||||
var _obj = {};
|
||||
|
||||
_defineProperty(_obj, "x" + foo, "heh");
|
||||
|
||||
_defineProperty(_obj, "y" + bar, "noo");
|
||||
|
||||
_defineProperty(_obj, "foo", "foo");
|
||||
|
||||
_defineProperty(_obj, "bar", "bar");
|
||||
|
||||
return _obj;
|
||||
})({
|
||||
foo: "foo",
|
||||
bar: "bar"
|
||||
});
|
||||
})();
|
||||
|
||||
@ -1,7 +1,20 @@
|
||||
"use strict";
|
||||
|
||||
var obj = (function (_obj) {
|
||||
_obj["x" + foo] = "heh";
|
||||
_obj["y" + bar] = "noo";
|
||||
var _defineProperty = function (obj, key, value) {
|
||||
return Object.defineProperty(obj, key, {
|
||||
value: value,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true
|
||||
});
|
||||
};
|
||||
|
||||
var obj = (function () {
|
||||
var _obj = {};
|
||||
|
||||
_defineProperty(_obj, "x" + foo, "heh");
|
||||
|
||||
_defineProperty(_obj, "y" + bar, "noo");
|
||||
|
||||
return _obj;
|
||||
})({});
|
||||
})();
|
||||
|
||||
@ -1,6 +1,12 @@
|
||||
"use strict";
|
||||
|
||||
var obj = (function (_obj) {
|
||||
_obj["x" + foo] = "heh";
|
||||
return _obj;
|
||||
})({});
|
||||
var _defineProperty = function (obj, key, value) {
|
||||
return Object.defineProperty(obj, key, {
|
||||
value: value,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true
|
||||
});
|
||||
};
|
||||
|
||||
var obj = _defineProperty({}, "x" + foo, "heh");
|
||||
|
||||
@ -1,7 +1,12 @@
|
||||
"use strict";
|
||||
|
||||
var _this = this;
|
||||
var obj = (function (_obj) {
|
||||
_obj["x" + _this.foo] = "heh";
|
||||
return _obj;
|
||||
})({});
|
||||
var _defineProperty = function (obj, key, value) {
|
||||
return Object.defineProperty(obj, key, {
|
||||
value: value,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true
|
||||
});
|
||||
};
|
||||
|
||||
var obj = _defineProperty({}, "x" + this.foo, "heh");
|
||||
|
||||
@ -1,6 +1,12 @@
|
||||
"use strict";
|
||||
|
||||
var foo = (function (_foo) {
|
||||
_foo[bar] = "foobar";
|
||||
return _foo;
|
||||
})({});
|
||||
var _defineProperty = function (obj, key, value) {
|
||||
return Object.defineProperty(obj, key, {
|
||||
value: value,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true
|
||||
});
|
||||
};
|
||||
|
||||
var foo = _defineProperty({}, bar, "foobar");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user