refakts
Version:
TypeScript refactoring tool built for AI coding agents to perform precise refactoring operations via command line instead of requiring complete code regeneration.
118 lines • 5.7 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.RefactorEngine = void 0;
const ts_morph_1 = require("ts-morph");
const path = __importStar(require("path"));
const tsquery_handler_1 = require("./tsquery-handler");
const variable_declaration_finder_1 = require("./variable-declaration-finder");
const expression_analyzer_1 = require("./expression-analyzer");
const variable_replacer_1 = require("./variable-replacer");
const variable_scope_1 = require("./variable-scope");
const rename_variable_transformation_1 = require("./transformations/rename-variable-transformation");
const variable_locator_1 = require("./locators/variable-locator");
class RefactorEngine {
constructor() {
this.tsQueryHandler = new tsquery_handler_1.TSQueryHandler();
this.declarationFinder = new variable_declaration_finder_1.VariableDeclarationFinder();
this.expressionAnalyzer = new expression_analyzer_1.ExpressionAnalyzer();
this.variableReplacer = new variable_replacer_1.VariableReplacer();
this.variableScope = new variable_scope_1.VariableScope();
this.project = new ts_morph_1.Project();
this.variableLocator = new variable_locator_1.VariableLocator(this.project);
}
async inlineVariableByQuery(filePath, query) {
const sourceFile = this.loadSourceFile(filePath);
const node = this.tsQueryHandler.findNodeByQuery(sourceFile, query);
await this.performInlineVariable(node);
await sourceFile.save();
}
async renameByQuery(filePath, query, newName) {
const sourceFile = this.loadSourceFile(filePath);
const node = this.tsQueryHandler.findNodeByQuery(sourceFile, query);
await this.performRename(node, newName);
await sourceFile.save();
}
async performInlineVariable(node) {
this.validateIdentifierNode(node);
const variableName = node.getText();
const sourceFile = node.getSourceFile();
const declaration = this.declarationFinder.findVariableDeclaration(sourceFile, variableName);
const initializerText = this.getInitializerText(declaration, variableName);
this.variableReplacer.replaceAllReferences(sourceFile, variableName, declaration, initializerText);
this.variableReplacer.removeDeclaration(declaration);
}
async performRename(node, newName) {
this.validateIdentifierNode(node);
const sourceFile = node.getSourceFile();
const targetPosition = sourceFile.getLineAndColumnAtPos(node.getStart());
const nodeResult = this.variableLocator.findVariableNodesByPositionSync(sourceFile, targetPosition.line, targetPosition.column);
const transformation = new rename_variable_transformation_1.RenameVariableTransformation(nodeResult.declaration, nodeResult.usages.map(u => u.node), newName);
await transformation.transform(sourceFile);
}
loadSourceFile(filePath) {
const absolutePath = path.resolve(filePath);
return this.project.addSourceFileAtPath(absolutePath);
}
validateIdentifierNode(node) {
if (node.getKind() !== 80) {
throw new Error(`Expected identifier, got ${node.getKindName()}`);
}
}
getInitializerText(declaration, variableName, context) {
const nameNode = declaration.getNameNode();
if (ts_morph_1.Node.isObjectBindingPattern(nameNode) && variableName) {
return this.getDestructuringInitializer(declaration, variableName);
}
return this.getRegularInitializer(declaration, context);
}
getDestructuringInitializer(declaration, variableName) {
const initializer = declaration.getInitializer();
if (!initializer) {
throw new Error('Destructuring declaration has no initializer to inline');
}
const initializerText = initializer.getText();
return `${initializerText}.${variableName}`;
}
getRegularInitializer(declaration, context) {
const initializer = declaration.getInitializer();
if (!initializer) {
throw new Error('Variable has no initializer to inline');
}
return this.expressionAnalyzer.formatWithParentheses(initializer, context);
}
}
exports.RefactorEngine = RefactorEngine;
//# sourceMappingURL=refactor-engine.js.map