22/// <reference path="scanner.ts"/>
33
44namespace 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+
514 let NodeConstructor : new ( kind : SyntaxKind , pos : number , end : number ) => Node ;
615 let TokenConstructor : new ( kind : SyntaxKind , pos : number , end : number ) => Node ;
716 let IdentifierConstructor : new ( kind : SyntaxKind , pos : number , end : number ) => Node ;
@@ -2218,25 +2227,32 @@ namespace ts {
22182227
22192228 function fillSignature (
22202229 returnToken : SyntaxKind . ColonToken | SyntaxKind . EqualsGreaterThanToken ,
2221- yieldContext : boolean ,
2222- awaitContext : boolean ,
2223- requireCompleteParameterList : boolean ,
2230+ flags : SignatureFlags ,
22242231 signature : SignatureDeclaration ) : void {
2225-
2226- const returnTokenRequired = returnToken === SyntaxKind . EqualsGreaterThanToken ;
22272232 signature . typeParameters = parseTypeParameters ( ) ;
2228- signature . parameters = parseParameterList ( yieldContext , awaitContext , requireCompleteParameterList ) ;
2233+ signature . parameters = parseParameterList ( flags ) ;
22292234
2235+ const returnTokenRequired = returnToken === SyntaxKind . EqualsGreaterThanToken ;
22302236 if ( returnTokenRequired ) {
22312237 parseExpected ( returnToken ) ;
22322238 signature . type = parseTypeOrTypePredicate ( ) ;
22332239 }
22342240 else if ( parseOptional ( returnToken ) ) {
22352241 signature . type = parseTypeOrTypePredicate ( ) ;
22362242 }
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+ }
22372253 }
22382254
2239- function parseParameterList ( yieldContext : boolean , awaitContext : boolean , requireCompleteParameterList : boolean ) {
2255+ function parseParameterList ( flags : SignatureFlags ) {
22402256 // FormalParameters [Yield,Await]: (modified)
22412257 // [empty]
22422258 // FormalParameterList[?Yield,Await]
@@ -2254,15 +2270,15 @@ namespace ts {
22542270 const savedYieldContext = inYieldContext ( ) ;
22552271 const savedAwaitContext = inAwaitContext ( ) ;
22562272
2257- setYieldContext ( yieldContext ) ;
2258- setAwaitContext ( awaitContext ) ;
2273+ setYieldContext ( ! ! ( flags & SignatureFlags . Yield ) ) ;
2274+ setAwaitContext ( ! ! ( flags & SignatureFlags . Await ) ) ;
22592275
22602276 const result = parseDelimitedList ( ParsingContext . Parameters , parseParameter ) ;
22612277
22622278 setYieldContext ( savedYieldContext ) ;
22632279 setAwaitContext ( savedAwaitContext ) ;
22642280
2265- if ( ! parseExpected ( SyntaxKind . CloseParenToken ) && requireCompleteParameterList ) {
2281+ if ( ! parseExpected ( SyntaxKind . CloseParenToken ) && ( flags & SignatureFlags . RequireCompleteParameterList ) ) {
22662282 // Caller insisted that we had to end with a ) We didn't. So just return
22672283 // undefined here.
22682284 return undefined ;
@@ -2274,7 +2290,7 @@ namespace ts {
22742290 // We didn't even have an open paren. If the caller requires a complete parameter list,
22752291 // we definitely can't provide that. However, if they're ok with an incomplete one,
22762292 // then just return an empty set of parameters.
2277- return requireCompleteParameterList ? undefined : createMissingList < ParameterDeclaration > ( ) ;
2293+ return ( flags & SignatureFlags . RequireCompleteParameterList ) ? undefined : createMissingList < ParameterDeclaration > ( ) ;
22782294 }
22792295
22802296 function parseTypeMemberSemicolon ( ) {
@@ -2293,7 +2309,7 @@ namespace ts {
22932309 if ( kind === SyntaxKind . ConstructSignature ) {
22942310 parseExpected ( SyntaxKind . NewKeyword ) ;
22952311 }
2296- fillSignature ( SyntaxKind . ColonToken , /*yieldContext*/ false , /*awaitContext*/ false , /*requireCompleteParameterList*/ false , node ) ;
2312+ fillSignature ( SyntaxKind . ColonToken , SignatureFlags . Type , node ) ;
22972313 parseTypeMemberSemicolon ( ) ;
22982314 return addJSDocComment ( finishNode ( node ) ) ;
22992315 }
@@ -2383,7 +2399,7 @@ namespace ts {
23832399
23842400 // Method signatures don't exist in expression contexts. So they have neither
23852401 // [Yield] nor [Await]
2386- fillSignature ( SyntaxKind . ColonToken , /*yieldContext*/ false , /*awaitContext*/ false , /*requireCompleteParameterList*/ false , method ) ;
2402+ fillSignature ( SyntaxKind . ColonToken , SignatureFlags . Type , method ) ;
23872403 parseTypeMemberSemicolon ( ) ;
23882404 return addJSDocComment ( finishNode ( method ) ) ;
23892405 }
@@ -2527,7 +2543,7 @@ namespace ts {
25272543 if ( kind === SyntaxKind . ConstructorType ) {
25282544 parseExpected ( SyntaxKind . NewKeyword ) ;
25292545 }
2530- fillSignature ( SyntaxKind . EqualsGreaterThanToken , /*yieldContext*/ false , /*awaitContext*/ false , /*requireCompleteParameterList*/ false , node ) ;
2546+ fillSignature ( SyntaxKind . EqualsGreaterThanToken , SignatureFlags . Type , node ) ;
25312547 return finishNode ( node ) ;
25322548 }
25332549
@@ -3254,7 +3270,7 @@ namespace ts {
32543270 function parseParenthesizedArrowFunctionExpressionHead ( allowAmbiguity : boolean ) : ArrowFunction {
32553271 const node = < ArrowFunction > createNode ( SyntaxKind . ArrowFunction ) ;
32563272 node . modifiers = parseModifiersForArrowFunction ( ) ;
3257- const isAsync = ! ! ( getModifierFlags ( node ) & ModifierFlags . Async ) ;
3273+ const isAsync = ( getModifierFlags ( node ) & ModifierFlags . Async ) ? SignatureFlags . Await : SignatureFlags . None ;
32583274
32593275 // Arrow functions are never generators.
32603276 //
@@ -3263,7 +3279,7 @@ namespace ts {
32633279 // a => (b => c)
32643280 // And think that "(b =>" was actually a parenthesized arrow function with a missing
32653281 // close paren.
3266- fillSignature ( SyntaxKind . ColonToken , /*yieldContext*/ false , /*awaitContext*/ isAsync , /*requireCompleteParameterList*/ ! allowAmbiguity , node ) ;
3282+ fillSignature ( SyntaxKind . ColonToken , isAsync | ( allowAmbiguity ? SignatureFlags . None : SignatureFlags . RequireCompleteParameterList ) , node ) ;
32673283
32683284 // If we couldn't get parameters, we definitely could not parse out an arrow function.
32693285 if ( ! node . parameters ) {
@@ -3288,7 +3304,7 @@ namespace ts {
32883304
32893305 function parseArrowFunctionExpressionBody ( isAsync : boolean ) : Block | Expression {
32903306 if ( token ( ) === SyntaxKind . OpenBraceToken ) {
3291- return parseFunctionBlock ( /*allowYield*/ false , /*allowAwait*/ isAsync , /*ignoreMissingOpenBrace*/ false ) ;
3307+ return parseFunctionBlock ( isAsync ? SignatureFlags . Await : SignatureFlags . None ) ;
32923308 }
32933309
32943310 if ( token ( ) !== SyntaxKind . SemicolonToken &&
@@ -3309,8 +3325,8 @@ namespace ts {
33093325 // try to recover better. If we don't do this, then the next close curly we see may end
33103326 // up preemptively closing the containing construct.
33113327 //
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 ) ) ;
33143330 }
33153331
33163332 return isAsync
@@ -4386,16 +4402,16 @@ namespace ts {
43864402 parseExpected ( SyntaxKind . FunctionKeyword ) ;
43874403 node . asteriskToken = parseOptionalToken ( SyntaxKind . AsteriskToken ) ;
43884404
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 ;
43914407 node . name =
43924408 isGenerator && isAsync ? doInYieldAndAwaitContext ( parseOptionalIdentifier ) :
43934409 isGenerator ? doInYieldContext ( parseOptionalIdentifier ) :
43944410 isAsync ? doInAwaitContext ( parseOptionalIdentifier ) :
43954411 parseOptionalIdentifier ( ) ;
43964412
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 ) ;
43994415
44004416 if ( saveDecoratorContext ) {
44014417 setDecoratorContext ( /*val*/ true ) ;
@@ -4444,12 +4460,12 @@ namespace ts {
44444460 return finishNode ( node ) ;
44454461 }
44464462
4447- function parseFunctionBlock ( allowYield : boolean , allowAwait : boolean , ignoreMissingOpenBrace : boolean , diagnosticMessage ?: DiagnosticMessage ) : Block {
4463+ function parseFunctionBlock ( flags : SignatureFlags , diagnosticMessage ?: DiagnosticMessage ) : Block {
44484464 const savedYieldContext = inYieldContext ( ) ;
4449- setYieldContext ( allowYield ) ;
4465+ setYieldContext ( ! ! ( flags & SignatureFlags . Yield ) ) ;
44504466
44514467 const savedAwaitContext = inAwaitContext ( ) ;
4452- setAwaitContext ( allowAwait ) ;
4468+ setAwaitContext ( ! ! ( flags & SignatureFlags . Await ) ) ;
44534469
44544470 // We may be in a [Decorator] context when parsing a function expression or
44554471 // arrow function. The body of the function is not in [Decorator] context.
@@ -4458,7 +4474,7 @@ namespace ts {
44584474 setDecoratorContext ( /*val*/ false ) ;
44594475 }
44604476
4461- const block = parseBlock ( ignoreMissingOpenBrace , diagnosticMessage ) ;
4477+ const block = parseBlock ( ! ! ( flags & SignatureFlags . IgnoreMissingOpenBrace ) , diagnosticMessage ) ;
44624478
44634479 if ( saveDecoratorContext ) {
44644480 setDecoratorContext ( /*val*/ true ) ;
@@ -5005,13 +5021,13 @@ namespace ts {
50055021 return ! scanner . hasPrecedingLineBreak ( ) && ( isIdentifier ( ) || token ( ) === SyntaxKind . StringLiteral ) ;
50065022 }
50075023
5008- function parseFunctionBlockOrSemicolon ( isGenerator : boolean , isAsync : boolean , diagnosticMessage ?: DiagnosticMessage ) : Block {
5024+ function parseFunctionBlockOrSemicolon ( flags : SignatureFlags , diagnosticMessage ?: DiagnosticMessage ) : Block {
50095025 if ( token ( ) !== SyntaxKind . OpenBraceToken && canParseSemicolon ( ) ) {
50105026 parseSemicolon ( ) ;
50115027 return ;
50125028 }
50135029
5014- return parseFunctionBlock ( isGenerator , isAsync , /*ignoreMissingOpenBrace*/ false , diagnosticMessage ) ;
5030+ return parseFunctionBlock ( flags , diagnosticMessage ) ;
50155031 }
50165032
50175033 // DECLARATIONS
@@ -5146,10 +5162,10 @@ namespace ts {
51465162 parseExpected ( SyntaxKind . FunctionKeyword ) ;
51475163 node . asteriskToken = parseOptionalToken ( SyntaxKind . AsteriskToken ) ;
51485164 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 ) ;
51535169 return addJSDocComment ( finishNode ( node ) ) ;
51545170 }
51555171
@@ -5158,8 +5174,8 @@ namespace ts {
51585174 node . decorators = decorators ;
51595175 node . modifiers = modifiers ;
51605176 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 ) ;
51635179 return addJSDocComment ( finishNode ( node ) ) ;
51645180 }
51655181
@@ -5170,10 +5186,10 @@ namespace ts {
51705186 method . asteriskToken = asteriskToken ;
51715187 method . name = name ;
51725188 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 ) ;
51775193 return addJSDocComment ( finishNode ( method ) ) ;
51785194 }
51795195
@@ -5226,8 +5242,8 @@ namespace ts {
52265242 node . decorators = decorators ;
52275243 node . modifiers = modifiers ;
52285244 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 ) ;
52315247 return addJSDocComment ( finishNode ( node ) ) ;
52325248 }
52335249
0 commit comments