@@ -25,6 +25,8 @@ namespace ts.refactor.addOrRemoveBracesToArrowFunction {
25
25
const signatureDecls = getConvertableOverloadListAtPosition ( file , startPosition , program ) ;
26
26
if ( ! signatureDecls ) return undefined ;
27
27
28
+ const checker = program . getTypeChecker ( ) ;
29
+
28
30
const lastDeclaration = signatureDecls [ signatureDecls . length - 1 ] ;
29
31
let updated = lastDeclaration ;
30
32
switch ( lastDeclaration . kind ) {
@@ -39,6 +41,21 @@ namespace ts.refactor.addOrRemoveBracesToArrowFunction {
39
41
) ;
40
42
break ;
41
43
}
44
+ case SyntaxKind . MethodDeclaration : {
45
+ updated = updateMethod (
46
+ lastDeclaration ,
47
+ lastDeclaration . decorators ,
48
+ lastDeclaration . modifiers ,
49
+ lastDeclaration . asteriskToken ,
50
+ lastDeclaration . name ,
51
+ lastDeclaration . questionToken ,
52
+ lastDeclaration . typeParameters ,
53
+ getNewParametersForCombinedSignature ( signatureDecls ) ,
54
+ lastDeclaration . type ,
55
+ lastDeclaration . body
56
+ ) ;
57
+ break ;
58
+ }
42
59
case SyntaxKind . CallSignature : {
43
60
updated = updateCallSignature (
44
61
lastDeclaration ,
@@ -48,6 +65,16 @@ namespace ts.refactor.addOrRemoveBracesToArrowFunction {
48
65
) ;
49
66
break ;
50
67
}
68
+ case SyntaxKind . Constructor : {
69
+ updated = updateConstructor (
70
+ lastDeclaration ,
71
+ lastDeclaration . decorators ,
72
+ lastDeclaration . modifiers ,
73
+ getNewParametersForCombinedSignature ( signatureDecls ) ,
74
+ lastDeclaration . body
75
+ ) ;
76
+ break ;
77
+ }
51
78
case SyntaxKind . ConstructSignature : {
52
79
updated = updateConstructSignature (
53
80
lastDeclaration ,
@@ -84,7 +111,12 @@ namespace ts.refactor.addOrRemoveBracesToArrowFunction {
84
111
85
112
return { renameFilename : undefined , renameLocation : undefined , edits } ;
86
113
87
- function getNewParametersForCombinedSignature ( signatureDeclarations : ( MethodSignature | CallSignatureDeclaration | ConstructSignatureDeclaration | FunctionDeclaration ) [ ] ) : NodeArray < ParameterDeclaration > {
114
+ function getNewParametersForCombinedSignature ( signatureDeclarations : ( MethodSignature | MethodDeclaration | CallSignatureDeclaration | ConstructorDeclaration | ConstructSignatureDeclaration | FunctionDeclaration ) [ ] ) : NodeArray < ParameterDeclaration > {
115
+ const lastSig = signatureDeclarations [ signatureDeclarations . length - 1 ] ;
116
+ if ( isFunctionLikeDeclaration ( lastSig ) && lastSig . body ) {
117
+ // Trim away implementation signature arguments (they should already be compatible with overloads, but are likely less precise to guarantee compatability with the overloads)
118
+ signatureDeclarations = signatureDeclarations . slice ( 0 , signatureDeclarations . length - 1 ) ;
119
+ }
88
120
return createNodeArray ( [
89
121
createParameter (
90
122
/*decorators*/ undefined ,
@@ -97,24 +129,56 @@ namespace ts.refactor.addOrRemoveBracesToArrowFunction {
97
129
] ) ;
98
130
}
99
131
100
- function convertSignatureParametersToTuple ( decl : MethodSignature | CallSignatureDeclaration | ConstructSignatureDeclaration | FunctionDeclaration ) : TupleTypeNode {
101
- return setEmitFlags ( createTupleTypeNode ( map ( decl . parameters , convertParameterToNamedTupleMember ) ) , EmitFlags . SingleLine ) ;
132
+ function convertSignatureParametersToTuple ( decl : MethodSignature | MethodDeclaration | CallSignatureDeclaration | ConstructorDeclaration | ConstructSignatureDeclaration | FunctionDeclaration ) : TupleTypeNode {
133
+ const members = map ( decl . parameters , convertParameterToNamedTupleMember ) ;
134
+ return setEmitFlags ( createTupleTypeNode ( members ) , some ( members , m => ! ! length ( getSyntheticLeadingComments ( m ) ) ) ? EmitFlags . None : EmitFlags . SingleLine ) ;
102
135
}
103
136
104
137
function convertParameterToNamedTupleMember ( p : ParameterDeclaration ) : NamedTupleMember {
105
138
Debug . assert ( isIdentifier ( p . name ) ) ; // This is checked during refactoring applicability checking
106
- return setTextRange ( createNamedTupleMember (
139
+ const result = setTextRange ( createNamedTupleMember (
107
140
p . dotDotDotToken ,
108
141
p . name ,
109
142
p . questionToken ,
110
143
p . type || createKeywordTypeNode ( SyntaxKind . AnyKeyword )
111
144
) , p ) ;
145
+ const parameterDocComment = p . symbol && p . symbol . getDocumentationComment ( checker ) ;
146
+ if ( parameterDocComment ) {
147
+ const newComment = displayPartsToString ( parameterDocComment ) ;
148
+ if ( newComment . length ) {
149
+ setSyntheticLeadingComments ( result , [ {
150
+ text : `*
151
+ ${ newComment . split ( "\n" ) . map ( c => ` * ${ c } ` ) . join ( "\n" ) }
152
+ ` ,
153
+ kind : SyntaxKind . MultiLineCommentTrivia ,
154
+ pos : - 1 ,
155
+ end : - 1 ,
156
+ hasTrailingNewLine : true ,
157
+ hasLeadingNewline : true ,
158
+ } ] ) ;
159
+ }
160
+ }
161
+ return result ;
112
162
}
163
+
164
+ }
165
+
166
+ function isConvertableSignatureDeclaration ( d : Node ) : d is MethodSignature | MethodDeclaration | CallSignatureDeclaration | ConstructorDeclaration | ConstructSignatureDeclaration | FunctionDeclaration {
167
+ switch ( d . kind ) {
168
+ case SyntaxKind . MethodSignature :
169
+ case SyntaxKind . MethodDeclaration :
170
+ case SyntaxKind . CallSignature :
171
+ case SyntaxKind . Constructor :
172
+ case SyntaxKind . ConstructSignature :
173
+ case SyntaxKind . FunctionDeclaration :
174
+ return true ;
175
+ }
176
+ return false ;
113
177
}
114
178
115
179
function getConvertableOverloadListAtPosition ( file : SourceFile , startPosition : number , program : Program ) {
116
180
const node = getTokenAtPosition ( file , startPosition ) ;
117
- const containingDecl = findAncestor ( node , n => isFunctionLikeDeclaration ( n ) ) ;
181
+ const containingDecl = findAncestor ( node , isConvertableSignatureDeclaration ) ;
118
182
if ( ! containingDecl ) {
119
183
return ;
120
184
}
@@ -130,14 +194,14 @@ namespace ts.refactor.addOrRemoveBracesToArrowFunction {
130
194
if ( ! every ( decls , d => getSourceFileOfNode ( d ) === file ) ) {
131
195
return ;
132
196
}
133
- const kindOne = decls [ 0 ] . kind ;
134
- if ( kindOne !== SyntaxKind . MethodSignature && kindOne !== SyntaxKind . CallSignature && kindOne !== SyntaxKind . ConstructSignature && kindOne !== SyntaxKind . FunctionDeclaration ) {
197
+ if ( ! isConvertableSignatureDeclaration ( decls [ 0 ] ) ) {
135
198
return ;
136
199
}
200
+ const kindOne = decls [ 0 ] . kind ;
137
201
if ( ! every ( decls , d => d . kind === kindOne ) ) {
138
202
return ;
139
203
}
140
- const signatureDecls = decls as ( MethodSignature | CallSignatureDeclaration | ConstructSignatureDeclaration | FunctionDeclaration ) [ ] ;
204
+ const signatureDecls = decls as ( MethodSignature | MethodDeclaration | CallSignatureDeclaration | ConstructorDeclaration | ConstructSignatureDeclaration | FunctionDeclaration ) [ ] ;
141
205
if ( some ( signatureDecls , d => ! ! d . typeParameters || some ( d . parameters , p => ! ! p . decorators || ! ! p . modifiers || ! isIdentifier ( p . name ) ) ) ) {
142
206
return ;
143
207
}
0 commit comments