@@ -628,12 +628,6 @@ module ts {
628628 Parameters , // Parameters in parameter list
629629 }
630630
631- enum TrailingCommaBehavior {
632- Disallow ,
633- Allow ,
634- Preserve
635- }
636-
637631 // Tracks whether we nested (directly or indirectly) in a certain control block.
638632 // Used for validating break and continue statements.
639633 enum ControlBlockContext {
@@ -1205,7 +1199,7 @@ module ts {
12051199 }
12061200
12071201 // Parses a comma-delimited list of elements
1208- function parseDelimitedList < T extends Node > ( kind : ParsingContext , parseElement : ( ) => T , trailingCommaBehavior : TrailingCommaBehavior ) : NodeArray < T > {
1202+ function parseDelimitedList < T extends Node > ( kind : ParsingContext , parseElement : ( ) => T , allowTrailingComma : boolean ) : NodeArray < T > {
12091203 var saveParsingContext = parsingContext ;
12101204 parsingContext |= 1 << kind ;
12111205 var result = < NodeArray < T > > [ ] ;
@@ -1230,15 +1224,14 @@ module ts {
12301224 else if ( isListTerminator ( kind ) ) {
12311225 // Check if the last token was a comma.
12321226 if ( commaStart >= 0 ) {
1233- if ( trailingCommaBehavior === TrailingCommaBehavior . Disallow ) {
1227+ if ( ! allowTrailingComma ) {
12341228 if ( file . syntacticErrors . length === errorCountBeforeParsingList ) {
12351229 // Report a grammar error so we don't affect lookahead
12361230 grammarErrorAtPos ( commaStart , scanner . getStartPos ( ) - commaStart , Diagnostics . Trailing_comma_not_allowed ) ;
12371231 }
12381232 }
1239- else if ( trailingCommaBehavior === TrailingCommaBehavior . Preserve ) {
1240- result . push ( < T > createNode ( SyntaxKind . OmittedExpression ) ) ;
1241- }
1233+ // Always preserve a trailing comma by marking it on the NodeArray
1234+ result . hasTrailingComma = true ;
12421235 }
12431236
12441237 break ;
@@ -1273,7 +1266,7 @@ module ts {
12731266
12741267 function parseBracketedList < T extends Node > ( kind : ParsingContext , parseElement : ( ) => T , startToken : SyntaxKind , endToken : SyntaxKind ) : NodeArray < T > {
12751268 if ( parseExpected ( startToken ) ) {
1276- var result = parseDelimitedList ( kind , parseElement , TrailingCommaBehavior . Disallow ) ;
1269+ var result = parseDelimitedList ( kind , parseElement , /*allowTrailingComma*/ false ) ;
12771270 parseExpected ( endToken ) ;
12781271 return result ;
12791272 }
@@ -2309,7 +2302,11 @@ module ts {
23092302 else {
23102303 parseExpected ( SyntaxKind . OpenParenToken ) ;
23112304 }
2312- callExpr . arguments = parseDelimitedList ( ParsingContext . ArgumentExpressions , parseAssignmentExpression , TrailingCommaBehavior . Disallow ) ;
2305+ // It is an error to have a trailing comma in an argument list. However, the checker
2306+ // needs evidence of a trailing comma in order to give good results for signature help.
2307+ // That is why we do not allow a trailing comma, but we "preserve" a trailing comma.
2308+ callExpr . arguments = parseDelimitedList ( ParsingContext . ArgumentExpressions ,
2309+ parseArgumentExpression , /*allowTrailingComma*/ false ) ;
23132310 parseExpected ( SyntaxKind . CloseParenToken ) ;
23142311 expr = finishNode ( callExpr ) ;
23152312 continue ;
@@ -2378,15 +2375,33 @@ module ts {
23782375 return finishNode ( node ) ;
23792376 }
23802377
2378+ function parseAssignmentExpressionOrOmittedExpression ( omittedExpressionDiagnostic : DiagnosticMessage ) : Expression {
2379+ if ( token === SyntaxKind . CommaToken ) {
2380+ if ( omittedExpressionDiagnostic ) {
2381+ var errorStart = scanner . getTokenPos ( ) ;
2382+ var errorLength = scanner . getTextPos ( ) - errorStart ;
2383+ grammarErrorAtPos ( errorStart , errorLength , omittedExpressionDiagnostic ) ;
2384+ }
2385+ return createNode ( SyntaxKind . OmittedExpression ) ;
2386+ }
2387+
2388+ return parseAssignmentExpression ( ) ;
2389+ }
2390+
23812391 function parseArrayLiteralElement ( ) : Expression {
2382- return token === SyntaxKind . CommaToken ? createNode ( SyntaxKind . OmittedExpression ) : parseAssignmentExpression ( ) ;
2392+ return parseAssignmentExpressionOrOmittedExpression ( /*omittedExpressionDiagnostic*/ undefined ) ;
2393+ }
2394+
2395+ function parseArgumentExpression ( ) : Expression {
2396+ return parseAssignmentExpressionOrOmittedExpression ( Diagnostics . Argument_expression_expected ) ;
23832397 }
23842398
23852399 function parseArrayLiteral ( ) : ArrayLiteral {
23862400 var node = < ArrayLiteral > createNode ( SyntaxKind . ArrayLiteral ) ;
23872401 parseExpected ( SyntaxKind . OpenBracketToken ) ;
23882402 if ( scanner . hasPrecedingLineBreak ( ) ) node . flags |= NodeFlags . MultiLine ;
2389- node . elements = parseDelimitedList ( ParsingContext . ArrayLiteralMembers , parseArrayLiteralElement , TrailingCommaBehavior . Preserve ) ;
2403+ node . elements = parseDelimitedList ( ParsingContext . ArrayLiteralMembers ,
2404+ parseArrayLiteralElement , /*allowTrailingComma*/ true ) ;
23902405 parseExpected ( SyntaxKind . CloseBracketToken ) ;
23912406 return finishNode ( node ) ;
23922407 }
@@ -2428,10 +2443,7 @@ module ts {
24282443 node . flags |= NodeFlags . MultiLine ;
24292444 }
24302445
2431- // ES3 itself does not accept a trailing comma in an object literal, however, we'd like to preserve it in ES5.
2432- var trailingCommaBehavior = languageVersion === ScriptTarget . ES3 ? TrailingCommaBehavior . Allow : TrailingCommaBehavior . Preserve ;
2433-
2434- node . properties = parseDelimitedList ( ParsingContext . ObjectLiteralMembers , parseObjectLiteralMember , trailingCommaBehavior ) ;
2446+ node . properties = parseDelimitedList ( ParsingContext . ObjectLiteralMembers , parseObjectLiteralMember , /*allowTrailingComma*/ true ) ;
24352447 parseExpected ( SyntaxKind . CloseBraceToken ) ;
24362448
24372449 var seen : Map < SymbolFlags > = { } ;
@@ -2520,7 +2532,11 @@ module ts {
25202532 parseExpected ( SyntaxKind . NewKeyword ) ;
25212533 node . func = parseCallAndAccess ( parsePrimaryExpression ( ) , /* inNewExpression */ true ) ;
25222534 if ( parseOptional ( SyntaxKind . OpenParenToken ) || token === SyntaxKind . LessThanToken && ( node . typeArguments = tryParse ( parseTypeArgumentsAndOpenParen ) ) ) {
2523- node . arguments = parseDelimitedList ( ParsingContext . ArgumentExpressions , parseAssignmentExpression , TrailingCommaBehavior . Disallow ) ;
2535+ // It is an error to have a trailing comma in an argument list. However, the checker
2536+ // needs evidence of a trailing comma in order to give good results for signature help.
2537+ // That is why we do not allow a trailing comma, but we "preserve" a trailing comma.
2538+ node . arguments = parseDelimitedList ( ParsingContext . ArgumentExpressions ,
2539+ parseArgumentExpression , /*allowTrailingComma*/ false ) ;
25242540 parseExpected ( SyntaxKind . CloseParenToken ) ;
25252541 }
25262542 return finishNode ( node ) ;
@@ -3089,7 +3105,8 @@ module ts {
30893105 }
30903106
30913107 function parseVariableDeclarationList ( flags : NodeFlags , noIn ?: boolean ) : NodeArray < VariableDeclaration > {
3092- return parseDelimitedList ( ParsingContext . VariableDeclarations , ( ) => parseVariableDeclaration ( flags , noIn ) , TrailingCommaBehavior . Disallow ) ;
3108+ return parseDelimitedList ( ParsingContext . VariableDeclarations ,
3109+ ( ) => parseVariableDeclaration ( flags , noIn ) , /*allowTrailingComma*/ false ) ;
30933110 }
30943111
30953112 function parseVariableStatement ( pos ?: number , flags ?: NodeFlags ) : VariableStatement {
@@ -3488,7 +3505,8 @@ module ts {
34883505 var implementsKeywordLength : number ;
34893506 if ( parseOptional ( SyntaxKind . ImplementsKeyword ) ) {
34903507 implementsKeywordLength = scanner . getStartPos ( ) - implementsKeywordStart ;
3491- node . implementedTypes = parseDelimitedList ( ParsingContext . BaseTypeReferences , parseTypeReference , TrailingCommaBehavior . Disallow ) ;
3508+ node . implementedTypes = parseDelimitedList ( ParsingContext . BaseTypeReferences ,
3509+ parseTypeReference , /*allowTrailingComma*/ false ) ;
34923510 }
34933511 var errorCountBeforeClassBody = file . syntacticErrors . length ;
34943512 if ( parseExpected ( SyntaxKind . OpenBraceToken ) ) {
@@ -3516,7 +3534,8 @@ module ts {
35163534 var extendsKeywordLength : number ;
35173535 if ( parseOptional ( SyntaxKind . ExtendsKeyword ) ) {
35183536 extendsKeywordLength = scanner . getStartPos ( ) - extendsKeywordStart ;
3519- node . baseTypes = parseDelimitedList ( ParsingContext . BaseTypeReferences , parseTypeReference , TrailingCommaBehavior . Disallow ) ;
3537+ node . baseTypes = parseDelimitedList ( ParsingContext . BaseTypeReferences ,
3538+ parseTypeReference , /*allowTrailingComma*/ false ) ;
35203539 }
35213540 var errorCountBeforeInterfaceBody = file . syntacticErrors . length ;
35223541 node . members = parseTypeLiteral ( ) . members ;
@@ -3580,7 +3599,8 @@ module ts {
35803599 parseExpected ( SyntaxKind . EnumKeyword ) ;
35813600 node . name = parseIdentifier ( ) ;
35823601 if ( parseExpected ( SyntaxKind . OpenBraceToken ) ) {
3583- node . members = parseDelimitedList ( ParsingContext . EnumMembers , parseAndCheckEnumMember , TrailingCommaBehavior . Allow ) ;
3602+ node . members = parseDelimitedList ( ParsingContext . EnumMembers ,
3603+ parseAndCheckEnumMember , /*allowTrailingComma*/ true ) ;
35843604 parseExpected ( SyntaxKind . CloseBraceToken ) ;
35853605 }
35863606 else {
0 commit comments