@textlint/kernel
Version:
textlint kernel is core logic by pure JavaScript.
157 lines (145 loc) • 5.67 kB
text/typescript
import { invariant } from "../util/invariant";
import { TxtNode } from "@textlint/ast-node-types";
import type { TextlintSourceCodeRange } from "@textlint/types";
/**
* Fix Command object has `range` and `text`.
* `IntermediateFixCommand` has also `isAbsolute` flag value.
*/
export interface IntermediateFixCommand {
text: string;
range: number[];
isAbsolute: boolean;
}
/**
* Creates a fix command that inserts text at the specified index in the source text.
* @param {number} index The 0-based index at which to insert the new text.
* @param {string} text The text to insert.
* @returns {IntermediateFixCommand} The fix command.
* @private
*/
function insertTextAt(index: number, text: string) {
invariant(text, "text must be string");
return {
range: [index, index],
text,
isAbsolute: false
};
}
/**
* Creates a fix command that inserts text at the specified index in the source text.
* @param {number} index The 0-based index at which to insert the new text.
* @param {string} text The text to insert.
* @returns {IntermediateFixCommand} The fix command.
* @private
*/
function insertTextAtAbsolute(index: number, text: string) {
invariant(text, "text must be string");
return {
range: [index, index] as const,
text,
isAbsolute: true
};
}
/**
* Creates code fixing commands for rules.
* It create command for fixing texts.
* The `range` arguments of these command is should be **relative** value from reported node.
* See {@link resolveLocation} class for more detail.
* @constructor
*/
export default class RuleFixer {
/**
* Creates a fix command that inserts text after the given node or token.
* The fix is not applied until applyFixes() is called.
* @param {TxtNode} node The node or token to insert after.
* @param {string} text The text to insert.
* @returns {IntermediateFixCommand} The fix command.
*/
insertTextAfter(node: TxtNode, text: string) {
return insertTextAtAbsolute(node.range[1], text);
}
/**
* Creates a fix command that inserts text after the specified range in the source text.
* The fix is not applied until applyFixes() is called.
* @param {number[]} range The range to replace, first item is start of range, second
* is end of range.
* The `range` should be **relative** value from reported node.
* @param {string} text The text to insert.
* @returns {IntermediateFixCommand} The fix command.
*/
insertTextAfterRange(range: TextlintSourceCodeRange, text: string) {
return insertTextAt(range[1], text);
}
/**
* Creates a fix command that inserts text before the given node or token.
* The fix is not applied until applyFixes() is called.
* @param {TxtNode} node The node or token to insert before.
* @param {string} text The text to insert.
* @returns {IntermediateFixCommand} The fix command.
*/
insertTextBefore(node: TxtNode, text: string) {
return insertTextAtAbsolute(node.range[0], text);
}
/**
* Creates a fix command that inserts text before the specified range in the source text.
* The fix is not applied until applyFixes() is called.
* @param {number[]} range The range to replace, first item is start of range, second
* is end of range.
* The `range` should be **relative** value from reported node.
* @param {string} text The text to insert.
* @returns {IntermediateFixCommand} The fix command.
*/
insertTextBeforeRange(range: TextlintSourceCodeRange, text: string) {
return insertTextAt(range[0], text);
}
/**
* Creates a fix command that replaces text at the node or token.
* The fix is not applied until applyFixes() is called.
* @param {TxtNode} node The node or token to remove.
* @param {string} text The text to insert.
* @returns {IntermediateFixCommand} The fix command.
*/
replaceText(node: TxtNode, text: string) {
return {
range: node.range,
text,
isAbsolute: true
};
}
/**
* Creates a fix command that replaces text at the specified range in the source text.
* The fix is not applied until applyFixes() is called.
* @param {number[]} range The range to replace, first item is start of range, second
* is end of range.
* The `range` should be **relative** value from reported node.
* @param {string} text The text to insert.
* @returns {IntermediateFixCommand} The fix command.
*/
replaceTextRange(range: TextlintSourceCodeRange, text: string) {
return {
range,
text,
isAbsolute: false
};
}
/**
* Creates a fix command that removes the node or token from the source.
* The fix is not applied until applyFixes() is called.
* @param {TxtNode} node The node or token to remove.
* @returns {IntermediateFixCommand} The fix command.
*/
remove(node: TxtNode) {
return this.replaceText(node, "");
}
/**
* Creates a fix command that removes the specified range of text from the source.
* The fix is not applied until applyFixes() is called.
* @param {number[]} range The range to remove, first item is start of range, second
* is end of range.
* The `range` should be **relative** value from reported node.
* @returns {IntermediateFixCommand} The fix command.
*/
removeRange(range: TextlintSourceCodeRange) {
return this.replaceTextRange(range, "");
}
}