diff --git a/src/babel/transformation/transformers/es6/properties.computed.js b/src/babel/transformation/transformers/es6/properties.computed.js index 6ca1e54992..ed832e8012 100644 --- a/src/babel/transformation/transformers/es6/properties.computed.js +++ b/src/babel/transformation/transformers/es6/properties.computed.js @@ -1,8 +1,8 @@ import * as t from "../../../types"; function loose(node, body, objId) { - for (var i = 0; i < node.properties.length; i++) { - var prop = node.properties[i]; + for (var prop of (node.properties: Array)) { + if (!prop) continue; body.push(t.expressionStatement( t.assignmentExpression( @@ -15,32 +15,18 @@ function loose(node, body, objId) { } function spec(node, body, objId, initProps, file) { - var props = node.properties; - - // add all non-computed properties and `__proto__` properties to the initializer - - var broken = false; - - for (let i = 0; i < props.length; i++) { - let prop = props[i]; - - if (prop.computed) { - broken = true; - } - - if (prop.kind !== "init" || !broken || t.isLiteral(t.toComputedKey(prop, 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 (let i = 0; i < props.length; i++) { - let prop = props[i]; + for (let prop of (node.properties: Array)) { if (!prop) continue; + // this wont work with Object.defineProperty + if (t.isLiteral(t.toComputedKey(prop), { value: "__proto__" })) { + initProps.push(prop); + continue; + } + let key = prop.key; if (t.isIdentifier(key) && !prop.computed) { key = t.literal(key.name); @@ -68,14 +54,33 @@ export var visitor = { exit(node, parent, scope, file) { var hasComputed = false; - for (var prop of (node.properties: Array)) { + for (let prop of (node.properties: Array)) { hasComputed = t.isProperty(prop, { computed: true, kind: "init" }); if (hasComputed) break; } if (!hasComputed) return; + // put all getters/setters into the first object expression as well as all initialisers up + // to the first computed property + var initProps = []; + var stopInits = false; + + for (var i = 0; i < node.properties.length; i++) { + let prop = node.properties[i]; + if (prop.computed) { + stopInits = true; + } + + if (prop.kind !== "init" || !stopInits) { + initProps.push(prop); + node.properties[i] = null; + } + } + + // + var objId = scope.generateUidIdentifierBasedOnNode(parent); // diff --git a/test.js b/test.js new file mode 100644 index 0000000000..d1c205fce6 --- /dev/null +++ b/test.js @@ -0,0 +1,36 @@ +var uglify = require("uglify-js"); +var babel = require("."); +var zlib = require("zlib"); +var vm = require("vm"); +var fs = require("fs"); + +var code = fs.readFileSync("/Users/sebmck/Downloads/jquery-1.11.3 (1).js", "utf8"); + +function sizeof(name, fn) { + var start = Date.now(); + var code = fn(); + var end = Date.now(); + console.log(name, "time:", (end - start) + "ms", "raw:", (code.length / 1000) + "KB", "gzipped:", (zlib.gzipSync(code).length / 1000) + "KB"); + fs.writeFileSync("jquery." + name + ".js", code); + new Function(code); +} + +sizeof("raw", function () { + return code; +}); + +sizeof("babel", function () { + return babel.transform(code, { + compact: true, + experimental: true, + blacklist: ["strict"], + plugins: ["minify-booleans", "merge-sibling-variables"] + }).code; +}); + +sizeof("uglify", function () { + return uglify.minify(code, { + mangle: false, + fromString: true + }).code; +}); diff --git a/test/core/fixtures/transformation/es6.properties.computed-loose/coerce/expected.js b/test/core/fixtures/transformation/es6.properties.computed-loose/coerce/expected.js new file mode 100644 index 0000000000..9bd540d65d --- /dev/null +++ b/test/core/fixtures/transformation/es6.properties.computed-loose/coerce/expected.js @@ -0,0 +1,7 @@ +"use strict"; + +var _obj; + +var obj = (_obj = { + foo: "bar" +}, _obj[bar] = "foo", _obj); diff --git a/test/core/fixtures/transformation/es6.properties.computed-loose/options.json b/test/core/fixtures/transformation/es6.properties.computed-loose/options.json index 79da122a18..e2f0353e41 100644 --- a/test/core/fixtures/transformation/es6.properties.computed-loose/options.json +++ b/test/core/fixtures/transformation/es6.properties.computed-loose/options.json @@ -1,3 +1,4 @@ { + "blacklist": ["es5.properties.mutators"], "loose": ["es6.properties.computed"] } diff --git a/test/core/fixtures/transformation/es6.properties.computed-loose/two/actual.js b/test/core/fixtures/transformation/es6.properties.computed-loose/two/actual.js index c63046dd19..954e58dadc 100644 --- a/test/core/fixtures/transformation/es6.properties.computed-loose/two/actual.js +++ b/test/core/fixtures/transformation/es6.properties.computed-loose/two/actual.js @@ -1,4 +1,4 @@ var obj = { first: "first", - ["second"]: "second", + [second]: "second", }; diff --git a/test/core/fixtures/transformation/es6.properties.computed-loose/two/expected.js b/test/core/fixtures/transformation/es6.properties.computed-loose/two/expected.js index 4c96e99ac6..636144a921 100644 --- a/test/core/fixtures/transformation/es6.properties.computed-loose/two/expected.js +++ b/test/core/fixtures/transformation/es6.properties.computed-loose/two/expected.js @@ -2,4 +2,6 @@ var _obj; -var obj = (_obj = {}, _obj.first = "first", _obj["second"] = "second", _obj); +var obj = (_obj = { + first: "first" +}, _obj[second] = "second", _obj);