UNPKG

@abaplint/core

Version:
125 lines 5.14 kB
"use strict"; 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