Check exported bindings are defined (#9589)

* Check exported bindings are defined

* Add tests

* Update flow whitelist

* Add tests for builtins
This commit is contained in:
Daniel Tschinder
2019-02-26 13:28:10 -08:00
committed by GitHub
parent e883ff295d
commit 43eed1ac92
81 changed files with 1594 additions and 315 deletions

View File

@@ -49,6 +49,14 @@ export default class StatementParser extends ExpressionParser {
this.parseBlockBody(program, true, true, tt.eof);
if (this.inModule && this.scope.undefinedExports.size > 0) {
for (const [name] of Array.from(this.scope.undefinedExports)) {
const pos = this.scope.undefinedExports.get(name);
// $FlowIssue
this.raise(pos, `Export '${name}' is not defined`);
}
}
file.program = this.finishNode(program, "Program");
file.comments = this.state.comments;
@@ -1631,7 +1639,7 @@ export default class StatementParser extends ExpressionParser {
}
if (isFromRequired || hasSpecifiers || hasDeclaration) {
this.checkExport(node, true);
this.checkExport(node, true, false, !!node.source);
return this.finishNode(node, "ExportNamedDeclaration");
}
@@ -1845,8 +1853,9 @@ export default class StatementParser extends ExpressionParser {
checkExport(
node: N.ExportNamedDeclaration,
checkNames: ?boolean,
checkNames?: boolean,
isDefault?: boolean,
isFrom?: boolean,
): void {
if (checkNames) {
// Check for duplicate exports
@@ -1857,6 +1866,11 @@ export default class StatementParser extends ExpressionParser {
// Named exports
for (const specifier of node.specifiers) {
this.checkDuplicateExports(specifier, specifier.exported.name);
// check if export is defined
// $FlowIgnore
if (!isFrom && specifier.local) {
this.scope.checkLocalExport(specifier.local);
}
}
} else if (node.declaration) {
// Exported declarations