parent
4e1fbd48d5
commit
650e33376a
@ -844,7 +844,7 @@ pp.parseExport = function (node) {
|
||||
}
|
||||
node.declaration = expr;
|
||||
if (needsSemi) this.semicolon();
|
||||
this.checkExport(node);
|
||||
this.checkExport(node, true, true);
|
||||
return this.finishNode(node, "ExportDefaultDeclaration");
|
||||
} else if (this.state.type.keyword || this.shouldParseExportDeclaration()) {
|
||||
node.specifiers = [];
|
||||
@ -855,7 +855,7 @@ pp.parseExport = function (node) {
|
||||
node.specifiers = this.parseExportSpecifiers();
|
||||
this.parseExportFrom(node);
|
||||
}
|
||||
this.checkExport(node);
|
||||
this.checkExport(node, true);
|
||||
return this.finishNode(node, "ExportNamedDeclaration");
|
||||
};
|
||||
|
||||
@ -903,7 +903,31 @@ pp.shouldParseExportDeclaration = function () {
|
||||
return this.isContextual("async");
|
||||
};
|
||||
|
||||
pp.checkExport = function (node) {
|
||||
pp.checkExport = function (node, checkNames, isDefault) {
|
||||
if (checkNames) {
|
||||
// Check for duplicate exports
|
||||
if (isDefault) {
|
||||
// Default exports
|
||||
this.checkDuplicateExports(node, "default", isDefault);
|
||||
} else if (node.specifiers && node.specifiers.length) {
|
||||
// Named exports
|
||||
for (let specifier of node.specifiers) {
|
||||
const name = specifier.exported.name;
|
||||
if (name === "default") isDefault = true;
|
||||
this.checkDuplicateExports(specifier, name, isDefault);
|
||||
}
|
||||
} else if (node.declaration) {
|
||||
// Exported declarations
|
||||
if (node.declaration.type === "FunctionDeclaration" || node.declaration.type === "ClassDeclaration") {
|
||||
this.checkDuplicateExports(node, node.declaration.id.name, isDefault);
|
||||
} else if (node.declaration.type === "VariableDeclaration") {
|
||||
for (let declaration of node.declaration.declarations) {
|
||||
this.checkDuplicateExports(declaration, declaration.id.name, isDefault);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.state.decorators.length) {
|
||||
let isClass = node.declaration && (node.declaration.type === "ClassDeclaration" || node.declaration.type === "ClassExpression");
|
||||
if (!node.declaration || !isClass) {
|
||||
@ -913,6 +937,20 @@ pp.checkExport = function (node) {
|
||||
}
|
||||
};
|
||||
|
||||
pp.checkDuplicateExports = function(node, name, isDefault) {
|
||||
if (this.state.exportedIdentifiers[name]) {
|
||||
this.raiseDuplicateExportError(node, name, isDefault);
|
||||
}
|
||||
this.state.exportedIdentifiers[name] = true;
|
||||
};
|
||||
|
||||
pp.raiseDuplicateExportError = function(node, name, isDefault) {
|
||||
this.raise(node.start, isDefault ?
|
||||
"Only one default export allowed per module." :
|
||||
`\`${name}\` has already been exported. Exported identifiers must be unique.`
|
||||
);
|
||||
};
|
||||
|
||||
// Parses a comma-separated list of module exports.
|
||||
|
||||
pp.parseExportSpecifiers = function () {
|
||||
|
||||
@ -43,6 +43,8 @@ export default class State {
|
||||
this.containsEsc = this.containsOctal = false;
|
||||
this.octalPosition = null;
|
||||
|
||||
this.exportedIdentifiers = {};
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -119,6 +121,10 @@ export default class State {
|
||||
containsOctal: boolean;
|
||||
octalPosition: ?number;
|
||||
|
||||
// Names of exports store. `default` is stored as a name for both
|
||||
// `export default foo;` and `export { foo as default };`.
|
||||
exportedIdentifiers: {[id:string]: boolean};
|
||||
|
||||
curPosition() {
|
||||
return new Position(this.curLine, this.pos - this.lineStart);
|
||||
}
|
||||
|
||||
2
test/fixtures/es2015/modules/duplicate-export-default-and-export-as-default/actual.js
vendored
Normal file
2
test/fixtures/es2015/modules/duplicate-export-default-and-export-as-default/actual.js
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
export default function() {};
|
||||
export { foo as default };
|
||||
3
test/fixtures/es2015/modules/duplicate-export-default-and-export-as-default/options.json
vendored
Normal file
3
test/fixtures/es2015/modules/duplicate-export-default-and-export-as-default/options.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"throws": "Only one default export allowed per module. (2:9)"
|
||||
}
|
||||
2
test/fixtures/es2015/modules/duplicate-export-default/actual.js
vendored
Normal file
2
test/fixtures/es2015/modules/duplicate-export-default/actual.js
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
export default {};
|
||||
export default function() {};
|
||||
3
test/fixtures/es2015/modules/duplicate-export-default/options.json
vendored
Normal file
3
test/fixtures/es2015/modules/duplicate-export-default/options.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"throws": "Only one default export allowed per module. (2:0)"
|
||||
}
|
||||
2
test/fixtures/es2015/modules/duplicate-named-export-class-declaration/actual.js
vendored
Normal file
2
test/fixtures/es2015/modules/duplicate-named-export-class-declaration/actual.js
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
export { Foo };
|
||||
export class Foo {};
|
||||
4
test/fixtures/es2015/modules/duplicate-named-export-class-declaration/options.json
vendored
Normal file
4
test/fixtures/es2015/modules/duplicate-named-export-class-declaration/options.json
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"throws": "`Foo` has already been exported. Exported identifiers must be unique. (2:0)"
|
||||
}
|
||||
|
||||
2
test/fixtures/es2015/modules/duplicate-named-export-function-declaration/actual.js
vendored
Normal file
2
test/fixtures/es2015/modules/duplicate-named-export-function-declaration/actual.js
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
export { foo };
|
||||
export function foo() {};
|
||||
3
test/fixtures/es2015/modules/duplicate-named-export-function-declaration/options.json
vendored
Normal file
3
test/fixtures/es2015/modules/duplicate-named-export-function-declaration/options.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"throws": "`foo` has already been exported. Exported identifiers must be unique. (2:0)"
|
||||
}
|
||||
2
test/fixtures/es2015/modules/duplicate-named-export-variable-declaration/actual.js
vendored
Normal file
2
test/fixtures/es2015/modules/duplicate-named-export-variable-declaration/actual.js
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
export { foo };
|
||||
export const foo = bar;
|
||||
3
test/fixtures/es2015/modules/duplicate-named-export-variable-declaration/options.json
vendored
Normal file
3
test/fixtures/es2015/modules/duplicate-named-export-variable-declaration/options.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"throws": "`foo` has already been exported. Exported identifiers must be unique. (2:13)"
|
||||
}
|
||||
2
test/fixtures/es2015/modules/duplicate-named-export/actual.js
vendored
Normal file
2
test/fixtures/es2015/modules/duplicate-named-export/actual.js
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
export { foo };
|
||||
export { bar as foo };
|
||||
3
test/fixtures/es2015/modules/duplicate-named-export/options.json
vendored
Normal file
3
test/fixtures/es2015/modules/duplicate-named-export/options.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"throws": "`foo` has already been exported. Exported identifiers must be unique. (2:9)"
|
||||
}
|
||||
@ -1,2 +1,2 @@
|
||||
export interface foo { p: number };
|
||||
export interface foo<T> { p: T };
|
||||
export interface bar<T> { p: T };
|
||||
|
||||
@ -206,7 +206,7 @@
|
||||
"column": 20
|
||||
}
|
||||
},
|
||||
"name": "foo"
|
||||
"name": "bar"
|
||||
},
|
||||
"typeParameters": {
|
||||
"type": "TypeParameterDeclaration",
|
||||
@ -346,4 +346,4 @@
|
||||
],
|
||||
"directives": []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user