Skip to content

Commit 5e1bd0c

Browse files
committed
Add applicableSpan to SignatureHelpItems
1 parent 9e81c5c commit 5e1bd0c

File tree

3 files changed

+41
-25
lines changed

3 files changed

+41
-25
lines changed

src/services/services.ts

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3483,32 +3483,43 @@ module ts {
34833483
function getSignatureHelpItems(fileName: string, position: number): SignatureHelpItems {
34843484
// If node is an argument, returns its index in the argument list
34853485
// If not, returns -1
3486-
function getArgumentIndex(node: Node): number {
3486+
function getArgumentIndexInfo(node: Node): ServicesSyntaxUtilities.ListItemInfo {
34873487
if (node.parent.kind !== SyntaxKind.CallExpression && node.parent.kind !== SyntaxKind.NewExpression) {
3488-
return -1;
3488+
return undefined;
34893489
}
34903490

34913491
var parent = <CallExpression>node.parent;
34923492
// Find out if 'node' is an argument, a type argument, or neither
3493-
// Treat the open paren / angle bracket of a call as the introduction of parameter slot 0
34943493
if (node.kind === SyntaxKind.LessThanToken || node.kind === SyntaxKind.OpenParenToken) {
3495-
return 0;
3494+
// Find the list that starts right *after* the < or ( token
3495+
var seenRelevantOpenerToken = false;
3496+
var list = forEach(parent.getChildren(), c => {
3497+
if (seenRelevantOpenerToken) {
3498+
Debug.assert(c.kind === SyntaxKind.SyntaxList);
3499+
return c;
3500+
}
3501+
if (c.kind === node.kind /*node is the relevant opener token we are looking for*/) {
3502+
seenRelevantOpenerToken = true;
3503+
}
3504+
});
3505+
Debug.assert(list);
3506+
// Treat the open paren / angle bracket of a call as the introduction of parameter slot 0
3507+
return {
3508+
listItemIndex: 0,
3509+
list: list
3510+
};
34963511
}
34973512

34983513
if (node.kind === SyntaxKind.GreaterThanToken
34993514
|| node.kind === SyntaxKind.CloseParenToken
35003515
|| node === parent.func) {
3501-
return -1;
3516+
return undefined;
35023517
}
35033518

3504-
return ServicesSyntaxUtilities.findListItemInfo(node).listItemIndex;
3519+
return ServicesSyntaxUtilities.findListItemInfo(node);
35053520
}
35063521

3507-
function getSignatureHelpArgumentContext(node: Node): {
3508-
argumentNode: Node;
3509-
argumentIndex: number;
3510-
isTypeArgument: boolean;
3511-
} {
3522+
function getSignatureHelpArgumentContext(node: Node): ServicesSyntaxUtilities.ListItemInfo {
35123523
// We only want this node if it is a token and it strictly contains the current position.
35133524
// Otherwise we want the previous token
35143525
var isToken = node.kind < SyntaxKind.Missing;
@@ -3526,13 +3537,9 @@ module ts {
35263537
return undefined;
35273538
}
35283539

3529-
var index = getArgumentIndex(n);
3530-
if (index >= 0) {
3531-
return {
3532-
argumentNode: n,
3533-
argumentIndex: index,
3534-
isTypeArgument: false
3535-
}
3540+
var argumentInfo = getArgumentIndexInfo(n);
3541+
if (argumentInfo) {
3542+
return argumentInfo;
35363543
}
35373544

35383545

@@ -3542,13 +3549,17 @@ module ts {
35423549
return undefined;
35433550
}
35443551

3545-
function getSignatureHelpItemsFromCandidateInfo(candidates: Signature[], bestSignature: Signature): SignatureHelpItems {
3552+
function getSignatureHelpItemsFromCandidateInfo(candidates: Signature[], bestSignature: Signature, argumentListOrTypeArgumentList: Node): SignatureHelpItems {
35463553
var items = map(candidates, candidateSignature => {
35473554
return new SignatureHelpItem(false, "", "", "", new Array<SignatureHelpParameter>(candidateSignature.parameters.length), "");
35483555
});
35493556
var selectedItemIndex = candidates.indexOf(bestSignature);
3550-
Debug.assert(selectedItemIndex >= 0);
3551-
return new SignatureHelpItems(items, undefined, selectedItemIndex);
3557+
if (selectedItemIndex < 0) {
3558+
selectedItemIndex = 0;
3559+
}
3560+
3561+
var applicableSpan = new TypeScript.TextSpan(argumentListOrTypeArgumentList.getFullStart(), argumentListOrTypeArgumentList.end);
3562+
return new SignatureHelpItems(items, applicableSpan, selectedItemIndex);
35523563
}
35533564

35543565
synchronizeHostData();
@@ -3561,11 +3572,11 @@ module ts {
35613572
// Semantic filtering of signature help
35623573
var signatureHelpContext = getSignatureHelpArgumentContext(node);
35633574
if (signatureHelpContext) {
3564-
var call = <CallExpression>signatureHelpContext.argumentNode.parent;
3575+
var call = <CallExpression>signatureHelpContext.list.parent;
35653576
var candidates = <Signature[]>[];
35663577
var resolvedSignature = typeInfoResolver.getResolvedSignature(call, candidates);
35673578
return candidates.length
3568-
? getSignatureHelpItemsFromCandidateInfo(candidates, resolvedSignature)
3579+
? getSignatureHelpItemsFromCandidateInfo(candidates, resolvedSignature, signatureHelpContext.list)
35693580
: undefined;
35703581
}
35713582

src/services/servicesSyntaxUtilities.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
// These utilities are common to multiple language service features.
22
module ts.ServicesSyntaxUtilities {
3-
export function findListItemInfo(node: Node): { listItemIndex: number; list: Node } {
3+
export interface ListItemInfo {
4+
listItemIndex: number;
5+
list: Node;
6+
}
7+
8+
export function findListItemInfo(node: Node): ListItemInfo {
49
// The node might be a list element (nonsynthetic) or a comma (synthetic). Either way, it will
510
// be parented by the container of the SyntaxList, not the SyntaxList itself.
611
// In order to find the list item index, we first need to locate SyntaxList itself and then search

tests/cases/fourslash/fourslash.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ module FourSlashInterface {
275275
}
276276

277277
public currentParameterHelpArgumentNameIs(name: string) {
278-
// FourSlash.currentTestState.verifyCurrentParameterHelpName(name);
278+
FourSlash.currentTestState.verifyCurrentParameterHelpName(name);
279279
}
280280

281281
public currentParameterSpanIs(parameter: string) {

0 commit comments

Comments
 (0)