namespace ts . refactor . addOrRemoveBracesToArrowFunction { const refactorName = "Add or remove braces in an arrow function" ; const refactorDescription = Diagnostics . Add_or_remove_braces_in_an_arrow_function . message ; const addBracesAction = { name : "Add braces to arrow function" , description : Diagnostics . Add_braces_to_arrow_function . message , kind : "refactor.rewrite.arrow.braces.add" , } ; const removeBracesAction = { name : "Remove braces from arrow function" , description : Diagnostics . Remove_braces_from_arrow_function . message , kind : "refactor.rewrite.arrow.braces.remove" } ; registerRefactor ( refactorName , { kinds : [ removeBracesAction . kind ] , getEditsForAction : getRefactorEditsToRemoveFunctionBraces , getAvailableActions : getRefactorActionsToRemoveFunctionBraces } ) ; interface FunctionBracesInfo { func : ArrowFunction ; expression : Expression | undefined ; returnStatement ? : ReturnStatement ; addBraces : boolean ; } function getRefactorActionsToRemoveFunctionBraces ( context ) { const { file , startPosition , triggerReason } = context ; const info = getConvertibleArrowFunctionAtPosition ( file , startPosition , triggerReason === "invoked" ) ; if ( ! info ) return emptyArray ; if ( ! isRefactorErrorInfo ( info ) ) { return [ { name : refactorName , description : refactorDescription , actions : [ info . addBraces ? addBracesAction : removeBracesAction ] } ] ; } if ( context . preferences . provideRefactorNotApplicableReason ) { return [ { name : refactorName , description : refactorDescription , actions : [ { ... addBracesAction , notApplicableReason : info . error } , { ... removeBracesAction , notApplicableReason : info . error } , ] } ] ; } return emptyArray ; } function getRefactorEditsToRemoveFunctionBraces ( context , actionName ) { const { file , startPosition } = context ; const info = getConvertibleArrowFunctionAtPosition ( file , startPosition ) ; Debug . assert ( info && ! isRefactorErrorInfo ( info ) , "Expected applicable refactor info" ) ; const { expression , returnStatement , func } = info ; let body ; if ( actionName === addBracesAction . name ) { const returnStatement = factory . createReturnStatement ( expression ) ; body = factory . createBlock ( [ returnStatement ] , true ) ; copyLeadingComments ( expression ! , returnStatement , file , SyntaxKind . MultiLineCommentTrivia , true ) ; } else if ( actionName === removeBracesAction . name && returnStatement ) { const actualExpression = expression || factory . createVoidZero ( ) ; body = needsParentheses ( actualExpression ) ? factory . createParenthesizedExpression ( actualExpression ) : actualExpression ; copyTrailingAsLeadingComments ( returnStatement , body , file , SyntaxKind . MultiLineCommentTrivia , false ) ; copyLeadingComments ( returnStatement , body , file , SyntaxKind . MultiLineCommentTrivia , false ) ; copyTrailingComments ( returnStatement , body , file , SyntaxKind . MultiLineCommentTrivia , false ) ; } else { Debug . fail ( "invalid action" ) ; } const edits = textChanges . ChangeTracker . with ( context , t => { t . replaceNode ( file , func . body , body ) ; } ) ; return { renameFilename : undefined , renameLocation : undefined , edits } ; } function getConvertibleArrowFunctionAtPosition ( file , startPosition , considerFunctionBodies = true , kind ? ) { const node = getTokenAtPosition ( file , startPosition ) ; const func = getContainingFunction ( node ) ; if ( ! func ) { return { error : getLocaleSpecificMessage ( Diagnostics . Could_not_find_a_containing_arrow_function ) } ; } if ( ! isArrowFunction ( func ) ) { return { error : getLocaleSpecificMessage ( Diagnostics . Containing_function_is_not_an_arrow_function ) } ; } if ( ( ! rangeContainsRange ( func , node ) || rangeContainsRange ( func . body , node ) && ! considerFunctionBodies ) ) { return undefined ; } if ( refactorKindBeginsWith ( addBracesAction . kind , kind ) && isExpression ( func . body ) ) { return { func , addBraces : true , expression : func . body } ; } else if ( refactorKindBeginsWith ( removeBracesAction . kind , kind ) && isBlock ( func . body ) && func . body . statements . length === 1 ) { const firstStatement = first ( func . body . statements ) ; if ( isReturnStatement ( firstStatement ) ) { return { func , addBraces : false , expression : firstStatement . expression , returnStatement : firstStatement } ; } } return undefined ; } }