namespace ts . refactor . addOrRemoveBracesToArrowFunction { const refactorName = "Convert overload list to single signature" ; const refactorDescription = Diagnostics . Convert_overload_list_to_single_signature . message ; const functionOverloadAction = { name : refactorName , description : refactorDescription , kind : "refactor.rewrite.function.overloadList" , } ; registerRefactor ( refactorName , { kinds : [ functionOverloadAction . kind ] , getEditsForAction : getRefactorEditsToConvertOverloadsToOneSignature , getAvailableActions : getRefactorActionsToConvertOverloadsToOneSignature } ) ; function getRefactorActionsToConvertOverloadsToOneSignature ( context ) { const { file , startPosition , program } = context ; const info = getConvertableOverloadListAtPosition ( file , startPosition , program ) ; if ( ! info ) return emptyArray ; return [ { name : refactorName , description : refactorDescription , actions : [ functionOverloadAction ] } ] ; } function getRefactorEditsToConvertOverloadsToOneSignature ( context ) { const { file , startPosition , program } = context ; const signatureDecls = getConvertableOverloadListAtPosition ( file , startPosition , program ) ; if ( ! signatureDecls ) return undefined ; const checker = program . getTypeChecker ( ) ; const lastDeclaration = signatureDecls [ signatureDecls . length - 1 ] ; let updated = lastDeclaration ; switch ( lastDeclaration . kind ) { case SyntaxKind . MethodSignature : { updated = factory . updateMethodSignature ( lastDeclaration , lastDeclaration . modifiers , lastDeclaration . name , lastDeclaration . questionToken , lastDeclaration . typeParameters , getNewParametersForCombinedSignature ( signatureDecls ) , lastDeclaration . type ) ; break ; } case SyntaxKind . MethodDeclaration : { updated = factory . updateMethodDeclaration ( lastDeclaration , lastDeclaration . decorators , lastDeclaration . modifiers , lastDeclaration . asteriskToken , lastDeclaration . name , lastDeclaration . questionToken , lastDeclaration . typeParameters , getNewParametersForCombinedSignature ( signatureDecls ) , lastDeclaration . type , lastDeclaration . body ) ; break ; } case SyntaxKind . CallSignature : { updated = factory . updateCallSignature ( lastDeclaration , lastDeclaration . typeParameters , getNewParametersForCombinedSignature ( signatureDecls ) , lastDeclaration . type ) ; break ; } case SyntaxKind . Constructor : { updated = factory . updateConstructorDeclaration ( lastDeclaration , lastDeclaration . decorators , lastDeclaration . modifiers , getNewParametersForCombinedSignature ( signatureDecls ) , lastDeclaration . body ) ; break ; } case SyntaxKind . ConstructSignature : { updated = factory . updateConstructSignature ( lastDeclaration , lastDeclaration . typeParameters , getNewParametersForCombinedSignature ( signatureDecls ) , lastDeclaration . type ) ; break ; } case SyntaxKind . FunctionDeclaration : { updated = factory . updateFunctionDeclaration ( lastDeclaration , lastDeclaration . decorators , lastDeclaration . modifiers , lastDeclaration . asteriskToken , lastDeclaration . name , lastDeclaration . typeParameters , getNewParametersForCombinedSignature ( signatureDecls ) , lastDeclaration . type , lastDeclaration . body ) ; break ; } default : return Debug . failBadSyntaxKind ( lastDeclaration , "Unhandled signature kind in overload list conversion refactoring" ) ; } if ( updated === lastDeclaration ) { return ; } const edits = textChanges . ChangeTracker . with ( context , t => { t . replaceNodeRange ( file , signatureDecls [ 0 ] , signatureDecls [ signatureDecls . length - 1 ] , updated ) ; } ) ; return { renameFilename : undefined , renameLocation : undefined , edits } ; function getNewParametersForCombinedSignature ( signatureDeclarations ) { const lastSig = signatureDeclarations [ signatureDeclarations . length - 1 ] ; if ( isFunctionLikeDeclaration ( lastSig ) && lastSig . body ) { signatureDeclarations = signatureDeclarations . slice ( 0 , signatureDeclarations . length - 1 ) ; } return factory . createNodeArray ( [ factory . createParameterDeclaration ( undefined , undefined , factory . createToken ( SyntaxKind . DotDotDotToken ) , "args" , undefined , factory . createUnionTypeNode ( map ( signatureDeclarations , convertSignatureParametersToTuple ) ) ) ] ) ; } function convertSignatureParametersToTuple ( decl ) { const members = map ( decl . parameters , convertParameterToNamedTupleMember ) ; return setEmitFlags ( factory . createTupleTypeNode ( members ) , some ( members , m => ! ! length ( getSyntheticLeadingComments ( m ) ) ) ? EmitFlags . None : EmitFlags . SingleLine ) ; } function convertParameterToNamedTupleMember ( p ) { Debug . assert ( isIdentifier ( p . name ) ) ; const result = setTextRange ( factory . createNamedTupleMember ( p . dotDotDotToken , p . name , p . questionToken , p . type || factory . createKeywordTypeNode ( SyntaxKind . AnyKeyword ) ) , p ) ; const parameterDocComment = p . symbol && p . symbol . getDocumentationComment ( checker ) ; if ( parameterDocComment ) { const newComment = displayPartsToString ( parameterDocComment ) ; if ( newComment . length ) { setSyntheticLeadingComments ( result , [ { text : `*
${ newComment . split ( "\n" ) . map ( c => ` * ${ c }` ) . join ( "\n" ) }
 ` , kind : SyntaxKind . MultiLineCommentTrivia , pos : - 1 , end : - 1 , hasTrailingNewLine : true , hasLeadingNewline : true , } ] ) ; } } return result ; } } function isConvertableSignatureDeclaration ( d ) { switch ( d . kind ) { case SyntaxKind . MethodSignature : case SyntaxKind . MethodDeclaration : case SyntaxKind . CallSignature : case SyntaxKind . Constructor : case SyntaxKind . ConstructSignature : case SyntaxKind . FunctionDeclaration : return true ; } return false ; } function getConvertableOverloadListAtPosition ( file , startPosition , program ) { const node = getTokenAtPosition ( file , startPosition ) ; const containingDecl = findAncestor ( node , isConvertableSignatureDeclaration ) ; if ( ! containingDecl ) { return ; } const checker = program . getTypeChecker ( ) ; const signatureSymbol = containingDecl . symbol ; if ( ! signatureSymbol ) { return ; } const decls = signatureSymbol . declarations ; if ( length ( decls ) <= 1 ) { return ; } if ( ! every ( decls , d => getSourceFileOfNode ( d ) === file ) ) { return ; } if ( ! isConvertableSignatureDeclaration ( decls ! [ 0 ] ) ) { return ; } const kindOne = decls ! [ 0 ] . kind ; if ( ! every ( decls , d => d . kind === kindOne ) ) { return ; } const signatureDecls = decls as ( MethodSignature | MethodDeclaration | CallSignatureDeclaration | ConstructorDeclaration | ConstructSignatureDeclaration | FunctionDeclaration ) [ ] ; if ( some ( signatureDecls , d => ! ! d . typeParameters || some ( d . parameters , p => ! ! p . decorators || ! ! p . modifiers || ! isIdentifier ( p . name ) ) ) ) { return ; } const signatures = mapDefined ( signatureDecls , d => checker . getSignatureFromDeclaration ( d ) ) ; if ( length ( signatures ) !== length ( decls ) ) { return ; } const returnOne = checker . getReturnTypeOfSignature ( signatures [ 0 ] ) ; if ( ! every ( signatures , s => checker . getReturnTypeOfSignature ( s ) === returnOne ) ) { return ; } return signatureDecls ; } }