Skip to content

Commit c20e4f5

Browse files
committed
Produce SignatureHelpParameters from type parameters for generic help
1 parent 808ded8 commit c20e4f5

File tree

3 files changed

+66
-30
lines changed

3 files changed

+66
-30
lines changed

src/compiler/checker.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,14 +1366,14 @@ module ts {
13661366
}
13671367
}
13681368

1369-
function buildDisplayForParametersAndDelimiters(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, typeStack?: Type[]) {
1369+
function buildDisplayForParametersAndDelimiters(parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, typeStack?: Type[]) {
13701370
writePunctuation(writer, SyntaxKind.OpenParenToken);
1371-
for (var i = 0; i < signature.parameters.length; i++) {
1371+
for (var i = 0; i < parameters.length; i++) {
13721372
if (i > 0) {
13731373
writePunctuation(writer, SyntaxKind.CommaToken);
13741374
writeSpace(writer);
13751375
}
1376-
buildParameterDisplay(signature.parameters[i], writer, enclosingDeclaration, flags, typeStack);
1376+
buildParameterDisplay(parameters[i], writer, enclosingDeclaration, flags, typeStack);
13771377
}
13781378
writePunctuation(writer, SyntaxKind.CloseParenToken);
13791379
}
@@ -1400,7 +1400,7 @@ module ts {
14001400
buildDisplayForTypeParametersAndDelimiters(signature.typeParameters, writer, enclosingDeclaration, flags, typeStack);
14011401
}
14021402

1403-
buildDisplayForParametersAndDelimiters(signature, writer, enclosingDeclaration, flags, typeStack);
1403+
buildDisplayForParametersAndDelimiters(signature.parameters, writer, enclosingDeclaration, flags, typeStack);
14041404
buildReturnTypeDisplay(signature, writer, enclosingDeclaration, flags, typeStack);
14051405
}
14061406

@@ -1411,6 +1411,7 @@ module ts {
14111411
buildTypeDisplay: buildTypeDisplay,
14121412
buildTypeParameterDisplay: buildTypeParameterDisplay,
14131413
buildParameterDisplay: buildParameterDisplay,
1414+
buildDisplayForParametersAndDelimiters: buildDisplayForParametersAndDelimiters,
14141415
buildDisplayForTypeParametersAndDelimiters: buildDisplayForTypeParametersAndDelimiters,
14151416
buildDisplayForTypeArgumentsAndDelimiters: buildDisplayForTypeArgumentsAndDelimiters,
14161417
buildTypeParameterDisplayFromSymbol: buildTypeParameterDisplayFromSymbol,

src/compiler/types.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -675,8 +675,9 @@ module ts {
675675
buildParameterDisplay(parameter: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
676676
buildTypeParameterDisplay(tp: TypeParameter, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
677677
buildTypeParameterDisplayFromSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaraiton?: Node, flags?: TypeFormatFlags): void;
678-
buildDisplayForTypeParametersAndDelimiters(typeParameters: TypeParameter[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, typeStack?: Type[]): void;
679-
buildReturnTypeDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, typeStack?: Type[]): void;
678+
buildDisplayForParametersAndDelimiters(parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
679+
buildDisplayForTypeParametersAndDelimiters(typeParameters: TypeParameter[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
680+
buildReturnTypeDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
680681
}
681682

682683
export interface SymbolWriter {

src/services/signatureHelp.ts

Lines changed: 58 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -293,33 +293,41 @@ module ts.SignatureHelp {
293293

294294
function createSignatureHelpItems(candidates: Signature[], bestSignature: Signature, argumentInfoOrTypeArgumentInfo: ListItemInfo): SignatureHelpItems {
295295
var argumentListOrTypeArgumentList = argumentInfoOrTypeArgumentInfo.list;
296-
var items: SignatureHelpItem[] = map(candidates, candidateSignature => {
297-
var parameters = candidateSignature.parameters;
298-
var parameterHelpItems: SignatureHelpParameter[] = parameters.length === 0 ? emptyArray : map(parameters, p => {
299-
var displayParts = mapToDisplayParts(writer =>
300-
typeInfoResolver.getSymbolDisplayBuilder().buildParameterDisplay(p, writer, argumentListOrTypeArgumentList));
301-
302-
var isOptional = !!(p.valueDeclaration.flags & NodeFlags.QuestionMark);
303-
304-
return {
305-
name: p.name,
306-
documentation: p.getDocumentationComment(),
307-
displayParts: displayParts,
308-
isOptional: isOptional
309-
};
310-
});
296+
var parent = <CallExpression>argumentListOrTypeArgumentList.parent;
297+
var isTypeParameterHelp = parent.typeArguments && parent.typeArguments.pos === argumentListOrTypeArgumentList.pos;
298+
Debug.assert(isTypeParameterHelp || parent.arguments.pos === argumentListOrTypeArgumentList.pos);
311299

312-
var callTargetNode = (<CallExpression>argumentListOrTypeArgumentList.parent).func;
313-
var callTargetSymbol = typeInfoResolver.getSymbolInfo(callTargetNode);
300+
var callTargetNode = (<CallExpression>argumentListOrTypeArgumentList.parent).func;
301+
var callTargetSymbol = typeInfoResolver.getSymbolInfo(callTargetNode);
302+
var callTargetDisplayParts = callTargetSymbol && symbolToDisplayParts(typeInfoResolver, callTargetSymbol, /*enclosingDeclaration*/ undefined, /*meaning*/ undefined);
303+
var items: SignatureHelpItem[] = map(candidates, candidateSignature => {
304+
var signatureHelpParameters: SignatureHelpParameter[];
305+
var prefixParts: SymbolDisplayPart[] = [];
306+
var suffixParts: SymbolDisplayPart[] = [];
314307

315-
var prefixParts = callTargetSymbol ? symbolToDisplayParts(typeInfoResolver, callTargetSymbol, /*enclosingDeclaration*/ undefined, /*meaning*/ undefined) : [];
308+
if (callTargetDisplayParts) {
309+
prefixParts.push.apply(prefixParts, callTargetDisplayParts);
310+
}
316311

317-
var typeParameterParts = mapToDisplayParts(writer =>
318-
typeInfoResolver.getSymbolDisplayBuilder().buildDisplayForTypeParametersAndDelimiters(candidateSignature.typeParameters, writer, argumentListOrTypeArgumentList));
319-
prefixParts.push.apply(prefixParts, typeParameterParts);
320-
prefixParts.push(punctuationPart(SyntaxKind.OpenParenToken));
312+
if (isTypeParameterHelp) {
313+
prefixParts.push(punctuationPart(SyntaxKind.LessThanToken));
314+
var typeParameters = candidateSignature.typeParameters;
315+
signatureHelpParameters = typeParameters && typeParameters.length > 0 ? map(typeParameters, createSignatureHelpParameterForTypeParameter) : emptyArray;
316+
suffixParts.push(punctuationPart(SyntaxKind.GreaterThanToken));
317+
var parameterParts = mapToDisplayParts(writer =>
318+
typeInfoResolver.getSymbolDisplayBuilder().buildDisplayForParametersAndDelimiters(candidateSignature.parameters, writer, argumentListOrTypeArgumentList));
319+
suffixParts.push.apply(suffixParts, parameterParts);
320+
}
321+
else {
322+
var typeParameterParts = mapToDisplayParts(writer =>
323+
typeInfoResolver.getSymbolDisplayBuilder().buildDisplayForTypeParametersAndDelimiters(candidateSignature.typeParameters, writer, argumentListOrTypeArgumentList));
324+
prefixParts.push.apply(prefixParts, typeParameterParts);
325+
prefixParts.push(punctuationPart(SyntaxKind.OpenParenToken));
326+
var parameters = candidateSignature.parameters;
327+
signatureHelpParameters = parameters.length > 0 ? map(parameters, createSignatureHelpParameterForParameter) : emptyArray;
328+
suffixParts.push(punctuationPart(SyntaxKind.CloseParenToken));
329+
}
321330

322-
var suffixParts = [punctuationPart(SyntaxKind.CloseParenToken)];
323331
var returnTypeParts = mapToDisplayParts(writer =>
324332
typeInfoResolver.getSymbolDisplayBuilder().buildReturnTypeDisplay(candidateSignature, writer, argumentListOrTypeArgumentList));
325333
suffixParts.push.apply(suffixParts, returnTypeParts);
@@ -329,7 +337,7 @@ module ts.SignatureHelp {
329337
prefixDisplayParts: prefixParts,
330338
suffixDisplayParts: suffixParts,
331339
separatorDisplayParts: [punctuationPart(SyntaxKind.CommaToken), spacePart()],
332-
parameters: parameterHelpItems,
340+
parameters: signatureHelpParameters,
333341
documentation: candidateSignature.getDocumentationComment()
334342
};
335343
});
@@ -375,6 +383,32 @@ module ts.SignatureHelp {
375383
argumentIndex: argumentIndex,
376384
argumentCount: argumentCount
377385
};
386+
387+
function createSignatureHelpParameterForParameter(parameter: Symbol): SignatureHelpParameter {
388+
var displayParts = mapToDisplayParts(writer =>
389+
typeInfoResolver.getSymbolDisplayBuilder().buildParameterDisplay(parameter, writer, argumentListOrTypeArgumentList));
390+
391+
var isOptional = !!(parameter.valueDeclaration.flags & NodeFlags.QuestionMark);
392+
393+
return {
394+
name: parameter.name,
395+
documentation: parameter.getDocumentationComment(),
396+
displayParts: displayParts,
397+
isOptional: isOptional
398+
};
399+
}
400+
401+
function createSignatureHelpParameterForTypeParameter(typeParameter: TypeParameter): SignatureHelpParameter {
402+
var displayParts = mapToDisplayParts(writer =>
403+
typeInfoResolver.getSymbolDisplayBuilder().buildTypeParameterDisplay(typeParameter, writer, argumentListOrTypeArgumentList));
404+
405+
return {
406+
name: typeParameter.symbol.name,
407+
documentation: emptyArray,
408+
displayParts: displayParts,
409+
isOptional: false
410+
};
411+
}
378412
}
379413
}
380414
}

0 commit comments

Comments
 (0)