@abaplint/core
Version:
abaplint - Core API
125 lines • 5.14 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Renamer = void 0;
const vscode_languageserver_types_1 = require("vscode-languageserver-types");
const memory_file_1 = require("../../files/memory_file");
const rename_data_element_1 = require("./rename_data_element");
const rename_domain_1 = require("./rename_domain");
const rename_global_class_1 = require("./rename_global_class");
const rename_global_interface_1 = require("./rename_global_interface");
const rename_table_1 = require("./rename_table");
const rename_table_type_1 = require("./rename_table_type");
const rename_message_class_1 = require("./rename_message_class");
class Renamer {
constructor(reg) {
this.reg = reg;
}
/** Applies the renaming to the objects and files in the registry,
* after renaming the registry is not parsed */
rename(type, oldName, newName) {
const edits = this.buildEdits(type, oldName, newName);
if (edits === undefined) {
throw new Error("no changes could be determined");
}
else if (edits.changes) {
throw new Error("only documentChanges expected");
}
const result = this.apply(edits);
this.reg.findIssues(); // hmm, this builds the ddic references
return result;
}
/** Builds edits, but does not apply to registry, used by LSP */
buildEdits(type, oldName, newName) {
this.reg.parse(); // the registry must be parsed to dermine references
const obj = this.reg.getObject(type, oldName);
if (obj === undefined) {
throw new Error("rename, object not found");
}
else if (newName.length > obj.getAllowedNaming().maxLength) {
// todo, also do not allow strange characters and spaces
throw new Error("Name not allowed");
}
const r = this.factory(type);
return r.buildEdits(obj, oldName.toUpperCase(), newName);
}
//////////////////
factory(type) {
switch (type) {
case "CLAS":
return new rename_global_class_1.RenameGlobalClass(this.reg);
case "DTEL":
return new rename_data_element_1.RenameDataElement(this.reg);
case "DOMA":
return new rename_domain_1.RenameDomain(this.reg);
case "TABL":
return new rename_table_1.RenameTable(this.reg);
case "TTYP":
return new rename_table_type_1.RenameTableType(this.reg);
case "INTF":
return new rename_global_interface_1.RenameGlobalInterface(this.reg);
case "MSAG":
return new rename_message_class_1.RenameMessageClass(this.reg);
default:
throw new Error("Renaming of " + type + " not yet supported");
}
}
apply(edits) {
const renames = [];
const result = {
addedFiles: new Set(),
deletedFiles: new Set(),
updatedFiles: new Set(),
};
// assumption: only renames or text changes, no deletes or creates
for (const dc of edits.documentChanges || []) {
if (vscode_languageserver_types_1.TextDocumentEdit.is(dc)) {
this.applyEdit(dc);
result.updatedFiles.add(dc.textDocument.uri);
}
else if (vscode_languageserver_types_1.RenameFile.is(dc)) {
renames.push(dc);
}
else {
throw new Error("unexpected documentChange type");
}
}
for (const rename of renames) {
result.updatedFiles.delete(rename.oldUri);
result.deletedFiles.add(rename.oldUri);
result.addedFiles.add(rename.newUri);
}
this.applyRenames(renames);
return result;
}
applyEdit(dc) {
const file = this.reg.getFileByName(dc.textDocument.uri);
if (file === undefined) {
throw new Error("file " + dc.textDocument.uri + " not found");
}
const rows = file.getRawRows();
for (const e of dc.edits) {
if (e.range.start.line !== e.range.end.line) {
throw new Error("applyEdit, start and end line differ");
}
const before = rows[e.range.start.line];
rows[e.range.start.line] = before.substring(0, e.range.start.character) +
e.newText +
before.substring(e.range.end.character);
}
const newFile = new memory_file_1.MemoryFile(dc.textDocument.uri, rows.join("\n"));
this.reg.updateFile(newFile);
}
applyRenames(renames) {
for (const r of renames) {
const old = this.reg.getFileByName(r.oldUri);
if (old === undefined) {
throw new Error("applyRenames, old not found");
}
const newFile = new memory_file_1.MemoryFile(r.newUri, old.getRaw());
this.reg.removeFile(old);
this.reg.addFile(newFile);
}
}
}
exports.Renamer = Renamer;
//# sourceMappingURL=renamer.js.map