diff --git a/lib/Parser.js b/lib/Parser.js index a92189dafc0..70c133afb25 100644 --- a/lib/Parser.js +++ b/lib/Parser.js @@ -578,21 +578,21 @@ Parser.prototype.walkExportNamedDeclaration = function walkExportNamedDeclaratio var pos = this.scope.definitions.length; this.walkStatement(statement.declaration); var newDefs = this.scope.definitions.slice(pos); - newDefs.reverse().forEach(function(def) { - this.applyPluginsBailResult("export specifier", statement, def, def); + newDefs.reverse().forEach(function(def, idx) { + this.applyPluginsBailResult("export specifier", statement, def, def, idx); }, this); } } } if(statement.specifiers) { - statement.specifiers.forEach(function(specifier) { + statement.specifiers.forEach(function(specifier, idx) { switch(specifier.type) { case "ExportSpecifier": var name = specifier.exported.name; if(source) - this.applyPluginsBailResult("export import specifier", statement, source, specifier.local.name, name); + this.applyPluginsBailResult("export import specifier", statement, source, specifier.local.name, name, idx); else - this.applyPluginsBailResult("export specifier", statement, specifier.local.name, name); + this.applyPluginsBailResult("export specifier", statement, specifier.local.name, name, idx); break; } }, this); diff --git a/lib/compareLocations.js b/lib/compareLocations.js index bfac0ee1fea..49e33022c78 100644 --- a/lib/compareLocations.js +++ b/lib/compareLocations.js @@ -17,12 +17,14 @@ module.exports = function compareLocations(a, b) { if(typeof b === "string") { return -1; } else if(typeof b === "object") { - if(a.start) a = a.start; - if(b.start) b = b.start; - if(a.line < b.line) return -1; - if(a.line > b.line) return 1; - if(a.column < b.column) return -1; - if(a.column > b.column) return 1; + let aa = a.start ? a.start : a; + let bb = b.start ? b.start : b; + if(aa.line < bb.line) return -1; + if(aa.line > bb.line) return 1; + if(aa.column < bb.column) return -1; + if(aa.column > bb.column) return 1; + if(aa.index < bb.index) return -1; + if(aa.index > bb.index) return 1; if(a.index < b.index) return -1; if(a.index > b.index) return 1; return 0; diff --git a/lib/dependencies/HarmonyExportDependencyParserPlugin.js b/lib/dependencies/HarmonyExportDependencyParserPlugin.js index 5a484cd41f5..a7ef11542db 100644 --- a/lib/dependencies/HarmonyExportDependencyParserPlugin.js +++ b/lib/dependencies/HarmonyExportDependencyParserPlugin.js @@ -15,7 +15,8 @@ const HarmonyModulesHelpers = require("./HarmonyModulesHelpers"); function makeHarmonyModule(module, loc) { if(!module.meta.harmonyModule) { const dep = new HarmonyCompatiblilityDependency(module); - dep.loc = loc; + dep.loc = Object.create(loc); + dep.loc.index = -2; module.addDependency(dep); module.meta.harmonyModule = true; module.strict = true; @@ -27,27 +28,30 @@ module.exports = class HarmonyExportDependencyParserPlugin { parser.plugin("export", statement => { const dep = new HarmonyExportHeaderDependency(statement.declaration && statement.declaration.range, statement.range); makeHarmonyModule(parser.state.module, statement.loc); - dep.loc = statement.loc; + dep.loc = Object.create(statement.loc); + dep.loc.index = -1; parser.state.current.addDependency(dep); return true; }); parser.plugin("export import", (statement, source) => { const dep = new HarmonyImportDependency(source, HarmonyModulesHelpers.getNewModuleVar(parser.state, source), statement.range); makeHarmonyModule(parser.state.module, statement.loc); - dep.loc = statement.loc; + dep.loc = Object.create(statement.loc); + dep.loc.index = -1; parser.state.current.addDependency(dep); parser.state.lastHarmoryImport = dep; return true; }); parser.plugin("export expression", (statement, expr) => { const dep = new HarmonyExportExpressionDependency(parser.state.module, expr.range, statement.range); - dep.loc = statement.loc; + dep.loc = Object.create(statement.loc); + dep.loc.index = -1; parser.state.current.addDependency(dep); parser.state.module.strict = true; return true; }); parser.plugin("export declaration", statement => {}); - parser.plugin("export specifier", (statement, id, name) => { + parser.plugin("export specifier", (statement, id, name, idx) => { const rename = parser.scope.renames[`$${id}`]; let dep; if(rename === "imported var") { @@ -58,13 +62,15 @@ module.exports = class HarmonyExportDependencyParserPlugin { const hoisted = statement.declaration && isHoistedStatement(statement.declaration); dep = new HarmonyExportSpecifierDependency(parser.state.module, id, name, !immutable || hoisted ? -0.5 : (statement.range[1] + 0.5), immutable); } - dep.loc = statement.loc; + dep.loc = Object.create(statement.loc); + dep.loc.index = idx; parser.state.current.addDependency(dep); return true; }); - parser.plugin("export import specifier", (statement, source, id, name) => { + parser.plugin("export import specifier", (statement, source, id, name, idx) => { const dep = new HarmonyExportImportedSpecifierDependency(parser.state.module, parser.state.lastHarmoryImport, HarmonyModulesHelpers.getModuleVar(parser.state, source), id, name); - dep.loc = statement.loc; + dep.loc = Object.create(statement.loc); + dep.loc.index = idx; parser.state.current.addDependency(dep); return true; }); diff --git a/test/cases/parsing/issue-3769/a.js b/test/cases/parsing/issue-3769/a.js new file mode 100644 index 00000000000..88491225de1 --- /dev/null +++ b/test/cases/parsing/issue-3769/a.js @@ -0,0 +1 @@ +export const thing = 123; diff --git a/test/cases/parsing/issue-3769/b.js b/test/cases/parsing/issue-3769/b.js new file mode 100644 index 00000000000..05e08712040 --- /dev/null +++ b/test/cases/parsing/issue-3769/b.js @@ -0,0 +1 @@ +export default 123; diff --git a/test/cases/parsing/issue-3769/c.js b/test/cases/parsing/issue-3769/c.js new file mode 100644 index 00000000000..05e08712040 --- /dev/null +++ b/test/cases/parsing/issue-3769/c.js @@ -0,0 +1 @@ +export default 123; diff --git a/test/cases/parsing/issue-3769/cjs.js b/test/cases/parsing/issue-3769/cjs.js new file mode 100644 index 00000000000..c69302f3c04 --- /dev/null +++ b/test/cases/parsing/issue-3769/cjs.js @@ -0,0 +1,2 @@ +exports.__esModule = true; +exports.test = 123; diff --git a/test/cases/parsing/issue-3769/d.js b/test/cases/parsing/issue-3769/d.js new file mode 100644 index 00000000000..05e08712040 --- /dev/null +++ b/test/cases/parsing/issue-3769/d.js @@ -0,0 +1 @@ +export default 123; diff --git a/test/cases/parsing/issue-3769/imported.js b/test/cases/parsing/issue-3769/imported.js new file mode 100644 index 00000000000..e89508f43c1 --- /dev/null +++ b/test/cases/parsing/issue-3769/imported.js @@ -0,0 +1 @@ +exports.test = "test"; diff --git a/test/cases/parsing/issue-3769/index.js b/test/cases/parsing/issue-3769/index.js new file mode 100644 index 00000000000..85d022ca5e6 --- /dev/null +++ b/test/cases/parsing/issue-3769/index.js @@ -0,0 +1,3 @@ +it("should generate valid code", function() { + require("./module").myTest.should.be.eql("test"); +}); diff --git a/test/cases/parsing/issue-3769/module.js b/test/cases/parsing/issue-3769/module.js new file mode 100644 index 00000000000..876aafe3df5 --- /dev/null +++ b/test/cases/parsing/issue-3769/module.js @@ -0,0 +1,19 @@ +import { thing } from './a' + +import user_settings_main from './c' +import user_settings_change_password from './d' + +export { test as myTest } from "./imported"; + +export { default as preload } from './d?1' +export { default as snackbar } from './d?2' +export { default as authentication } from './d?3' +export { default as navigator } from './d?4' +export { default as locale } from './d?5' +export { default as example_users } from './d?6' +export { default as user_profile } from './d?7' +export { default as block_user } from './d?8' +export { default as log } from './d?9' + +export const user_settings = (thing, user_settings_main, user_settings_change_password) +