@@ -42,19 +42,34 @@ namespace ts.codefix {
42
42
43
43
function doChange ( changes : textChanges . ChangeTracker , sourceFile : SourceFile , decl : DeclarationWithType ) : void {
44
44
if ( isFunctionLikeDeclaration ( decl ) && ( getJSDocReturnType ( decl ) || decl . parameters . some ( p => ! ! getJSDocType ( p ) ) ) ) {
45
- findAncestor ( decl , isFunctionLike ) ;
46
- const fn = findAncestor ( decl , isFunctionLikeDeclaration ) ;
47
- const functionWithType = addTypesToFunctionLike ( fn ) ;
48
- suppressLeadingAndTrailingTrivia ( functionWithType ) ;
49
- changes . replaceNode ( sourceFile , fn , functionWithType , textChanges . useNonAdjustedPositions ) ;
50
- return ;
45
+ const typeParameters = getJSDocTypeParameterDeclarations ( decl ) ;
46
+ const returnType = getJSDocReturnType ( decl ) ;
47
+ const returnTypeNode = returnType && transformJSDocType ( returnType ) ;
48
+
49
+ if ( isArrowFunction ( decl ) && ! findChildOfKind ( decl , SyntaxKind . OpenParenToken , sourceFile ) ) {
50
+ const params = decl . parameters . map ( p => {
51
+ const paramType = getJSDocType ( p ) ;
52
+ return paramType && ! p . type ? updateParameter ( p , p . decorators , p . modifiers , p . dotDotDotToken , p . name , p . questionToken , transformJSDocType ( paramType ) , p . initializer ) : p ;
53
+ } ) ;
54
+ changes . replaceNode ( sourceFile , decl , updateArrowFunction ( decl , decl . modifiers , decl . typeParameters || typeParameters , params , decl . type || returnTypeNode , decl . equalsGreaterThanToken , decl . body ) ) ;
55
+ }
56
+ else {
57
+ if ( typeParameters && ! decl . typeParameters ) {
58
+ changes . insertTypeParameters ( sourceFile , decl , typeParameters ) ;
59
+ }
60
+ for ( const param of decl . parameters ) {
61
+ if ( ! param . type ) {
62
+ const paramType = getJSDocType ( param ) ;
63
+ if ( paramType ) changes . insertTypeAnnotation ( sourceFile , param , transformJSDocType ( paramType ) ) ;
64
+ }
65
+ }
66
+ if ( returnTypeNode && ! decl . type ) changes . insertTypeAnnotation ( sourceFile , decl , returnTypeNode ) ;
67
+ }
51
68
}
52
69
else {
53
70
const jsdocType = Debug . assertDefined ( getJSDocType ( decl ) ) ; // If not defined, shouldn't have been an error to fix
54
71
Debug . assert ( ! decl . type ) ; // If defined, shouldn't have been an error to fix.
55
- const declarationWithType = addType ( decl , transformJSDocType ( jsdocType ) as TypeNode ) ;
56
- suppressLeadingAndTrailingTrivia ( declarationWithType ) ;
57
- changes . replaceNode ( sourceFile , decl , declarationWithType , textChanges . useNonAdjustedPositions ) ;
72
+ changes . insertTypeAnnotation ( sourceFile , decl , transformJSDocType ( jsdocType ) ) ;
58
73
}
59
74
}
60
75
@@ -65,48 +80,7 @@ namespace ts.codefix {
65
80
node . kind === SyntaxKind . PropertyDeclaration ;
66
81
}
67
82
68
- function addTypesToFunctionLike ( decl : FunctionLikeDeclaration ) {
69
- const typeParameters = getEffectiveTypeParameterDeclarations ( decl , /*checkJSDoc*/ true ) ;
70
- const parameters = decl . parameters . map (
71
- p => createParameter ( p . decorators , p . modifiers , p . dotDotDotToken , p . name , p . questionToken , transformJSDocType ( getEffectiveTypeAnnotationNode ( p , /*checkJSDoc*/ true ) ) as TypeNode , p . initializer ) ) ;
72
- const returnType = transformJSDocType ( getEffectiveReturnTypeNode ( decl , /*checkJSDoc*/ true ) ) as TypeNode ;
73
- switch ( decl . kind ) {
74
- case SyntaxKind . FunctionDeclaration :
75
- return createFunctionDeclaration ( decl . decorators , decl . modifiers , decl . asteriskToken , decl . name , typeParameters , parameters , returnType , decl . body ) ;
76
- case SyntaxKind . Constructor :
77
- return createConstructor ( decl . decorators , decl . modifiers , parameters , decl . body ) ;
78
- case SyntaxKind . FunctionExpression :
79
- return createFunctionExpression ( decl . modifiers , decl . asteriskToken , decl . name , typeParameters , parameters , returnType , decl . body ) ;
80
- case SyntaxKind . ArrowFunction :
81
- return createArrowFunction ( decl . modifiers , typeParameters , parameters , returnType , decl . equalsGreaterThanToken , decl . body ) ;
82
- case SyntaxKind . MethodDeclaration :
83
- return createMethod ( decl . decorators , decl . modifiers , decl . asteriskToken , decl . name , decl . questionToken , typeParameters , parameters , returnType , decl . body ) ;
84
- case SyntaxKind . GetAccessor :
85
- return createGetAccessor ( decl . decorators , decl . modifiers , decl . name , decl . parameters , returnType , decl . body ) ;
86
- case SyntaxKind . SetAccessor :
87
- return createSetAccessor ( decl . decorators , decl . modifiers , decl . name , parameters , decl . body ) ;
88
- default :
89
- return Debug . assertNever ( decl , `Unexpected SyntaxKind: ${ ( decl as any ) . kind } ` ) ;
90
- }
91
- }
92
-
93
- function addType ( decl : DeclarationWithType , jsdocType : TypeNode ) {
94
- switch ( decl . kind ) {
95
- case SyntaxKind . VariableDeclaration :
96
- return createVariableDeclaration ( decl . name , jsdocType , decl . initializer ) ;
97
- case SyntaxKind . PropertySignature :
98
- return createPropertySignature ( decl . modifiers , decl . name , decl . questionToken , jsdocType , decl . initializer ) ;
99
- case SyntaxKind . PropertyDeclaration :
100
- return createProperty ( decl . decorators , decl . modifiers , decl . name , decl . questionToken , jsdocType , decl . initializer ) ;
101
- default :
102
- return Debug . fail ( `Unexpected SyntaxKind: ${ decl . kind } ` ) ;
103
- }
104
- }
105
-
106
- function transformJSDocType ( node : Node ) : Node | undefined {
107
- if ( node === undefined ) {
108
- return undefined ;
109
- }
83
+ function transformJSDocType ( node : TypeNode ) : TypeNode | undefined {
110
84
switch ( node . kind ) {
111
85
case SyntaxKind . JSDocAllType :
112
86
case SyntaxKind . JSDocUnknownType :
@@ -121,12 +95,10 @@ namespace ts.codefix {
121
95
return transformJSDocVariadicType ( node as JSDocVariadicType ) ;
122
96
case SyntaxKind . JSDocFunctionType :
123
97
return transformJSDocFunctionType ( node as JSDocFunctionType ) ;
124
- case SyntaxKind . Parameter :
125
- return transformJSDocParameter ( node as ParameterDeclaration ) ;
126
98
case SyntaxKind . TypeReference :
127
99
return transformJSDocTypeReference ( node as TypeReferenceNode ) ;
128
100
default :
129
- const visited = visitEachChild ( node , transformJSDocType , /*context*/ undefined ) as TypeNode ;
101
+ const visited = visitEachChild ( node , transformJSDocType , /*context*/ undefined ) ;
130
102
setEmitFlags ( visited , EmitFlags . SingleLine ) ;
131
103
return visited ;
132
104
}
@@ -145,8 +117,7 @@ namespace ts.codefix {
145
117
}
146
118
147
119
function transformJSDocFunctionType ( node : JSDocFunctionType ) {
148
- const parameters = node . parameters && node . parameters . map ( transformJSDocType ) ;
149
- return createFunctionTypeNode ( emptyArray , parameters as ParameterDeclaration [ ] , node . type ) ;
120
+ return createFunctionTypeNode ( emptyArray , node . parameters . map ( transformJSDocParameter ) , node . type ) ;
150
121
}
151
122
152
123
function transformJSDocParameter ( node : ParameterDeclaration ) {
0 commit comments