2
2
/// <reference path="scanner.ts"/>
3
3
4
4
namespace ts {
5
+ const enum SignatureFlags {
6
+ None = 0 ,
7
+ Yield = 1 << 0 ,
8
+ Await = 1 << 1 ,
9
+ Type = 1 << 2 ,
10
+ RequireCompleteParameterList = 1 << 3 ,
11
+ IgnoreMissingOpenBrace = 1 << 4 ,
12
+ }
13
+
5
14
let NodeConstructor : new ( kind : SyntaxKind , pos : number , end : number ) => Node ;
6
15
let TokenConstructor : new ( kind : SyntaxKind , pos : number , end : number ) => Node ;
7
16
let IdentifierConstructor : new ( kind : SyntaxKind , pos : number , end : number ) => Node ;
@@ -2218,25 +2227,32 @@ namespace ts {
2218
2227
2219
2228
function fillSignature (
2220
2229
returnToken : SyntaxKind . ColonToken | SyntaxKind . EqualsGreaterThanToken ,
2221
- yieldContext : boolean ,
2222
- awaitContext : boolean ,
2223
- requireCompleteParameterList : boolean ,
2230
+ flags : SignatureFlags ,
2224
2231
signature : SignatureDeclaration ) : void {
2225
-
2226
- const returnTokenRequired = returnToken === SyntaxKind . EqualsGreaterThanToken ;
2227
2232
signature . typeParameters = parseTypeParameters ( ) ;
2228
- signature . parameters = parseParameterList ( yieldContext , awaitContext , requireCompleteParameterList ) ;
2233
+ signature . parameters = parseParameterList ( flags ) ;
2229
2234
2235
+ const returnTokenRequired = returnToken === SyntaxKind . EqualsGreaterThanToken ;
2230
2236
if ( returnTokenRequired ) {
2231
2237
parseExpected ( returnToken ) ;
2232
2238
signature . type = parseTypeOrTypePredicate ( ) ;
2233
2239
}
2234
2240
else if ( parseOptional ( returnToken ) ) {
2235
2241
signature . type = parseTypeOrTypePredicate ( ) ;
2236
2242
}
2243
+ else if ( flags & SignatureFlags . Type ) {
2244
+ const start = scanner . getTokenPos ( ) ;
2245
+ const length = scanner . getTextPos ( ) - start ;
2246
+ const backwardToken = parseOptional ( returnToken === SyntaxKind . ColonToken ? SyntaxKind . EqualsGreaterThanToken : SyntaxKind . ColonToken ) ;
2247
+ if ( backwardToken ) {
2248
+ // This is easy to get backward, especially in type contexts, so parse the type anyway
2249
+ signature . type = parseTypeOrTypePredicate ( ) ;
2250
+ parseErrorAtPosition ( start , length , Diagnostics . _0_expected , tokenToString ( returnToken ) ) ;
2251
+ }
2252
+ }
2237
2253
}
2238
2254
2239
- function parseParameterList ( yieldContext : boolean , awaitContext : boolean , requireCompleteParameterList : boolean ) {
2255
+ function parseParameterList ( flags : SignatureFlags ) {
2240
2256
// FormalParameters [Yield,Await]: (modified)
2241
2257
// [empty]
2242
2258
// FormalParameterList[?Yield,Await]
@@ -2254,15 +2270,15 @@ namespace ts {
2254
2270
const savedYieldContext = inYieldContext ( ) ;
2255
2271
const savedAwaitContext = inAwaitContext ( ) ;
2256
2272
2257
- setYieldContext ( yieldContext ) ;
2258
- setAwaitContext ( awaitContext ) ;
2273
+ setYieldContext ( ! ! ( flags & SignatureFlags . Yield ) ) ;
2274
+ setAwaitContext ( ! ! ( flags & SignatureFlags . Await ) ) ;
2259
2275
2260
2276
const result = parseDelimitedList ( ParsingContext . Parameters , parseParameter ) ;
2261
2277
2262
2278
setYieldContext ( savedYieldContext ) ;
2263
2279
setAwaitContext ( savedAwaitContext ) ;
2264
2280
2265
- if ( ! parseExpected ( SyntaxKind . CloseParenToken ) && requireCompleteParameterList ) {
2281
+ if ( ! parseExpected ( SyntaxKind . CloseParenToken ) && ( flags & SignatureFlags . RequireCompleteParameterList ) ) {
2266
2282
// Caller insisted that we had to end with a ) We didn't. So just return
2267
2283
// undefined here.
2268
2284
return undefined ;
@@ -2274,7 +2290,7 @@ namespace ts {
2274
2290
// We didn't even have an open paren. If the caller requires a complete parameter list,
2275
2291
// we definitely can't provide that. However, if they're ok with an incomplete one,
2276
2292
// then just return an empty set of parameters.
2277
- return requireCompleteParameterList ? undefined : createMissingList < ParameterDeclaration > ( ) ;
2293
+ return ( flags & SignatureFlags . RequireCompleteParameterList ) ? undefined : createMissingList < ParameterDeclaration > ( ) ;
2278
2294
}
2279
2295
2280
2296
function parseTypeMemberSemicolon ( ) {
@@ -2293,7 +2309,7 @@ namespace ts {
2293
2309
if ( kind === SyntaxKind . ConstructSignature ) {
2294
2310
parseExpected ( SyntaxKind . NewKeyword ) ;
2295
2311
}
2296
- fillSignature ( SyntaxKind . ColonToken , /*yieldContext*/ false , /*awaitContext*/ false , /*requireCompleteParameterList*/ false , node ) ;
2312
+ fillSignature ( SyntaxKind . ColonToken , SignatureFlags . Type , node ) ;
2297
2313
parseTypeMemberSemicolon ( ) ;
2298
2314
return addJSDocComment ( finishNode ( node ) ) ;
2299
2315
}
@@ -2383,7 +2399,7 @@ namespace ts {
2383
2399
2384
2400
// Method signatures don't exist in expression contexts. So they have neither
2385
2401
// [Yield] nor [Await]
2386
- fillSignature ( SyntaxKind . ColonToken , /*yieldContext*/ false , /*awaitContext*/ false , /*requireCompleteParameterList*/ false , method ) ;
2402
+ fillSignature ( SyntaxKind . ColonToken , SignatureFlags . Type , method ) ;
2387
2403
parseTypeMemberSemicolon ( ) ;
2388
2404
return addJSDocComment ( finishNode ( method ) ) ;
2389
2405
}
@@ -2527,7 +2543,7 @@ namespace ts {
2527
2543
if ( kind === SyntaxKind . ConstructorType ) {
2528
2544
parseExpected ( SyntaxKind . NewKeyword ) ;
2529
2545
}
2530
- fillSignature ( SyntaxKind . EqualsGreaterThanToken , /*yieldContext*/ false , /*awaitContext*/ false , /*requireCompleteParameterList*/ false , node ) ;
2546
+ fillSignature ( SyntaxKind . EqualsGreaterThanToken , SignatureFlags . Type , node ) ;
2531
2547
return finishNode ( node ) ;
2532
2548
}
2533
2549
@@ -3254,7 +3270,7 @@ namespace ts {
3254
3270
function parseParenthesizedArrowFunctionExpressionHead ( allowAmbiguity : boolean ) : ArrowFunction {
3255
3271
const node = < ArrowFunction > createNode ( SyntaxKind . ArrowFunction ) ;
3256
3272
node . modifiers = parseModifiersForArrowFunction ( ) ;
3257
- const isAsync = ! ! ( getModifierFlags ( node ) & ModifierFlags . Async ) ;
3273
+ const isAsync = ( getModifierFlags ( node ) & ModifierFlags . Async ) ? SignatureFlags . Await : SignatureFlags . None ;
3258
3274
3259
3275
// Arrow functions are never generators.
3260
3276
//
@@ -3263,7 +3279,7 @@ namespace ts {
3263
3279
// a => (b => c)
3264
3280
// And think that "(b =>" was actually a parenthesized arrow function with a missing
3265
3281
// close paren.
3266
- fillSignature ( SyntaxKind . ColonToken , /*yieldContext*/ false , /*awaitContext*/ isAsync , /*requireCompleteParameterList*/ ! allowAmbiguity , node ) ;
3282
+ fillSignature ( SyntaxKind . ColonToken , isAsync | ( allowAmbiguity ? SignatureFlags . None : SignatureFlags . RequireCompleteParameterList ) , node ) ;
3267
3283
3268
3284
// If we couldn't get parameters, we definitely could not parse out an arrow function.
3269
3285
if ( ! node . parameters ) {
@@ -3288,7 +3304,7 @@ namespace ts {
3288
3304
3289
3305
function parseArrowFunctionExpressionBody ( isAsync : boolean ) : Block | Expression {
3290
3306
if ( token ( ) === SyntaxKind . OpenBraceToken ) {
3291
- return parseFunctionBlock ( /*allowYield*/ false , /*allowAwait*/ isAsync , /*ignoreMissingOpenBrace*/ false ) ;
3307
+ return parseFunctionBlock ( isAsync ? SignatureFlags . Await : SignatureFlags . None ) ;
3292
3308
}
3293
3309
3294
3310
if ( token ( ) !== SyntaxKind . SemicolonToken &&
@@ -3309,8 +3325,8 @@ namespace ts {
3309
3325
// try to recover better. If we don't do this, then the next close curly we see may end
3310
3326
// up preemptively closing the containing construct.
3311
3327
//
3312
- // Note: even when 'ignoreMissingOpenBrace ' is passed as true , parseBody will still error.
3313
- return parseFunctionBlock ( /*allowYield*/ false , /*allowAwait*/ isAsync , /*ignoreMissingOpenBrace*/ true ) ;
3328
+ // Note: even when 'IgnoreMissingOpenBrace ' is passed, parseBody will still error.
3329
+ return parseFunctionBlock ( SignatureFlags . IgnoreMissingOpenBrace | ( isAsync ? SignatureFlags . Await : SignatureFlags . None ) ) ;
3314
3330
}
3315
3331
3316
3332
return isAsync
@@ -4386,16 +4402,16 @@ namespace ts {
4386
4402
parseExpected ( SyntaxKind . FunctionKeyword ) ;
4387
4403
node . asteriskToken = parseOptionalToken ( SyntaxKind . AsteriskToken ) ;
4388
4404
4389
- const isGenerator = ! ! node . asteriskToken ;
4390
- const isAsync = ! ! ( getModifierFlags ( node ) & ModifierFlags . Async ) ;
4405
+ const isGenerator = node . asteriskToken ? SignatureFlags . Yield : SignatureFlags . None ;
4406
+ const isAsync = ( getModifierFlags ( node ) & ModifierFlags . Async ) ? SignatureFlags . Await : SignatureFlags . None ;
4391
4407
node . name =
4392
4408
isGenerator && isAsync ? doInYieldAndAwaitContext ( parseOptionalIdentifier ) :
4393
4409
isGenerator ? doInYieldContext ( parseOptionalIdentifier ) :
4394
4410
isAsync ? doInAwaitContext ( parseOptionalIdentifier ) :
4395
4411
parseOptionalIdentifier ( ) ;
4396
4412
4397
- fillSignature ( SyntaxKind . ColonToken , /*yieldContext*/ isGenerator , /*awaitContext*/ isAsync , /*requireCompleteParameterList*/ false , node ) ;
4398
- node . body = parseFunctionBlock ( /*allowYield*/ isGenerator , /*allowAwait*/ isAsync , /*ignoreMissingOpenBrace*/ false ) ;
4413
+ fillSignature ( SyntaxKind . ColonToken , isGenerator | isAsync , node ) ;
4414
+ node . body = parseFunctionBlock ( isGenerator | isAsync ) ;
4399
4415
4400
4416
if ( saveDecoratorContext ) {
4401
4417
setDecoratorContext ( /*val*/ true ) ;
@@ -4444,12 +4460,12 @@ namespace ts {
4444
4460
return finishNode ( node ) ;
4445
4461
}
4446
4462
4447
- function parseFunctionBlock ( allowYield : boolean , allowAwait : boolean , ignoreMissingOpenBrace : boolean , diagnosticMessage ?: DiagnosticMessage ) : Block {
4463
+ function parseFunctionBlock ( flags : SignatureFlags , diagnosticMessage ?: DiagnosticMessage ) : Block {
4448
4464
const savedYieldContext = inYieldContext ( ) ;
4449
- setYieldContext ( allowYield ) ;
4465
+ setYieldContext ( ! ! ( flags & SignatureFlags . Yield ) ) ;
4450
4466
4451
4467
const savedAwaitContext = inAwaitContext ( ) ;
4452
- setAwaitContext ( allowAwait ) ;
4468
+ setAwaitContext ( ! ! ( flags & SignatureFlags . Await ) ) ;
4453
4469
4454
4470
// We may be in a [Decorator] context when parsing a function expression or
4455
4471
// arrow function. The body of the function is not in [Decorator] context.
@@ -4458,7 +4474,7 @@ namespace ts {
4458
4474
setDecoratorContext ( /*val*/ false ) ;
4459
4475
}
4460
4476
4461
- const block = parseBlock ( ignoreMissingOpenBrace , diagnosticMessage ) ;
4477
+ const block = parseBlock ( ! ! ( flags & SignatureFlags . IgnoreMissingOpenBrace ) , diagnosticMessage ) ;
4462
4478
4463
4479
if ( saveDecoratorContext ) {
4464
4480
setDecoratorContext ( /*val*/ true ) ;
@@ -5005,13 +5021,13 @@ namespace ts {
5005
5021
return ! scanner . hasPrecedingLineBreak ( ) && ( isIdentifier ( ) || token ( ) === SyntaxKind . StringLiteral ) ;
5006
5022
}
5007
5023
5008
- function parseFunctionBlockOrSemicolon ( isGenerator : boolean , isAsync : boolean , diagnosticMessage ?: DiagnosticMessage ) : Block {
5024
+ function parseFunctionBlockOrSemicolon ( flags : SignatureFlags , diagnosticMessage ?: DiagnosticMessage ) : Block {
5009
5025
if ( token ( ) !== SyntaxKind . OpenBraceToken && canParseSemicolon ( ) ) {
5010
5026
parseSemicolon ( ) ;
5011
5027
return ;
5012
5028
}
5013
5029
5014
- return parseFunctionBlock ( isGenerator , isAsync , /*ignoreMissingOpenBrace*/ false , diagnosticMessage ) ;
5030
+ return parseFunctionBlock ( flags , diagnosticMessage ) ;
5015
5031
}
5016
5032
5017
5033
// DECLARATIONS
@@ -5146,10 +5162,10 @@ namespace ts {
5146
5162
parseExpected ( SyntaxKind . FunctionKeyword ) ;
5147
5163
node . asteriskToken = parseOptionalToken ( SyntaxKind . AsteriskToken ) ;
5148
5164
node . name = hasModifier ( node , ModifierFlags . Default ) ? parseOptionalIdentifier ( ) : parseIdentifier ( ) ;
5149
- const isGenerator = ! ! node . asteriskToken ;
5150
- const isAsync = hasModifier ( node , ModifierFlags . Async ) ;
5151
- fillSignature ( SyntaxKind . ColonToken , /*yieldContext*/ isGenerator , /*awaitContext*/ isAsync , /*requireCompleteParameterList*/ false , node ) ;
5152
- node . body = parseFunctionBlockOrSemicolon ( isGenerator , isAsync , Diagnostics . or_expected ) ;
5165
+ const isGenerator = node . asteriskToken ? SignatureFlags . Yield : SignatureFlags . None ;
5166
+ const isAsync = hasModifier ( node , ModifierFlags . Async ) ? SignatureFlags . Await : SignatureFlags . None ;
5167
+ fillSignature ( SyntaxKind . ColonToken , isGenerator | isAsync , node ) ;
5168
+ node . body = parseFunctionBlockOrSemicolon ( isGenerator | isAsync , Diagnostics . or_expected ) ;
5153
5169
return addJSDocComment ( finishNode ( node ) ) ;
5154
5170
}
5155
5171
@@ -5158,8 +5174,8 @@ namespace ts {
5158
5174
node . decorators = decorators ;
5159
5175
node . modifiers = modifiers ;
5160
5176
parseExpected ( SyntaxKind . ConstructorKeyword ) ;
5161
- fillSignature ( SyntaxKind . ColonToken , /*yieldContext*/ false , /*awaitContext*/ false , /*requireCompleteParameterList*/ false , node ) ;
5162
- node . body = parseFunctionBlockOrSemicolon ( /*isGenerator*/ false , /*isAsync*/ false , Diagnostics . or_expected ) ;
5177
+ fillSignature ( SyntaxKind . ColonToken , SignatureFlags . None , node ) ;
5178
+ node . body = parseFunctionBlockOrSemicolon ( SignatureFlags . None , Diagnostics . or_expected ) ;
5163
5179
return addJSDocComment ( finishNode ( node ) ) ;
5164
5180
}
5165
5181
@@ -5170,10 +5186,10 @@ namespace ts {
5170
5186
method . asteriskToken = asteriskToken ;
5171
5187
method . name = name ;
5172
5188
method . questionToken = questionToken ;
5173
- const isGenerator = ! ! asteriskToken ;
5174
- const isAsync = hasModifier ( method , ModifierFlags . Async ) ;
5175
- fillSignature ( SyntaxKind . ColonToken , /*yieldContext*/ isGenerator , /*awaitContext*/ isAsync , /*requireCompleteParameterList*/ false , method ) ;
5176
- method . body = parseFunctionBlockOrSemicolon ( isGenerator , isAsync , diagnosticMessage ) ;
5189
+ const isGenerator = asteriskToken ? SignatureFlags . Yield : SignatureFlags . None ;
5190
+ const isAsync = hasModifier ( method , ModifierFlags . Async ) ? SignatureFlags . Await : SignatureFlags . None ;
5191
+ fillSignature ( SyntaxKind . ColonToken , isGenerator | isAsync , method ) ;
5192
+ method . body = parseFunctionBlockOrSemicolon ( isGenerator | isAsync , diagnosticMessage ) ;
5177
5193
return addJSDocComment ( finishNode ( method ) ) ;
5178
5194
}
5179
5195
@@ -5226,8 +5242,8 @@ namespace ts {
5226
5242
node . decorators = decorators ;
5227
5243
node . modifiers = modifiers ;
5228
5244
node . name = parsePropertyName ( ) ;
5229
- fillSignature ( SyntaxKind . ColonToken , /*yieldContext*/ false , /*awaitContext*/ false , /*requireCompleteParameterList*/ false , node ) ;
5230
- node . body = parseFunctionBlockOrSemicolon ( /*isGenerator*/ false , /*isAsync*/ false ) ;
5245
+ fillSignature ( SyntaxKind . ColonToken , SignatureFlags . None , node ) ;
5246
+ node . body = parseFunctionBlockOrSemicolon ( SignatureFlags . None ) ;
5231
5247
return addJSDocComment ( finishNode ( node ) ) ;
5232
5248
}
5233
5249
0 commit comments