namespace ts . codefix { const errorCodeToFixes = createMultiMap < CodeFixRegistration > ( ) ; const fixIdToRegistration = new Map < string , CodeFixRegistration > ( ) ; export function createCodeFixActionWithoutFixAll ( fixName , changes , description ) { return createCodeFixActionWorker ( fixName , diagnosticToString ( description ) , changes , undefined , undefined ) ; } export function createCodeFixAction ( fixName , changes , description , fixId , fixAllDescription , command ? ) { return createCodeFixActionWorker ( fixName , diagnosticToString ( description ) , changes , fixId , diagnosticToString ( fixAllDescription ) , command ) ; } export function createCodeFixActionMaybeFixAll ( fixName , changes , description , fixId ? , fixAllDescription ? , command ? ) { return createCodeFixActionWorker ( fixName , diagnosticToString ( description ) , changes , fixId , fixAllDescription && diagnosticToString ( fixAllDescription ) , command ) ; } function createCodeFixActionWorker ( fixName , description , changes , fixId ? , fixAllDescription ? , command ? ) { return { fixName , description , changes , fixId , fixAllDescription , commands : command ? [ command ] : undefined } ; } export function registerCodeFix ( reg ) { for ( const error of reg . errorCodes ) { errorCodeToFixes . add ( String ( error ) , reg ) ; } if ( reg . fixIds ) { for ( const fixId of reg . fixIds ) { Debug . assert ( ! fixIdToRegistration . has ( fixId ) ) ; fixIdToRegistration . set ( fixId , reg ) ; } } } export function getSupportedErrorCodes ( ) { return arrayFrom ( errorCodeToFixes . keys ( ) ) ; } function removeFixIdIfFixAllUnavailable ( registration , diagnostics ) { const { errorCodes } = registration ; let maybeFixableDiagnostics = 0 ; for ( const diag of diagnostics ) { if ( contains ( errorCodes , diag . code ) ) maybeFixableDiagnostics ++ ; if ( maybeFixableDiagnostics > 1 ) break ; } const fixAllUnavailable = maybeFixableDiagnostics < 2 ; return ( { fixId , fixAllDescription , ... action } ) : CodeFixAction => { return fixAllUnavailable ? action : { ... action , fixId , fixAllDescription } ; } ; } export function getFixes ( context ) { const diagnostics = getDiagnostics ( context ) ; const registrations = errorCodeToFixes . get ( String ( context . errorCode ) ) ; return flatMap ( registrations , f => map ( f . getCodeActions ( context ) , removeFixIdIfFixAllUnavailable ( f , diagnostics ) ) ) ; } export function getAllFixes ( context ) { return fixIdToRegistration . get ( cast ( context . fixId , isString ) ) ! . getAllCodeActions ! ( context ) ; } export function createCombinedCodeActions ( changes , commands ? ) { return { changes , commands } ; } export function createFileTextChanges ( fileName , textChanges ) { return { fileName , textChanges } ; } export function codeFixAll ( context , errorCodes , use ) { const commands = [ ] ; const changes = textChanges . ChangeTracker . with ( context , t => eachDiagnostic ( context , errorCodes , diag => use ( t , diag , commands ) ) ) ; return createCombinedCodeActions ( changes , commands . length === 0 ? undefined : commands ) ; } export function eachDiagnostic ( context , errorCodes , cb ) { for ( const diag of getDiagnostics ( context ) ) { if ( contains ( errorCodes , diag . code ) ) { cb ( diag as DiagnosticWithLocation ) ; } } } function getDiagnostics ( { program , sourceFile , cancellationToken } ) { return [ ... program . getSemanticDiagnostics ( sourceFile , cancellationToken ) , ... program . getSyntacticDiagnostics ( sourceFile , cancellationToken ) , ... computeSuggestionDiagnostics ( sourceFile , program , cancellationToken ) ] ; } }