From e38a0cefab21a68f91718e35af29398db4e4d689 Mon Sep 17 00:00:00 2001 From: Jesse Trinity Date: Thu, 27 May 2021 13:16:04 -0700 Subject: [PATCH] fix missing opening brace match error --- src/compiler/parser.ts | 34 +++++++++++-------- .../reference/reservedWords2.errors.txt | 2 -- .../smartIndentMissingBracketsDoKeyword.ts | 7 ++++ .../smartIndentMissingBracketsIfKeyword.ts | 7 ++++ .../smartIndentMissingBracketsWhileKeyword.ts | 7 ++++ .../smartIndentMissingBracketsWithKeyword.ts | 7 ++++ 6 files changed, 47 insertions(+), 17 deletions(-) create mode 100644 tests/cases/fourslash/smartIndentMissingBracketsDoKeyword.ts create mode 100644 tests/cases/fourslash/smartIndentMissingBracketsIfKeyword.ts create mode 100644 tests/cases/fourslash/smartIndentMissingBracketsWhileKeyword.ts create mode 100644 tests/cases/fourslash/smartIndentMissingBracketsWithKeyword.ts diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 80bea252a5e..ed200683849 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1555,7 +1555,10 @@ namespace ts { return false; } - function parseExpectedMatchingBrackets(openKind: SyntaxKind, closeKind: SyntaxKind, openPosition: number) { + function parseExpectedMatchingBrackets(openKind: SyntaxKind, closeKind: SyntaxKind, openParsed: boolean, openPosition: number) { + if (!openParsed) { + return parseExpected(closeKind); + } if (token() === closeKind) { nextToken(); return; @@ -5499,10 +5502,10 @@ namespace ts { function parseArrayLiteralExpression(): ArrayLiteralExpression { const pos = getNodePos(); const openBracketPosition = scanner.getTokenPos(); - parseExpected(SyntaxKind.OpenBracketToken); + const openBracketParsed = parseExpected(SyntaxKind.OpenBracketToken); const multiLine = scanner.hasPrecedingLineBreak(); const elements = parseDelimitedList(ParsingContext.ArrayLiteralMembers, parseArgumentOrArrayLiteralElement); - parseExpectedMatchingBrackets(SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken, openBracketPosition); + parseExpectedMatchingBrackets(SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken, openBracketParsed, openBracketPosition); return finishNode(factory.createArrayLiteralExpression(elements, multiLine), pos); } @@ -5568,10 +5571,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); - parseExpectedMatchingBrackets(SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken, openBracePosition); + parseExpectedMatchingBrackets(SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken, openBraceParsed, openBracePosition); return finishNode(factory.createObjectLiteralExpression(properties, multiLine), pos); } @@ -5654,10 +5657,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); - parseExpectedMatchingBrackets(SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken, openBracePosition); + 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); @@ -5714,9 +5718,9 @@ namespace ts { const hasJSDoc = hasPrecedingJSDocComment(); parseExpected(SyntaxKind.IfKeyword); const openParenPosition = scanner.getTokenPos(); - parseExpected(SyntaxKind.OpenParenToken); + const openParenParsed = parseExpected(SyntaxKind.OpenParenToken); const expression = allowInAnd(parseExpression); - parseExpectedMatchingBrackets(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, openParenPosition); + 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); @@ -5729,9 +5733,9 @@ namespace ts { const statement = parseStatement(); parseExpected(SyntaxKind.WhileKeyword); const openParenPosition = scanner.getTokenPos(); - parseExpected(SyntaxKind.OpenParenToken); + const openParenParsed = parseExpected(SyntaxKind.OpenParenToken); const expression = allowInAnd(parseExpression); - parseExpectedMatchingBrackets(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, openParenPosition); + 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 @@ -5746,9 +5750,9 @@ namespace ts { const hasJSDoc = hasPrecedingJSDocComment(); parseExpected(SyntaxKind.WhileKeyword); const openParenPosition = scanner.getTokenPos(); - parseExpected(SyntaxKind.OpenParenToken); + const openParenParsed = parseExpected(SyntaxKind.OpenParenToken); const expression = allowInAnd(parseExpression); - parseExpectedMatchingBrackets(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, openParenPosition); + parseExpectedMatchingBrackets(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, openParenParsed, openParenPosition); const statement = parseStatement(); return withJSDoc(finishNode(factory.createWhileStatement(expression, statement), pos), hasJSDoc); } @@ -5825,9 +5829,9 @@ namespace ts { const hasJSDoc = hasPrecedingJSDocComment(); parseExpected(SyntaxKind.WithKeyword); const openParenPosition = scanner.getTokenPos(); - parseExpected(SyntaxKind.OpenParenToken); + const openParenParsed = parseExpected(SyntaxKind.OpenParenToken); const expression = allowInAnd(parseExpression); - parseExpectedMatchingBrackets(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, openParenPosition); + parseExpectedMatchingBrackets(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, openParenParsed, openParenPosition); const statement = doInsideOfContext(NodeFlags.InWithStatement, parseStatement); return withJSDoc(finishNode(factory.createWithStatement(expression, statement), pos), hasJSDoc); } diff --git a/tests/baselines/reference/reservedWords2.errors.txt b/tests/baselines/reference/reservedWords2.errors.txt index 6ecb9471631..599010b4368 100644 --- a/tests/baselines/reference/reservedWords2.errors.txt +++ b/tests/baselines/reference/reservedWords2.errors.txt @@ -45,7 +45,6 @@ tests/cases/compiler/reservedWords2.ts(12,17): error TS1138: Parameter declarati !!! error TS2580: Cannot find name 'require'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`. ~ !!! error TS1005: ')' expected. -!!! related TS1007 tests/cases/compiler/reservedWords2.ts:1:14: The parser expected to find a ')' to match the '(' token here. import * as while from "foo" !!! error TS2300: Duplicate identifier '(Missing)'. @@ -59,7 +58,6 @@ tests/cases/compiler/reservedWords2.ts(12,17): error TS1138: Parameter declarati !!! error TS2304: Cannot find name 'from'. ~~~~~ !!! error TS1005: ')' expected. -!!! related TS1007 tests/cases/compiler/reservedWords2.ts:2:20: The parser expected to find a ')' to match the '(' token here. var typeof = 10; ~~~~~~ diff --git a/tests/cases/fourslash/smartIndentMissingBracketsDoKeyword.ts b/tests/cases/fourslash/smartIndentMissingBracketsDoKeyword.ts new file mode 100644 index 00000000000..984499db5ae --- /dev/null +++ b/tests/cases/fourslash/smartIndentMissingBracketsDoKeyword.ts @@ -0,0 +1,7 @@ +/// + +////do {/*1*/ + +goTo.marker("1"); +edit.insert("\n"); +verify.indentationIs(4); diff --git a/tests/cases/fourslash/smartIndentMissingBracketsIfKeyword.ts b/tests/cases/fourslash/smartIndentMissingBracketsIfKeyword.ts new file mode 100644 index 00000000000..0e260cdf142 --- /dev/null +++ b/tests/cases/fourslash/smartIndentMissingBracketsIfKeyword.ts @@ -0,0 +1,7 @@ +/// + +////if /*1*/ + +goTo.marker("1"); +edit.insert("\n"); +verify.indentationIs(4); diff --git a/tests/cases/fourslash/smartIndentMissingBracketsWhileKeyword.ts b/tests/cases/fourslash/smartIndentMissingBracketsWhileKeyword.ts new file mode 100644 index 00000000000..03e9be630ca --- /dev/null +++ b/tests/cases/fourslash/smartIndentMissingBracketsWhileKeyword.ts @@ -0,0 +1,7 @@ +/// + +////while /*1*/ + +goTo.marker("1"); +edit.insert("\n"); +verify.indentationIs(4); diff --git a/tests/cases/fourslash/smartIndentMissingBracketsWithKeyword.ts b/tests/cases/fourslash/smartIndentMissingBracketsWithKeyword.ts new file mode 100644 index 00000000000..733fc0560a7 --- /dev/null +++ b/tests/cases/fourslash/smartIndentMissingBracketsWithKeyword.ts @@ -0,0 +1,7 @@ +/// + +////with /*1*/ + +goTo.marker("1"); +edit.insert("\n"); +verify.indentationIs(0);