10
10
/// <reference path='braceMatcher.ts' />
11
11
/// <reference path='breakpoints.ts' />
12
12
/// <reference path='indentation.ts' />
13
+ /// <reference path='signatureInfoHelpers.ts' />
13
14
/// <reference path='formatting\formatting.ts' />
14
15
/// <reference path='formatting\smartIndenter.ts' />
15
16
@@ -95,6 +96,7 @@ module ts {
95
96
public flags : NodeFlags ;
96
97
public parent : Node ;
97
98
private _children : Node [ ] ;
99
+ private _syntheticParent : Node ;
98
100
99
101
public getSourceFile ( ) : SourceFile {
100
102
var node : Node = this ;
@@ -150,6 +152,9 @@ module ts {
150
152
if ( pos < node . pos ) {
151
153
pos = this . addSyntheticNodes ( list . _children , pos , node . pos ) ;
152
154
}
155
+ else {
156
+ ( < NodeObject > node ) . _syntheticParent = list ;
157
+ }
153
158
list . _children . push ( node ) ;
154
159
pos = node . end ;
155
160
}
@@ -202,8 +207,13 @@ module ts {
202
207
return this . _children ;
203
208
}
204
209
210
+ public getIndexOfChild ( child : Node ) : number {
211
+ if ( ! this . _children ) this . createChildren ( ) ;
212
+ return this . _children . indexOf ( child ) ;
213
+ }
214
+
205
215
public getFirstToken ( sourceFile ?: SourceFile ) : Node {
206
- var children = this . getChildren ( sourceFile ) ;
216
+ var children = this . getChildren ( ) ;
207
217
for ( var i = 0 ; i < children . length ; i ++ ) {
208
218
var child = children [ i ] ;
209
219
if ( child . kind < SyntaxKind . Missing ) return child ;
@@ -219,6 +229,10 @@ module ts {
219
229
if ( child . kind > SyntaxKind . Missing ) return child . getLastToken ( sourceFile ) ;
220
230
}
221
231
}
232
+
233
+ public getSyntheticParentOrParent ( ) : Node {
234
+ return this . _syntheticParent || this . parent ;
235
+ }
222
236
}
223
237
224
238
class SymbolObject implements Symbol {
@@ -3474,7 +3488,105 @@ module ts {
3474
3488
3475
3489
// Reset writer back to undefined to make sure that we produce an error message if CompilerHost.writeFile method is called when we are not in getEmitOutput
3476
3490
writer = undefined ;
3477
- return emitOutput ;
3491
+ return emitOutput ;
3492
+ }
3493
+
3494
+ // Signature help
3495
+ function getSignatureHelpItems ( fileName : string , position : number ) : SignatureHelpItems {
3496
+ // If node is an argument, returns its index in the argument list
3497
+ // If not, returns -1
3498
+ function getArgumentIndex ( node : Node ) : number {
3499
+ // Treat the open paren / angle bracket of a call as the introduction of parameter slot 0
3500
+ var parent = ( < NodeObject > node ) . getSyntheticParentOrParent ( ) ;
3501
+ if ( parent . kind === SyntaxKind . SyntaxList ) {
3502
+ var grandparent = parent . parent ;
3503
+ if ( grandparent . kind === SyntaxKind . CallExpression || grandparent . kind === SyntaxKind . NewExpression ) {
3504
+ var index = ( < NodeObject > parent ) . getIndexOfChild ( node ) ;
3505
+ Debug . assert ( index >= 0 ) ;
3506
+ return index ;
3507
+ }
3508
+ }
3509
+
3510
+ if ( node . kind === SyntaxKind . LessThanToken || node . kind === SyntaxKind . OpenParenToken ) {
3511
+ return parent . kind === SyntaxKind . CallExpression || parent . kind === SyntaxKind . NewExpression
3512
+ ? 0
3513
+ : - 1 ;
3514
+ }
3515
+
3516
+ // TODO: Handle close paren or close angle bracket on nonempty list
3517
+
3518
+ return - 1 ;
3519
+ }
3520
+ //// Technically signature help should only be triggered on these characters
3521
+ //if (node.kind !== SyntaxKind.CommaToken && node.kind !== SyntaxKind.OpenParenToken && node.kind !== SyntaxKind.LessThanToken) {
3522
+ // return false;
3523
+ //}
3524
+
3525
+ //if (node.kind === SyntaxKind.CommaToken) {
3526
+ // if (node.parent.kind !== SyntaxKind.SyntaxList) {
3527
+ // return false;
3528
+ // }
3529
+
3530
+ // // node becomes the containing SyntaxList
3531
+ // node = node.parent;
3532
+ //}
3533
+
3534
+ //// node is open paren, less than, or a syntax list containing a comma
3535
+ //if (node.parent.kind === SyntaxKind.CallExpression || node.parent.kind === SyntaxKind.NewExpression) {
3536
+ // return true;
3537
+ //}
3538
+
3539
+ synchronizeHostData ( ) ;
3540
+
3541
+ // Decide whether to show signature help
3542
+ var sourceFile = getSourceFile ( fileName ) ;
3543
+ var node = getNodeAtPosition ( sourceFile , position ) ;
3544
+ // We only want this node if it is a token and it strictly contains the current position.
3545
+ // Otherwise we want the previous token
3546
+ var isToken = node . kind < SyntaxKind . Missing ;
3547
+ if ( ! isToken || position <= node . getStart ( ) || position >= node . getEnd ( ) ) {
3548
+ // This is a temporary hack until we figure out our token story.
3549
+ // The correct solution is to get the previous token
3550
+ node = SignatureInfoHelpers . findClosestRightmostSiblingFromLeft ( position , sourceFile ) ;
3551
+
3552
+ if ( ! node ) {
3553
+ return undefined ;
3554
+ }
3555
+ if ( node . parent . kind === SyntaxKind . CallExpression || node . parent . kind === SyntaxKind . NewExpression ) {
3556
+ if ( node === ( < CallExpression > node . parent ) . func ) {
3557
+ node = node . parent . getChildAt ( 1 ) ;
3558
+ }
3559
+ }
3560
+ }
3561
+
3562
+ var signatureHelpAvailable = false ;
3563
+ for ( var n = node ; n . kind !== SyntaxKind . SourceFile ; n = n . parent ) {
3564
+ if ( n . kind === SyntaxKind . FunctionBlock ) {
3565
+ break ;
3566
+ }
3567
+
3568
+ var index = getArgumentIndex ( n ) ;
3569
+ if ( index >= 0 ) {
3570
+ signatureHelpAvailable = true ;
3571
+ break ;
3572
+ }
3573
+
3574
+
3575
+ // TODO: Handle previous token logic
3576
+ // TODO: Handle generic call with incomplete
3577
+ }
3578
+
3579
+
3580
+ return signatureHelpAvailable
3581
+ ? new SignatureHelpItems ( undefined , undefined , undefined )
3582
+ : undefined ;
3583
+
3584
+
3585
+ }
3586
+
3587
+ function getSignatureHelpCurrentArgumentState ( fileName : string , position : number , applicableSpanStart : number ) : SignatureHelpState {
3588
+ synchronizeHostData ( ) ;
3589
+ return null ;
3478
3590
}
3479
3591
3480
3592
/// Syntactic features
@@ -4026,8 +4138,8 @@ module ts {
4026
4138
getCompletionsAtPosition : getCompletionsAtPosition ,
4027
4139
getCompletionEntryDetails : getCompletionEntryDetails ,
4028
4140
getTypeAtPosition : getTypeAtPosition ,
4029
- getSignatureHelpItems : ( filename , position ) : SignatureHelpItems => null ,
4030
- getSignatureHelpCurrentArgumentState : ( fileName , position , applicableSpanStart ) : SignatureHelpState => null ,
4141
+ getSignatureHelpItems : getSignatureHelpItems ,
4142
+ getSignatureHelpCurrentArgumentState : getSignatureHelpCurrentArgumentState ,
4031
4143
getDefinitionAtPosition : getDefinitionAtPosition ,
4032
4144
getReferencesAtPosition : getReferencesAtPosition ,
4033
4145
getOccurrencesAtPosition : getOccurrencesAtPosition ,
0 commit comments