Skip to content

Commit 998c911

Browse files
author
Andy
authored
Break createSignatureHelpItems into functions (microsoft#25948)
1 parent 0227997 commit 998c911

File tree

1 file changed

+68
-91
lines changed

1 file changed

+68
-91
lines changed

src/services/signatureHelp.ts

+68-91
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,8 @@ namespace ts.SignatureHelp {
5858
return typeChecker.runWithCancellationToken(cancellationToken, typeChecker => createSignatureHelpItems(candidateInfo.candidates, candidateInfo.resolvedSignature, argumentInfo, sourceFile, typeChecker));
5959
}
6060

61-
function getCandidateInfo(
62-
argumentInfo: ArgumentListInfo, checker: TypeChecker, sourceFile: SourceFile, startingToken: Node, onlyUseSyntacticOwners: boolean):
63-
{ readonly candidates: ReadonlyArray<Signature>, readonly resolvedSignature: Signature } | undefined {
64-
61+
interface CandidateInfo { readonly candidates: ReadonlyArray<Signature>; readonly resolvedSignature: Signature; }
62+
function getCandidateInfo(argumentInfo: ArgumentListInfo, checker: TypeChecker, sourceFile: SourceFile, startingToken: Node, onlyUseSyntacticOwners: boolean): CandidateInfo | undefined {
6563
const { invocation } = argumentInfo;
6664
if (invocation.kind === InvocationKind.Call) {
6765
if (onlyUseSyntacticOwners && !isSyntacticOwner(startingToken, invocation.node, sourceFile)) {
@@ -416,69 +414,8 @@ namespace ts.SignatureHelp {
416414

417415
const enclosingDeclaration = invocation.kind === InvocationKind.Call ? invocation.node : invocation.called;
418416
const callTargetSymbol = typeChecker.getSymbolAtLocation(getExpressionFromInvocation(invocation));
419-
const callTargetDisplayParts = callTargetSymbol && symbolToDisplayParts(typeChecker, callTargetSymbol, /*enclosingDeclaration*/ undefined, /*meaning*/ undefined);
420-
const printer = createPrinter({ removeComments: true });
421-
const items = candidates.map<SignatureHelpItem>(candidateSignature => {
422-
let signatureHelpParameters: SignatureHelpParameter[];
423-
const prefixDisplayParts: SymbolDisplayPart[] = [];
424-
const suffixDisplayParts: SymbolDisplayPart[] = [];
425-
426-
if (callTargetDisplayParts) {
427-
addRange(prefixDisplayParts, callTargetDisplayParts);
428-
}
429-
430-
let isVariadic: boolean;
431-
if (isTypeParameterList) {
432-
isVariadic = false; // type parameter lists are not variadic
433-
prefixDisplayParts.push(punctuationPart(SyntaxKind.LessThanToken));
434-
const typeParameters = (candidateSignature.target || candidateSignature).typeParameters;
435-
signatureHelpParameters = typeParameters && typeParameters.length > 0 ? map(typeParameters, createSignatureHelpParameterForTypeParameter) : emptyArray;
436-
suffixDisplayParts.push(punctuationPart(SyntaxKind.GreaterThanToken));
437-
const parameterParts = mapToDisplayParts(writer => {
438-
const thisParameter = candidateSignature.thisParameter ? [typeChecker.symbolToParameterDeclaration(candidateSignature.thisParameter, enclosingDeclaration, signatureHelpNodeBuilderFlags)!] : [];
439-
const params = createNodeArray([...thisParameter, ...candidateSignature.parameters.map(param => typeChecker.symbolToParameterDeclaration(param, enclosingDeclaration, signatureHelpNodeBuilderFlags)!)]);
440-
printer.writeList(ListFormat.CallExpressionArguments, params, sourceFile, writer);
441-
});
442-
addRange(suffixDisplayParts, parameterParts);
443-
}
444-
else {
445-
isVariadic = candidateSignature.hasRestParameter;
446-
const typeParameterParts = mapToDisplayParts(writer => {
447-
if (candidateSignature.typeParameters && candidateSignature.typeParameters.length) {
448-
const args = createNodeArray(candidateSignature.typeParameters.map(p => typeChecker.typeParameterToDeclaration(p, enclosingDeclaration)!));
449-
printer.writeList(ListFormat.TypeParameters, args, sourceFile, writer);
450-
}
451-
});
452-
addRange(prefixDisplayParts, typeParameterParts);
453-
prefixDisplayParts.push(punctuationPart(SyntaxKind.OpenParenToken));
454-
455-
signatureHelpParameters = map(candidateSignature.parameters, createSignatureHelpParameterForParameter);
456-
suffixDisplayParts.push(punctuationPart(SyntaxKind.CloseParenToken));
457-
}
458-
459-
const returnTypeParts = mapToDisplayParts(writer => {
460-
writer.writePunctuation(":");
461-
writer.writeSpace(" ");
462-
const predicate = typeChecker.getTypePredicateOfSignature(candidateSignature);
463-
if (predicate) {
464-
typeChecker.writeTypePredicate(predicate, enclosingDeclaration, /*flags*/ undefined, writer);
465-
}
466-
else {
467-
typeChecker.writeType(typeChecker.getReturnTypeOfSignature(candidateSignature), enclosingDeclaration, /*flags*/ undefined, writer);
468-
}
469-
});
470-
addRange(suffixDisplayParts, returnTypeParts);
471-
472-
return {
473-
isVariadic,
474-
prefixDisplayParts,
475-
suffixDisplayParts,
476-
separatorDisplayParts: [punctuationPart(SyntaxKind.CommaToken), spacePart()],
477-
parameters: signatureHelpParameters,
478-
documentation: candidateSignature.getDocumentationComment(typeChecker),
479-
tags: candidateSignature.getJsDocTags()
480-
};
481-
});
417+
const callTargetDisplayParts = callTargetSymbol ? symbolToDisplayParts(typeChecker, callTargetSymbol, /*enclosingDeclaration*/ undefined, /*meaning*/ undefined) : emptyArray;
418+
const items = candidates.map(candidateSignature => getSignatureHelpItem(candidateSignature, callTargetDisplayParts, isTypeParameterList, typeChecker, enclosingDeclaration, sourceFile));
482419

483420
if (argumentIndex !== 0) {
484421
Debug.assertLessThan(argumentIndex, argumentCount);
@@ -488,33 +425,73 @@ namespace ts.SignatureHelp {
488425
Debug.assert(selectedItemIndex !== -1); // If candidates is non-empty it should always include bestSignature. We check for an empty candidates before calling this function.
489426

490427
return { items, applicableSpan, selectedItemIndex, argumentIndex, argumentCount };
428+
}
491429

492-
function createSignatureHelpParameterForParameter(parameter: Symbol): SignatureHelpParameter {
493-
const displayParts = mapToDisplayParts(writer => {
494-
const param = typeChecker.symbolToParameterDeclaration(parameter, enclosingDeclaration, signatureHelpNodeBuilderFlags)!;
495-
printer.writeNode(EmitHint.Unspecified, param, sourceFile, writer);
496-
});
430+
function getSignatureHelpItem(candidateSignature: Signature, callTargetDisplayParts: ReadonlyArray<SymbolDisplayPart>, isTypeParameterList: boolean, checker: TypeChecker, enclosingDeclaration: Node, sourceFile: SourceFile): SignatureHelpItem {
431+
const { isVariadic, parameters, prefix, suffix } = (isTypeParameterList ? itemInfoForTypeParameters : itemInfoForParameters)(candidateSignature, checker, enclosingDeclaration, sourceFile);
432+
const prefixDisplayParts = [...callTargetDisplayParts, ...prefix];
433+
const suffixDisplayParts = [...suffix, ...returnTypeToDisplayParts(candidateSignature, enclosingDeclaration, checker)];
434+
const separatorDisplayParts = [punctuationPart(SyntaxKind.CommaToken), spacePart()];
435+
const documentation = candidateSignature.getDocumentationComment(checker);
436+
const tags = candidateSignature.getJsDocTags();
437+
return { isVariadic, prefixDisplayParts, suffixDisplayParts, separatorDisplayParts, parameters, documentation, tags };
438+
}
497439

498-
return {
499-
name: parameter.name,
500-
documentation: parameter.getDocumentationComment(typeChecker),
501-
displayParts,
502-
isOptional: typeChecker.isOptionalParameter(<ParameterDeclaration>parameter.valueDeclaration)
503-
};
504-
}
440+
function returnTypeToDisplayParts(candidateSignature: Signature, enclosingDeclaration: Node, checker: TypeChecker): ReadonlyArray<SymbolDisplayPart> {
441+
return mapToDisplayParts(writer => {
442+
writer.writePunctuation(":");
443+
writer.writeSpace(" ");
444+
const predicate = checker.getTypePredicateOfSignature(candidateSignature);
445+
if (predicate) {
446+
checker.writeTypePredicate(predicate, enclosingDeclaration, /*flags*/ undefined, writer);
447+
}
448+
else {
449+
checker.writeType(checker.getReturnTypeOfSignature(candidateSignature), enclosingDeclaration, /*flags*/ undefined, writer);
450+
}
451+
});
452+
}
505453

506-
function createSignatureHelpParameterForTypeParameter(typeParameter: TypeParameter): SignatureHelpParameter {
507-
const displayParts = mapToDisplayParts(writer => {
508-
const param = typeChecker.typeParameterToDeclaration(typeParameter, enclosingDeclaration)!;
509-
printer.writeNode(EmitHint.Unspecified, param, sourceFile, writer);
510-
});
454+
interface SignatureHelpItemInfo { readonly isVariadic: boolean; readonly parameters: SignatureHelpParameter[]; readonly prefix: ReadonlyArray<SymbolDisplayPart>; readonly suffix: ReadonlyArray<SymbolDisplayPart>; }
511455

512-
return {
513-
name: typeParameter.symbol.name,
514-
documentation: emptyArray,
515-
displayParts,
516-
isOptional: false
517-
};
518-
}
456+
function itemInfoForTypeParameters(candidateSignature: Signature, checker: TypeChecker, enclosingDeclaration: Node, sourceFile: SourceFile): SignatureHelpItemInfo {
457+
const typeParameters = (candidateSignature.target || candidateSignature).typeParameters;
458+
const printer = createPrinter({ removeComments: true });
459+
const parameters = (typeParameters || emptyArray).map(t => createSignatureHelpParameterForTypeParameter(t, checker, enclosingDeclaration, sourceFile, printer));
460+
const parameterParts = mapToDisplayParts(writer => {
461+
const thisParameter = candidateSignature.thisParameter ? [checker.symbolToParameterDeclaration(candidateSignature.thisParameter, enclosingDeclaration, signatureHelpNodeBuilderFlags)!] : [];
462+
const params = createNodeArray([...thisParameter, ...candidateSignature.parameters.map(param => checker.symbolToParameterDeclaration(param, enclosingDeclaration, signatureHelpNodeBuilderFlags)!)]);
463+
printer.writeList(ListFormat.CallExpressionArguments, params, sourceFile, writer);
464+
});
465+
return { isVariadic: false, parameters, prefix: [punctuationPart(SyntaxKind.LessThanToken)], suffix: [punctuationPart(SyntaxKind.GreaterThanToken), ...parameterParts] };
466+
}
467+
468+
function itemInfoForParameters(candidateSignature: Signature, checker: TypeChecker, enclosingDeclaration: Node, sourceFile: SourceFile): SignatureHelpItemInfo {
469+
const isVariadic = candidateSignature.hasRestParameter;
470+
const printer = createPrinter({ removeComments: true });
471+
const typeParameterParts = mapToDisplayParts(writer => {
472+
if (candidateSignature.typeParameters && candidateSignature.typeParameters.length) {
473+
const args = createNodeArray(candidateSignature.typeParameters.map(p => checker.typeParameterToDeclaration(p, enclosingDeclaration)!));
474+
printer.writeList(ListFormat.TypeParameters, args, sourceFile, writer);
475+
}
476+
});
477+
const parameters = candidateSignature.parameters.map(p => createSignatureHelpParameterForParameter(p, checker, enclosingDeclaration, sourceFile, printer));
478+
return { isVariadic, parameters, prefix: [...typeParameterParts, punctuationPart(SyntaxKind.OpenParenToken)], suffix: [punctuationPart(SyntaxKind.CloseParenToken)] };
479+
}
480+
481+
function createSignatureHelpParameterForParameter(parameter: Symbol, checker: TypeChecker, enclosingDeclaration: Node, sourceFile: SourceFile, printer: Printer): SignatureHelpParameter {
482+
const displayParts = mapToDisplayParts(writer => {
483+
const param = checker.symbolToParameterDeclaration(parameter, enclosingDeclaration, signatureHelpNodeBuilderFlags)!;
484+
printer.writeNode(EmitHint.Unspecified, param, sourceFile, writer);
485+
});
486+
const isOptional = checker.isOptionalParameter(<ParameterDeclaration>parameter.valueDeclaration);
487+
return { name: parameter.name, documentation: parameter.getDocumentationComment(checker), displayParts, isOptional };
488+
}
489+
490+
function createSignatureHelpParameterForTypeParameter(typeParameter: TypeParameter, checker: TypeChecker, enclosingDeclaration: Node, sourceFile: SourceFile, printer: Printer): SignatureHelpParameter {
491+
const displayParts = mapToDisplayParts(writer => {
492+
const param = checker.typeParameterToDeclaration(typeParameter, enclosingDeclaration)!;
493+
printer.writeNode(EmitHint.Unspecified, param, sourceFile, writer);
494+
});
495+
return { name: typeParameter.symbol.name, documentation: emptyArray, displayParts, isOptional: false };
519496
}
520497
}

0 commit comments

Comments
 (0)