fix incorrect interpreation of export default shorthand, update to new ast definitions - #1091

This commit is contained in:
Sebastian McKenzie
2015-03-30 06:08:37 +11:00
parent eb2f61e43f
commit f9c8d7d1fd
12 changed files with 232 additions and 77 deletions

View File

@@ -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()

View File

@@ -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 ");

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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"],

View File

@@ -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": [],