@@ -628,12 +628,6 @@ module ts {
628
628
Parameters , // Parameters in parameter list
629
629
}
630
630
631
- enum TrailingCommaBehavior {
632
- Disallow ,
633
- Allow ,
634
- Preserve
635
- }
636
-
637
631
// Tracks whether we nested (directly or indirectly) in a certain control block.
638
632
// Used for validating break and continue statements.
639
633
enum ControlBlockContext {
@@ -1205,7 +1199,7 @@ module ts {
1205
1199
}
1206
1200
1207
1201
// 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 > {
1209
1203
var saveParsingContext = parsingContext ;
1210
1204
parsingContext |= 1 << kind ;
1211
1205
var result = < NodeArray < T > > [ ] ;
@@ -1230,15 +1224,14 @@ module ts {
1230
1224
else if ( isListTerminator ( kind ) ) {
1231
1225
// Check if the last token was a comma.
1232
1226
if ( commaStart >= 0 ) {
1233
- if ( trailingCommaBehavior === TrailingCommaBehavior . Disallow ) {
1227
+ if ( ! allowTrailingComma ) {
1234
1228
if ( file . syntacticErrors . length === errorCountBeforeParsingList ) {
1235
1229
// Report a grammar error so we don't affect lookahead
1236
1230
grammarErrorAtPos ( commaStart , scanner . getStartPos ( ) - commaStart , Diagnostics . Trailing_comma_not_allowed ) ;
1237
1231
}
1238
1232
}
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 ;
1242
1235
}
1243
1236
1244
1237
break ;
@@ -1273,7 +1266,7 @@ module ts {
1273
1266
1274
1267
function parseBracketedList < T extends Node > ( kind : ParsingContext , parseElement : ( ) => T , startToken : SyntaxKind , endToken : SyntaxKind ) : NodeArray < T > {
1275
1268
if ( parseExpected ( startToken ) ) {
1276
- var result = parseDelimitedList ( kind , parseElement , TrailingCommaBehavior . Disallow ) ;
1269
+ var result = parseDelimitedList ( kind , parseElement , /*allowTrailingComma*/ false ) ;
1277
1270
parseExpected ( endToken ) ;
1278
1271
return result ;
1279
1272
}
@@ -2174,10 +2167,10 @@ module ts {
2174
2167
// The identifier eval or arguments may not appear as the LeftHandSideExpression of an
2175
2168
// Assignment operator(11.13) or of a PostfixExpression(11.3) or as the UnaryExpression
2176
2169
// operated upon by a Prefix Increment(11.4.4) or a Prefix Decrement(11.4.5) operator
2177
- if ( ( token === SyntaxKind . PlusPlusToken || token === SyntaxKind . MinusMinusToken ) && isEvalOrArgumentsIdentifier ( operand ) ) {
2170
+ if ( ( operator === SyntaxKind . PlusPlusToken || operator === SyntaxKind . MinusMinusToken ) && isEvalOrArgumentsIdentifier ( operand ) ) {
2178
2171
reportInvalidUseInStrictMode ( < Identifier > operand ) ;
2179
2172
}
2180
- else if ( token === SyntaxKind . DeleteKeyword && operand . kind === SyntaxKind . Identifier ) {
2173
+ else if ( operator === SyntaxKind . DeleteKeyword && operand . kind === SyntaxKind . Identifier ) {
2181
2174
// When a delete operator occurs within strict mode code, a SyntaxError is thrown if its
2182
2175
// UnaryExpression is a direct reference to a variable, function argument, or function name
2183
2176
grammarErrorOnNode ( operand , Diagnostics . delete_cannot_be_called_on_an_identifier_in_strict_mode ) ;
@@ -2309,7 +2302,11 @@ module ts {
2309
2302
else {
2310
2303
parseExpected ( SyntaxKind . OpenParenToken ) ;
2311
2304
}
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 ) ;
2313
2310
parseExpected ( SyntaxKind . CloseParenToken ) ;
2314
2311
expr = finishNode ( callExpr ) ;
2315
2312
continue ;
@@ -2378,15 +2375,33 @@ module ts {
2378
2375
return finishNode ( node ) ;
2379
2376
}
2380
2377
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
+
2381
2391
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 ) ;
2383
2397
}
2384
2398
2385
2399
function parseArrayLiteral ( ) : ArrayLiteral {
2386
2400
var node = < ArrayLiteral > createNode ( SyntaxKind . ArrayLiteral ) ;
2387
2401
parseExpected ( SyntaxKind . OpenBracketToken ) ;
2388
2402
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 ) ;
2390
2405
parseExpected ( SyntaxKind . CloseBracketToken ) ;
2391
2406
return finishNode ( node ) ;
2392
2407
}
@@ -2428,10 +2443,7 @@ module ts {
2428
2443
node . flags |= NodeFlags . MultiLine ;
2429
2444
}
2430
2445
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 ) ;
2435
2447
parseExpected ( SyntaxKind . CloseBraceToken ) ;
2436
2448
2437
2449
var seen : Map < SymbolFlags > = { } ;
@@ -2520,7 +2532,11 @@ module ts {
2520
2532
parseExpected ( SyntaxKind . NewKeyword ) ;
2521
2533
node . func = parseCallAndAccess ( parsePrimaryExpression ( ) , /* inNewExpression */ true ) ;
2522
2534
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 ) ;
2524
2540
parseExpected ( SyntaxKind . CloseParenToken ) ;
2525
2541
}
2526
2542
return finishNode ( node ) ;
@@ -3089,7 +3105,8 @@ module ts {
3089
3105
}
3090
3106
3091
3107
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 ) ;
3093
3110
}
3094
3111
3095
3112
function parseVariableStatement ( pos ?: number , flags ?: NodeFlags ) : VariableStatement {
@@ -3488,7 +3505,8 @@ module ts {
3488
3505
var implementsKeywordLength : number ;
3489
3506
if ( parseOptional ( SyntaxKind . ImplementsKeyword ) ) {
3490
3507
implementsKeywordLength = scanner . getStartPos ( ) - implementsKeywordStart ;
3491
- node . implementedTypes = parseDelimitedList ( ParsingContext . BaseTypeReferences , parseTypeReference , TrailingCommaBehavior . Disallow ) ;
3508
+ node . implementedTypes = parseDelimitedList ( ParsingContext . BaseTypeReferences ,
3509
+ parseTypeReference , /*allowTrailingComma*/ false ) ;
3492
3510
}
3493
3511
var errorCountBeforeClassBody = file . syntacticErrors . length ;
3494
3512
if ( parseExpected ( SyntaxKind . OpenBraceToken ) ) {
@@ -3516,7 +3534,8 @@ module ts {
3516
3534
var extendsKeywordLength : number ;
3517
3535
if ( parseOptional ( SyntaxKind . ExtendsKeyword ) ) {
3518
3536
extendsKeywordLength = scanner . getStartPos ( ) - extendsKeywordStart ;
3519
- node . baseTypes = parseDelimitedList ( ParsingContext . BaseTypeReferences , parseTypeReference , TrailingCommaBehavior . Disallow ) ;
3537
+ node . baseTypes = parseDelimitedList ( ParsingContext . BaseTypeReferences ,
3538
+ parseTypeReference , /*allowTrailingComma*/ false ) ;
3520
3539
}
3521
3540
var errorCountBeforeInterfaceBody = file . syntacticErrors . length ;
3522
3541
node . members = parseTypeLiteral ( ) . members ;
@@ -3580,7 +3599,8 @@ module ts {
3580
3599
parseExpected ( SyntaxKind . EnumKeyword ) ;
3581
3600
node . name = parseIdentifier ( ) ;
3582
3601
if ( parseExpected ( SyntaxKind . OpenBraceToken ) ) {
3583
- node . members = parseDelimitedList ( ParsingContext . EnumMembers , parseAndCheckEnumMember , TrailingCommaBehavior . Allow ) ;
3602
+ node . members = parseDelimitedList ( ParsingContext . EnumMembers ,
3603
+ parseAndCheckEnumMember , /*allowTrailingComma*/ true ) ;
3584
3604
parseExpected ( SyntaxKind . CloseBraceToken ) ;
3585
3605
}
3586
3606
else {
0 commit comments