UNPKG

@abaplint/core

Version:
167 lines 7.49 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.RenamerHelper = void 0; const vscode_languageserver_types_1 = require("vscode-languageserver-types"); const syntax_1 = require("../../abap/5_syntax/syntax"); const _scope_type_1 = require("../../abap/5_syntax/_scope_type"); const virtual_position_1 = require("../../virtual_position"); const _abap_object_1 = require("../_abap_object"); const _reference_1 = require("../../abap/5_syntax/_reference"); class RenamerHelper { constructor(reg) { this.reg = reg; } renameReferences(id, oldName, newName) { if (id === undefined) { throw new Error("renameReferences, no main identifier found"); } let refs = []; for (const o of this.reg.getObjects()) { if (o instanceof _abap_object_1.ABAPObject) { if (this.reg.isDependency(o)) { continue; // do not search in dependencies } refs = refs.concat(this.findReferences(new syntax_1.SyntaxLogic(this.reg, o).run().spaghetti.getTop(), id)); } } // start with the last reference in the file first, if there are multiple refs per line return this.replaceRefs(refs, oldName, newName).reverse(); } renameDDICCodeReferences(obj, oldName, newName) { const changes = []; const used = this.reg.getDDICReferences().listWhereUsed(obj); for (const u of used) { if (u.token === undefined || u.filename === undefined) { continue; } const range = vscode_languageserver_types_1.Range.create(u.token.getStart().getRow() - 1, u.token.getStart().getCol() - 1, u.token.getStart().getRow() - 1, u.token.getStart().getCol() - 1 + oldName.length); changes.push(vscode_languageserver_types_1.TextDocumentEdit.create({ uri: u.filename, version: 1 }, [vscode_languageserver_types_1.TextEdit.replace(range, newName.toLowerCase())])); } return changes; } renameDDICTABLReferences(obj, oldName, newName) { const changes = []; const used = this.reg.getDDICReferences().listWhereUsed(obj); const handled = {}; for (const u of used) { if (u.type !== "TABL" || handled[u.name.toUpperCase()] === true) { // a TABL might reference the object multiple times, but they are all fixes in one call to buildXMLFileEdits continue; } const tabl = this.reg.getObject(u.type, u.name); if (tabl === undefined) { continue; } changes.push(...this.buildXMLFileEdits(tabl, "ROLLNAME", oldName, newName)); handled[u.name.toUpperCase()] = true; } return changes; } renameDDICDTELReferences(obj, oldName, newName) { const changes = []; const used = this.reg.getDDICReferences().listWhereUsed(obj); for (const u of used) { if (u.type !== "DTEL") { continue; } const tabl = this.reg.getObject(u.type, u.name); if (tabl === undefined) { continue; } changes.push(...this.buildXMLFileEdits(tabl, "DOMNAME", oldName, newName)); } return changes; } renameDDICTTYPReferences(obj, oldName, newName) { const changes = []; const used = this.reg.getDDICReferences().listWhereUsed(obj); for (const u of used) { if (u.type !== "TTYP") { continue; } const tabl = this.reg.getObject(u.type, u.name); if (tabl === undefined) { continue; } changes.push(...this.buildXMLFileEdits(tabl, "ROWTYPE", oldName, newName)); } return changes; } renameDDICAUTHReferences(obj, oldName, newName) { const changes = []; const used = this.reg.getDDICReferences().listWhereUsed(obj); for (const u of used) { if (u.type !== "AUTH") { continue; } const tabl = this.reg.getObject(u.type, u.name); if (tabl === undefined) { continue; } changes.push(...this.buildXMLFileEdits(tabl, "ROLLNAME", oldName, newName)); } return changes; } buildXMLFileEdits(object, xmlTag, oldName, newName) { const changes = []; const xml = object.getXMLFile(); if (xml === undefined) { return []; } const tag = xmlTag.toUpperCase(); const search = "<" + tag + ">" + oldName.toUpperCase() + "</" + tag + ">"; const length = tag.length + 2; const rows = xml.getRawRows(); for (let i = 0; i < rows.length; i++) { const index = rows[i].indexOf(search); if (index >= 0) { const range = vscode_languageserver_types_1.Range.create(i, index + length, i, index + oldName.length + length); changes.push(vscode_languageserver_types_1.TextDocumentEdit.create({ uri: xml.getFilename(), version: 1 }, [vscode_languageserver_types_1.TextEdit.replace(range, newName.toUpperCase())])); } } return changes; } renameFiles(obj, oldName, name) { const list = []; const newName = name.toLowerCase().replace(/\//g, "#"); oldName = oldName.toLowerCase().replace(/\//g, "#"); for (const f of obj.getFiles()) { // todo, this is not completely correct, ie. if the URI contains the same directory name as the object name const newFilename = f.getFilename().replace(oldName, newName); list.push(vscode_languageserver_types_1.RenameFile.create(f.getFilename(), newFilename)); } return list; } //////////////////////// replaceRefs(refs, oldName, newName) { const changes = []; // "zif_abapgit_auth~is_allowed" is a single token so only replace the first part of a token for (const r of refs) { const range = vscode_languageserver_types_1.Range.create(r.getStart().getRow() - 1, r.getStart().getCol() - 1, r.getStart().getRow() - 1, r.getStart().getCol() - 1 + oldName.length); changes.push(vscode_languageserver_types_1.TextDocumentEdit.create({ uri: r.getFilename(), version: 1 }, [vscode_languageserver_types_1.TextEdit.replace(range, newName.toLowerCase())])); } return changes; } findReferences(node, identifier) { var _a; let ret = []; if (node.getIdentifier().stype !== _scope_type_1.ScopeType.BuiltIn) { for (const r of node.getData().references) { if (r.referenceType === _reference_1.ReferenceType.ConstructorReference) { continue; } if (((_a = r.resolved) === null || _a === void 0 ? void 0 : _a.equals(identifier)) && r.referenceType !== _reference_1.ReferenceType.InferredType && !(r.position.getStart() instanceof virtual_position_1.VirtualPosition)) { ret.push(r.position); } } } for (const c of node.getChildren()) { ret = ret.concat(this.findReferences(c, identifier)); } return ret; } } exports.RenamerHelper = RenamerHelper; //# sourceMappingURL=renamer_helper.js.map