Skip to content

Commit 03821df

Browse files
committed
Remove getCurrentArgumentState
1 parent a79a1d2 commit 03821df

File tree

1 file changed

+32
-62
lines changed

1 file changed

+32
-62
lines changed

src/services/signatureHelp.ts

Lines changed: 32 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -172,15 +172,15 @@ module ts.SignatureHelp {
172172
return undefined;
173173
}
174174

175-
var argumentList = getContainingArgumentList(startingToken);
175+
var argumentInfo = getContainingArgumentInfo(startingToken);
176176
cancellationToken.throwIfCancellationRequested();
177177

178178
// Semantic filtering of signature help
179-
if (!argumentList) {
179+
if (!argumentInfo) {
180180
return undefined;
181181
}
182182

183-
var call = <CallExpression>argumentList.parent;
183+
var call = <CallExpression>argumentInfo.list.parent;
184184
var candidates = <Signature[]>[];
185185
var resolvedSignature = typeInfoResolver.getResolvedSignature(call, candidates);
186186
cancellationToken.throwIfCancellationRequested();
@@ -189,13 +189,13 @@ module ts.SignatureHelp {
189189
return undefined;
190190
}
191191

192-
return createSignatureHelpItems(candidates, resolvedSignature, argumentList);
192+
return createSignatureHelpItems(candidates, resolvedSignature, argumentInfo);
193193

194194
/**
195195
* If node is an argument, returns its index in the argument list.
196196
* If not, returns -1.
197197
*/
198-
function getImmediatelyContainingArgumentList(node: Node): Node {
198+
function getImmediatelyContainingArgumentInfo(node: Node): ListItemInfo {
199199
if (node.parent.kind !== SyntaxKind.CallExpression && node.parent.kind !== SyntaxKind.NewExpression) {
200200
return undefined;
201201
}
@@ -216,10 +216,14 @@ module ts.SignatureHelp {
216216
var parent = <CallExpression>node.parent;
217217
// Find out if 'node' is an argument, a type argument, or neither
218218
if (node.kind === SyntaxKind.LessThanToken || node.kind === SyntaxKind.OpenParenToken) {
219-
// Find the list that starts right *after* the < or ( token
219+
// Find the list that starts right *after* the < or ( token.
220+
// If the user has just opened a list, consider this item 0.
220221
var list = getChildListThatStartsWithOpenerToken(parent, node, sourceFile);
221222
Debug.assert(list);
222-
return list;
223+
return {
224+
list: list,
225+
listItemIndex: 0
226+
};
223227
}
224228

225229
if (node.kind === SyntaxKind.GreaterThanToken
@@ -228,18 +232,18 @@ module ts.SignatureHelp {
228232
return undefined;
229233
}
230234

231-
return findContainingList(node);
235+
return findListItemInfo(node);
232236
}
233237

234-
function getContainingArgumentList(node: Node): Node {
238+
function getContainingArgumentInfo(node: Node): ListItemInfo {
235239
for (var n = node; n.kind !== SyntaxKind.SourceFile; n = n.parent) {
236240
if (n.kind === SyntaxKind.FunctionBlock) {
237241
return undefined;
238242
}
239243

240-
var argumentList = getImmediatelyContainingArgumentList(n);
241-
if (argumentList) {
242-
return argumentList;
244+
var argumentInfo = getImmediatelyContainingArgumentInfo(n);
245+
if (argumentInfo) {
246+
return argumentInfo;
243247
}
244248

245249

@@ -248,7 +252,8 @@ module ts.SignatureHelp {
248252
return undefined;
249253
}
250254

251-
function createSignatureHelpItems(candidates: Signature[], bestSignature: Signature, argumentListOrTypeArgumentList: Node): SignatureHelpItems {
255+
function createSignatureHelpItems(candidates: Signature[], bestSignature: Signature, argumentInfoOrTypeArgumentInfo: ListItemInfo): SignatureHelpItems {
256+
var argumentListOrTypeArgumentList = argumentInfoOrTypeArgumentInfo.list;
252257
var items: SignatureHelpItem[] = map(candidates, candidateSignature => {
253258
var parameters = candidateSignature.parameters;
254259
var parameterHelpItems: SignatureHelpParameter[] = parameters.length === 0 ? emptyArray : map(parameters, p => {
@@ -338,63 +343,28 @@ module ts.SignatureHelp {
338343
var applicableSpanEnd = skipTrivia(sourceFile.text, argumentListOrTypeArgumentList.end, /*stopAfterLineBreak*/ false);
339344
var applicableSpan = new TypeScript.TextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart);
340345

341-
var state = getSignatureHelpCurrentArgumentState(sourceFile, position, applicableSpanStart);
346+
// The listItemIndex we got back includes commas. Our goal is to return the index of the proper
347+
// item (not including commas). Here are some examples:
348+
// 1. foo(a, b, c $) -> the listItemIndex is 4, we want to return 2
349+
// 2. foo(a, b, $ c) -> listItemIndex is 3, we want to return 2
350+
// 3. foo($a) -> listItemIndex is 0, we want to return 0
351+
//
352+
// In general, we want to subtract the number of commas before the current index.
353+
// But if we are on a comma, we also want to pretend we are on the argument *following*
354+
// the comma. That amounts to taking the ceiling of half the index.
355+
var argumentIndex = (argumentInfoOrTypeArgumentInfo.listItemIndex + 1) >> 1;
356+
var numberOfCommas = countWhere(argumentListOrTypeArgumentList.getChildren(), arg => arg.kind === SyntaxKind.CommaToken);
357+
var argumentCount = numberOfCommas + 1;
342358
return {
343359
items: items,
344360
applicableSpan: applicableSpan,
345361
selectedItemIndex: selectedItemIndex,
346-
argumentIndex: state.argumentIndex,
347-
argumentCount: state.argumentCount
362+
argumentIndex: argumentIndex,
363+
argumentCount: argumentCount
348364
};
349365
}
350366
}
351367

352-
function getSignatureHelpCurrentArgumentState(sourceFile: SourceFile, position: number, applicableSpanStart: number): { argumentIndex: number; argumentCount: number } {
353-
var tokenPrecedingSpanStart = findPrecedingToken(applicableSpanStart, sourceFile);
354-
if (!tokenPrecedingSpanStart) {
355-
return undefined;
356-
}
357-
358-
if (tokenPrecedingSpanStart.kind !== SyntaxKind.OpenParenToken && tokenPrecedingSpanStart.kind !== SyntaxKind.LessThanToken) {
359-
// The span start must have moved backward in the file (for example if the open paren was backspaced)
360-
return undefined;
361-
}
362-
363-
var tokenPrecedingCurrentPosition = findPrecedingToken(position, sourceFile);
364-
var call = <CallExpression>tokenPrecedingSpanStart.parent;
365-
Debug.assert(call.kind === SyntaxKind.CallExpression || call.kind === SyntaxKind.NewExpression, "wrong call kind " + SyntaxKind[call.kind]);
366-
if (tokenPrecedingCurrentPosition.kind === SyntaxKind.CloseParenToken || tokenPrecedingCurrentPosition.kind === SyntaxKind.GreaterThanToken) {
367-
if (tokenPrecedingCurrentPosition.parent === call) {
368-
// This call expression is complete. Stop signature help.
369-
return undefined;
370-
}
371-
}
372-
373-
var argumentListOrTypeArgumentList = getChildListThatStartsWithOpenerToken(call, tokenPrecedingSpanStart, sourceFile);
374-
// Debug.assert(argumentListOrTypeArgumentList.getChildCount() === 0 || argumentListOrTypeArgumentList.getChildCount() % 2 === 1, "Even number of children");
375-
376-
// The call might be finished, but incorrectly. Check if we are still within the bounds of the call
377-
if (position > skipTrivia(sourceFile.text, argumentListOrTypeArgumentList.end, /*stopAfterLineBreak*/ false)) {
378-
return undefined;
379-
}
380-
381-
var numberOfCommas = countWhere(argumentListOrTypeArgumentList.getChildren(), arg => arg.kind === SyntaxKind.CommaToken);
382-
var argumentCount = numberOfCommas + 1;
383-
if (argumentCount <= 1) {
384-
return { argumentIndex: 0, argumentCount: argumentCount };
385-
}
386-
387-
var indexOfNodeContainingPosition = findListItemIndexContainingPosition(argumentListOrTypeArgumentList, position);
388-
389-
// indexOfNodeContainingPosition checks that position is between pos and end of each child, so it is
390-
// possible that we are to the right of all children. Assume that we are still within
391-
// the applicable span and that we are typing the last argument
392-
// Alternatively, we could be in range of one of the arguments, in which case we need to divide
393-
// by 2 to exclude commas. Use bit shifting in order to take the floor of the division.
394-
var argumentIndex = indexOfNodeContainingPosition < 0 ? argumentCount - 1 : indexOfNodeContainingPosition >> 1;
395-
return { argumentIndex: argumentIndex, argumentCount: argumentCount };
396-
}
397-
398368
function getChildListThatStartsWithOpenerToken(parent: Node, openerToken: Node, sourceFile: SourceFile): Node {
399369
var children = parent.getChildren(sourceFile);
400370
var indexOfOpenerToken = children.indexOf(openerToken);

0 commit comments

Comments
 (0)