@@ -1335,24 +1335,27 @@ namespace ts {
13351335 return inContext ( NodeFlags . AwaitContext ) ;
13361336 }
13371337
1338- function parseErrorAtCurrentToken ( message : DiagnosticMessage , arg0 ?: any ) : void {
1339- parseErrorAt ( scanner . getTokenPos ( ) , scanner . getTextPos ( ) , message , arg0 ) ;
1338+ function parseErrorAtCurrentToken ( message : DiagnosticMessage , arg0 ?: any ) : DiagnosticWithDetachedLocation | undefined {
1339+ return parseErrorAt ( scanner . getTokenPos ( ) , scanner . getTextPos ( ) , message , arg0 ) ;
13401340 }
13411341
1342- function parseErrorAtPosition ( start : number , length : number , message : DiagnosticMessage , arg0 ?: any ) : void {
1342+ function parseErrorAtPosition ( start : number , length : number , message : DiagnosticMessage , arg0 ?: any ) : DiagnosticWithDetachedLocation | undefined {
13431343 // Don't report another error if it would just be at the same position as the last error.
13441344 const lastError = lastOrUndefined ( parseDiagnostics ) ;
1345+ let result : DiagnosticWithDetachedLocation | undefined ;
13451346 if ( ! lastError || start !== lastError . start ) {
1346- parseDiagnostics . push ( createDetachedDiagnostic ( fileName , start , length , message , arg0 ) ) ;
1347+ result = createDetachedDiagnostic ( fileName , start , length , message , arg0 ) ;
1348+ parseDiagnostics . push ( result ) ;
13471349 }
13481350
13491351 // Mark that we've encountered an error. We'll set an appropriate bit on the next
13501352 // node we finish so that it can't be reused incrementally.
13511353 parseErrorBeforeNextFinishedNode = true ;
1354+ return result ;
13521355 }
13531356
1354- function parseErrorAt ( start : number , end : number , message : DiagnosticMessage , arg0 ?: any ) : void {
1355- parseErrorAtPosition ( start , end - start , message , arg0 ) ;
1357+ function parseErrorAt ( start : number , end : number , message : DiagnosticMessage , arg0 ?: any ) : DiagnosticWithDetachedLocation | undefined {
1358+ return parseErrorAtPosition ( start , end - start , message , arg0 ) ;
13561359 }
13571360
13581361 function parseErrorAtRange ( range : TextRange , message : DiagnosticMessage , arg0 ?: any ) : void {
@@ -1542,6 +1545,20 @@ namespace ts {
15421545 return false ;
15431546 }
15441547
1548+ function parseExpectedMatchingBrackets ( openKind : SyntaxKind , closeKind : SyntaxKind , openPosition : number ) {
1549+ if ( token ( ) === closeKind ) {
1550+ nextToken ( ) ;
1551+ return ;
1552+ }
1553+ const lastError = parseErrorAtCurrentToken ( Diagnostics . _0_expected , tokenToString ( closeKind ) ) ;
1554+ if ( lastError ) {
1555+ addRelatedInfo (
1556+ lastError ,
1557+ createDetachedDiagnostic ( fileName , openPosition , 1 , Diagnostics . The_parser_expected_to_find_a_1_to_match_the_0_token_here , tokenToString ( openKind ) , tokenToString ( closeKind ) )
1558+ ) ;
1559+ }
1560+ }
1561+
15451562 function parseOptional ( t : SyntaxKind ) : boolean {
15461563 if ( token ( ) === t ) {
15471564 nextToken ( ) ;
@@ -2092,8 +2109,7 @@ namespace ts {
20922109
20932110 while ( ! isListTerminator ( kind ) ) {
20942111 if ( isListElement ( kind , /*inErrorRecovery*/ false ) ) {
2095- const element = parseListElement ( kind , parseElement ) ;
2096- list . push ( element ) ;
2112+ list . push ( parseListElement ( kind , parseElement ) ) ;
20972113
20982114 continue ;
20992115 }
@@ -5426,10 +5442,11 @@ namespace ts {
54265442
54275443 function parseArrayLiteralExpression ( ) : ArrayLiteralExpression {
54285444 const pos = getNodePos ( ) ;
5445+ const openBracketPosition = scanner . getTokenPos ( ) ;
54295446 parseExpected ( SyntaxKind . OpenBracketToken ) ;
54305447 const multiLine = scanner . hasPrecedingLineBreak ( ) ;
54315448 const elements = parseDelimitedList ( ParsingContext . ArrayLiteralMembers , parseArgumentOrArrayLiteralElement ) ;
5432- parseExpected ( SyntaxKind . CloseBracketToken ) ;
5449+ parseExpectedMatchingBrackets ( SyntaxKind . OpenBracketToken , SyntaxKind . CloseBracketToken , openBracketPosition ) ;
54335450 return finishNode ( factory . createArrayLiteralExpression ( elements , multiLine ) , pos ) ;
54345451 }
54355452
@@ -5498,15 +5515,7 @@ namespace ts {
54985515 parseExpected ( SyntaxKind . OpenBraceToken ) ;
54995516 const multiLine = scanner . hasPrecedingLineBreak ( ) ;
55005517 const properties = parseDelimitedList ( ParsingContext . ObjectLiteralMembers , parseObjectLiteralElement , /*considerSemicolonAsDelimiter*/ true ) ;
5501- if ( ! parseExpected ( SyntaxKind . CloseBraceToken ) ) {
5502- const lastError = lastOrUndefined ( parseDiagnostics ) ;
5503- if ( lastError && lastError . code === Diagnostics . _0_expected . code ) {
5504- addRelatedInfo (
5505- lastError ,
5506- createDetachedDiagnostic ( fileName , openBracePosition , 1 , Diagnostics . The_parser_expected_to_find_a_to_match_the_token_here )
5507- ) ;
5508- }
5509- }
5518+ parseExpectedMatchingBrackets ( SyntaxKind . OpenBraceToken , SyntaxKind . CloseBraceToken , openBracePosition ) ;
55105519 return finishNode ( factory . createObjectLiteralExpression ( properties , multiLine ) , pos ) ;
55115520 }
55125521
@@ -5591,16 +5600,14 @@ namespace ts {
55915600 if ( parseExpected ( SyntaxKind . OpenBraceToken , diagnosticMessage ) || ignoreMissingOpenBrace ) {
55925601 const multiLine = scanner . hasPrecedingLineBreak ( ) ;
55935602 const statements = parseList ( ParsingContext . BlockStatements , parseStatement ) ;
5594- if ( ! parseExpected ( SyntaxKind . CloseBraceToken ) ) {
5595- const lastError = lastOrUndefined ( parseDiagnostics ) ;
5596- if ( lastError && lastError . code === Diagnostics . _0_expected . code ) {
5597- addRelatedInfo (
5598- lastError ,
5599- createDetachedDiagnostic ( fileName , openBracePosition , 1 , Diagnostics . The_parser_expected_to_find_a_to_match_the_token_here )
5600- ) ;
5601- }
5603+ parseExpectedMatchingBrackets ( SyntaxKind . OpenBraceToken , SyntaxKind . CloseBraceToken , openBracePosition ) ;
5604+ const result = finishNode ( factory . createBlock ( statements , multiLine ) , pos ) ;
5605+ if ( token ( ) === SyntaxKind . EqualsToken ) {
5606+ 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 ) ;
5607+ nextToken ( ) ;
56025608 }
5603- return finishNode ( factory . createBlock ( statements , multiLine ) , pos ) ;
5609+
5610+ return result ;
56045611 }
56055612 else {
56065613 const statements = createMissingList < Statement > ( ) ;
@@ -5647,9 +5654,10 @@ namespace ts {
56475654 function parseIfStatement ( ) : IfStatement {
56485655 const pos = getNodePos ( ) ;
56495656 parseExpected ( SyntaxKind . IfKeyword ) ;
5657+ const openParenPosition = scanner . getTokenPos ( ) ;
56505658 parseExpected ( SyntaxKind . OpenParenToken ) ;
56515659 const expression = allowInAnd ( parseExpression ) ;
5652- parseExpected ( SyntaxKind . CloseParenToken ) ;
5660+ parseExpectedMatchingBrackets ( SyntaxKind . OpenParenToken , SyntaxKind . CloseParenToken , openParenPosition ) ;
56535661 const thenStatement = parseStatement ( ) ;
56545662 const elseStatement = parseOptional ( SyntaxKind . ElseKeyword ) ? parseStatement ( ) : undefined ;
56555663 return finishNode ( factory . createIfStatement ( expression , thenStatement , elseStatement ) , pos ) ;
@@ -5660,9 +5668,10 @@ namespace ts {
56605668 parseExpected ( SyntaxKind . DoKeyword ) ;
56615669 const statement = parseStatement ( ) ;
56625670 parseExpected ( SyntaxKind . WhileKeyword ) ;
5671+ const openParenPosition = scanner . getTokenPos ( ) ;
56635672 parseExpected ( SyntaxKind . OpenParenToken ) ;
56645673 const expression = allowInAnd ( parseExpression ) ;
5665- parseExpected ( SyntaxKind . CloseParenToken ) ;
5674+ parseExpectedMatchingBrackets ( SyntaxKind . OpenParenToken , SyntaxKind . CloseParenToken , openParenPosition ) ;
56665675
56675676 // From: https://mail.mozilla.org/pipermail/es-discuss/2011-August/016188.html
56685677 // 157 min --- All allen at wirfs-brock.com CONF --- "do{;}while(false)false" prohibited in
@@ -5675,9 +5684,10 @@ namespace ts {
56755684 function parseWhileStatement ( ) : WhileStatement {
56765685 const pos = getNodePos ( ) ;
56775686 parseExpected ( SyntaxKind . WhileKeyword ) ;
5687+ const openParenPosition = scanner . getTokenPos ( ) ;
56785688 parseExpected ( SyntaxKind . OpenParenToken ) ;
56795689 const expression = allowInAnd ( parseExpression ) ;
5680- parseExpected ( SyntaxKind . CloseParenToken ) ;
5690+ parseExpectedMatchingBrackets ( SyntaxKind . OpenParenToken , SyntaxKind . CloseParenToken , openParenPosition ) ;
56815691 const statement = parseStatement ( ) ;
56825692 return finishNode ( factory . createWhileStatement ( expression , statement ) , pos ) ;
56835693 }
@@ -5749,9 +5759,10 @@ namespace ts {
57495759 function parseWithStatement ( ) : WithStatement {
57505760 const pos = getNodePos ( ) ;
57515761 parseExpected ( SyntaxKind . WithKeyword ) ;
5762+ const openParenPosition = scanner . getTokenPos ( ) ;
57525763 parseExpected ( SyntaxKind . OpenParenToken ) ;
57535764 const expression = allowInAnd ( parseExpression ) ;
5754- parseExpected ( SyntaxKind . CloseParenToken ) ;
5765+ parseExpectedMatchingBrackets ( SyntaxKind . OpenParenToken , SyntaxKind . CloseParenToken , openParenPosition ) ;
57555766 const statement = doInsideOfContext ( NodeFlags . InWithStatement , parseStatement ) ;
57565767 return finishNode ( factory . createWithStatement ( expression , statement ) , pos ) ;
57575768 }
@@ -7973,13 +7984,9 @@ namespace ts {
79737984 hasChildren = true ;
79747985 if ( child . kind === SyntaxKind . JSDocTypeTag ) {
79757986 if ( childTypeTag ) {
7976- parseErrorAtCurrentToken ( Diagnostics . A_JSDoc_typedef_comment_may_not_contain_multiple_type_tags ) ;
7977- const lastError = lastOrUndefined ( parseDiagnostics ) ;
7987+ const lastError = parseErrorAtCurrentToken ( Diagnostics . A_JSDoc_typedef_comment_may_not_contain_multiple_type_tags ) ;
79787988 if ( lastError ) {
7979- addRelatedInfo (
7980- lastError ,
7981- createDetachedDiagnostic ( fileName , 0 , 0 , Diagnostics . The_tag_was_first_specified_here )
7982- ) ;
7989+ addRelatedInfo ( lastError , createDetachedDiagnostic ( fileName , 0 , 0 , Diagnostics . The_tag_was_first_specified_here ) ) ;
79837990 }
79847991 break ;
79857992 }
@@ -8011,7 +8018,7 @@ namespace ts {
80118018 }
80128019
80138020 const typedefTag = factory . createJSDocTypedefTag ( tagName , typeExpression , fullName , comment ) ;
8014- return finishNode ( typedefTag , start ) ;
8021+ return finishNode ( typedefTag , start , end ) ;
80158022 }
80168023
80178024 function parseJSDocTypeNameWithNamespace ( nested ?: boolean ) {
0 commit comments