Break createSignatureHelpItems into functions (#25948)
This commit is contained in:
parent
0227997fa5
commit
998c911c49
|
@ -58,10 +58,8 @@ namespace ts.SignatureHelp {
|
|||
return typeChecker.runWithCancellationToken(cancellationToken, typeChecker => createSignatureHelpItems(candidateInfo.candidates, candidateInfo.resolvedSignature, argumentInfo, sourceFile, typeChecker));
|
||||
}
|
||||
|
||||
function getCandidateInfo(
|
||||
argumentInfo: ArgumentListInfo, checker: TypeChecker, sourceFile: SourceFile, startingToken: Node, onlyUseSyntacticOwners: boolean):
|
||||
{ readonly candidates: ReadonlyArray<Signature>, readonly resolvedSignature: Signature } | undefined {
|
||||
|
||||
interface CandidateInfo { readonly candidates: ReadonlyArray<Signature>; readonly resolvedSignature: Signature; }
|
||||
function getCandidateInfo(argumentInfo: ArgumentListInfo, checker: TypeChecker, sourceFile: SourceFile, startingToken: Node, onlyUseSyntacticOwners: boolean): CandidateInfo | undefined {
|
||||
const { invocation } = argumentInfo;
|
||||
if (invocation.kind === InvocationKind.Call) {
|
||||
if (onlyUseSyntacticOwners && !isSyntacticOwner(startingToken, invocation.node, sourceFile)) {
|
||||
|
@ -416,69 +414,8 @@ namespace ts.SignatureHelp {
|
|||
|
||||
const enclosingDeclaration = invocation.kind === InvocationKind.Call ? invocation.node : invocation.called;
|
||||
const callTargetSymbol = typeChecker.getSymbolAtLocation(getExpressionFromInvocation(invocation));
|
||||
const callTargetDisplayParts = callTargetSymbol && symbolToDisplayParts(typeChecker, callTargetSymbol, /*enclosingDeclaration*/ undefined, /*meaning*/ undefined);
|
||||
const printer = createPrinter({ removeComments: true });
|
||||
const items = candidates.map<SignatureHelpItem>(candidateSignature => {
|
||||
let signatureHelpParameters: SignatureHelpParameter[];
|
||||
const prefixDisplayParts: SymbolDisplayPart[] = [];
|
||||
const suffixDisplayParts: SymbolDisplayPart[] = [];
|
||||
|
||||
if (callTargetDisplayParts) {
|
||||
addRange(prefixDisplayParts, callTargetDisplayParts);
|
||||
}
|
||||
|
||||
let isVariadic: boolean;
|
||||
if (isTypeParameterList) {
|
||||
isVariadic = false; // type parameter lists are not variadic
|
||||
prefixDisplayParts.push(punctuationPart(SyntaxKind.LessThanToken));
|
||||
const typeParameters = (candidateSignature.target || candidateSignature).typeParameters;
|
||||
signatureHelpParameters = typeParameters && typeParameters.length > 0 ? map(typeParameters, createSignatureHelpParameterForTypeParameter) : emptyArray;
|
||||
suffixDisplayParts.push(punctuationPart(SyntaxKind.GreaterThanToken));
|
||||
const parameterParts = mapToDisplayParts(writer => {
|
||||
const thisParameter = candidateSignature.thisParameter ? [typeChecker.symbolToParameterDeclaration(candidateSignature.thisParameter, enclosingDeclaration, signatureHelpNodeBuilderFlags)!] : [];
|
||||
const params = createNodeArray([...thisParameter, ...candidateSignature.parameters.map(param => typeChecker.symbolToParameterDeclaration(param, enclosingDeclaration, signatureHelpNodeBuilderFlags)!)]);
|
||||
printer.writeList(ListFormat.CallExpressionArguments, params, sourceFile, writer);
|
||||
});
|
||||
addRange(suffixDisplayParts, parameterParts);
|
||||
}
|
||||
else {
|
||||
isVariadic = candidateSignature.hasRestParameter;
|
||||
const typeParameterParts = mapToDisplayParts(writer => {
|
||||
if (candidateSignature.typeParameters && candidateSignature.typeParameters.length) {
|
||||
const args = createNodeArray(candidateSignature.typeParameters.map(p => typeChecker.typeParameterToDeclaration(p, enclosingDeclaration)!));
|
||||
printer.writeList(ListFormat.TypeParameters, args, sourceFile, writer);
|
||||
}
|
||||
});
|
||||
addRange(prefixDisplayParts, typeParameterParts);
|
||||
prefixDisplayParts.push(punctuationPart(SyntaxKind.OpenParenToken));
|
||||
|
||||
signatureHelpParameters = map(candidateSignature.parameters, createSignatureHelpParameterForParameter);
|
||||
suffixDisplayParts.push(punctuationPart(SyntaxKind.CloseParenToken));
|
||||
}
|
||||
|
||||
const returnTypeParts = mapToDisplayParts(writer => {
|
||||
writer.writePunctuation(":");
|
||||
writer.writeSpace(" ");
|
||||
const predicate = typeChecker.getTypePredicateOfSignature(candidateSignature);
|
||||
if (predicate) {
|
||||
typeChecker.writeTypePredicate(predicate, enclosingDeclaration, /*flags*/ undefined, writer);
|
||||
}
|
||||
else {
|
||||
typeChecker.writeType(typeChecker.getReturnTypeOfSignature(candidateSignature), enclosingDeclaration, /*flags*/ undefined, writer);
|
||||
}
|
||||
});
|
||||
addRange(suffixDisplayParts, returnTypeParts);
|
||||
|
||||
return {
|
||||
isVariadic,
|
||||
prefixDisplayParts,
|
||||
suffixDisplayParts,
|
||||
separatorDisplayParts: [punctuationPart(SyntaxKind.CommaToken), spacePart()],
|
||||
parameters: signatureHelpParameters,
|
||||
documentation: candidateSignature.getDocumentationComment(typeChecker),
|
||||
tags: candidateSignature.getJsDocTags()
|
||||
};
|
||||
});
|
||||
const callTargetDisplayParts = callTargetSymbol ? symbolToDisplayParts(typeChecker, callTargetSymbol, /*enclosingDeclaration*/ undefined, /*meaning*/ undefined) : emptyArray;
|
||||
const items = candidates.map(candidateSignature => getSignatureHelpItem(candidateSignature, callTargetDisplayParts, isTypeParameterList, typeChecker, enclosingDeclaration, sourceFile));
|
||||
|
||||
if (argumentIndex !== 0) {
|
||||
Debug.assertLessThan(argumentIndex, argumentCount);
|
||||
|
@ -488,33 +425,73 @@ namespace ts.SignatureHelp {
|
|||
Debug.assert(selectedItemIndex !== -1); // If candidates is non-empty it should always include bestSignature. We check for an empty candidates before calling this function.
|
||||
|
||||
return { items, applicableSpan, selectedItemIndex, argumentIndex, argumentCount };
|
||||
}
|
||||
|
||||
function createSignatureHelpParameterForParameter(parameter: Symbol): SignatureHelpParameter {
|
||||
const displayParts = mapToDisplayParts(writer => {
|
||||
const param = typeChecker.symbolToParameterDeclaration(parameter, enclosingDeclaration, signatureHelpNodeBuilderFlags)!;
|
||||
printer.writeNode(EmitHint.Unspecified, param, sourceFile, writer);
|
||||
});
|
||||
function getSignatureHelpItem(candidateSignature: Signature, callTargetDisplayParts: ReadonlyArray<SymbolDisplayPart>, isTypeParameterList: boolean, checker: TypeChecker, enclosingDeclaration: Node, sourceFile: SourceFile): SignatureHelpItem {
|
||||
const { isVariadic, parameters, prefix, suffix } = (isTypeParameterList ? itemInfoForTypeParameters : itemInfoForParameters)(candidateSignature, checker, enclosingDeclaration, sourceFile);
|
||||
const prefixDisplayParts = [...callTargetDisplayParts, ...prefix];
|
||||
const suffixDisplayParts = [...suffix, ...returnTypeToDisplayParts(candidateSignature, enclosingDeclaration, checker)];
|
||||
const separatorDisplayParts = [punctuationPart(SyntaxKind.CommaToken), spacePart()];
|
||||
const documentation = candidateSignature.getDocumentationComment(checker);
|
||||
const tags = candidateSignature.getJsDocTags();
|
||||
return { isVariadic, prefixDisplayParts, suffixDisplayParts, separatorDisplayParts, parameters, documentation, tags };
|
||||
}
|
||||
|
||||
return {
|
||||
name: parameter.name,
|
||||
documentation: parameter.getDocumentationComment(typeChecker),
|
||||
displayParts,
|
||||
isOptional: typeChecker.isOptionalParameter(<ParameterDeclaration>parameter.valueDeclaration)
|
||||
};
|
||||
}
|
||||
function returnTypeToDisplayParts(candidateSignature: Signature, enclosingDeclaration: Node, checker: TypeChecker): ReadonlyArray<SymbolDisplayPart> {
|
||||
return mapToDisplayParts(writer => {
|
||||
writer.writePunctuation(":");
|
||||
writer.writeSpace(" ");
|
||||
const predicate = checker.getTypePredicateOfSignature(candidateSignature);
|
||||
if (predicate) {
|
||||
checker.writeTypePredicate(predicate, enclosingDeclaration, /*flags*/ undefined, writer);
|
||||
}
|
||||
else {
|
||||
checker.writeType(checker.getReturnTypeOfSignature(candidateSignature), enclosingDeclaration, /*flags*/ undefined, writer);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function createSignatureHelpParameterForTypeParameter(typeParameter: TypeParameter): SignatureHelpParameter {
|
||||
const displayParts = mapToDisplayParts(writer => {
|
||||
const param = typeChecker.typeParameterToDeclaration(typeParameter, enclosingDeclaration)!;
|
||||
printer.writeNode(EmitHint.Unspecified, param, sourceFile, writer);
|
||||
});
|
||||
interface SignatureHelpItemInfo { readonly isVariadic: boolean; readonly parameters: SignatureHelpParameter[]; readonly prefix: ReadonlyArray<SymbolDisplayPart>; readonly suffix: ReadonlyArray<SymbolDisplayPart>; }
|
||||
|
||||
return {
|
||||
name: typeParameter.symbol.name,
|
||||
documentation: emptyArray,
|
||||
displayParts,
|
||||
isOptional: false
|
||||
};
|
||||
}
|
||||
function itemInfoForTypeParameters(candidateSignature: Signature, checker: TypeChecker, enclosingDeclaration: Node, sourceFile: SourceFile): SignatureHelpItemInfo {
|
||||
const typeParameters = (candidateSignature.target || candidateSignature).typeParameters;
|
||||
const printer = createPrinter({ removeComments: true });
|
||||
const parameters = (typeParameters || emptyArray).map(t => createSignatureHelpParameterForTypeParameter(t, checker, enclosingDeclaration, sourceFile, printer));
|
||||
const parameterParts = mapToDisplayParts(writer => {
|
||||
const thisParameter = candidateSignature.thisParameter ? [checker.symbolToParameterDeclaration(candidateSignature.thisParameter, enclosingDeclaration, signatureHelpNodeBuilderFlags)!] : [];
|
||||
const params = createNodeArray([...thisParameter, ...candidateSignature.parameters.map(param => checker.symbolToParameterDeclaration(param, enclosingDeclaration, signatureHelpNodeBuilderFlags)!)]);
|
||||
printer.writeList(ListFormat.CallExpressionArguments, params, sourceFile, writer);
|
||||
});
|
||||
return { isVariadic: false, parameters, prefix: [punctuationPart(SyntaxKind.LessThanToken)], suffix: [punctuationPart(SyntaxKind.GreaterThanToken), ...parameterParts] };
|
||||
}
|
||||
|
||||
function itemInfoForParameters(candidateSignature: Signature, checker: TypeChecker, enclosingDeclaration: Node, sourceFile: SourceFile): SignatureHelpItemInfo {
|
||||
const isVariadic = candidateSignature.hasRestParameter;
|
||||
const printer = createPrinter({ removeComments: true });
|
||||
const typeParameterParts = mapToDisplayParts(writer => {
|
||||
if (candidateSignature.typeParameters && candidateSignature.typeParameters.length) {
|
||||
const args = createNodeArray(candidateSignature.typeParameters.map(p => checker.typeParameterToDeclaration(p, enclosingDeclaration)!));
|
||||
printer.writeList(ListFormat.TypeParameters, args, sourceFile, writer);
|
||||
}
|
||||
});
|
||||
const parameters = candidateSignature.parameters.map(p => createSignatureHelpParameterForParameter(p, checker, enclosingDeclaration, sourceFile, printer));
|
||||
return { isVariadic, parameters, prefix: [...typeParameterParts, punctuationPart(SyntaxKind.OpenParenToken)], suffix: [punctuationPart(SyntaxKind.CloseParenToken)] };
|
||||
}
|
||||
|
||||
function createSignatureHelpParameterForParameter(parameter: Symbol, checker: TypeChecker, enclosingDeclaration: Node, sourceFile: SourceFile, printer: Printer): SignatureHelpParameter {
|
||||
const displayParts = mapToDisplayParts(writer => {
|
||||
const param = checker.symbolToParameterDeclaration(parameter, enclosingDeclaration, signatureHelpNodeBuilderFlags)!;
|
||||
printer.writeNode(EmitHint.Unspecified, param, sourceFile, writer);
|
||||
});
|
||||
const isOptional = checker.isOptionalParameter(<ParameterDeclaration>parameter.valueDeclaration);
|
||||
return { name: parameter.name, documentation: parameter.getDocumentationComment(checker), displayParts, isOptional };
|
||||
}
|
||||
|
||||
function createSignatureHelpParameterForTypeParameter(typeParameter: TypeParameter, checker: TypeChecker, enclosingDeclaration: Node, sourceFile: SourceFile, printer: Printer): SignatureHelpParameter {
|
||||
const displayParts = mapToDisplayParts(writer => {
|
||||
const param = checker.typeParameterToDeclaration(typeParameter, enclosingDeclaration)!;
|
||||
printer.writeNode(EmitHint.Unspecified, param, sourceFile, writer);
|
||||
});
|
||||
return { name: typeParameter.symbol.name, documentation: emptyArray, displayParts, isOptional: false };
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue