Skip to content

Commit 123347d

Browse files
committed
Convert @template tag to type parameters in refactor
1 parent 260d37e commit 123347d

File tree

2 files changed

+21
-20
lines changed

2 files changed

+21
-20
lines changed

src/compiler/utilities.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2700,11 +2700,11 @@ namespace ts {
27002700
* Gets the effective type annotation of a variable, parameter, or property. If the node was
27012701
* parsed in a JavaScript file, gets the type annotation from JSDoc.
27022702
*/
2703-
export function getEffectiveTypeAnnotationNode(node: VariableLikeDeclaration): TypeNode | undefined {
2703+
export function getEffectiveTypeAnnotationNode(node: VariableLikeDeclaration, checkJSDoc?: boolean): TypeNode | undefined {
27042704
if (node.type) {
27052705
return node.type;
27062706
}
2707-
if (isInJavaScriptFile(node)) {
2707+
if (checkJSDoc || isInJavaScriptFile(node)) {
27082708
return getJSDocType(node);
27092709
}
27102710
}
@@ -2713,11 +2713,11 @@ namespace ts {
27132713
* Gets the effective return type annotation of a signature. If the node was parsed in a
27142714
* JavaScript file, gets the return type annotation from JSDoc.
27152715
*/
2716-
export function getEffectiveReturnTypeNode(node: SignatureDeclaration): TypeNode | undefined {
2716+
export function getEffectiveReturnTypeNode(node: SignatureDeclaration, checkJSDoc?: boolean): TypeNode | undefined {
27172717
if (node.type) {
27182718
return node.type;
27192719
}
2720-
if (isInJavaScriptFile(node)) {
2720+
if (checkJSDoc || isInJavaScriptFile(node)) {
27212721
return getJSDocReturnType(node);
27222722
}
27232723
}
@@ -2726,11 +2726,11 @@ namespace ts {
27262726
* Gets the effective type parameters. If the node was parsed in a
27272727
* JavaScript file, gets the type parameters from the `@template` tag from JSDoc.
27282728
*/
2729-
export function getEffectiveTypeParameterDeclarations(node: DeclarationWithTypeParameters): ReadonlyArray<TypeParameterDeclaration> {
2729+
export function getEffectiveTypeParameterDeclarations(node: DeclarationWithTypeParameters, checkJSDoc?: boolean): ReadonlyArray<TypeParameterDeclaration> {
27302730
if (node.typeParameters) {
27312731
return node.typeParameters;
27322732
}
2733-
if (isInJavaScriptFile(node)) {
2733+
if (checkJSDoc || isInJavaScriptFile(node)) {
27342734
const templateTag = getJSDocTemplateTag(node);
27352735
return templateTag && templateTag.typeParameters;
27362736
}
@@ -2740,9 +2740,9 @@ namespace ts {
27402740
* Gets the effective type annotation of the value parameter of a set accessor. If the node
27412741
* was parsed in a JavaScript file, gets the type annotation from JSDoc.
27422742
*/
2743-
export function getEffectiveSetAccessorTypeAnnotationNode(node: SetAccessorDeclaration): TypeNode {
2743+
export function getEffectiveSetAccessorTypeAnnotationNode(node: SetAccessorDeclaration, checkJSDoc?: boolean): TypeNode {
27442744
const parameter = getSetAccessorValueParameter(node);
2745-
return parameter && getEffectiveTypeAnnotationNode(parameter);
2745+
return parameter && getEffectiveTypeAnnotationNode(parameter, checkJSDoc);
27462746
}
27472747

27482748
export function emitNewLineBeforeLeadingComments(lineMap: ReadonlyArray<number>, writer: EmitTextWriter, node: TextRange, leadingComments: ReadonlyArray<CommentRange>) {

src/services/refactors/annotateWithTypeFromJSDoc.ts

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ namespace ts.refactor.annotateWithTypeFromJSDoc {
3131
}
3232

3333
const node = getTokenAtPosition(context.file, context.startPosition, /*includeJsDocComment*/ false);
34-
const decl = findAncestor(node, isTypedNode);
34+
const decl = findAncestor(node, isDeclarationWithType);
3535
if (decl && !decl.type) {
3636
const type = getJSDocType(decl);
37-
const returnType = getJSDocReturnType(decl);
38-
const annotate = (returnType || type && decl.kind === SyntaxKind.Parameter) ? annotateFunctionFromJSDoc :
37+
const isFunctionWithJSDoc = isFunctionLikeDeclaration(decl) && (getJSDocReturnType(decl) || decl.parameters.some(p => !!getJSDocType(p)));
38+
const annotate = (isFunctionWithJSDoc || type && decl.kind === SyntaxKind.Parameter) ? annotateFunctionFromJSDoc :
3939
type ? annotateTypeFromJSDoc :
4040
undefined;
4141
if (annotate) {
@@ -61,7 +61,7 @@ namespace ts.refactor.annotateWithTypeFromJSDoc {
6161

6262
const sourceFile = context.file;
6363
const token = getTokenAtPosition(sourceFile, context.startPosition, /*includeJsDocComment*/ false);
64-
const decl = findAncestor(token, isTypedNode);
64+
const decl = findAncestor(token, isDeclarationWithType);
6565
const jsdocType = getJSDocReturnType(decl) || getJSDocType(decl);
6666
if (!decl || !jsdocType || decl.type) {
6767
Debug.fail(`!decl || !jsdocType || decl.type: !${decl} || !${jsdocType} || ${decl.type}`);
@@ -95,7 +95,7 @@ namespace ts.refactor.annotateWithTypeFromJSDoc {
9595
};
9696
}
9797

98-
function isTypedNode(node: Node): node is DeclarationWithType {
98+
function isDeclarationWithType(node: Node): node is DeclarationWithType {
9999
return isFunctionLikeDeclaration(node) ||
100100
node.kind === SyntaxKind.VariableDeclaration ||
101101
node.kind === SyntaxKind.Parameter ||
@@ -104,22 +104,23 @@ namespace ts.refactor.annotateWithTypeFromJSDoc {
104104
}
105105

106106
function addTypesToFunctionLike(decl: FunctionLikeDeclaration) {
107-
const returnType = decl.type || transformJSDocType(getJSDocReturnType(decl)) as TypeNode;
107+
const typeParameters = getEffectiveTypeParameterDeclarations(decl, /*checkJSDoc*/ true);
108108
const parameters = decl.parameters.map(
109-
p => createParameter(p.decorators, p.modifiers, p.dotDotDotToken, p.name, p.questionToken, p.type || transformJSDocType(getJSDocType(p)) as TypeNode, p.initializer));
109+
p => createParameter(p.decorators, p.modifiers, p.dotDotDotToken, p.name, p.questionToken, transformJSDocType(getEffectiveTypeAnnotationNode(p, /*checkJSDoc*/ true)) as TypeNode, p.initializer));
110+
const returnType = transformJSDocType(getEffectiveReturnTypeNode(decl, /*checkJSDoc*/ true)) as TypeNode;
110111
switch (decl.kind) {
111112
case SyntaxKind.FunctionDeclaration:
112-
return createFunctionDeclaration(decl.decorators, decl.modifiers, decl.asteriskToken, decl.name, decl.typeParameters, parameters, returnType, decl.body);
113+
return createFunctionDeclaration(decl.decorators, decl.modifiers, decl.asteriskToken, decl.name, typeParameters, parameters, returnType, decl.body);
113114
case SyntaxKind.Constructor:
114115
return createConstructor(decl.decorators, decl.modifiers, parameters, decl.body);
115116
case SyntaxKind.FunctionExpression:
116-
return createFunctionExpression(decl.modifiers, decl.asteriskToken, (decl as FunctionExpression).name, decl.typeParameters, parameters, returnType, decl.body);
117+
return createFunctionExpression(decl.modifiers, decl.asteriskToken, (decl as FunctionExpression).name, typeParameters, parameters, returnType, decl.body);
117118
case SyntaxKind.ArrowFunction:
118-
return createArrowFunction(decl.modifiers, decl.typeParameters, parameters, returnType, decl.equalsGreaterThanToken, decl.body);
119+
return createArrowFunction(decl.modifiers, typeParameters, parameters, returnType, decl.equalsGreaterThanToken, decl.body);
119120
case SyntaxKind.MethodDeclaration:
120-
return createMethod(decl.decorators, decl.modifiers, decl.asteriskToken, decl.name, decl.questionToken, decl.typeParameters, parameters, returnType, decl.body);
121+
return createMethod(decl.decorators, decl.modifiers, decl.asteriskToken, decl.name, decl.questionToken, typeParameters, parameters, returnType, decl.body);
121122
case SyntaxKind.GetAccessor:
122-
return createGetAccessor(decl.decorators, decl.modifiers, decl.name, parameters, returnType, decl.body);
123+
return createGetAccessor(decl.decorators, decl.modifiers, decl.name, decl.parameters, returnType, decl.body);
123124
case SyntaxKind.SetAccessor:
124125
return createSetAccessor(decl.decorators, decl.modifiers, decl.name, parameters, decl.body);
125126
default:

0 commit comments

Comments
 (0)