UNPKG

code-replacer

Version:

Replace codes line by line with regex for target files

269 lines 12 kB
"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