code-replacer
Version:
Replace codes line by line with regex for target files
269 lines • 12 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getMatchingPoints = exports.getReplacedCode = void 0;
const chalk_1 = __importDefault(require("chalk"));
const matchAll_1 = __importDefault(require("./matchAll"));
const yn_1 = __importDefault(require("yn"));
const readline_sync_1 = __importDefault(require("readline-sync"));
const debuggingInfo_1 = __importDefault(require("./config/debuggingInfo"));
const optionManager_1 = __importDefault(require("./cli/optionManager"));
const template_1 = require("./template");
const error_1 = require("./error");
const util_1 = __importDefault(require("./util"));
const matchingPoints_1 = require("./matchingPoints");
const replacingListDict_1 = __importDefault(require("./replacingListDict"));
const displayConsoleMsg = ({ lineIdx, matchingInfo, replacingListDict, resultLines, srcFileLines, srcFileName, srcLine, }) => {
const matchingStr = matchingInfo[0];
const sourceStr = util_1.default.createHighlightedLine(srcLine, matchingInfo.index, matchingStr, matchingInfo.index + matchingStr.length, "redBright");
const replacedStr = util_1.default.createHighlightedLine(srcLine, matchingInfo.index, replacingListDict.get(matchingStr), matchingInfo.index + matchingStr.length, "green");
util_1.default.funcExecByFlag(optionManager_1.default.getInstance().confOpt ||
optionManager_1.default.getInstance().verboseOpt, () => util_1.default.printLines({
srcFileName,
lineIdx,
sourceStr,
replacedStr,
srcFileLines,
resultLines,
}));
util_1.default.logByFlag(optionManager_1.default.getInstance().confOpt, chalk_1.default.dim(chalk_1.default.italic("## Press enter to replace the string or 'n' to skip this word or 's' to skip this file.")));
};
const getMatchingPoints = ({ srcLine, replacingKeys, template }) => {
const matchingPoints = new matchingPoints_1.MatchingPoints();
for (const replacingKey of replacingKeys) {
matchingPoints.addMatchingPoint({
srcLine,
replacingKey,
template
});
}
matchingPoints.sortMatchingPoints();
return matchingPoints;
};
exports.getMatchingPoints = getMatchingPoints;
const getMatchingPointsWithOnlyTemplate = ({ srcLine, templateLValue, template }) => {
const matchingPoints = new matchingPoints_1.MatchingPoints();
matchingPoints.addMatchingPoint({
srcLine,
replacingKey: templateLValue,
template
});
matchingPoints.sortMatchingPoints();
return matchingPoints;
};
const getReplacedString = ({ replacingListDict, matchingStr, templateRValue, }) => {
const noEscapeOpt = optionManager_1.default.getInstance()["no-escape"];
// exactly match :: use regexp and insert new item
// not exactly match, but match in regexp :: use regexp and dont insert one
if (noEscapeOpt && !replacingListDict.get(matchingStr)) {
for (const key of replacingListDict.keys()) {
const regexMatch = new RegExp(key).test(matchingStr);
if (regexMatch) {
return replacingListDict.get(key);
}
}
}
const exactMatch = replacingListDict.get(matchingStr);
const constantMatch = !replacingListDict.get(matchingStr);
if (constantMatch)
return templateRValue;
return exactMatch;
};
// Todo: Need to refactor function
const handleLRefKey = ({ srcLine, lRefKey, replacingListDict, matchingStr, lvalue, rvalue, template }) => {
lvalue = template.getGroupKeyForm(template_1.handleSpecialCharEscapeInTemplateLValue(lvalue));
const findMatchingStringReg = new RegExp(lvalue);
const groupKeyMatching = srcLine.match(findMatchingStringReg);
// continue to next case
if (!groupKeyMatching || !groupKeyMatching.groups) {
return {
continueFlag: true
};
}
const groupKeyMatchingStr = groupKeyMatching.groups[lRefKey] || groupKeyMatching.groups[lRefKey + "_1"];
if (!groupKeyMatchingStr) {
throw new error_1.InvalidLeftReferenceError(error_1.ERROR_CONSTANT.NON_EXISTENT_GROUPKEY);
}
const newLValue = template_1.handleGroupKeysInTemplateLValue({
matchingStr,
lRefKey,
groupKeyMatchingStr,
});
const newRValue = template_1.handleLRefKeyInTemplateRValue({
replacingListDict,
matchingStr,
lRefKey,
groupKeyMatching,
rvalue,
});
return {
newLValue,
newRValue,
};
};
const replaceOneline = ({ csvTbl, excludeRegValue, lineIdx, replacingListDict, resultLines, srcFileLines, srcFileName, srcLine, template: templateObj }) => {
if (excludeRegValue && srcLine.match(new RegExp(excludeRegValue))) {
return srcLine;
}
const hasOneToManyMatching = csvTbl.length < 1;
const matchingPoints = hasOneToManyMatching
? getMatchingPointsWithOnlyTemplate({
srcLine,
templateLValue: templateObj.lvalue,
template: templateObj
})
: getMatchingPoints({
srcLine,
replacingKeys: replacingListDict.replacingKeys,
template: templateObj
});
for (let matchingPtIdx = 0; matchingPtIdx < matchingPoints.length; ++matchingPtIdx) {
// Match the longest string first
const matchingCandidates = matchingPoints[matchingPtIdx];
for (let candidateIdx = 0; candidateIdx < matchingCandidates.length; candidateIdx++) {
const matchingInfo = matchingCandidates[candidateIdx];
let matchingStr = matchingInfo[0];
// handle grouping value
const findLRefKey = new RegExp(/\$\[(?<lRefKey>[\d\w]*)\]/);
const lRefKeys = matchAll_1.default(templateObj.rvalue, findLRefKey);
const rvalue = hasOneToManyMatching
? templateObj.rvalue
: replacingListDict.get(matchingPoints.replacingKey);
const oldKeysToDelete = new Set();
for (const lRefKeyInfo of lRefKeys) {
const lRefKey = lRefKeyInfo[1];
if (hasOneToManyMatching) {
const result = handleLRefKey({
srcLine,
lRefKey,
replacingListDict,
matchingStr,
template: templateObj,
lvalue: templateObj.lvalue,
rvalue,
});
matchingStr = result.newLValue;
replacingListDict.set(matchingStr, result.newRValue);
continue;
}
const replaceObjectsKey = replacingListDict.keys();
for (const replaceObjectKey of replaceObjectsKey) {
const result = handleLRefKey({
srcLine,
lRefKey,
replacingListDict,
matchingStr,
template: templateObj,
lvalue: replaceObjectKey,
rvalue,
});
if (result.continueFlag === true) {
continue;
}
else {
matchingStr = result.newLValue;
replacingListDict.set(matchingStr, result.newRValue);
if (replaceObjectKey !== matchingStr)
oldKeysToDelete.add(replaceObjectKey);
break;
}
}
}
// Remove the keys that have been replaced and are not needed
for (const oldKey of oldKeysToDelete) {
replacingListDict.delete(oldKey);
}
displayConsoleMsg({
srcLine,
matchingInfo,
replacingListDict,
srcFileName,
lineIdx,
srcFileLines,
resultLines,
});
let input = "y";
optionManager_1.default.getInstance().confOpt && (input = readline_sync_1.default.prompt());
if (yn_1.default(input) === false) {
// skip this word. choose other candidate if you have a shorter string to replace.
util_1.default.logByFlag(optionManager_1.default.getInstance().confOpt ||
optionManager_1.default.getInstance().verboseOpt, chalk_1.default.red("\nskip.."));
}
else if (input.startsWith("s")) {
// skip this file.
console.log(chalk_1.default.red(`\nskip '${srcFileName}'..`));
return -1;
}
else {
const replacedString = getReplacedString({
replacingListDict,
matchingStr,
templateRValue: templateObj.rvalue,
});
// push the index value of the other matching points.
matchingPoints.pushIndex({
matchingPtIdx,
matchingStr,
replacedString,
});
util_1.default.logByFlag(optionManager_1.default.getInstance().confOpt ||
optionManager_1.default.getInstance().verboseOpt, chalk_1.default.yellow("\nreplace.."));
util_1.default.funcExecByFlag(optionManager_1.default.getInstance().printOpt, () => debuggingInfo_1.default
.getInstance()
.append(`Replace ${lineIdx} line, key: ${matchingStr}, value: ${replacedString}`));
srcLine =
srcLine.substr(0, matchingInfo.index) +
replacedString +
srcLine.substr(matchingInfo.index + matchingStr.length, srcLine.length);
break;
}
}
if (optionManager_1.default.getInstance().onceOpt)
break;
}
return srcLine;
};
const getReplacedCode = ({ srcFileName, srcFileLines, csvTbl, template: templateObj, excludeRegValue, startLine, endLine, }) => {
const resultLines = [];
const replacingListDict = new replacingListDict_1.default(csvTbl, templateObj);
let lineIdx = 1;
let blockingReplaceFlag = !!startLine;
for (const srcLine of srcFileLines) {
// handle blocking replace
util_1.default.funcExecByFlag(blockingReplaceFlag && !!startLine && srcLine.trim() === startLine.trim(), () => {
util_1.default.funcExecByFlag(optionManager_1.default.getInstance().printOpt, () => debuggingInfo_1.default
.getInstance()
.append(`Encountered startLine on line ${lineIdx}`));
blockingReplaceFlag = false;
});
util_1.default.funcExecByFlag(!blockingReplaceFlag && !!endLine && srcLine.trim() === endLine.trim(), () => {
util_1.default.funcExecByFlag(optionManager_1.default.getInstance().printOpt, () => debuggingInfo_1.default
.getInstance()
.append(`Encountered endLine on line ${lineIdx}`));
blockingReplaceFlag = true;
});
let resultLine = srcLine;
if (!blockingReplaceFlag) {
resultLine = replaceOneline({
csvTbl,
lineIdx,
excludeRegValue,
replacingListDict,
resultLines,
srcFileLines,
srcFileName,
srcLine,
template: templateObj
});
}
if (resultLine === -1)
return -1;
resultLines.push(resultLine);
lineIdx++;
}
return resultLines;
};
exports.getReplacedCode = getReplacedCode;
//# sourceMappingURL=getReplacedCode.js.map