@textlint/kernel
Version:
textlint kernel is core logic by pure JavaScript.
102 lines • 4.44 kB
JavaScript
// LICENSE : MIT
;
import FixerTask from "../task/fixer-task";
import TaskRunner from "../task/task-runner";
import { TextlintSourceCodeImpl } from "../context/TextlintSourceCodeImpl";
import _debug from "debug";
import { applyFixesToSourceCode } from "@textlint/source-code-fixer";
import { invariant } from "../util/invariant";
import { parseByPlugin } from "../util/parse-by-plugin";
const debug = _debug("textlint:fixer-processor");
export default class FixerProcessor {
/**
* @param {Processor} processor
* @param {MessageProcessManager} messageProcessManager
*/
constructor(processor, messageProcessManager) {
this.processor = processor;
this.messageProcessManager = messageProcessManager;
}
/**
* Run fixer process
* @param {Config} config
* @param {string} [configBaseDir]
* @param {TextlintKernelRule[]} [rules]
* @param {TextlintKernelFilterRule[]} [filterRules]
* @param {SourceCode} sourceCode
* @returns {Promise.<TextlintFixResult>}
*/
async process({ config, configBaseDir, ruleDescriptors, filterRules, sourceCode }) {
invariant(sourceCode);
const { preProcess, postProcess } = this.processor.processor(sourceCode.ext);
// messages
let resultFilePath = sourceCode.filePath;
// applied fixing messages
// Revert = Sequentially apply message to applied output
// SourceCodeFixer.sequentiallyApplyFixes(fixedOutput, result.applyingMessages);
const applyingMessages = [];
// not applied fixing messages
const remainingMessages = [];
// original means original for applyingMessages and remainingMessages
// pre-applyingMessages + remainingMessages
const originalMessages = [];
// apply fixes to sourceText sequentially
let sourceText = sourceCode.text;
for (const ruleDescriptor of ruleDescriptors.fixableDescriptors) {
const parseResult = await parseByPlugin({
preProcess,
sourceText,
filePath: sourceCode.filePath
});
if (parseResult instanceof Error) {
// --fix can not report error as lint error
// Because fix's result has output content, It makes confuse user.
throw parseResult;
}
const newSourceCode = new TextlintSourceCodeImpl({
text: parseResult.text,
ast: parseResult.ast,
filePath: resultFilePath,
ext: sourceCode.ext
});
// create new Task
const task = new FixerTask({
config,
fixableRuleDescriptor: ruleDescriptor,
filterRuleDescriptors: filterRules,
sourceCode: newSourceCode,
configBaseDir
});
const messages = await TaskRunner.process(task);
const result = await postProcess(messages, sourceCode.filePath);
const filteredResult = {
messages: this.messageProcessManager.process(result.messages),
filePath: result.filePath ? result.filePath : `<Unknown{sourceCode.ext}>`
};
// TODO: should be removed resultFilePath
resultFilePath = filteredResult.filePath;
const applied = applyFixesToSourceCode(newSourceCode, filteredResult.messages);
// add messages
Array.prototype.push.apply(applyingMessages, applied.applyingMessages);
Array.prototype.push.apply(remainingMessages, applied.remainingMessages);
Array.prototype.push.apply(originalMessages, applied.messages);
// if not fixed, still use current sourceText
if (!applied.fixed) {
continue;
}
// if fixed, use fixed text at next
sourceText = applied.output;
}
debug(`Finish Processing: ${resultFilePath}`);
debug(`applyingMessages: ${applyingMessages.length}`);
debug(`remainingMessages: ${remainingMessages.length}`);
return {
filePath: resultFilePath ? resultFilePath : `<Unknown{sourceCode.ext}>`,
output: sourceText,
messages: originalMessages,
applyingMessages,
remainingMessages
};
}
}
//# sourceMappingURL=fixer-processor.js.map