fix incorrect interpreation of export default shorthand, update to new ast definitions - #1091
This commit is contained in:
@@ -560,12 +560,22 @@ pp.parseExport = function(node) {
|
||||
// export * from '...'
|
||||
if (this.eat(tt.star)) {
|
||||
if (this.options.features["es7.exportExtensions"] && this.eatContextual("as")) {
|
||||
node.exported = this.parseIdent()
|
||||
let specifier = this.startNode()
|
||||
specifier.exported = this.parseIdent()
|
||||
node.specifiers = [this.finishNode(specifier, "ExportNamespaceSpecifier")]
|
||||
this.parseExportSpecifiersMaybe(node)
|
||||
this.parseExportFrom(node)
|
||||
} else {
|
||||
this.parseExportFrom(node)
|
||||
return this.finishNode(node, "ExportAllDeclaration")
|
||||
}
|
||||
} else if (this.isExportDefaultSpecifier()) {
|
||||
let specifier = this.startNode()
|
||||
specifier.exported = this.parseIdent(true)
|
||||
node.specifiers = [this.finishNode(specifier, "ExportDefaultSpecifier")]
|
||||
this.parseExportSpecifiersMaybe(node)
|
||||
this.parseExportFrom(node)
|
||||
return this.finishNode(node, "ExportAllDeclaration")
|
||||
}
|
||||
if (this.eat(tt._default)) { // export default ...
|
||||
} else if (this.eat(tt._default)) { // export default ...
|
||||
let expr = this.parseMaybeAssign()
|
||||
let needsSemi = true
|
||||
if (expr.type == "FunctionExpression" ||
|
||||
@@ -581,16 +591,10 @@ pp.parseExport = function(node) {
|
||||
if (needsSemi) this.semicolon()
|
||||
this.checkExport(node)
|
||||
return this.finishNode(node, "ExportDefaultDeclaration")
|
||||
}
|
||||
// export var|const|let|function|class ...
|
||||
if (this.type.keyword || this.shouldParseExportDeclaration()) {
|
||||
} else if (this.type.keyword || this.shouldParseExportDeclaration()) {
|
||||
node.declaration = this.parseStatement(true)
|
||||
node.specifiers = []
|
||||
node.source = null
|
||||
} else if (this.type === tt.name) {
|
||||
node.exported = this.parseIdent()
|
||||
this.parseExportFrom(node)
|
||||
return this.finishNode(node, "ExportNamespaceDeclaration")
|
||||
} else { // export { x, y as z } [from '...']
|
||||
node.declaration = null
|
||||
node.specifiers = this.parseExportSpecifiers()
|
||||
@@ -605,6 +609,25 @@ pp.parseExport = function(node) {
|
||||
return this.finishNode(node, "ExportNamedDeclaration")
|
||||
}
|
||||
|
||||
pp.isExportDefaultSpecifier = function () {
|
||||
if (this.type === tt.name) {
|
||||
return this.value !== "type" && this.value !== "async"
|
||||
}
|
||||
|
||||
if (this.type !== tt._default) {
|
||||
return false
|
||||
}
|
||||
|
||||
var lookahead = this.lookahead()
|
||||
return lookahead.type === tt.comma || (lookahead.type === tt.name && lookahead.value === "from")
|
||||
}
|
||||
|
||||
pp.parseExportSpecifiersMaybe = function (node) {
|
||||
if (this.eat(tt.comma)) {
|
||||
node.specifiers = node.specifiers.concat(this.parseExportSpecifiers())
|
||||
}
|
||||
}
|
||||
|
||||
pp.parseExportFrom = function(node) {
|
||||
this.expectContextual("from")
|
||||
node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected()
|
||||
|
||||
@@ -13,6 +13,10 @@ export function ImportDefaultSpecifier(node, print) {
|
||||
print(node.local);
|
||||
}
|
||||
|
||||
export function ExportDefaultSpecifier(node, print) {
|
||||
print(node.exported);
|
||||
}
|
||||
|
||||
export function ExportSpecifier(node, print) {
|
||||
print(node.local);
|
||||
if (node.exported && node.local !== node.exported) {
|
||||
@@ -21,12 +25,9 @@ export function ExportSpecifier(node, print) {
|
||||
}
|
||||
}
|
||||
|
||||
export function ExportNamespaceDeclaration(node, print) {
|
||||
this.push("export ");
|
||||
export function ExportNamespaceSpecifier(node, print) {
|
||||
this.push("* as ");
|
||||
print(node.exported);
|
||||
this.push(" from ");
|
||||
print(node.source);
|
||||
this.semicolon();
|
||||
}
|
||||
|
||||
export function ExportAllDeclaration(node, print) {
|
||||
@@ -54,16 +55,29 @@ function ExportDeclaration(node, print) {
|
||||
var specifiers = node.specifiers;
|
||||
|
||||
if (node.declaration) {
|
||||
print(node.declaration);
|
||||
if (t.isStatement(node.declaration)) return;
|
||||
var declar = node.declaration;
|
||||
print(declar);
|
||||
if (t.isStatement(declar) || t.isFunction(declar) || t.isClass(declar)) return;
|
||||
} else {
|
||||
this.push("{");
|
||||
if (specifiers.length) {
|
||||
this.space();
|
||||
print.join(specifiers, { separator: ", " });
|
||||
this.space();
|
||||
var first = specifiers[0];
|
||||
var hasSpecial = false;
|
||||
if (t.isExportDefaultSpecifier(first) || t.isExportNamespaceSpecifier(first)) {
|
||||
hasSpecial = true;
|
||||
print(specifiers.shift());
|
||||
if (specifiers.length) {
|
||||
this.push(", ");
|
||||
}
|
||||
}
|
||||
|
||||
if (specifiers.length || (!specifiers.length && !hasSpecial)) {
|
||||
this.push("{");
|
||||
if (specifiers.length) {
|
||||
this.space();
|
||||
print.join(specifiers, { separator: ", " });
|
||||
this.space();
|
||||
}
|
||||
this.push("}");
|
||||
}
|
||||
this.push("}");
|
||||
|
||||
if (node.source) {
|
||||
this.push(" from ");
|
||||
@@ -83,25 +97,20 @@ export function ImportDeclaration(node, print) {
|
||||
|
||||
var specfiers = node.specifiers;
|
||||
if (specfiers && specfiers.length) {
|
||||
var foundImportSpecifier = false;
|
||||
|
||||
for (var i = 0; i < node.specifiers.length; i++) {
|
||||
var spec = node.specifiers[i];
|
||||
|
||||
if (i > 0) {
|
||||
var first = node.specifiers[0];
|
||||
if (t.isImportDefaultSpecifier(first) || t.isImportNamespaceSpecifier(first)) {
|
||||
print(node.specifiers.shift());
|
||||
if (node.specifiers.length) {
|
||||
this.push(", ");
|
||||
}
|
||||
|
||||
if (!t.isImportDefaultSpecifier(spec) && !t.isImportNamespaceSpecifier(spec) && !foundImportSpecifier) {
|
||||
foundImportSpecifier = true;
|
||||
this.push("{ ");
|
||||
}
|
||||
|
||||
print(spec);
|
||||
}
|
||||
|
||||
if (foundImportSpecifier) {
|
||||
this.push(" }");
|
||||
if (node.specifiers.length) {
|
||||
this.push("{");
|
||||
this.space()
|
||||
print.join(node.specifiers, { separator: ", " });
|
||||
this.space()
|
||||
this.push("}");
|
||||
}
|
||||
|
||||
this.push(" from ");
|
||||
|
||||
@@ -62,7 +62,7 @@ var exportsVisitor = traverse.explode({
|
||||
extend(formatter.localExports, declar.getBindingIdentifiers());
|
||||
}
|
||||
|
||||
if (!t.isExportDefaultDeclaration(node) && !t.isExportNamespaceDeclaration(node)) {
|
||||
if (!t.isExportDefaultDeclaration(node)) {
|
||||
formatter.hasNonDefaultExports = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,23 +3,33 @@
|
||||
import * as t from "../../../types";
|
||||
|
||||
export function check(node) {
|
||||
return t.isExportNamespaceDeclaration(node) || (t.isExportAllDeclaration(node) && node.exported);
|
||||
return t.isExportDefaultSpecifier(node) || t.isExportNamespaceSpecifier(node);
|
||||
}
|
||||
|
||||
export function ExportNamespaceDeclaration(node, parent, scope) {
|
||||
var uid = scope.generateUidIdentifier("default");
|
||||
return [
|
||||
t.importDeclaration([t.importDefaultSpecifier(uid)], node.source),
|
||||
t.exportDefaultDeclaration(uid)
|
||||
];
|
||||
}
|
||||
export function ExportNamedDeclaration(node, parent, scope) {
|
||||
var nodes = [];
|
||||
|
||||
export function ExportAllDeclaration(node, parent, scope) {
|
||||
if (node.exported) {
|
||||
var uid = scope.generateUidIdentifier(node.exported.name);
|
||||
return [
|
||||
if (t.isExportNamespaceSpecifier(node.specifiers[0])) {
|
||||
var specifier = node.specifiers.shift();
|
||||
var uid = scope.generateUidIdentifier(specifier.exported.name);
|
||||
nodes.push(
|
||||
t.importDeclaration([t.importNamespaceSpecifier(uid)], node.source),
|
||||
t.exportNamedDeclaration(null, [t.exportSpecifier(uid, node.exported)])
|
||||
];
|
||||
t.exportNamedDeclaration(null, [t.exportSpecifier(uid, specifier.exported)])
|
||||
);
|
||||
} else if (t.isExportDefaultSpecifier(node.specifiers[0])) {
|
||||
var specifier = node.specifiers.shift();
|
||||
var uid = scope.generateUidIdentifier(specifier.exported.name);
|
||||
nodes.push(
|
||||
t.importDeclaration([t.importSpecifier(uid, specifier.exported)], node.source),
|
||||
t.exportNamedDeclaration(null, [t.exportSpecifier(uid, specifier.exported)])
|
||||
);
|
||||
}
|
||||
|
||||
if (!nodes.length) return;
|
||||
|
||||
if (node.specifiers.length > 1) {
|
||||
nodes.push(node);
|
||||
}
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
"LabeledStatement": ["Statement"],
|
||||
"VariableDeclaration": ["Statement", "Declaration"],
|
||||
|
||||
"ExportNamespaceDeclaration": ["Statement", "Declaration", "ModuleDeclaration", "ExportDeclaration"],
|
||||
"ExportDefaultSpecifier": ["ModuleSpecifier"],
|
||||
"ExportNamespaceSpecifier": ["ModuleSpecifier"],
|
||||
"ExportDefaultFromSpecifier": ["ModuleSpecifier"],
|
||||
"ExportAllDeclaration": ["Statement", "Declaration", "ModuleDeclaration", "ExportDeclaration"],
|
||||
"ExportDefaultDeclaration": ["Statement", "Declaration", "ModuleDeclaration", "ExportDeclaration"],
|
||||
"ExportNamedDeclaration": ["Statement", "Declaration", "ModuleDeclaration", "ExportDeclaration"],
|
||||
|
||||
@@ -69,9 +69,10 @@
|
||||
"YieldExpression": ["argument"],
|
||||
|
||||
"ExportAllDeclaration": ["source", "exported"],
|
||||
"ExportNamespaceDeclaration": ["exported"],
|
||||
"ExportDefaultDeclaration": ["declaration"],
|
||||
"ExportNamedDeclaration": ["declaration", "specifiers", "source"],
|
||||
"ExportDefaultSpecifier": ["exported"],
|
||||
"ExportNamespaceSpecifier": ["exported"],
|
||||
"ExportSpecifier": ["local", "exported"],
|
||||
|
||||
"AnyTypeAnnotation": [],
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
else callback("fail", test.code,
|
||||
"Expected error message: " + test.error + "\nGot error message: " + e.message);
|
||||
} else {
|
||||
callback("error", test.code, e.message || e.toString());
|
||||
callback("error", test.code, e.stack || e.toString());
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -2789,18 +2789,89 @@ test('class Foo { @bar static foo = "bar"; }', {
|
||||
|
||||
// ES7 export extensions - https://github.com/leebyron/ecmascript-more-export-from
|
||||
|
||||
test('export foo, { bar } from "bar";', {
|
||||
type: "Program",
|
||||
body: [{
|
||||
type: "ExportNamedDeclaration",
|
||||
start: 0,
|
||||
end: 31,
|
||||
specifiers: [{
|
||||
type: "ExportDefaultSpecifier",
|
||||
exported: {
|
||||
type: "Identifier",
|
||||
name: "foo",
|
||||
start: 7,
|
||||
end: 10,
|
||||
}
|
||||
}, {
|
||||
type: "ExportSpecifier",
|
||||
exported: {
|
||||
type: "Identifier",
|
||||
name: "bar"
|
||||
}
|
||||
}],
|
||||
source: {
|
||||
type: "Literal",
|
||||
value: "bar",
|
||||
start: 25,
|
||||
end: 30
|
||||
}
|
||||
}]
|
||||
}, {
|
||||
ecmaVersion: 7,
|
||||
sourceType: "module",
|
||||
features: { "es7.exportExtensions": true }
|
||||
});
|
||||
|
||||
test('export * as foo, { bar } from "bar";', {
|
||||
type: "Program",
|
||||
body: [{
|
||||
type: "ExportNamedDeclaration",
|
||||
start: 0,
|
||||
end: 36,
|
||||
specifiers: [{
|
||||
type: "ExportNamespaceSpecifier",
|
||||
exported: {
|
||||
type: "Identifier",
|
||||
name: "foo",
|
||||
start: 12,
|
||||
end: 15,
|
||||
}
|
||||
}, {
|
||||
type: "ExportSpecifier",
|
||||
exported: {
|
||||
type: "Identifier",
|
||||
name: "bar"
|
||||
}
|
||||
}],
|
||||
source: {
|
||||
type: "Literal",
|
||||
value: "bar",
|
||||
start: 30,
|
||||
end: 35
|
||||
}
|
||||
}]
|
||||
}, {
|
||||
ecmaVersion: 7,
|
||||
sourceType: "module",
|
||||
features: { "es7.exportExtensions": true }
|
||||
});
|
||||
|
||||
test('export foo from "bar";', {
|
||||
type: "Program",
|
||||
body: [{
|
||||
type: "ExportNamespaceDeclaration",
|
||||
type: "ExportNamedDeclaration",
|
||||
start: 0,
|
||||
end: 22,
|
||||
exported: {
|
||||
type: "Identifier",
|
||||
name: "foo",
|
||||
start: 7,
|
||||
end: 10,
|
||||
},
|
||||
specifiers: [{
|
||||
type: "ExportDefaultSpecifier",
|
||||
exported: {
|
||||
type: "Identifier",
|
||||
name: "foo",
|
||||
start: 7,
|
||||
end: 10,
|
||||
}
|
||||
}],
|
||||
source: {
|
||||
type: "Literal",
|
||||
value: "bar",
|
||||
@@ -2814,18 +2885,49 @@ test('export foo from "bar";', {
|
||||
features: { "es7.exportExtensions": true }
|
||||
});
|
||||
|
||||
test('export default from "bar";', {
|
||||
type: "Program",
|
||||
body: [{
|
||||
type: "ExportNamedDeclaration",
|
||||
start: 0,
|
||||
end: 26,
|
||||
specifiers: [{
|
||||
type: "ExportDefaultSpecifier",
|
||||
exported: {
|
||||
type: "Identifier",
|
||||
name: "default",
|
||||
start: 7,
|
||||
end: 14,
|
||||
}
|
||||
}],
|
||||
source: {
|
||||
type: "Literal",
|
||||
value: "bar",
|
||||
start: 20,
|
||||
end: 25
|
||||
}
|
||||
}]
|
||||
}, {
|
||||
ecmaVersion: 7,
|
||||
sourceType: "module",
|
||||
features: { "es7.exportExtensions": true }
|
||||
});
|
||||
|
||||
test('export * as foo from "bar";', {
|
||||
type: "Program",
|
||||
body: [{
|
||||
type: "ExportAllDeclaration",
|
||||
type: "ExportNamedDeclaration",
|
||||
start: 0,
|
||||
end: 27,
|
||||
exported: {
|
||||
type: "Identifier",
|
||||
name: "foo",
|
||||
start: 12,
|
||||
end: 15,
|
||||
},
|
||||
specifiers: [{
|
||||
type: "ExportNamespaceSpecifier",
|
||||
exported: {
|
||||
type: "Identifier",
|
||||
name: "foo",
|
||||
start: 12,
|
||||
end: 15,
|
||||
}
|
||||
}],
|
||||
source: {
|
||||
type: "Literal",
|
||||
value: "bar",
|
||||
|
||||
@@ -9,6 +9,8 @@ export default class Foo {}
|
||||
export * from "foo";
|
||||
export * as foo from "foo";
|
||||
export foo from "foo";
|
||||
export * as foo, { bar } from "foo";
|
||||
export foo, { bar } from "foo";
|
||||
export { foo } from "foo";
|
||||
export { foo, bar } from "foo";
|
||||
export { foo as bar } from "foo";
|
||||
|
||||
@@ -2,13 +2,15 @@ export default 42;
|
||||
export default {};
|
||||
export default [];
|
||||
export default foo;
|
||||
export default function () {};
|
||||
export default class {};
|
||||
export default function () {}
|
||||
export default class {}
|
||||
export default function foo() {}
|
||||
export default class Foo {}
|
||||
export * from "foo";
|
||||
export * as foo from "foo";
|
||||
export foo from "foo";
|
||||
export * as foo, { bar } from "foo";
|
||||
export foo, { bar } from "foo";
|
||||
export { foo } from "foo";
|
||||
export { foo, bar } from "foo";
|
||||
export { foo as bar } from "foo";
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
"use strict";
|
||||
|
||||
var _default = babelHelpers.interopRequire(require("bar"));
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
module.exports = _default;
|
||||
var _foo = require("bar").foo;
|
||||
|
||||
exports.foo = _foo;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"use strict";
|
||||
|
||||
import _default from "bar";
|
||||
export default _default;
|
||||
import { foo as _foo } from "bar";
|
||||
export { _foo as foo };
|
||||
|
||||
Reference in New Issue
Block a user