in server/src/eslintServer.ts [2279:2356]
async function computeAllFixes(identifier: VersionedTextDocumentIdentifier, mode: AllFixesMode): Promise<TextEdit[] | undefined> {
const uri = identifier.uri;
const textDocument = documents.get(uri)!;
if (textDocument === undefined || identifier.version !== textDocument.version) {
return undefined;
}
const settings = await resolveSettings(textDocument);
if (settings.validate !== Validate.on || !TextDocumentSettings.hasLibrary(settings) || (mode === AllFixesMode.format && !settings.format)) {
return [];
}
const filePath = getFilePath(textDocument);
const problems = codeActions.get(uri);
const originalContent = textDocument.getText();
let start = Date.now();
// Only use known fixes when running in onSave mode. See https://github.com/microsoft/vscode-eslint/issues/871
// for details
if (mode === AllFixesMode.onSave && settings.codeActionOnSave.mode === CodeActionsOnSaveMode.problems) {
const result = problems !== undefined && problems.size > 0
? new Fixes(problems).getApplicable().map(fix => FixableProblem.createTextEdit(textDocument, fix))
: [];
connection.tracer.log(`Computing all fixes took: ${Date.now() - start} ms.`);
return result;
} else {
const saveConfig = filePath !== undefined && mode === AllFixesMode.onSave ? await getSaveRuleConfig(uri, settings) : undefined;
const offRules = saveConfig?.offRules;
const onRules = saveConfig?.onRules;
let overrideConfig: Required<ConfigData> | undefined;
if (offRules !== undefined) {
overrideConfig = { rules: Object.create(null) };
for (const ruleId of offRules) {
overrideConfig.rules[ruleId] = 'off';
}
}
return withESLintClass(async (eslintClass) => {
const result: TextEdit[] = [];
let fixes: TextEdit[] | undefined;
if (problems !== undefined && problems.size > 0) {
// We have override rules that turn rules off. Filter the fixes for these rules.
if (offRules !== undefined) {
const filtered: typeof problems = new Map();
for (const [key, problem] of problems) {
if (onRules?.has(problem.ruleId)) {
filtered.set(key, problem);
}
}
fixes = filtered.size > 0 ? new Fixes(filtered).getApplicable().map(fix => FixableProblem.createTextEdit(textDocument, fix)) : undefined;
} else {
fixes = new Fixes(problems).getApplicable().map(fix => FixableProblem.createTextEdit(textDocument, fix));
}
}
const content = fixes !== undefined
? TextDocument.applyEdits(textDocument, fixes)
: originalContent;
const reportResults = await eslintClass.lintText(content, { filePath });
connection.tracer.log(`Computing all fixes took: ${Date.now() - start} ms.`);
if (Array.isArray(reportResults) && reportResults.length === 1 && reportResults[0].output !== undefined) {
const fixedContent = reportResults[0].output;
start = Date.now();
const diffs = stringDiff(originalContent, fixedContent, false);
connection.tracer.log(`Computing minimal edits took: ${Date.now() - start} ms.`);
for (const diff of diffs) {
result.push({
range: {
start: textDocument.positionAt(diff.originalStart),
end: textDocument.positionAt(diff.originalStart + diff.originalLength)
},
newText: fixedContent.substr(diff.modifiedStart, diff.modifiedLength)
});
}
} else if (fixes !== undefined) {
result.push(...fixes);
}
return result;
}, settings, overrideConfig !== undefined ? { fix: true, overrideConfig } : { fix: true });
}
}