240 lines
9.5 KiB
Plaintext
240 lines
9.5 KiB
Plaintext
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.register = void 0;
|
|
const getFormatCodeSettings_1 = require("../configs/getFormatCodeSettings");
|
|
const getUserPreferences_1 = require("../configs/getUserPreferences");
|
|
const shared_1 = require("../shared");
|
|
const fixNames = require("../utils/fixNames");
|
|
const codeActionResolve_1 = require("./codeActionResolve");
|
|
const rename_1 = require("./rename");
|
|
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.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.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.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.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 |