@abaplint/core
Version:
abaplint - Core API
167 lines • 7.49 kB
JavaScript
"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