Improved "certainty" when parsing arrow-function-lookin' expressions.

This commit is contained in:
Daniel Rosenwasser 2014-07-23 13:31:24 -07:00
parent 5fc2792297
commit 57d7cf54c6
5 changed files with 31 additions and 57 deletions

View File

@ -1448,12 +1448,10 @@ module ts {
// Indicates whether we are certain that we should parse an arrow expression.
var triState = isParenthesizedArrowFunctionExpression();
// It is not a parenthesized arrow function.
if (triState === Tristate.False) {
return undefined;
}
// If we're certain that we have an arrow function expression, then just parse one out.
if (triState === Tristate.True) {
var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken);
@ -1468,8 +1466,8 @@ module ts {
}
}
// Otherwise, *maybe* we had an arrow function and we need to *try* to parse it out
// (which will ensure we rollback if we fail).
// *Maybe* we had an arrow function and we need to try to parse it out,
// rolling back and trying other parses if we fail.
var sig = tryParse(parseSignatureIfArrowOrBraceFollows);
if (sig === undefined) {
return undefined;
@ -1522,6 +1520,12 @@ module ts {
return Tristate.False;
}
// If we have something like "(a:", then we must have a
// type-annotated parameter in an arrow function expression.
if (nextToken() === SyntaxKind.ColonToken) {
return Tristate.True;
}
// This *could* be a parenthesized arrow function.
// Return Unknown to let the caller know.
return Tristate.Unknown;
@ -1547,9 +1551,19 @@ module ts {
function parseSignatureIfArrowOrBraceFollows(): ParsedSignature {
var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken);
// Parsing a signature isn't enough.
// Parenthesized arrow signatures often look like other valid expressions.
// For instance:
// - "(x = 10)" is an assignment expression parsed as a signature with a default parameter value.
// - "(x,y)" is a comma expression parsed as a signature with two parameters.
// - "a ? (b): c" will have "(b):" parsed as a signature with a return type annotation.
//
// So we need just a bit of lookahead to ensure that it can only be a signature.
if (token === SyntaxKind.EqualsGreaterThanToken || token === SyntaxKind.OpenBraceToken) {
return sig;
}
return undefined;
}

View File

@ -1,4 +1,4 @@
==== tests/cases/compiler/arrowFunctionsMissingTokens.ts (31 errors) ====
==== tests/cases/compiler/arrowFunctionsMissingTokens.ts (24 errors) ====
module missingArrowsWithCurly {
var a = () { };
@ -94,26 +94,12 @@
!!! Cannot find name 'x'.
var d = (x: number, y: string);
~
!!! ')' expected.
~
!!! ',' expected.
~
!!! Cannot find name 'x'.
~
!!! '=>' expected.
var e = (x: number, y: string): void;
~
!!! ')' expected.
~
!!! ',' expected.
~
!!! Variable declaration expected.
~~~~
!!! Variable declaration expected.
~
!!! Expression expected.
~
!!! Cannot find name 'x'.
!!! '=>' expected.
}
module okay {

View File

@ -1,10 +1,6 @@
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserErrorRecovery_ParameterList5.ts (4 errors) ====
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserErrorRecovery_ParameterList5.ts (2 errors) ====
(a:number => { }
~
!!! ')' expected.
~~
!!! ';' expected.
~
!!! Cannot find name 'a'.
~~~~~~
!!! Cannot find name 'number'.
!!! ',' expected.
~
!!! ')' expected.

View File

@ -1,4 +1,4 @@
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserUnterminatedGeneric2.ts (23 errors) ====
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserUnterminatedGeneric2.ts (15 errors) ====
declare module ng {
interfaceICompiledExpression {
~
@ -6,24 +6,8 @@
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! Cannot find name 'interfaceICompiledExpression'.
(context: any, locals?: any): any;
~
!!! ')' expected.
~
!!! Expression expected.
~
!!! ';' expected.
~
!!! Statement expected.
~~~~~~~
!!! Cannot find name 'context'.
~~~
!!! Cannot find name 'any'.
~~~~~~
!!! Cannot find name 'locals'.
~~~
!!! Cannot find name 'any'.
~~~
!!! Cannot find name 'any'.
~
!!! '=>' expected.
assign(context: any, value: any): any;
~
!!! ',' expected.

View File

@ -1,12 +1,6 @@
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/parserX_ArrowFunction1.ts (4 errors) ====
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/parserX_ArrowFunction1.ts (1 errors) ====
var v = (a: ) => {
~
!!! ')' expected.
~
!!! Variable declaration expected.
~~
!!! ';' expected.
~
!!! Cannot find name 'a'.
!!! Type expected.
};