From 601bbb86cd2dad93f99dde09e0747b7993a91c8a Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sun, 28 Dec 2014 01:00:53 +1100 Subject: [PATCH] remap UpdateExpression in module exports - closes #334 --- lib/6to5/transformation/modules/_default.js | 36 ++++++++++++++++--- lib/6to5/transformation/modules/amd.js | 2 +- lib/6to5/transformation/modules/system.js | 3 +- lib/6to5/traverse/index.js | 15 +++++--- lib/6to5/types/index.js | 19 +++++----- .../es6-modules-amd/remap/actual.js | 2 ++ .../es6-modules-amd/remap/expected.js | 4 ++- .../es6-modules-common/remap/actual.js | 2 ++ .../es6-modules-common/remap/expected.js | 2 ++ .../es6-modules-ignore/remap/actual.js | 2 ++ .../es6-modules-ignore/remap/expected.js | 2 ++ .../es6-modules-system/remap/actual.js | 2 ++ .../es6-modules-system/remap/expected.js | 6 ++-- .../es6-modules-umd/remap/actual.js | 2 ++ .../es6-modules-umd/remap/expected.js | 4 ++- 15 files changed, 80 insertions(+), 23 deletions(-) diff --git a/lib/6to5/transformation/modules/_default.js b/lib/6to5/transformation/modules/_default.js index e4fedc0b48..a5c9e76801 100644 --- a/lib/6to5/transformation/modules/_default.js +++ b/lib/6to5/transformation/modules/_default.js @@ -44,16 +44,42 @@ DefaultFormatter.prototype.remapAssignments = function () { var self = this; var isLocalReference = function (node, scope) { - var left = node.left; - var name = left.name; - return t.isIdentifier(left) && localExports[name] && localExports[name] === scope.get(name, true); + var name = node.name; + return t.isIdentifier(node) && localExports[name] && localExports[name] === scope.get(name, true); }; traverse(this.file.ast, { enter: function (node, parent, scope) { - if (t.isExportDeclaration(node)) return false; + if (t.isUpdateExpression(node) && isLocalReference(node.argument, scope)) { + this.stop(); - if (t.isAssignmentExpression(node) && isLocalReference(node, scope)) { + // expand to long file assignment expression + var assign = t.assignmentExpression(node.operator[0] + "=", node.argument, t.literal(1)); + + // remap this assignment expression + var remapped = self.remapExportAssignment(assign); + + // we don't need to change the result + if (t.isExpressionStatement(parent) || node.prefix) { + return remapped; + } + + var nodes = []; + nodes.push(remapped); + + var operator; + if (node.operator === "--") { + operator = "+"; + } else { // "++" + operator = "-"; + } + nodes.push(t.binaryExpression(operator, node.argument, t.literal(1))); + + return t.sequenceExpression(nodes); + } + + if (t.isAssignmentExpression(node) && isLocalReference(node.left, scope)) { + this.stop(); return self.remapExportAssignment(node); } } diff --git a/lib/6to5/transformation/modules/amd.js b/lib/6to5/transformation/modules/amd.js index 226bdfc937..98f0f82c54 100644 --- a/lib/6to5/transformation/modules/amd.js +++ b/lib/6to5/transformation/modules/amd.js @@ -6,7 +6,7 @@ var t = require("../../types"); var _ = require("lodash"); function AMDFormatter(file) { - this.file = file; + DefaultFormatter.apply(this, arguments); this.ids = {}; } diff --git a/lib/6to5/transformation/modules/system.js b/lib/6to5/transformation/modules/system.js index 3358599e57..7257753e65 100644 --- a/lib/6to5/transformation/modules/system.js +++ b/lib/6to5/transformation/modules/system.js @@ -7,10 +7,11 @@ var t = require("../../types"); var _ = require("lodash"); function SystemFormatter(file) { + this.exportIdentifier = file.generateUidIdentifier("export"); + AMDFormatter.apply(this, arguments); this.moduleNameLiteral = t.literal(this.getModuleName()); - this.exportIdentifier = file.generateUidIdentifier("export"); } util.inherits(SystemFormatter, AMDFormatter); diff --git a/lib/6to5/traverse/index.js b/lib/6to5/traverse/index.js index fcbdf1f587..c04eb88ece 100644 --- a/lib/6to5/traverse/index.js +++ b/lib/6to5/traverse/index.js @@ -50,17 +50,25 @@ function traverse(parent, opts, scope) { } }; + var stop = false; + + var context = { + stop: function () { + stop = true; + } + }; + // var ourScope = scope; if (t.isScope(node)) ourScope = new Scope(node, scope); // enter if (opts.enter) { - var result = opts.enter(node, parent, ourScope); + var result = opts.enter.call(context, node, parent, ourScope); maybeReplace(result); // stop iteration - if (result === false) return; + if (stop || result === false) return; } // traverse node @@ -68,7 +76,7 @@ function traverse(parent, opts, scope) { // exit if (opts.exit) { - maybeReplace(opts.exit(node, parent, ourScope)); + maybeReplace(opts.exit.call(context, node, parent, ourScope)); } }; @@ -89,7 +97,6 @@ traverse.removeProperties = function (tree) { delete node._declarations; delete node.extendedRange; delete node._scopeInfo; - delete node._scope; delete node.tokens; delete node.range; delete node.start; diff --git a/lib/6to5/types/index.js b/lib/6to5/types/index.js index 97be33b034..dd839faa23 100644 --- a/lib/6to5/types/index.js +++ b/lib/6to5/types/index.js @@ -240,14 +240,17 @@ t.getIds = function (node, map, ignoreTypes) { if (_.contains(ignoreTypes, id.type)) continue; var nodeKey = t.getIds.nodes[id.type]; - var arrKey = t.getIds.arrays[id.type]; + var arrKeys = t.getIds.arrays[id.type]; if (t.isIdentifier(id)) { ids[id.name] = id; } else if (nodeKey) { if (id[nodeKey]) search.push(id[nodeKey]); - } else if (arrKey) { - search = search.concat(id[arrKey] || []); + } else if (arrKeys) { + for (var i in arrKeys) { + var key = arrKeys[i]; + search = search.concat(id[key] || []); + } } } @@ -268,11 +271,11 @@ t.getIds.nodes = { }; t.getIds.arrays = { - ExportDeclaration: "specifiers", - ImportDeclaration: "specifiers", - VariableDeclaration: "declarations", - ArrayPattern: "elements", - ObjectPattern: "properties" + ExportDeclaration: ["specifiers", "declaration"], + ImportDeclaration: ["specifiers"], + VariableDeclaration: ["declarations"], + ArrayPattern: ["elements"], + ObjectPattern: ["properties"] }; t.isLet = function (node) { diff --git a/test/fixtures/transformation/es6-modules-amd/remap/actual.js b/test/fixtures/transformation/es6-modules-amd/remap/actual.js index 7345a055a5..79c234d8ae 100644 --- a/test/fixtures/transformation/es6-modules-amd/remap/actual.js +++ b/test/fixtures/transformation/es6-modules-amd/remap/actual.js @@ -1,7 +1,9 @@ export var test = 2; test = 5; +test++; (function () { var test = 2; test = 3; + test++; })(); diff --git a/test/fixtures/transformation/es6-modules-amd/remap/expected.js b/test/fixtures/transformation/es6-modules-amd/remap/expected.js index 5fc760fd92..26b004e6e5 100644 --- a/test/fixtures/transformation/es6-modules-amd/remap/expected.js +++ b/test/fixtures/transformation/es6-modules-amd/remap/expected.js @@ -2,10 +2,12 @@ define(["exports"], function (exports) { "use strict"; var test = exports.test = 2; - test = 5; + test = exports.test = 5; + test = exports.test += 1; (function () { var test = 2; test = 3; + test++; })(); }); diff --git a/test/fixtures/transformation/es6-modules-common/remap/actual.js b/test/fixtures/transformation/es6-modules-common/remap/actual.js index 7345a055a5..79c234d8ae 100644 --- a/test/fixtures/transformation/es6-modules-common/remap/actual.js +++ b/test/fixtures/transformation/es6-modules-common/remap/actual.js @@ -1,7 +1,9 @@ export var test = 2; test = 5; +test++; (function () { var test = 2; test = 3; + test++; })(); diff --git a/test/fixtures/transformation/es6-modules-common/remap/expected.js b/test/fixtures/transformation/es6-modules-common/remap/expected.js index f4f8f05b7b..35eccf917c 100644 --- a/test/fixtures/transformation/es6-modules-common/remap/expected.js +++ b/test/fixtures/transformation/es6-modules-common/remap/expected.js @@ -2,8 +2,10 @@ var test = exports.test = 2; test = exports.test = 5; +test = exports.test += 1; (function () { var test = 2; test = 3; + test++; })(); diff --git a/test/fixtures/transformation/es6-modules-ignore/remap/actual.js b/test/fixtures/transformation/es6-modules-ignore/remap/actual.js index 7345a055a5..79c234d8ae 100644 --- a/test/fixtures/transformation/es6-modules-ignore/remap/actual.js +++ b/test/fixtures/transformation/es6-modules-ignore/remap/actual.js @@ -1,7 +1,9 @@ export var test = 2; test = 5; +test++; (function () { var test = 2; test = 3; + test++; })(); diff --git a/test/fixtures/transformation/es6-modules-ignore/remap/expected.js b/test/fixtures/transformation/es6-modules-ignore/remap/expected.js index 15120d6616..e6187004bb 100644 --- a/test/fixtures/transformation/es6-modules-ignore/remap/expected.js +++ b/test/fixtures/transformation/es6-modules-ignore/remap/expected.js @@ -2,8 +2,10 @@ var test = 2; test = 5; +test++; (function () { var test = 2; test = 3; + test++; })(); diff --git a/test/fixtures/transformation/es6-modules-system/remap/actual.js b/test/fixtures/transformation/es6-modules-system/remap/actual.js index 7345a055a5..79c234d8ae 100644 --- a/test/fixtures/transformation/es6-modules-system/remap/actual.js +++ b/test/fixtures/transformation/es6-modules-system/remap/actual.js @@ -1,7 +1,9 @@ export var test = 2; test = 5; +test++; (function () { var test = 2; test = 3; + test++; })(); diff --git a/test/fixtures/transformation/es6-modules-system/remap/expected.js b/test/fixtures/transformation/es6-modules-system/remap/expected.js index 58803da194..111c718241 100644 --- a/test/fixtures/transformation/es6-modules-system/remap/expected.js +++ b/test/fixtures/transformation/es6-modules-system/remap/expected.js @@ -5,12 +5,14 @@ System.register("es6-modules-system/remap/expected", [], function (_export) { "use strict"; var test = _export("test", 2); - test = 5; + _export("test", test = 5); + _export("test", test += 1); (function () { var test = 2; test = 3; + test++; })(); } }; -}); \ No newline at end of file +}); diff --git a/test/fixtures/transformation/es6-modules-umd/remap/actual.js b/test/fixtures/transformation/es6-modules-umd/remap/actual.js index 7345a055a5..79c234d8ae 100644 --- a/test/fixtures/transformation/es6-modules-umd/remap/actual.js +++ b/test/fixtures/transformation/es6-modules-umd/remap/actual.js @@ -1,7 +1,9 @@ export var test = 2; test = 5; +test++; (function () { var test = 2; test = 3; + test++; })(); diff --git a/test/fixtures/transformation/es6-modules-umd/remap/expected.js b/test/fixtures/transformation/es6-modules-umd/remap/expected.js index 0fe2bbd0f4..d40522682e 100644 --- a/test/fixtures/transformation/es6-modules-umd/remap/expected.js +++ b/test/fixtures/transformation/es6-modules-umd/remap/expected.js @@ -8,10 +8,12 @@ "use strict"; var test = exports.test = 2; - test = 5; + test = exports.test = 5; + test = exports.test += 1; (function () { var test = 2; test = 3; + test++; })(); });