@@ -224,12 +224,10 @@ namespace ts.codefix {
224
224
}
225
225
226
226
function tryDeleteParameter ( changes : textChanges . ChangeTracker , sourceFile : SourceFile , p : ParameterDeclaration , checker : TypeChecker , sourceFiles : readonly SourceFile [ ] , isFixAll = false ) : void {
227
- if ( mayDeleteParameter ( p , checker , isFixAll ) ) {
228
- if ( p . modifiers && p . modifiers . length > 0
229
- && ( ! isIdentifier ( p . name ) || FindAllReferences . Core . isSymbolReferencedInFile ( p . name , checker , sourceFile ) ) ) {
230
- p . modifiers . forEach ( modifier => {
231
- changes . deleteModifier ( sourceFile , modifier ) ;
232
- } ) ;
227
+ if ( mayDeleteParameter ( checker , sourceFile , p , isFixAll ) ) {
228
+ if ( p . modifiers && p . modifiers . length > 0 &&
229
+ ( ! isIdentifier ( p . name ) || FindAllReferences . Core . isSymbolReferencedInFile ( p . name , checker , sourceFile ) ) ) {
230
+ p . modifiers . forEach ( modifier => changes . deleteModifier ( sourceFile , modifier ) ) ;
233
231
}
234
232
else {
235
233
changes . delete ( sourceFile , p ) ;
@@ -238,29 +236,26 @@ namespace ts.codefix {
238
236
}
239
237
}
240
238
241
- function mayDeleteParameter ( p : ParameterDeclaration , checker : TypeChecker , isFixAll : boolean ) : boolean {
242
- const { parent } = p ;
239
+ function mayDeleteParameter ( checker : TypeChecker , sourceFile : SourceFile , parameter : ParameterDeclaration , isFixAll : boolean ) : boolean {
240
+ const { parent } = parameter ;
243
241
switch ( parent . kind ) {
244
242
case SyntaxKind . MethodDeclaration :
245
243
// Don't remove a parameter if this overrides something.
246
244
const symbol = checker . getSymbolAtLocation ( parent . name ) ! ;
247
245
if ( isMemberSymbolInBaseType ( symbol , checker ) ) return false ;
248
246
// falls through
249
-
250
247
case SyntaxKind . Constructor :
251
- case SyntaxKind . FunctionDeclaration :
252
248
return true ;
253
-
249
+ case SyntaxKind . FunctionDeclaration : {
250
+ if ( parent . name && isCallbackLike ( checker , sourceFile , parent . name ) ) {
251
+ return isLastParameter ( parent , parameter , isFixAll ) ;
252
+ }
253
+ return true ;
254
+ }
254
255
case SyntaxKind . FunctionExpression :
255
- case SyntaxKind . ArrowFunction : {
256
+ case SyntaxKind . ArrowFunction :
256
257
// Can't remove a non-last parameter in a callback. Can remove a parameter in code-fix-all if future parameters are also unused.
257
- const { parameters } = parent ;
258
- const index = parameters . indexOf ( p ) ;
259
- Debug . assert ( index !== - 1 , "The parameter should already be in the list" ) ;
260
- return isFixAll
261
- ? parameters . slice ( index + 1 ) . every ( p => p . name . kind === SyntaxKind . Identifier && ! p . symbol . isReferenced )
262
- : index === parameters . length - 1 ;
263
- }
258
+ return isLastParameter ( parent , parameter , isFixAll ) ;
264
259
265
260
case SyntaxKind . SetAccessor :
266
261
// Setter must have a parameter
@@ -279,4 +274,18 @@ namespace ts.codefix {
279
274
}
280
275
} ) ;
281
276
}
277
+
278
+ function isCallbackLike ( checker : TypeChecker , sourceFile : SourceFile , name : Identifier ) : boolean {
279
+ return ! ! FindAllReferences . Core . eachSymbolReferenceInFile ( name , checker , sourceFile , reference =>
280
+ isIdentifier ( reference ) && isCallExpression ( reference . parent ) && reference . parent . arguments . indexOf ( reference ) >= 0 ) ;
281
+ }
282
+
283
+ function isLastParameter ( func : FunctionLikeDeclaration , parameter : ParameterDeclaration , isFixAll : boolean ) : boolean {
284
+ const parameters = func . parameters ;
285
+ const index = parameters . indexOf ( parameter ) ;
286
+ Debug . assert ( index !== - 1 , "The parameter should already be in the list" ) ;
287
+ return isFixAll ?
288
+ parameters . slice ( index + 1 ) . every ( p => isIdentifier ( p . name ) && ! p . symbol . isReferenced ) :
289
+ index === parameters . length - 1 ;
290
+ }
282
291
}
0 commit comments