From 69f93fe116b95acd0e4072fc9b2ebe0c17c0ee1f Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 10 Jul 2015 16:27:40 -0700 Subject: [PATCH] Added error recovery for missing 'from' keyword in an export declaration. --- src/compiler/parser.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 3635a88b608..c01e1036a0d 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -4345,6 +4345,10 @@ namespace ts { } } + function nextTokenIsStringLiteralOnSameLine() { + return !scanner.hasPrecedingLineBreak() && token === SyntaxKind.StringLiteral; + } + function nextTokenIsIdentifierOrStringLiteralOnSameLine() { nextToken(); return !scanner.hasPrecedingLineBreak() && (isIdentifier() || token === SyntaxKind.StringLiteral); @@ -5135,7 +5139,12 @@ namespace ts { } else { node.exportClause = parseNamedImportsOrExports(SyntaxKind.NamedExports); - if (parseOptional(SyntaxKind.FromKeyword)) { + + // It is not uncommon to accidentally omit the 'from' keyword. Additionally, in editing scenarios, + // the 'from' keyword be parsed as a named export when the export clause is unterminated (i.e. `export { from "moduleName";`) + // If we don't have a 'from' keyword, see if we have a string literal such that ASI won't take effect. + if (token === SyntaxKind.FromKeyword || lookAhead(nextTokenIsStringLiteralOnSameLine)) { + parseExpected(SyntaxKind.FromKeyword) node.moduleSpecifier = parseModuleSpecifier(); } }