@@ -1434,24 +1434,27 @@ namespace ts {
14341434 return inContext ( NodeFlags . AwaitContext ) ;
14351435 }
14361436
1437- function parseErrorAtCurrentToken ( message : DiagnosticMessage , arg0 ?: any ) : void {
1438- parseErrorAt ( scanner . getTokenPos ( ) , scanner . getTextPos ( ) , message , arg0 ) ;
1437+ function parseErrorAtCurrentToken ( message : DiagnosticMessage , arg0 ?: any ) : DiagnosticWithDetachedLocation | undefined {
1438+ return parseErrorAt ( scanner . getTokenPos ( ) , scanner . getTextPos ( ) , message , arg0 ) ;
14391439 }
14401440
1441- function parseErrorAtPosition ( start : number , length : number , message : DiagnosticMessage , arg0 ?: any ) : void {
1441+ function parseErrorAtPosition ( start : number , length : number , message : DiagnosticMessage , arg0 ?: any ) : DiagnosticWithDetachedLocation | undefined {
14421442 // Don't report another error if it would just be at the same position as the last error.
14431443 const lastError = lastOrUndefined ( parseDiagnostics ) ;
1444+ let result : DiagnosticWithDetachedLocation | undefined ;
14441445 if ( ! lastError || start !== lastError . start ) {
1445- parseDiagnostics . push ( createDetachedDiagnostic ( fileName , start , length , message , arg0 ) ) ;
1446+ result = createDetachedDiagnostic ( fileName , start , length , message , arg0 ) ;
1447+ parseDiagnostics . push ( result ) ;
14461448 }
14471449
14481450 // Mark that we've encountered an error. We'll set an appropriate bit on the next
14491451 // node we finish so that it can't be reused incrementally.
14501452 parseErrorBeforeNextFinishedNode = true ;
1453+ return result ;
14511454 }
14521455
1453- function parseErrorAt ( start : number , end : number , message : DiagnosticMessage , arg0 ?: any ) : void {
1454- parseErrorAtPosition ( start , end - start , message , arg0 ) ;
1456+ function parseErrorAt ( start : number , end : number , message : DiagnosticMessage , arg0 ?: any ) : DiagnosticWithDetachedLocation | undefined {
1457+ return parseErrorAtPosition ( start , end - start , message , arg0 ) ;
14551458 }
14561459
14571460 function parseErrorAtRange ( range : TextRange , message : DiagnosticMessage , arg0 ?: any ) : void {
@@ -1779,6 +1782,23 @@ namespace ts {
17791782 return false ;
17801783 }
17811784
1785+ function parseExpectedMatchingBrackets ( openKind : SyntaxKind , closeKind : SyntaxKind , openParsed : boolean , openPosition : number ) {
1786+ if ( token ( ) === closeKind ) {
1787+ nextToken ( ) ;
1788+ return ;
1789+ }
1790+ const lastError = parseErrorAtCurrentToken ( Diagnostics . _0_expected , tokenToString ( closeKind ) ) ;
1791+ if ( ! openParsed ) {
1792+ return ;
1793+ }
1794+ if ( lastError ) {
1795+ addRelatedInfo (
1796+ lastError ,
1797+ createDetachedDiagnostic ( fileName , openPosition , 1 , Diagnostics . The_parser_expected_to_find_a_1_to_match_the_0_token_here , tokenToString ( openKind ) , tokenToString ( closeKind ) )
1798+ ) ;
1799+ }
1800+ }
1801+
17821802 function parseOptional ( t : SyntaxKind ) : boolean {
17831803 if ( token ( ) === t ) {
17841804 nextToken ( ) ;
@@ -3739,7 +3759,7 @@ namespace ts {
37393759 if ( lastError && lastError . code === Diagnostics . _0_expected . code ) {
37403760 addRelatedInfo (
37413761 lastError ,
3742- createDetachedDiagnostic ( fileName , openBracePosition , 1 , Diagnostics . The_parser_expected_to_find_a_to_match_the_token_here )
3762+ createDetachedDiagnostic ( fileName , openBracePosition , 1 , Diagnostics . The_parser_expected_to_find_a_1_to_match_the_0_token_here , "{" , "}" )
37433763 ) ;
37443764 }
37453765 }
@@ -5772,10 +5792,11 @@ namespace ts {
57725792
57735793 function parseArrayLiteralExpression ( ) : ArrayLiteralExpression {
57745794 const pos = getNodePos ( ) ;
5775- parseExpected ( SyntaxKind . OpenBracketToken ) ;
5795+ const openBracketPosition = scanner . getTokenPos ( ) ;
5796+ const openBracketParsed = parseExpected ( SyntaxKind . OpenBracketToken ) ;
57765797 const multiLine = scanner . hasPrecedingLineBreak ( ) ;
57775798 const elements = parseDelimitedList ( ParsingContext . ArrayLiteralMembers , parseArgumentOrArrayLiteralElement ) ;
5778- parseExpected ( SyntaxKind . CloseBracketToken ) ;
5799+ parseExpectedMatchingBrackets ( SyntaxKind . OpenBracketToken , SyntaxKind . CloseBracketToken , openBracketParsed , openBracketPosition ) ;
57795800 return finishNode ( factory . createArrayLiteralExpression ( elements , multiLine ) , pos ) ;
57805801 }
57815802
@@ -5841,18 +5862,10 @@ namespace ts {
58415862 function parseObjectLiteralExpression ( ) : ObjectLiteralExpression {
58425863 const pos = getNodePos ( ) ;
58435864 const openBracePosition = scanner . getTokenPos ( ) ;
5844- parseExpected ( SyntaxKind . OpenBraceToken ) ;
5865+ const openBraceParsed = parseExpected ( SyntaxKind . OpenBraceToken ) ;
58455866 const multiLine = scanner . hasPrecedingLineBreak ( ) ;
58465867 const properties = parseDelimitedList ( ParsingContext . ObjectLiteralMembers , parseObjectLiteralElement , /*considerSemicolonAsDelimiter*/ true ) ;
5847- if ( ! parseExpected ( SyntaxKind . CloseBraceToken ) ) {
5848- const lastError = lastOrUndefined ( parseDiagnostics ) ;
5849- if ( lastError && lastError . code === Diagnostics . _0_expected . code ) {
5850- addRelatedInfo (
5851- lastError ,
5852- createDetachedDiagnostic ( fileName , openBracePosition , 1 , Diagnostics . The_parser_expected_to_find_a_to_match_the_token_here )
5853- ) ;
5854- }
5855- }
5868+ parseExpectedMatchingBrackets ( SyntaxKind . OpenBraceToken , SyntaxKind . CloseBraceToken , openBraceParsed , openBracePosition ) ;
58565869 return finishNode ( factory . createObjectLiteralExpression ( properties , multiLine ) , pos ) ;
58575870 }
58585871
@@ -5916,18 +5929,11 @@ namespace ts {
59165929 const pos = getNodePos ( ) ;
59175930 const hasJSDoc = hasPrecedingJSDocComment ( ) ;
59185931 const openBracePosition = scanner . getTokenPos ( ) ;
5919- if ( parseExpected ( SyntaxKind . OpenBraceToken , diagnosticMessage ) || ignoreMissingOpenBrace ) {
5932+ const openBraceParsed = parseExpected ( SyntaxKind . OpenBraceToken , diagnosticMessage ) ;
5933+ if ( openBraceParsed || ignoreMissingOpenBrace ) {
59205934 const multiLine = scanner . hasPrecedingLineBreak ( ) ;
59215935 const statements = parseList ( ParsingContext . BlockStatements , parseStatement ) ;
5922- if ( ! parseExpected ( SyntaxKind . CloseBraceToken ) ) {
5923- const lastError = lastOrUndefined ( parseDiagnostics ) ;
5924- if ( lastError && lastError . code === Diagnostics . _0_expected . code ) {
5925- addRelatedInfo (
5926- lastError ,
5927- createDetachedDiagnostic ( fileName , openBracePosition , 1 , Diagnostics . The_parser_expected_to_find_a_to_match_the_token_here )
5928- ) ;
5929- }
5930- }
5936+ parseExpectedMatchingBrackets ( SyntaxKind . OpenBraceToken , SyntaxKind . CloseBraceToken , openBraceParsed , openBracePosition ) ;
59315937 const result = withJSDoc ( finishNode ( factory . createBlock ( statements , multiLine ) , pos ) , hasJSDoc ) ;
59325938 if ( token ( ) === SyntaxKind . EqualsToken ) {
59335939 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 {
59835989 const pos = getNodePos ( ) ;
59845990 const hasJSDoc = hasPrecedingJSDocComment ( ) ;
59855991 parseExpected ( SyntaxKind . IfKeyword ) ;
5986- parseExpected ( SyntaxKind . OpenParenToken ) ;
5992+ const openParenPosition = scanner . getTokenPos ( ) ;
5993+ const openParenParsed = parseExpected ( SyntaxKind . OpenParenToken ) ;
59875994 const expression = allowInAnd ( parseExpression ) ;
5988- parseExpected ( SyntaxKind . CloseParenToken ) ;
5995+ parseExpectedMatchingBrackets ( SyntaxKind . OpenParenToken , SyntaxKind . CloseParenToken , openParenParsed , openParenPosition ) ;
59895996 const thenStatement = parseStatement ( ) ;
59905997 const elseStatement = parseOptional ( SyntaxKind . ElseKeyword ) ? parseStatement ( ) : undefined ;
59915998 return withJSDoc ( finishNode ( factory . createIfStatement ( expression , thenStatement , elseStatement ) , pos ) , hasJSDoc ) ;
@@ -5997,9 +6004,10 @@ namespace ts {
59976004 parseExpected ( SyntaxKind . DoKeyword ) ;
59986005 const statement = parseStatement ( ) ;
59996006 parseExpected ( SyntaxKind . WhileKeyword ) ;
6000- parseExpected ( SyntaxKind . OpenParenToken ) ;
6007+ const openParenPosition = scanner . getTokenPos ( ) ;
6008+ const openParenParsed = parseExpected ( SyntaxKind . OpenParenToken ) ;
60016009 const expression = allowInAnd ( parseExpression ) ;
6002- parseExpected ( SyntaxKind . CloseParenToken ) ;
6010+ parseExpectedMatchingBrackets ( SyntaxKind . OpenParenToken , SyntaxKind . CloseParenToken , openParenParsed , openParenPosition ) ;
60036011
60046012 // From: https://mail.mozilla.org/pipermail/es-discuss/2011-August/016188.html
60056013 // 157 min --- All allen at wirfs-brock.com CONF --- "do{;}while(false)false" prohibited in
@@ -6013,9 +6021,10 @@ namespace ts {
60136021 const pos = getNodePos ( ) ;
60146022 const hasJSDoc = hasPrecedingJSDocComment ( ) ;
60156023 parseExpected ( SyntaxKind . WhileKeyword ) ;
6016- parseExpected ( SyntaxKind . OpenParenToken ) ;
6024+ const openParenPosition = scanner . getTokenPos ( ) ;
6025+ const openParenParsed = parseExpected ( SyntaxKind . OpenParenToken ) ;
60176026 const expression = allowInAnd ( parseExpression ) ;
6018- parseExpected ( SyntaxKind . CloseParenToken ) ;
6027+ parseExpectedMatchingBrackets ( SyntaxKind . OpenParenToken , SyntaxKind . CloseParenToken , openParenParsed , openParenPosition ) ;
60196028 const statement = parseStatement ( ) ;
60206029 return withJSDoc ( finishNode ( factory . createWhileStatement ( expression , statement ) , pos ) , hasJSDoc ) ;
60216030 }
@@ -6091,9 +6100,10 @@ namespace ts {
60916100 const pos = getNodePos ( ) ;
60926101 const hasJSDoc = hasPrecedingJSDocComment ( ) ;
60936102 parseExpected ( SyntaxKind . WithKeyword ) ;
6094- parseExpected ( SyntaxKind . OpenParenToken ) ;
6103+ const openParenPosition = scanner . getTokenPos ( ) ;
6104+ const openParenParsed = parseExpected ( SyntaxKind . OpenParenToken ) ;
60956105 const expression = allowInAnd ( parseExpression ) ;
6096- parseExpected ( SyntaxKind . CloseParenToken ) ;
6106+ parseExpectedMatchingBrackets ( SyntaxKind . OpenParenToken , SyntaxKind . CloseParenToken , openParenParsed , openParenPosition ) ;
60976107 const statement = doInsideOfContext ( NodeFlags . InWithStatement , parseStatement ) ;
60986108 return withJSDoc ( finishNode ( factory . createWithStatement ( expression , statement ) , pos ) , hasJSDoc ) ;
60996109 }
@@ -7398,7 +7408,7 @@ namespace ts {
73987408 if ( lastError && lastError . code === Diagnostics . _0_expected . code ) {
73997409 addRelatedInfo (
74007410 lastError ,
7401- createDetachedDiagnostic ( fileName , openBracePosition , 1 , Diagnostics . The_parser_expected_to_find_a_to_match_the_token_here )
7411+ createDetachedDiagnostic ( fileName , openBracePosition , 1 , Diagnostics . The_parser_expected_to_find_a_1_to_match_the_0_token_here , "{" , "}" )
74027412 ) ;
74037413 }
74047414 }
@@ -8453,13 +8463,9 @@ namespace ts {
84538463 hasChildren = true ;
84548464 if ( child . kind === SyntaxKind . JSDocTypeTag ) {
84558465 if ( childTypeTag ) {
8456- parseErrorAtCurrentToken ( Diagnostics . A_JSDoc_typedef_comment_may_not_contain_multiple_type_tags ) ;
8457- const lastError = lastOrUndefined ( parseDiagnostics ) ;
8466+ const lastError = parseErrorAtCurrentToken ( Diagnostics . A_JSDoc_typedef_comment_may_not_contain_multiple_type_tags ) ;
84588467 if ( lastError ) {
8459- addRelatedInfo (
8460- lastError ,
8461- createDetachedDiagnostic ( fileName , 0 , 0 , Diagnostics . The_tag_was_first_specified_here )
8462- ) ;
8468+ addRelatedInfo ( lastError , createDetachedDiagnostic ( fileName , 0 , 0 , Diagnostics . The_tag_was_first_specified_here ) ) ;
84638469 }
84648470 break ;
84658471 }
0 commit comments