Merge pull request #262 from Microsoft/trylessCatchesFinallyParseNicely

Improved errors for 'catch'/'finally' blocks missing 'try' statements
This commit is contained in:
Daniel Rosenwasser 2014-08-04 15:56:20 -07:00
commit 40f6ed0b65
5 changed files with 66 additions and 11 deletions

View file

@ -1271,4 +1271,4 @@
"category": "Error",
"code": -9999999
}
}
}

View file

@ -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();

View file

@ -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.
}
}

View file

@ -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'.

View file

@ -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) {
}
}