@@ -3479,175 +3479,22 @@ module ts {
3479
3479
return emitOutput ;
3480
3480
}
3481
3481
3482
- function getChildListThatStartsWithOpenerToken ( parent : Node , openerToken : Node , sourceFile : SourceFile ) : Node {
3483
- var children = parent . getChildren ( sourceFile ) ;
3484
- var indexOfOpenerToken = children . indexOf ( openerToken ) ;
3485
- return children [ indexOfOpenerToken + 1 ] ;
3486
- }
3487
-
3488
3482
// Signature help
3489
3483
function getSignatureHelpItems ( fileName : string , position : number ) : SignatureHelpItems {
3490
3484
synchronizeHostData ( ) ;
3491
3485
3492
- // Decide whether to show signature help
3493
3486
fileName = TypeScript . switchToForwardSlashes ( fileName ) ;
3494
3487
var sourceFile = getSourceFile ( fileName ) ;
3495
3488
var node = getNodeAtPosition ( sourceFile , position ) ;
3496
3489
3497
-
3498
- // Semantic filtering of signature help
3499
- var signatureHelpContext = getSignatureHelpArgumentContext ( node ) ;
3500
- if ( signatureHelpContext ) {
3501
- var call = < CallExpression > signatureHelpContext . list . parent ;
3502
- var candidates = < Signature [ ] > [ ] ;
3503
- var resolvedSignature = typeInfoResolver . getResolvedSignature ( call , candidates ) ;
3504
- return candidates . length
3505
- ? createSignatureHelpItems ( candidates , resolvedSignature , signatureHelpContext . list )
3506
- : undefined ;
3507
- }
3508
-
3509
- return undefined ;
3510
-
3511
-
3512
- // If node is an argument, returns its index in the argument list
3513
- // If not, returns -1
3514
- function getArgumentIndexInfo ( node : Node ) : ServicesSyntaxUtilities . ListItemInfo {
3515
- if ( node . parent . kind !== SyntaxKind . CallExpression && node . parent . kind !== SyntaxKind . NewExpression ) {
3516
- return undefined ;
3517
- }
3518
-
3519
- var parent = < CallExpression > node . parent ;
3520
- // Find out if 'node' is an argument, a type argument, or neither
3521
- if ( node . kind === SyntaxKind . LessThanToken || node . kind === SyntaxKind . OpenParenToken ) {
3522
- // Find the list that starts right *after* the < or ( token
3523
- var list = getChildListThatStartsWithOpenerToken ( parent , node , sourceFile ) ;
3524
- Debug . assert ( list ) ;
3525
- // Treat the open paren / angle bracket of a call as the introduction of parameter slot 0
3526
- return {
3527
- listItemIndex : 0 ,
3528
- list : list
3529
- } ;
3530
- }
3531
-
3532
- if ( node . kind === SyntaxKind . GreaterThanToken
3533
- || node . kind === SyntaxKind . CloseParenToken
3534
- || node === parent . func ) {
3535
- return undefined ;
3536
- }
3537
-
3538
- return ServicesSyntaxUtilities . findListItemInfo ( node ) ;
3539
- }
3540
-
3541
- function getSignatureHelpArgumentContext ( node : Node ) : ServicesSyntaxUtilities . ListItemInfo {
3542
- // We only want this node if it is a token and it strictly contains the current position.
3543
- // Otherwise we want the previous token
3544
- var isToken = node . kind < SyntaxKind . Missing ;
3545
- if ( ! isToken || position <= node . getStart ( ) || position >= node . getEnd ( ) ) {
3546
- node = ServicesSyntaxUtilities . findPrecedingToken ( position , sourceFile ) ;
3547
-
3548
- if ( ! node ) {
3549
- return undefined ;
3550
- }
3551
- }
3552
-
3553
- var signatureHelpAvailable = false ;
3554
- for ( var n = node ; n . kind !== SyntaxKind . SourceFile ; n = n . parent ) {
3555
- if ( n . kind === SyntaxKind . FunctionBlock ) {
3556
- return undefined ;
3557
- }
3558
-
3559
- var argumentInfo = getArgumentIndexInfo ( n ) ;
3560
- if ( argumentInfo ) {
3561
- return argumentInfo ;
3562
- }
3563
-
3564
-
3565
- // TODO: Handle previous token logic
3566
- // TODO: Handle generic call with incomplete
3567
- }
3568
- return undefined ;
3569
- }
3570
-
3571
- function createSignatureHelpItems ( candidates : Signature [ ] , bestSignature : Signature , argumentListOrTypeArgumentList : Node ) : SignatureHelpItems {
3572
- var items = map ( candidates , candidateSignature => {
3573
- var parameters = candidateSignature . parameters ;
3574
- var parameterHelpItems = parameters . length === 0 ? emptyArray : map ( parameters , p => {
3575
- var display = p . name ;
3576
- if ( candidateSignature . hasRestParameter && parameters [ parameters . length - 1 ] === p ) {
3577
- display = "..." + display ;
3578
- }
3579
- var isOptional = ! ! ( p . valueDeclaration . flags & NodeFlags . QuestionMark ) ;
3580
- if ( isOptional ) {
3581
- display += "?" ;
3582
- }
3583
- display += ": " + typeInfoResolver . typeToString ( typeInfoResolver . getTypeOfSymbol ( p ) , argumentListOrTypeArgumentList ) ;
3584
- return new SignatureHelpParameter ( p . name , "" , display , isOptional ) ;
3585
- } ) ;
3586
- var callTargetNode = ( < CallExpression > argumentListOrTypeArgumentList . parent ) . func ;
3587
- var callTargetSymbol = typeInfoResolver . getSymbolInfo ( callTargetNode ) ;
3588
- var signatureName = callTargetSymbol ? typeInfoResolver . symbolToString ( callTargetSymbol , /*enclosingDeclaration*/ undefined , /*meaning*/ undefined ) : "" ;
3589
- var prefix = signatureName ;
3590
- // TODO(jfreeman): Constraints?
3591
- if ( candidateSignature . typeParameters && candidateSignature . typeParameters . length ) {
3592
- prefix += "<" + map ( candidateSignature . typeParameters , tp => tp . symbol . name ) . join ( ", " ) + ">" ;
3593
- }
3594
- prefix += "(" ;
3595
- var suffix = "): " + typeInfoResolver . typeToString ( candidateSignature . getReturnType ( ) , argumentListOrTypeArgumentList ) ;
3596
- return new SignatureHelpItem ( candidateSignature . hasRestParameter , prefix , suffix , ", " , parameterHelpItems , "" ) ;
3597
- } ) ;
3598
- var selectedItemIndex = candidates . indexOf ( bestSignature ) ;
3599
- if ( selectedItemIndex < 0 ) {
3600
- selectedItemIndex = 0 ;
3601
- }
3602
-
3603
- var applicableSpanStart = argumentListOrTypeArgumentList . getFullStart ( ) ;
3604
- var applicableSpanEnd = skipTrivia ( sourceFile . text , argumentListOrTypeArgumentList . end , /*stopAfterLineBreak*/ false ) ;
3605
- var applicableSpan = new TypeScript . TextSpan ( applicableSpanStart , applicableSpanEnd - applicableSpanStart ) ;
3606
- return new SignatureHelpItems ( items , applicableSpan , selectedItemIndex ) ;
3607
- }
3490
+ return SignatureHelp . getSignatureHelpItems ( sourceFile , position , node , typeInfoResolver ) ;
3608
3491
}
3609
3492
3610
3493
function getSignatureHelpCurrentArgumentState ( fileName : string , position : number , applicableSpanStart : number ) : SignatureHelpState {
3611
3494
fileName = TypeScript . switchToForwardSlashes ( fileName ) ;
3612
3495
var sourceFile = getCurrentSourceFile ( fileName ) ;
3613
- var tokenPrecedingSpanStart = ServicesSyntaxUtilities . findPrecedingToken ( applicableSpanStart , sourceFile ) ;
3614
- if ( tokenPrecedingSpanStart . kind !== SyntaxKind . OpenParenToken && tokenPrecedingSpanStart . kind !== SyntaxKind . LessThanToken ) {
3615
- // The span start must have moved backward in the file (for example if the open paren was backspaced)
3616
- return undefined ;
3617
- }
3618
-
3619
- var tokenPrecedingCurrentPosition = ServicesSyntaxUtilities . findPrecedingToken ( position , sourceFile ) ;
3620
- var call = < CallExpression > tokenPrecedingSpanStart . parent ;
3621
- if ( tokenPrecedingCurrentPosition . kind === SyntaxKind . CloseParenToken || tokenPrecedingCurrentPosition . kind === SyntaxKind . GreaterThanToken ) {
3622
- if ( tokenPrecedingCurrentPosition . parent === call ) {
3623
- // This call expression is complete. Stop signature help.
3624
- return undefined ;
3625
- }
3626
- // TODO(jfreeman): handle other (incorrect) ways that a call expression can end
3627
- }
3628
-
3629
- Debug . assert ( call . kind === SyntaxKind . CallExpression || call . kind === SyntaxKind . NewExpression , "wrong call kind " + SyntaxKind [ call . kind ] ) ;
3630
-
3631
- var argumentListOrTypeArgumentList = getChildListThatStartsWithOpenerToken ( call , tokenPrecedingSpanStart , sourceFile ) ;
3632
- // Debug.assert(argumentListOrTypeArgumentList.getChildCount() === 0 || argumentListOrTypeArgumentList.getChildCount() % 2 === 1, "Even number of children");
3633
-
3634
- var numberOfCommas = countWhere ( argumentListOrTypeArgumentList . getChildren ( ) , arg => arg . kind === SyntaxKind . CommaToken ) ;
3635
- var argumentCount = numberOfCommas + 1 ;
3636
-
3637
-
3638
- if ( argumentCount <= 1 ) {
3639
- return new SignatureHelpState ( /*argumentIndex*/ 0 , argumentCount ) ;
3640
- }
3641
-
3642
- var indexOfNodeContainingPosition = ServicesSyntaxUtilities . findListItemIndexContainingPosition ( argumentListOrTypeArgumentList , position ) ;
3643
3496
3644
- // indexOfNodeContainingPosition checks that position is between pos and end of each child, so it is
3645
- // possible that we are to the right of all children. Assume that we are still within
3646
- // the applicable span and that we are typing the last argument
3647
- // Alternatively, we could be in range of one of the arguments, in which case we need to divide
3648
- // by 2 to exclude commas
3649
- var argumentIndex = indexOfNodeContainingPosition < 0 ? argumentCount - 1 : indexOfNodeContainingPosition / 2 ;
3650
- return new SignatureHelpState ( argumentIndex , argumentCount ) ;
3497
+ return SignatureHelp . getSignatureHelpCurrentArgumentState ( sourceFile , position , applicableSpanStart ) ;
3651
3498
}
3652
3499
3653
3500
/// Syntactic features
0 commit comments