Import assertion: do no parse } if { is not present (#46388)

Previously, import assertion parsing would try to parse both { and },
even if both were missing. If both were missing, the error for } could
occur past the end of the file, causing an assertion.

Fixes #46364
This commit is contained in:
Nathan Shively-Sanders
2021-10-15 13:26:46 -07:00
committed by GitHub
parent 7582b1bbae
commit 6a75689a25
11 changed files with 71 additions and 11 deletions

View File

@@ -7277,19 +7277,24 @@ namespace ts {
const pos = getNodePos();
parseExpected(SyntaxKind.AssertKeyword);
const openBracePosition = scanner.getTokenPos();
parseExpected(SyntaxKind.OpenBraceToken);
const multiLine = scanner.hasPrecedingLineBreak();
const elements = parseDelimitedList(ParsingContext.AssertEntries, parseAssertEntry, /*considerSemicolonAsDelimiter*/ true);
if (!parseExpected(SyntaxKind.CloseBraceToken)) {
const lastError = lastOrUndefined(parseDiagnostics);
if (lastError && lastError.code === Diagnostics._0_expected.code) {
addRelatedInfo(
lastError,
createDetachedDiagnostic(fileName, openBracePosition, 1, Diagnostics.The_parser_expected_to_find_a_to_match_the_token_here)
);
if (parseExpected(SyntaxKind.OpenBraceToken)) {
const multiLine = scanner.hasPrecedingLineBreak();
const elements = parseDelimitedList(ParsingContext.AssertEntries, parseAssertEntry, /*considerSemicolonAsDelimiter*/ true);
if (!parseExpected(SyntaxKind.CloseBraceToken)) {
const lastError = lastOrUndefined(parseDiagnostics);
if (lastError && lastError.code === Diagnostics._0_expected.code) {
addRelatedInfo(
lastError,
createDetachedDiagnostic(fileName, openBracePosition, 1, Diagnostics.The_parser_expected_to_find_a_to_match_the_token_here)
);
}
}
return finishNode(factory.createAssertClause(elements, multiLine), pos);
}
else {
const elements = createNodeArray([], getNodePos(), /*end*/ undefined, /*hasTrailingComma*/ false);
return finishNode(factory.createAssertClause(elements, /*multiLine*/ false), pos);
}
return finishNode(factory.createAssertClause(elements, multiLine), pos);
}
function tokenAfterImportDefinitelyProducesImportDeclaration() {