Better error recovery when encountering an errant comma in a semicolon delimited list.
This commit is contained in:
parent
9351fc1920
commit
5db51fead8
2 changed files with 29 additions and 32 deletions
|
@ -1338,15 +1338,17 @@ module ts {
|
|||
return token === SyntaxKind.CloseBraceToken || token === SyntaxKind.EndOfFileToken || scanner.hasPrecedingLineBreak();
|
||||
}
|
||||
|
||||
function parseSemicolon(diagnosticMessage?: DiagnosticMessage): void {
|
||||
function parseSemicolon(diagnosticMessage?: DiagnosticMessage): boolean {
|
||||
if (canParseSemicolon()) {
|
||||
if (token === SyntaxKind.SemicolonToken) {
|
||||
// consume the semicolon if it was explicitly provided.
|
||||
nextToken();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
parseExpected(SyntaxKind.SemicolonToken, diagnosticMessage);
|
||||
return parseExpected(SyntaxKind.SemicolonToken, diagnosticMessage);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2052,13 +2054,27 @@ module ts {
|
|||
return requireCompleteParameterList ? undefined : createMissingList<ParameterDeclaration>();
|
||||
}
|
||||
|
||||
function parseTypeMemberSemicolon() {
|
||||
// Try to parse out an explicit or implicit (ASI) semicolon for a type member. If we
|
||||
// don't have one, then an appropriate error will be reported.
|
||||
if (parseSemicolon()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we don't have a semicolon, then the user may have written a comma instead
|
||||
// accidently (pretty easy to do since commas are so prevalent as list separators). So
|
||||
// just consume the comma and keep going. Note: we'll have already reported the error
|
||||
// about the missing semicolon above.
|
||||
parseOptional(SyntaxKind.CommaToken);
|
||||
}
|
||||
|
||||
function parseSignatureMember(kind: SyntaxKind): SignatureDeclaration {
|
||||
var node = <SignatureDeclaration>createNode(kind);
|
||||
if (kind === SyntaxKind.ConstructSignature) {
|
||||
parseExpected(SyntaxKind.NewKeyword);
|
||||
}
|
||||
fillSignature(SyntaxKind.ColonToken, /*yieldAndGeneratorParameterContext:*/ false, /*requireCompleteParameterList:*/ false, node);
|
||||
parseSemicolon();
|
||||
parseTypeMemberSemicolon();
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
|
@ -2130,11 +2146,11 @@ module ts {
|
|||
setModifiers(node, modifiers);
|
||||
node.parameters = parseBracketedList(ParsingContext.Parameters, parseParameter, SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken);
|
||||
node.type = parseTypeAnnotation();
|
||||
parseSemicolon();
|
||||
parseTypeMemberSemicolon();
|
||||
return finishNode(node)
|
||||
}
|
||||
|
||||
function parsePropertyOrMethod(): Declaration {
|
||||
function parsePropertyOrMethodSignature(): Declaration {
|
||||
var fullStart = scanner.getStartPos();
|
||||
var name = parsePropertyName();
|
||||
var questionToken = parseOptionalToken(SyntaxKind.QuestionToken);
|
||||
|
@ -2147,8 +2163,7 @@ module ts {
|
|||
// Method signatues don't exist in expression contexts. So they have neither
|
||||
// [Yield] nor [GeneratorParameter]
|
||||
fillSignature(SyntaxKind.ColonToken, /*yieldAndGeneratorParameterContext:*/ false, /*requireCompleteParameterList:*/ false, method);
|
||||
|
||||
parseSemicolon();
|
||||
parseTypeMemberSemicolon();
|
||||
return finishNode(method);
|
||||
}
|
||||
else {
|
||||
|
@ -2156,7 +2171,7 @@ module ts {
|
|||
property.name = name;
|
||||
property.questionToken = questionToken;
|
||||
property.type = parseTypeAnnotation();
|
||||
parseSemicolon();
|
||||
parseTypeMemberSemicolon();
|
||||
return finishNode(property);
|
||||
}
|
||||
}
|
||||
|
@ -2188,7 +2203,7 @@ module ts {
|
|||
return parseSignatureMember(SyntaxKind.CallSignature);
|
||||
case SyntaxKind.OpenBracketToken:
|
||||
// Indexer or computed property
|
||||
return isIndexSignature() ? parseIndexSignatureDeclaration(scanner.getStartPos(), /*modifiers:*/ undefined) : parsePropertyOrMethod();
|
||||
return isIndexSignature() ? parseIndexSignatureDeclaration(scanner.getStartPos(), /*modifiers:*/ undefined) : parsePropertyOrMethodSignature();
|
||||
case SyntaxKind.NewKeyword:
|
||||
if (lookAhead(isStartOfConstructSignature)) {
|
||||
return parseSignatureMember(SyntaxKind.ConstructSignature);
|
||||
|
@ -2196,10 +2211,10 @@ module ts {
|
|||
// fall through.
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
return parsePropertyOrMethod();
|
||||
return parsePropertyOrMethodSignature();
|
||||
default:
|
||||
if (isIdentifierOrKeyword()) {
|
||||
return parsePropertyOrMethod();
|
||||
return parsePropertyOrMethodSignature();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,29 +1,11 @@
|
|||
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserCommaInTypeMemberList2.ts(1,38): error TS1134: Variable declaration expected.
|
||||
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserCommaInTypeMemberList2.ts(1,60): error TS1005: ';' expected.
|
||||
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserCommaInTypeMemberList2.ts(1,70): error TS1128: Declaration or statement expected.
|
||||
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserCommaInTypeMemberList2.ts(1,53): error TS1005: ';' expected.
|
||||
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserCommaInTypeMemberList2.ts(1,9): error TS2304: Cannot find name '$'.
|
||||
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserCommaInTypeMemberList2.ts(1,31): error TS2304: Cannot find name 'any'.
|
||||
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserCommaInTypeMemberList2.ts(1,50): error TS2304: Cannot find name 'any'.
|
||||
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserCommaInTypeMemberList2.ts(1,55): error TS2304: Cannot find name 'width'.
|
||||
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserCommaInTypeMemberList2.ts(1,62): error TS2304: Cannot find name 'string'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserCommaInTypeMemberList2.ts (8 errors) ====
|
||||
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserCommaInTypeMemberList2.ts (2 errors) ====
|
||||
var s = $.extend< { workItem: any }, { workItem: any, width: string }>({ workItem: this._workItem }, {});
|
||||
~
|
||||
!!! error TS1134: Variable declaration expected.
|
||||
~
|
||||
~
|
||||
!!! error TS1005: ';' expected.
|
||||
~
|
||||
!!! error TS1128: Declaration or statement expected.
|
||||
~
|
||||
!!! error TS2304: Cannot find name '$'.
|
||||
~~~
|
||||
!!! error TS2304: Cannot find name 'any'.
|
||||
~~~
|
||||
!!! error TS2304: Cannot find name 'any'.
|
||||
~~~~~
|
||||
!!! error TS2304: Cannot find name 'width'.
|
||||
~~~~~~
|
||||
!!! error TS2304: Cannot find name 'string'.
|
||||
|
Loading…
Reference in a new issue