Have better error recovery for whne a user uses semicolons instead of commas to delimit an object literal.

This commit is contained in:
Cyrus Najmabadi 2015-02-06 17:30:29 -08:00
parent 369f784cfa
commit 449f4a4f37
26 changed files with 177 additions and 31 deletions

View file

@ -1878,7 +1878,7 @@ module ts {
}
// Parses a comma-delimited list of elements
function parseDelimitedList<T extends Node>(kind: ParsingContext, parseElement: () => T): NodeArray<T> {
function parseDelimitedList<T extends Node>(kind: ParsingContext, parseElement: () => T, considerSemicolonAsDelimeter?: boolean): NodeArray<T> {
var saveParsingContext = parsingContext;
parsingContext |= 1 << kind;
var result = <NodeArray<T>>[];
@ -1892,11 +1892,24 @@ module ts {
if (parseOptional(SyntaxKind.CommaToken)) {
continue;
}
commaStart = -1; // Back to the state where the last token was not a comma
if (isListTerminator(kind)) {
break;
}
// We didn't get a comma, and the list wasn't terminated, explicitly parse
// out a comma so we give a good error message.
parseExpected(SyntaxKind.CommaToken);
// If the token was a semicolon, and the caller allows that, then skip it and
// continue. This ensures we get back on track and don't result in tons of
// parse errors. For example, this can happen when people do things like use
// a semicolon to delimit object literal members. Note: we'll have already
// reported an error when we called parseExpected above.
if (considerSemicolonAsDelimeter && token === SyntaxKind.SemicolonToken && !scanner.hasPrecedingLineBreak()) {
nextToken();
}
continue;
}
@ -3598,7 +3611,7 @@ module ts {
node.flags |= NodeFlags.MultiLine;
}
node.properties = parseDelimitedList(ParsingContext.ObjectLiteralMembers, parseObjectLiteralElement);
node.properties = parseDelimitedList(ParsingContext.ObjectLiteralMembers, parseObjectLiteralElement, /*considerSemicolonAsDelimeter:*/ true);
parseExpected(SyntaxKind.CloseBraceToken);
return finishNode(node);
}

View file

@ -3,8 +3,6 @@ tests/cases/compiler/fatarrowfunctionsErrors.ts(2,1): error TS2304: Cannot find
tests/cases/compiler/fatarrowfunctionsErrors.ts(2,8): error TS1005: ',' expected.
tests/cases/compiler/fatarrowfunctionsErrors.ts(2,18): error TS1005: ':' expected.
tests/cases/compiler/fatarrowfunctionsErrors.ts(2,19): error TS1005: ',' expected.
tests/cases/compiler/fatarrowfunctionsErrors.ts(2,20): error TS1128: Declaration or statement expected.
tests/cases/compiler/fatarrowfunctionsErrors.ts(2,21): error TS1128: Declaration or statement expected.
tests/cases/compiler/fatarrowfunctionsErrors.ts(3,1): error TS2304: Cannot find name 'foo'.
tests/cases/compiler/fatarrowfunctionsErrors.ts(4,1): error TS2304: Cannot find name 'foo'.
tests/cases/compiler/fatarrowfunctionsErrors.ts(5,9): error TS2304: Cannot find name 'x'.
@ -18,7 +16,7 @@ tests/cases/compiler/fatarrowfunctionsErrors.ts(11,21): error TS1005: '=>' expec
tests/cases/compiler/fatarrowfunctionsErrors.ts(12,23): error TS1005: '=>' expected.
==== tests/cases/compiler/fatarrowfunctionsErrors.ts (18 errors) ====
==== tests/cases/compiler/fatarrowfunctionsErrors.ts (16 errors) ====
foo((...Far:any[])=>{return 0;})
~~~
!!! error TS2304: Cannot find name 'foo'.
@ -31,10 +29,6 @@ tests/cases/compiler/fatarrowfunctionsErrors.ts(12,23): error TS1005: '=>' expec
!!! error TS1005: ':' expected.
~
!!! error TS1005: ',' expected.
~
!!! error TS1128: Declaration or statement expected.
~
!!! error TS1128: Declaration or statement expected.
foo((x?)=>{return x;})
~~~
!!! error TS2304: Cannot find name 'foo'.

View file

@ -21,7 +21,6 @@ foo(function () {
return 0;
});
foo((1), { return: 0 });
;
foo(function (x) {
return x;
});

View file

@ -1,11 +1,8 @@
tests/cases/compiler/incompleteObjectLiteral1.ts(1,14): error TS1005: ':' expected.
tests/cases/compiler/incompleteObjectLiteral1.ts(1,16): error TS1128: Declaration or statement expected.
==== tests/cases/compiler/incompleteObjectLiteral1.ts (2 errors) ====
==== tests/cases/compiler/incompleteObjectLiteral1.ts (1 errors) ====
var tt = { aa; }
~
!!! error TS1005: ':' expected.
~
!!! error TS1128: Declaration or statement expected.
var x = tt;

View file

@ -0,0 +1,13 @@
tests/cases/compiler/objectLiteralWithSemicolons1.ts(1,12): error TS1005: ':' expected.
tests/cases/compiler/objectLiteralWithSemicolons1.ts(1,15): error TS1005: ':' expected.
tests/cases/compiler/objectLiteralWithSemicolons1.ts(1,17): error TS2304: Cannot find name 'c'.
==== tests/cases/compiler/objectLiteralWithSemicolons1.ts (3 errors) ====
var v = { a; b; c }
~
!!! error TS1005: ':' expected.
~
!!! error TS1005: ':' expected.
~
!!! error TS2304: Cannot find name 'c'.

View file

@ -0,0 +1,5 @@
//// [objectLiteralWithSemicolons1.ts]
var v = { a; b; c }
//// [objectLiteralWithSemicolons1.js]
var v = { a: , b: , c: c };

View file

@ -0,0 +1,17 @@
tests/cases/compiler/objectLiteralWithSemicolons2.ts(2,4): error TS1005: ':' expected.
tests/cases/compiler/objectLiteralWithSemicolons2.ts(3,4): error TS1005: ':' expected.
tests/cases/compiler/objectLiteralWithSemicolons2.ts(4,3): error TS2304: Cannot find name 'c'.
==== tests/cases/compiler/objectLiteralWithSemicolons2.ts (3 errors) ====
var v = {
a;
~
!!! error TS1005: ':' expected.
b;
~
!!! error TS1005: ':' expected.
c
~
!!! error TS2304: Cannot find name 'c'.
}

View file

@ -0,0 +1,13 @@
//// [objectLiteralWithSemicolons2.ts]
var v = {
a;
b;
c
}
//// [objectLiteralWithSemicolons2.js]
var v = {
a: ,
b: ,
c: c
};

View file

@ -0,0 +1,17 @@
tests/cases/compiler/objectLiteralWithSemicolons3.ts(2,4): error TS1005: ':' expected.
tests/cases/compiler/objectLiteralWithSemicolons3.ts(3,4): error TS1005: ':' expected.
tests/cases/compiler/objectLiteralWithSemicolons3.ts(4,4): error TS1005: ':' expected.
==== tests/cases/compiler/objectLiteralWithSemicolons3.ts (3 errors) ====
var v = {
a;
~
!!! error TS1005: ':' expected.
b;
~
!!! error TS1005: ':' expected.
c;
~
!!! error TS1005: ':' expected.
}

View file

@ -0,0 +1,13 @@
//// [objectLiteralWithSemicolons3.ts]
var v = {
a;
b;
c;
}
//// [objectLiteralWithSemicolons3.js]
var v = {
a: ,
b: ,
c:
};

View file

@ -0,0 +1,9 @@
tests/cases/compiler/objectLiteralWithSemicolons4.ts(3,1): error TS1005: ':' expected.
==== tests/cases/compiler/objectLiteralWithSemicolons4.ts (1 errors) ====
var v = {
a
;
~
!!! error TS1005: ':' expected.

View file

@ -0,0 +1,9 @@
//// [objectLiteralWithSemicolons4.ts]
var v = {
a
;
//// [objectLiteralWithSemicolons4.js]
var v = {
a:
};

View file

@ -0,0 +1,19 @@
tests/cases/compiler/objectLiteralWithSemicolons5.ts(1,20): error TS1005: ',' expected.
tests/cases/compiler/objectLiteralWithSemicolons5.ts(1,25): error TS2304: Cannot find name 'b'.
tests/cases/compiler/objectLiteralWithSemicolons5.ts(1,26): error TS1005: ',' expected.
tests/cases/compiler/objectLiteralWithSemicolons5.ts(1,32): error TS2378: A 'get' accessor must return a value or consist of a single 'throw' statement.
tests/cases/compiler/objectLiteralWithSemicolons5.ts(1,41): error TS1005: ',' expected.
==== tests/cases/compiler/objectLiteralWithSemicolons5.ts (5 errors) ====
var v = { foo() { }; a: b; get baz() { }; }
~
!!! error TS1005: ',' expected.
~
!!! error TS2304: Cannot find name 'b'.
~
!!! error TS1005: ',' expected.
~~~
!!! error TS2378: A 'get' accessor must return a value or consist of a single 'throw' statement.
~
!!! error TS1005: ',' expected.

View file

@ -0,0 +1,7 @@
//// [objectLiteralWithSemicolons5.ts]
var v = { foo() { }; a: b; get baz() { }; }
//// [objectLiteralWithSemicolons5.js]
var v = { foo: function () {
}, a: b, get baz() {
} };

View file

@ -1,13 +1,10 @@
tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512097.ts(1,14): error TS1005: ':' expected.
tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512097.ts(1,16): error TS1128: Declaration or statement expected.
==== tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512097.ts (2 errors) ====
==== tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512097.ts (1 errors) ====
var tt = { aa; } // After this point, no useful parsing occurs in the entire file
~
!!! error TS1005: ':' expected.
~
!!! error TS1128: Declaration or statement expected.
if (true) {
}

View file

@ -5,6 +5,6 @@ if (true) {
}
//// [parser512097.js]
var tt = { aa: };
var tt = { aa: }; // After this point, no useful parsing occurs in the entire file
if (true) {
}

View file

@ -1,11 +1,14 @@
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserErrorRecovery_ObjectLiteral2.ts(2,1): error TS1005: ':' expected.
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserErrorRecovery_ObjectLiteral2.ts(2,7): error TS1005: ':' expected.
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserErrorRecovery_ObjectLiteral2.ts(2,8): error TS1005: '}' expected.
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserErrorRecovery_ObjectLiteral2.ts (2 errors) ====
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserErrorRecovery_ObjectLiteral2.ts (3 errors) ====
var v = { a
return;
~~~~~~
!!! error TS1005: ':' expected.
~
!!! error TS1005: ':' expected.
!!! error TS1005: ':' expected.
!!! error TS1005: '}' expected.

View file

@ -1,11 +1,14 @@
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserErrorRecovery_ObjectLiteral3.ts(2,1): error TS1109: Expression expected.
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserErrorRecovery_ObjectLiteral3.ts(2,7): error TS1005: ':' expected.
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserErrorRecovery_ObjectLiteral3.ts(2,8): error TS1005: '}' expected.
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserErrorRecovery_ObjectLiteral3.ts (2 errors) ====
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserErrorRecovery_ObjectLiteral3.ts (3 errors) ====
var v = { a:
return;
~~~~~~
!!! error TS1109: Expression expected.
~
!!! error TS1005: ':' expected.
!!! error TS1005: ':' expected.
!!! error TS1005: '}' expected.

View file

@ -1,11 +1,14 @@
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserErrorRecovery_ObjectLiteral4.ts(2,1): error TS1005: ',' expected.
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserErrorRecovery_ObjectLiteral4.ts(2,7): error TS1005: ':' expected.
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserErrorRecovery_ObjectLiteral4.ts(2,8): error TS1005: '}' expected.
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserErrorRecovery_ObjectLiteral4.ts (2 errors) ====
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserErrorRecovery_ObjectLiteral4.ts (3 errors) ====
var v = { a: 1
return;
~~~~~~
!!! error TS1005: ',' expected.
~
!!! error TS1005: ':' expected.
!!! error TS1005: ':' expected.
!!! error TS1005: '}' expected.

View file

@ -1,8 +1,11 @@
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserErrorRecovery_ObjectLiteral5.ts(2,7): error TS1005: ':' expected.
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserErrorRecovery_ObjectLiteral5.ts(2,8): error TS1005: '}' expected.
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserErrorRecovery_ObjectLiteral5.ts (1 errors) ====
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserErrorRecovery_ObjectLiteral5.ts (2 errors) ====
var v = { a: 1,
return;
~
!!! error TS1005: ':' expected.
!!! error TS1005: ':' expected.
!!! error TS1005: '}' expected.

View file

@ -3,10 +3,9 @@ tests/cases/conformance/classes/indexMemberDeclarations/privateIndexer2.ts(4,17)
tests/cases/conformance/classes/indexMemberDeclarations/privateIndexer2.ts(4,23): error TS1005: ',' expected.
tests/cases/conformance/classes/indexMemberDeclarations/privateIndexer2.ts(4,24): error TS1136: Property assignment expected.
tests/cases/conformance/classes/indexMemberDeclarations/privateIndexer2.ts(4,32): error TS1005: ':' expected.
tests/cases/conformance/classes/indexMemberDeclarations/privateIndexer2.ts(5,1): error TS1128: Declaration or statement expected.
==== tests/cases/conformance/classes/indexMemberDeclarations/privateIndexer2.ts (6 errors) ====
==== tests/cases/conformance/classes/indexMemberDeclarations/privateIndexer2.ts (5 errors) ====
// private indexers not allowed
var x = {
@ -22,8 +21,6 @@ tests/cases/conformance/classes/indexMemberDeclarations/privateIndexer2.ts(5,1):
~
!!! error TS1005: ':' expected.
}
~
!!! error TS1128: Declaration or statement expected.
var y: {
private[x: string]: string;

View file

@ -0,0 +1 @@
var v = { a; b; c }

View file

@ -0,0 +1,5 @@
var v = {
a;
b;
c
}

View file

@ -0,0 +1,5 @@
var v = {
a;
b;
c;
}

View file

@ -0,0 +1,3 @@
var v = {
a
;

View file

@ -0,0 +1 @@
var v = { foo() { }; a: b; get baz() { }; }