mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-30 01:04:49 -05:00
Fix parser regression for bad related diagnostic on missing matching brackets (#44158)
* Revert "Revert #43460 and #40884 (#44175)"
This reverts commit 5770434891.
* fix missing opening brace match error
* refactor parseExpectedMatchingBrackets
* use getNodePos
* accept baselines
* delete mistakenly added files
* Revert getNodePos addition
Co-authored-by: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
"category": "Error",
|
||||
"code": 1006
|
||||
},
|
||||
"The parser expected to find a '}' to match the '{' token here.": {
|
||||
"The parser expected to find a '{1}' to match the '{0}' token here.": {
|
||||
"category": "Error",
|
||||
"code": 1007
|
||||
},
|
||||
|
||||
@@ -1434,24 +1434,27 @@ namespace ts {
|
||||
return inContext(NodeFlags.AwaitContext);
|
||||
}
|
||||
|
||||
function parseErrorAtCurrentToken(message: DiagnosticMessage, arg0?: any): void {
|
||||
parseErrorAt(scanner.getTokenPos(), scanner.getTextPos(), message, arg0);
|
||||
function parseErrorAtCurrentToken(message: DiagnosticMessage, arg0?: any): DiagnosticWithDetachedLocation | undefined {
|
||||
return parseErrorAt(scanner.getTokenPos(), scanner.getTextPos(), message, arg0);
|
||||
}
|
||||
|
||||
function parseErrorAtPosition(start: number, length: number, message: DiagnosticMessage, arg0?: any): void {
|
||||
function parseErrorAtPosition(start: number, length: number, message: DiagnosticMessage, arg0?: any): DiagnosticWithDetachedLocation | undefined {
|
||||
// Don't report another error if it would just be at the same position as the last error.
|
||||
const lastError = lastOrUndefined(parseDiagnostics);
|
||||
let result: DiagnosticWithDetachedLocation | undefined;
|
||||
if (!lastError || start !== lastError.start) {
|
||||
parseDiagnostics.push(createDetachedDiagnostic(fileName, start, length, message, arg0));
|
||||
result = createDetachedDiagnostic(fileName, start, length, message, arg0);
|
||||
parseDiagnostics.push(result);
|
||||
}
|
||||
|
||||
// Mark that we've encountered an error. We'll set an appropriate bit on the next
|
||||
// node we finish so that it can't be reused incrementally.
|
||||
parseErrorBeforeNextFinishedNode = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
function parseErrorAt(start: number, end: number, message: DiagnosticMessage, arg0?: any): void {
|
||||
parseErrorAtPosition(start, end - start, message, arg0);
|
||||
function parseErrorAt(start: number, end: number, message: DiagnosticMessage, arg0?: any): DiagnosticWithDetachedLocation | undefined {
|
||||
return parseErrorAtPosition(start, end - start, message, arg0);
|
||||
}
|
||||
|
||||
function parseErrorAtRange(range: TextRange, message: DiagnosticMessage, arg0?: any): void {
|
||||
@@ -1779,6 +1782,23 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
function parseExpectedMatchingBrackets(openKind: SyntaxKind, closeKind: SyntaxKind, openParsed: boolean, openPosition: number) {
|
||||
if (token() === closeKind) {
|
||||
nextToken();
|
||||
return;
|
||||
}
|
||||
const lastError = parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(closeKind));
|
||||
if (!openParsed) {
|
||||
return;
|
||||
}
|
||||
if (lastError) {
|
||||
addRelatedInfo(
|
||||
lastError,
|
||||
createDetachedDiagnostic(fileName, openPosition, 1, Diagnostics.The_parser_expected_to_find_a_1_to_match_the_0_token_here, tokenToString(openKind), tokenToString(closeKind))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function parseOptional(t: SyntaxKind): boolean {
|
||||
if (token() === t) {
|
||||
nextToken();
|
||||
@@ -3739,7 +3759,7 @@ namespace ts {
|
||||
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)
|
||||
createDetachedDiagnostic(fileName, openBracePosition, 1, Diagnostics.The_parser_expected_to_find_a_1_to_match_the_0_token_here, "{", "}")
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -5772,10 +5792,11 @@ namespace ts {
|
||||
|
||||
function parseArrayLiteralExpression(): ArrayLiteralExpression {
|
||||
const pos = getNodePos();
|
||||
parseExpected(SyntaxKind.OpenBracketToken);
|
||||
const openBracketPosition = scanner.getTokenPos();
|
||||
const openBracketParsed = parseExpected(SyntaxKind.OpenBracketToken);
|
||||
const multiLine = scanner.hasPrecedingLineBreak();
|
||||
const elements = parseDelimitedList(ParsingContext.ArrayLiteralMembers, parseArgumentOrArrayLiteralElement);
|
||||
parseExpected(SyntaxKind.CloseBracketToken);
|
||||
parseExpectedMatchingBrackets(SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken, openBracketParsed, openBracketPosition);
|
||||
return finishNode(factory.createArrayLiteralExpression(elements, multiLine), pos);
|
||||
}
|
||||
|
||||
@@ -5841,18 +5862,10 @@ namespace ts {
|
||||
function parseObjectLiteralExpression(): ObjectLiteralExpression {
|
||||
const pos = getNodePos();
|
||||
const openBracePosition = scanner.getTokenPos();
|
||||
parseExpected(SyntaxKind.OpenBraceToken);
|
||||
const openBraceParsed = parseExpected(SyntaxKind.OpenBraceToken);
|
||||
const multiLine = scanner.hasPrecedingLineBreak();
|
||||
const properties = parseDelimitedList(ParsingContext.ObjectLiteralMembers, parseObjectLiteralElement, /*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)
|
||||
);
|
||||
}
|
||||
}
|
||||
parseExpectedMatchingBrackets(SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken, openBraceParsed, openBracePosition);
|
||||
return finishNode(factory.createObjectLiteralExpression(properties, multiLine), pos);
|
||||
}
|
||||
|
||||
@@ -5916,18 +5929,11 @@ namespace ts {
|
||||
const pos = getNodePos();
|
||||
const hasJSDoc = hasPrecedingJSDocComment();
|
||||
const openBracePosition = scanner.getTokenPos();
|
||||
if (parseExpected(SyntaxKind.OpenBraceToken, diagnosticMessage) || ignoreMissingOpenBrace) {
|
||||
const openBraceParsed = parseExpected(SyntaxKind.OpenBraceToken, diagnosticMessage);
|
||||
if (openBraceParsed || ignoreMissingOpenBrace) {
|
||||
const multiLine = scanner.hasPrecedingLineBreak();
|
||||
const statements = parseList(ParsingContext.BlockStatements, parseStatement);
|
||||
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)
|
||||
);
|
||||
}
|
||||
}
|
||||
parseExpectedMatchingBrackets(SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken, openBraceParsed, openBracePosition);
|
||||
const result = withJSDoc(finishNode(factory.createBlock(statements, multiLine), pos), hasJSDoc);
|
||||
if (token() === SyntaxKind.EqualsToken) {
|
||||
parseErrorAtCurrentToken(Diagnostics.Declaration_or_statement_expected_This_follows_a_block_of_statements_so_if_you_intended_to_write_a_destructuring_assignment_you_might_need_to_wrap_the_the_whole_assignment_in_parentheses);
|
||||
@@ -5983,9 +5989,10 @@ namespace ts {
|
||||
const pos = getNodePos();
|
||||
const hasJSDoc = hasPrecedingJSDocComment();
|
||||
parseExpected(SyntaxKind.IfKeyword);
|
||||
parseExpected(SyntaxKind.OpenParenToken);
|
||||
const openParenPosition = scanner.getTokenPos();
|
||||
const openParenParsed = parseExpected(SyntaxKind.OpenParenToken);
|
||||
const expression = allowInAnd(parseExpression);
|
||||
parseExpected(SyntaxKind.CloseParenToken);
|
||||
parseExpectedMatchingBrackets(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, openParenParsed, openParenPosition);
|
||||
const thenStatement = parseStatement();
|
||||
const elseStatement = parseOptional(SyntaxKind.ElseKeyword) ? parseStatement() : undefined;
|
||||
return withJSDoc(finishNode(factory.createIfStatement(expression, thenStatement, elseStatement), pos), hasJSDoc);
|
||||
@@ -5997,9 +6004,10 @@ namespace ts {
|
||||
parseExpected(SyntaxKind.DoKeyword);
|
||||
const statement = parseStatement();
|
||||
parseExpected(SyntaxKind.WhileKeyword);
|
||||
parseExpected(SyntaxKind.OpenParenToken);
|
||||
const openParenPosition = scanner.getTokenPos();
|
||||
const openParenParsed = parseExpected(SyntaxKind.OpenParenToken);
|
||||
const expression = allowInAnd(parseExpression);
|
||||
parseExpected(SyntaxKind.CloseParenToken);
|
||||
parseExpectedMatchingBrackets(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, openParenParsed, openParenPosition);
|
||||
|
||||
// From: https://mail.mozilla.org/pipermail/es-discuss/2011-August/016188.html
|
||||
// 157 min --- All allen at wirfs-brock.com CONF --- "do{;}while(false)false" prohibited in
|
||||
@@ -6013,9 +6021,10 @@ namespace ts {
|
||||
const pos = getNodePos();
|
||||
const hasJSDoc = hasPrecedingJSDocComment();
|
||||
parseExpected(SyntaxKind.WhileKeyword);
|
||||
parseExpected(SyntaxKind.OpenParenToken);
|
||||
const openParenPosition = scanner.getTokenPos();
|
||||
const openParenParsed = parseExpected(SyntaxKind.OpenParenToken);
|
||||
const expression = allowInAnd(parseExpression);
|
||||
parseExpected(SyntaxKind.CloseParenToken);
|
||||
parseExpectedMatchingBrackets(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, openParenParsed, openParenPosition);
|
||||
const statement = parseStatement();
|
||||
return withJSDoc(finishNode(factory.createWhileStatement(expression, statement), pos), hasJSDoc);
|
||||
}
|
||||
@@ -6091,9 +6100,10 @@ namespace ts {
|
||||
const pos = getNodePos();
|
||||
const hasJSDoc = hasPrecedingJSDocComment();
|
||||
parseExpected(SyntaxKind.WithKeyword);
|
||||
parseExpected(SyntaxKind.OpenParenToken);
|
||||
const openParenPosition = scanner.getTokenPos();
|
||||
const openParenParsed = parseExpected(SyntaxKind.OpenParenToken);
|
||||
const expression = allowInAnd(parseExpression);
|
||||
parseExpected(SyntaxKind.CloseParenToken);
|
||||
parseExpectedMatchingBrackets(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, openParenParsed, openParenPosition);
|
||||
const statement = doInsideOfContext(NodeFlags.InWithStatement, parseStatement);
|
||||
return withJSDoc(finishNode(factory.createWithStatement(expression, statement), pos), hasJSDoc);
|
||||
}
|
||||
@@ -7398,7 +7408,7 @@ namespace ts {
|
||||
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)
|
||||
createDetachedDiagnostic(fileName, openBracePosition, 1, Diagnostics.The_parser_expected_to_find_a_1_to_match_the_0_token_here, "{", "}")
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -8453,13 +8463,9 @@ namespace ts {
|
||||
hasChildren = true;
|
||||
if (child.kind === SyntaxKind.JSDocTypeTag) {
|
||||
if (childTypeTag) {
|
||||
parseErrorAtCurrentToken(Diagnostics.A_JSDoc_typedef_comment_may_not_contain_multiple_type_tags);
|
||||
const lastError = lastOrUndefined(parseDiagnostics);
|
||||
const lastError = parseErrorAtCurrentToken(Diagnostics.A_JSDoc_typedef_comment_may_not_contain_multiple_type_tags);
|
||||
if (lastError) {
|
||||
addRelatedInfo(
|
||||
lastError,
|
||||
createDetachedDiagnostic(fileName, 0, 0, Diagnostics.The_tag_was_first_specified_here)
|
||||
);
|
||||
addRelatedInfo(lastError, createDetachedDiagnostic(fileName, 0, 0, Diagnostics.The_tag_was_first_specified_here));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user