diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index fac4ba6732f..4bc314d6409 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1271,4 +1271,4 @@ "category": "Error", "code": -9999999 } -} \ No newline at end of file +} diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 25038d71d4a..e248da99075 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2665,6 +2665,10 @@ module ts { case SyntaxKind.ThrowKeyword: case SyntaxKind.TryKeyword: case SyntaxKind.DebuggerKeyword: + // 'catch' and 'finally' do not actually indicate that the code is part of a statement, + // however, we say they are here so that we may gracefully parse them and error later. + case SyntaxKind.CatchKeyword: + case SyntaxKind.FinallyKeyword: return true; case SyntaxKind.InterfaceKeyword: case SyntaxKind.ClassKeyword: @@ -2672,13 +2676,17 @@ module ts { case SyntaxKind.EnumKeyword: // When followed by an identifier, these do not start a statement but might // instead be following declarations - if (isDeclaration()) return false; + if (isDeclaration()) { + return false; + } case SyntaxKind.PublicKeyword: case SyntaxKind.PrivateKeyword: case SyntaxKind.StaticKeyword: // When followed by an identifier or keyword, these do not start a statement but // might instead be following type members - if (lookAhead(() => nextToken() >= SyntaxKind.Identifier)) return false; + if (lookAhead(() => nextToken() >= SyntaxKind.Identifier)) { + return false; + } default: return isExpression(); } @@ -2715,6 +2723,9 @@ module ts { case SyntaxKind.ThrowKeyword: return parseThrowStatement(); case SyntaxKind.TryKeyword: + // Include the next two for error recovery. + case SyntaxKind.CatchKeyword: + case SyntaxKind.FinallyKeyword: return parseTryStatement(); case SyntaxKind.DebuggerKeyword: return parseDebuggerStatement(); diff --git a/tests/baselines/reference/invalidTryStatements2.errors.txt b/tests/baselines/reference/invalidTryStatements2.errors.txt index fcb8ad3560d..a600210a605 100644 --- a/tests/baselines/reference/invalidTryStatements2.errors.txt +++ b/tests/baselines/reference/invalidTryStatements2.errors.txt @@ -1,4 +1,4 @@ -==== tests/cases/conformance/statements/tryStatements/invalidTryStatements2.ts (4 errors) ==== +==== tests/cases/conformance/statements/tryStatements/invalidTryStatements2.ts (6 errors) ==== function fn() { try { } catch { // syntax error, missing '(x)' @@ -8,11 +8,34 @@ catch(x) { } // error missing try ~~~~~ -!!! Statement expected. - ~ -!!! '=>' expected. +!!! 'try' expected. - finally{ } // error missing try + finally{ } // potential error; can be absorbed by the 'catch' + } + + function fn2() { + finally { } // error missing try ~~~~~~~ -!!! Statement expected. +!!! 'try' expected. + catch (x) { } // error missing try + ~~~~~ +!!! 'try' expected. + + // no error + try { + } + finally { + } + + // error missing try + finally { + ~~~~~~~ +!!! 'try' expected. + } + + // error missing try + catch (x) { + ~~~~~ +!!! 'try' expected. + } } \ No newline at end of file diff --git a/tests/baselines/reference/parserMissingToken1.errors.txt b/tests/baselines/reference/parserMissingToken1.errors.txt index 670da2ef5c1..35e5e605cb5 100644 --- a/tests/baselines/reference/parserMissingToken1.errors.txt +++ b/tests/baselines/reference/parserMissingToken1.errors.txt @@ -1,6 +1,8 @@ -==== tests/cases/conformance/parser/ecmascript5/MissingTokens/parserMissingToken1.ts (2 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/MissingTokens/parserMissingToken1.ts (3 errors) ==== a / finally ~~~~~~~ !!! Expression expected. + +!!! '{' expected. ~ !!! Cannot find name 'a'. \ No newline at end of file diff --git a/tests/cases/conformance/statements/tryStatements/invalidTryStatements2.ts b/tests/cases/conformance/statements/tryStatements/invalidTryStatements2.ts index de37313e92a..6937e509845 100644 --- a/tests/cases/conformance/statements/tryStatements/invalidTryStatements2.ts +++ b/tests/cases/conformance/statements/tryStatements/invalidTryStatements2.ts @@ -5,5 +5,24 @@ function fn() { catch(x) { } // error missing try - finally{ } // error missing try + finally{ } // potential error; can be absorbed by the 'catch' +} + +function fn2() { + finally { } // error missing try + catch (x) { } // error missing try + + // no error + try { + } + finally { + } + + // error missing try + finally { + } + + // error missing try + catch (x) { + } } \ No newline at end of file