"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.register = void 0; const rename_1 = require("./rename"); const fixNames = require("../utils/fixNames"); const getFormatCodeSettings_1 = require("../configs/getFormatCodeSettings"); const getUserPreferences_1 = require("../configs/getUserPreferences"); const shared_1 = require("../shared"); const codeActionResolve_1 = require("./codeActionResolve"); function register(ctx) { let resolveCommandSupport = ctx.env.clientCapabilities?.textDocument?.codeAction?.resolveSupport?.properties?.includes('command'); let resolveEditSupport = ctx.env.clientCapabilities?.textDocument?.codeAction?.resolveSupport?.properties?.includes('edit'); if (!ctx.env.clientCapabilities) { resolveCommandSupport = true; resolveEditSupport = true; } return async (uri, range, context) => { const document = ctx.getTextDocument(uri); if (!document) return; const [formatOptions, preferences] = await Promise.all([ (0, getFormatCodeSettings_1.getFormatCodeSettings)(ctx, document), (0, getUserPreferences_1.getUserPreferences)(ctx, document), ]); const fileName = ctx.env.uriToFileName(document.uri); const start = document.offsetAt(range.start); const end = document.offsetAt(range.end); let result = []; const onlyQuickFix = matchOnlyKind(`${'quickfix'}.ts`); if (!context.only || onlyQuickFix) { for (const error of context.diagnostics) { const codeFixes = (0, shared_1.safeCall)(() => ctx.typescript.languageService.getCodeFixesAtPosition(fileName, document.offsetAt(error.range.start), document.offsetAt(error.range.end), [Number(error.code)], formatOptions, preferences)) ?? []; for (const codeFix of codeFixes) { result = result.concat(transformCodeFix(codeFix, [error], onlyQuickFix ?? '')); } } } if (context.only) { for (const only of context.only) { if (only.split('.')[0] === 'refactor') { const refactors = (0, shared_1.safeCall)(() => ctx.typescript.languageService.getApplicableRefactors(fileName, { pos: start, end: end }, preferences, undefined, only)) ?? []; for (const refactor of refactors) { result = result.concat(transformRefactor(refactor)); } } } } else { const refactors = (0, shared_1.safeCall)(() => ctx.typescript.languageService.getApplicableRefactors(fileName, { pos: start, end: end }, preferences, undefined, undefined)) ?? []; for (const refactor of refactors) { result = result.concat(transformRefactor(refactor)); } } const onlySourceOrganizeImports = matchOnlyKind(`${'source.organizeImports'}.ts`); if (onlySourceOrganizeImports) { const action = { title: 'Organize Imports', kind: onlySourceOrganizeImports, }; const data = { type: 'organizeImports', uri, fileName, }; if (resolveEditSupport) { action.data = data; } else { (0, codeActionResolve_1.resolveOrganizeImportsCodeAction)(ctx, action, data, formatOptions, preferences); } result.push(action); } const onlySourceFixAll = matchOnlyKind(`${'source.fixAll'}.ts`); if (onlySourceFixAll) { const action = { title: 'Fix All', kind: onlySourceFixAll, }; const data = { uri, type: 'fixAll', fileName, fixIds: [ fixNames.classIncorrectlyImplementsInterface, fixNames.awaitInSyncFunction, fixNames.unreachableCode, ], }; if (resolveEditSupport) { action.data = data; } else { (0, codeActionResolve_1.resolveFixAllCodeAction)(ctx, action, data, formatOptions, preferences); } result.push(action); } const onlyRemoveUnused = matchOnlyKind(`${'source'}.removeUnused.ts`); if (onlyRemoveUnused) { const action = { title: 'Remove all unused code', kind: onlyRemoveUnused, }; const data = { uri, type: 'fixAll', fileName, fixIds: [ // not working and throw fixNames.unusedIdentifier, // TODO: remove patching 'unusedIdentifier_prefix', 'unusedIdentifier_deleteImports', 'unusedIdentifier_delete', 'unusedIdentifier_infer', ], }; if (resolveEditSupport) { action.data = data; } else { (0, codeActionResolve_1.resolveFixAllCodeAction)(ctx, action, data, formatOptions, preferences); } result.push(action); } const onlyAddMissingImports = matchOnlyKind(`${'source'}.addMissingImports.ts`); if (onlyAddMissingImports) { const action = { title: 'Add all missing imports', kind: onlyAddMissingImports, }; const data = { uri, type: 'fixAll', fileName, fixIds: [ // not working and throw fixNames.fixImport, // TODO: remove patching 'fixMissingImport', ], }; if (resolveEditSupport) { action.data = data; } else { (0, codeActionResolve_1.resolveFixAllCodeAction)(ctx, action, data, formatOptions, preferences); } result.push(action); } for (const codeAction of result) { if (codeAction.diagnostics === undefined) { codeAction.diagnostics = context.diagnostics; } } return result; function matchOnlyKind(kind) { if (context.only) { for (const only of context.only) { const a = only.split('.'); const b = kind.split('.'); if (a.length <= b.length) { let matchNums = 0; for (let i = 0; i < a.length; i++) { if (a[i] == b[i]) { matchNums++; } } if (matchNums === a.length) return only; } } } } function transformCodeFix(codeFix, diagnostics, kind) { const edit = (0, rename_1.fileTextChangesToWorkspaceEdit)(codeFix.changes, ctx); const codeActions = []; const fix = { title: codeFix.description, kind, edit, }; fix.diagnostics = diagnostics; codeActions.push(fix); if (codeFix.fixAllDescription && codeFix.fixId) { const fixAll = { title: codeFix.fixAllDescription, kind, }; const data = { uri, type: 'fixAll', fileName, fixIds: [codeFix.fixId], }; if (resolveEditSupport) { fixAll.data = data; } else { (0, codeActionResolve_1.resolveFixAllCodeAction)(ctx, fixAll, data, formatOptions, preferences); } fixAll.diagnostics = diagnostics; codeActions.push(fixAll); } return codeActions; } function transformRefactor(refactor) { const codeActions = []; for (const action of refactor.actions) { const codeAction = { title: action.description, kind: action.kind, }; if (action.notApplicableReason) { codeAction.disabled = { reason: action.notApplicableReason }; } if (refactor.inlineable) { codeAction.isPreferred = true; } const data = { uri, type: 'refactor', fileName, range: { pos: start, end: end }, refactorName: refactor.name, actionName: action.name, }; if (resolveCommandSupport && resolveEditSupport) { codeAction.data = data; } else if (!codeAction.disabled && document) { (0, codeActionResolve_1.resolveRefactorCodeAction)(ctx, codeAction, data, document, formatOptions, preferences); } codeActions.push(codeAction); } return codeActions; } }; } exports.register = register; //# sourceMappingURL=codeAction.js.map