Refactor unambiguous to track state during parsing.

This commit is contained in:
Logan Smyth
2018-03-09 14:35:55 -08:00
parent b5e6536f26
commit 958551fd89
3 changed files with 21 additions and 15 deletions

View File

@@ -22,11 +22,12 @@ export function parse(input: string, options?: Options): File {
options = Object.assign({}, options);
try {
options.sourceType = "module";
const ast = getParser(options, input).parse();
const parser = getParser(options, input);
const ast = parser.parse();
// Rather than try to parse as a script first, we opt to parse as a module and convert back
// to a script where possible to avoid having to do a full re-parse of the input content.
if (!hasModuleSyntax(ast)) ast.program.sourceType = "script";
if (!parser.sawUnambiguousESM) ast.program.sourceType = "script";
return ast;
} catch (moduleError) {
try {
@@ -111,16 +112,3 @@ function getParserClass(
}
return cls;
}
function hasModuleSyntax(ast) {
return ast.program.body.some(
child =>
(child.type === "ImportDeclaration" &&
(!child.importKind || child.importKind === "value")) ||
(child.type === "ExportNamedDeclaration" &&
(!child.exportKind || child.exportKind === "value")) ||
(child.type === "ExportAllDeclaration" &&
(!child.exportKind || child.exportKind === "value")) ||
child.type === "ExportDefaultDeclaration",
);
}

View File

@@ -11,6 +11,7 @@ export default class BaseParser {
inModule: boolean;
plugins: { [key: string]: boolean };
filename: ?string;
sawUnambiguousESM: boolean = false;
// Initialized by Tokenizer
state: State;

View File

@@ -146,8 +146,25 @@ export default class StatementParser extends ExpressionParser {
let result;
if (starttype == tt._import) {
result = this.parseImport(node);
if (
result.type === "ImportDeclaration" &&
(!result.importKind || result.importKind === "value")
) {
this.sawUnambiguousESM = true;
}
} else {
result = this.parseExport(node);
if (
(result.type === "ExportNamedDeclaration" &&
(!result.exportKind || result.exportKind === "value")) ||
(result.type === "ExportAllDeclaration" &&
(!result.exportKind || result.exportKind === "value")) ||
result.type === "ExportDefaultDeclaration"
) {
this.sawUnambiguousESM = true;
}
}
this.assertModuleNodeAllowed(node);