Skip to content

Commit 49fdb98

Browse files
committed
Signature help present with completed signatures
1 parent 927bab6 commit 49fdb98

File tree

4 files changed

+533
-320
lines changed

4 files changed

+533
-320
lines changed

Jakefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ var servicesSources = [
5454
}).concat([
5555
"services.ts",
5656
"shims.ts",
57+
"signatureInfoHelpers.ts"
5758
].map(function (f) {
5859
return path.join(servicesDirectory, f);
5960
}));

src/services/services.ts

Lines changed: 116 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
/// <reference path='braceMatcher.ts' />
1111
/// <reference path='breakpoints.ts' />
1212
/// <reference path='indentation.ts' />
13+
/// <reference path='signatureInfoHelpers.ts' />
1314
/// <reference path='formatting\formatting.ts' />
1415
/// <reference path='formatting\smartIndenter.ts' />
1516

@@ -95,6 +96,7 @@ module ts {
9596
public flags: NodeFlags;
9697
public parent: Node;
9798
private _children: Node[];
99+
private _syntheticParent: Node;
98100

99101
public getSourceFile(): SourceFile {
100102
var node: Node = this;
@@ -150,6 +152,9 @@ module ts {
150152
if (pos < node.pos) {
151153
pos = this.addSyntheticNodes(list._children, pos, node.pos);
152154
}
155+
else {
156+
(<NodeObject>node)._syntheticParent = list;
157+
}
153158
list._children.push(node);
154159
pos = node.end;
155160
}
@@ -202,8 +207,13 @@ module ts {
202207
return this._children;
203208
}
204209

210+
public getIndexOfChild(child: Node): number {
211+
if (!this._children) this.createChildren();
212+
return this._children.indexOf(child);
213+
}
214+
205215
public getFirstToken(sourceFile?: SourceFile): Node {
206-
var children = this.getChildren(sourceFile);
216+
var children = this.getChildren();
207217
for (var i = 0; i < children.length; i++) {
208218
var child = children[i];
209219
if (child.kind < SyntaxKind.Missing) return child;
@@ -219,6 +229,10 @@ module ts {
219229
if (child.kind > SyntaxKind.Missing) return child.getLastToken(sourceFile);
220230
}
221231
}
232+
233+
public getSyntheticParentOrParent(): Node {
234+
return this._syntheticParent || this.parent;
235+
}
222236
}
223237

224238
class SymbolObject implements Symbol {
@@ -3474,7 +3488,105 @@ module ts {
34743488

34753489
// 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
34763490
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;
34783590
}
34793591

34803592
/// Syntactic features
@@ -4026,8 +4138,8 @@ module ts {
40264138
getCompletionsAtPosition: getCompletionsAtPosition,
40274139
getCompletionEntryDetails: getCompletionEntryDetails,
40284140
getTypeAtPosition: getTypeAtPosition,
4029-
getSignatureHelpItems: (filename, position): SignatureHelpItems => null,
4030-
getSignatureHelpCurrentArgumentState: (fileName, position, applicableSpanStart): SignatureHelpState => null,
4141+
getSignatureHelpItems: getSignatureHelpItems,
4142+
getSignatureHelpCurrentArgumentState: getSignatureHelpCurrentArgumentState,
40314143
getDefinitionAtPosition: getDefinitionAtPosition,
40324144
getReferencesAtPosition: getReferencesAtPosition,
40334145
getOccurrencesAtPosition: getOccurrencesAtPosition,

0 commit comments

Comments
 (0)