Break createSignatureHelpItems into functions (#25948)

This commit is contained in:
Andy 2018-07-26 17:26:29 -07:00 committed by GitHub
parent 0227997fa5
commit 998c911c49
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -58,10 +58,8 @@ namespace ts.SignatureHelp {
return typeChecker.runWithCancellationToken(cancellationToken, typeChecker => createSignatureHelpItems(candidateInfo.candidates, candidateInfo.resolvedSignature, argumentInfo, sourceFile, typeChecker)); return typeChecker.runWithCancellationToken(cancellationToken, typeChecker => createSignatureHelpItems(candidateInfo.candidates, candidateInfo.resolvedSignature, argumentInfo, sourceFile, typeChecker));
} }
function getCandidateInfo( interface CandidateInfo { readonly candidates: ReadonlyArray<Signature>; readonly resolvedSignature: Signature; }
argumentInfo: ArgumentListInfo, checker: TypeChecker, sourceFile: SourceFile, startingToken: Node, onlyUseSyntacticOwners: boolean): function getCandidateInfo(argumentInfo: ArgumentListInfo, checker: TypeChecker, sourceFile: SourceFile, startingToken: Node, onlyUseSyntacticOwners: boolean): CandidateInfo | undefined {
{ readonly candidates: ReadonlyArray<Signature>, readonly resolvedSignature: Signature } | undefined {
const { invocation } = argumentInfo; const { invocation } = argumentInfo;
if (invocation.kind === InvocationKind.Call) { if (invocation.kind === InvocationKind.Call) {
if (onlyUseSyntacticOwners && !isSyntacticOwner(startingToken, invocation.node, sourceFile)) { 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 enclosingDeclaration = invocation.kind === InvocationKind.Call ? invocation.node : invocation.called;
const callTargetSymbol = typeChecker.getSymbolAtLocation(getExpressionFromInvocation(invocation)); const callTargetSymbol = typeChecker.getSymbolAtLocation(getExpressionFromInvocation(invocation));
const callTargetDisplayParts = callTargetSymbol && symbolToDisplayParts(typeChecker, callTargetSymbol, /*enclosingDeclaration*/ undefined, /*meaning*/ undefined); const callTargetDisplayParts = callTargetSymbol ? symbolToDisplayParts(typeChecker, callTargetSymbol, /*enclosingDeclaration*/ undefined, /*meaning*/ undefined) : emptyArray;
const printer = createPrinter({ removeComments: true }); const items = candidates.map(candidateSignature => getSignatureHelpItem(candidateSignature, callTargetDisplayParts, isTypeParameterList, typeChecker, enclosingDeclaration, sourceFile));
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()
};
});
if (argumentIndex !== 0) { if (argumentIndex !== 0) {
Debug.assertLessThan(argumentIndex, argumentCount); 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. 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 }; return { items, applicableSpan, selectedItemIndex, argumentIndex, argumentCount };
}
function createSignatureHelpParameterForParameter(parameter: Symbol): SignatureHelpParameter { function getSignatureHelpItem(candidateSignature: Signature, callTargetDisplayParts: ReadonlyArray<SymbolDisplayPart>, isTypeParameterList: boolean, checker: TypeChecker, enclosingDeclaration: Node, sourceFile: SourceFile): SignatureHelpItem {
const displayParts = mapToDisplayParts(writer => { const { isVariadic, parameters, prefix, suffix } = (isTypeParameterList ? itemInfoForTypeParameters : itemInfoForParameters)(candidateSignature, checker, enclosingDeclaration, sourceFile);
const param = typeChecker.symbolToParameterDeclaration(parameter, enclosingDeclaration, signatureHelpNodeBuilderFlags)!; const prefixDisplayParts = [...callTargetDisplayParts, ...prefix];
printer.writeNode(EmitHint.Unspecified, param, sourceFile, writer); 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 { function returnTypeToDisplayParts(candidateSignature: Signature, enclosingDeclaration: Node, checker: TypeChecker): ReadonlyArray<SymbolDisplayPart> {
name: parameter.name, return mapToDisplayParts(writer => {
documentation: parameter.getDocumentationComment(typeChecker), writer.writePunctuation(":");
displayParts, writer.writeSpace(" ");
isOptional: typeChecker.isOptionalParameter(<ParameterDeclaration>parameter.valueDeclaration) 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 { interface SignatureHelpItemInfo { readonly isVariadic: boolean; readonly parameters: SignatureHelpParameter[]; readonly prefix: ReadonlyArray<SymbolDisplayPart>; readonly suffix: ReadonlyArray<SymbolDisplayPart>; }
const displayParts = mapToDisplayParts(writer => {
const param = typeChecker.typeParameterToDeclaration(typeParameter, enclosingDeclaration)!;
printer.writeNode(EmitHint.Unspecified, param, sourceFile, writer);
});
return { function itemInfoForTypeParameters(candidateSignature: Signature, checker: TypeChecker, enclosingDeclaration: Node, sourceFile: SourceFile): SignatureHelpItemInfo {
name: typeParameter.symbol.name, const typeParameters = (candidateSignature.target || candidateSignature).typeParameters;
documentation: emptyArray, const printer = createPrinter({ removeComments: true });
displayParts, const parameters = (typeParameters || emptyArray).map(t => createSignatureHelpParameterForTypeParameter(t, checker, enclosingDeclaration, sourceFile, printer));
isOptional: false 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 };
} }
} }