UNPKG

abap-adt-api

Version:

Interface to Abap Developer Tools webservice

354 lines (353 loc) 17.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.extractMethodExecute = exports.extractMethodPreview = exports.extractMethodEvaluate = exports.renameExecute = exports.renamePreview = exports.renameEvaluate = exports.fixEdits = exports.fixProposals = void 0; const html_entities_1 = require("html-entities"); const _1 = require("."); const AdtException_1 = require("../AdtException"); const utilities_1 = require("../utilities"); const urlparser_1 = require("./urlparser"); async function fixProposals(h, uri, body, line, column) { const qs = { uri: `${uri}#start=${line},${column}` }; const headers = { "Content-Type": "application/*", Accept: "application/*" }; const response = await h.request("/sap/bc/adt/quickfixes/evaluation", { method: "POST", qs, headers, body }); const raw = (0, utilities_1.fullParse)(response.body, { processEntities: false }); const rawResults = (0, utilities_1.xmlArray)(raw, "qf:evaluationResults", "evaluationResult"); return rawResults.map(x => { const attrs = (0, utilities_1.xmlNodeAttr)((0, utilities_1.xmlNode)(x, "adtcore:objectReference")); const userContent = (0, html_entities_1.decode)((0, utilities_1.xmlNode)(x, "userContent") || ""); return { ...attrs, "adtcore:name": attrs["adtcore:name"], "adtcore:description": attrs["adtcore:description"], uri, line, column, userContent }; }); } exports.fixProposals = fixProposals; async function fixEdits(h, proposal, source) { if (!proposal["adtcore:uri"].match(/\/sap\/bc\/adt\/quickfixes/)) throw (0, AdtException_1.adtException)("Invalid fix proposal"); const body = `<?xml version="1.0" encoding="UTF-8"?> <quickfixes:proposalRequest xmlns:quickfixes="http://www.sap.com/adt/quickfixes" xmlns:adtcore="http://www.sap.com/adt/core"> <input> <content>${(0, utilities_1.encodeEntity)(source)}</content> <adtcore:objectReference adtcore:uri="${proposal.uri}#start=${proposal.line},${proposal.column}"/> </input> <userContent>${(0, utilities_1.encodeEntity)(proposal.userContent)}</userContent> </quickfixes:proposalRequest>`; const headers = { "Content-Type": "application/*", Accept: "application/*" }; const response = await h.request(proposal["adtcore:uri"], { method: "POST", headers, body }); const raw = (0, utilities_1.fullParse)(response.body); const parseDelta = (d) => { const attr = (0, utilities_1.xmlNodeAttr)((0, utilities_1.xmlNode)(d, "adtcore:objectReference")); const content = d.content; const { uri, range } = (0, urlparser_1.parseUri)(attr["adtcore:uri"]); return { uri, range, name: attr["adtcore:name"], type: attr["adtcore:type"], content }; }; const deltas = (0, utilities_1.xmlArray)(raw, "qf:proposalResult", "deltas", "unit").map(parseDelta); return deltas; } exports.fixEdits = fixEdits; const parseGeneric = (generic) => { const affectedObjects = (0, utilities_1.xmlArray)(generic, "affectedObjects", "affectedObject").map(o => { const { uri, type, name, parentUri } = (0, utilities_1.xmlNodeAttr)(o); const textReplaceDeltas = (0, utilities_1.xmlArray)(o, "textReplaceDeltas", "textReplaceDelta").map(z => { return { rangeFragment: (0, urlparser_1.parseUri)((0, utilities_1.xmlNode)(z, "rangeFragment")).range, contentOld: (0, utilities_1.xmlNode)(z, "contentOld"), contentNew: (0, utilities_1.xmlNode)(z, "contentNew") }; }); return { uri, type, name, parentUri, userContent: o.userContent, textReplaceDeltas }; }); const { ignoreSyntaxErrorsAllowed, ignoreSyntaxErrors, transport, userContent = "", adtObjectUri = "", title } = generic; return { title, ignoreSyntaxErrorsAllowed, ignoreSyntaxErrors, transport, adtObjectUri: (0, urlparser_1.parseUri)(adtObjectUri), userContent: (0, html_entities_1.decode)(userContent), affectedObjects }; }; function parseRenameRefactoring(body) { const raw = (0, utilities_1.fullParse)(body, { removeNSPrefix: true }); const root = (0, utilities_1.xmlNode)(raw, "renameRefactoring"); const { ignoreSyntaxErrorsAllowed, ignoreSyntaxErrors, transport, adtObjectUri, affectedObjects, userContent } = parseGeneric((0, utilities_1.xmlNode)(root || raw, "genericRefactoring")); // depending on the caller the generic refactoring might be wrapped or not return { oldName: (0, utilities_1.xmlNode)(root, "oldName") || "", newName: (0, utilities_1.xmlNode)(root, "newName") || "", adtObjectUri, ignoreSyntaxErrorsAllowed: !!ignoreSyntaxErrorsAllowed, ignoreSyntaxErrors: !!ignoreSyntaxErrors, transport, affectedObjects, userContent: userContent }; } async function renameEvaluate(h, uri, line, startColumn, endColumn) { const qs = { step: `evaluate`, rel: `http://www.sap.com/adt/relations/refactoring/rename`, uri: `${uri}#start=${line},${startColumn};end=${line},${endColumn}` }; const headers = { "Content-Type": "application/*", Accept: "application/*" }; const response = await h.request("/sap/bc/adt/refactorings", { method: "POST", qs: qs, headers: headers }); return parseRenameRefactoring(response.body); } exports.renameEvaluate = renameEvaluate; const serializeAffectedObject = (o) => { const pu = o.parentUri ? `adtcore:parentUri="${o.parentUri}"` : ""; return `<generic:affectedObject adtcore:name="${o.name}" ${pu} adtcore:type="${o.type}" adtcore:uri="${o.uri}"> <generic:textReplaceDeltas> ${o.textReplaceDeltas .map(y => { return `<generic:textReplaceDelta> <generic:rangeFragment>${(0, _1.rangeToString)(y.rangeFragment)}</generic:rangeFragment> <generic:contentOld>${(0, utilities_1.encodeEntity)(y.contentOld)}</generic:contentOld> <generic:contentNew>${(0, utilities_1.encodeEntity)(y.contentNew)}</generic:contentNew> </generic:textReplaceDelta>`; }) .join("")} </generic:textReplaceDeltas> <generic:userContent>${o.userContent}</generic:userContent> </generic:affectedObject>`; }; const serializeGenericRefactoring = (g) => { return `<?xml version="1.0" encoding="utf-8"?> <generic:genericRefactoring xmlns:adtcore="http://www.sap.com/adt/core" xmlns:generic="http://www.sap.com/adt/refactoring/genericrefactoring"> <generic:title>${g.title}</generic:title> <generic:adtObjectUri>${(0, urlparser_1.uriPartsToString)(g.adtObjectUri)}</generic:adtObjectUri> <generic:affectedObjects> ${g.affectedObjects.map(serializeAffectedObject).join("\n")} </generic:affectedObjects> <generic:transport>${g.transport}</generic:transport> <generic:ignoreSyntaxErrorsAllowed>${g.ignoreSyntaxErrorsAllowed}</generic:ignoreSyntaxErrorsAllowed> <generic:ignoreSyntaxErrors>${g.ignoreSyntaxErrors}</generic:ignoreSyntaxErrors> <generic:userContent/> </generic:genericRefactoring>`; }; const srializeRefactoring = (renameRefactoring, wrapped, transport = "") => { const start = wrapped ? `<rename:renameRefactoring xmlns:adtcore="http://www.sap.com/adt/core" xmlns:generic="http://www.sap.com/adt/refactoring/genericrefactoring" xmlns:rename="http://www.sap.com/adt/refactoring/renamerefactoring"> <rename:oldName>${renameRefactoring.oldName}</rename:oldName> <rename:newName>${renameRefactoring.newName}</rename:newName>` : ""; const end = wrapped ? `<rename:userContent/></rename:renameRefactoring>` : ""; const genns = wrapped ? "" : ` xmlns:generic="http://www.sap.com/adt/refactoring/genericrefactoring" xmlns:adtcore="http://www.sap.com/adt/core"`; const addAffectedObjects = (affectedObject) => affectedObject.map(serializeAffectedObject); const bodyXml = `<?xml version="1.0" encoding="ASCII"?> ${start} <generic:genericRefactoring ${genns}> <generic:title>Rename Field</generic:title> <generic:adtObjectUri>${renameRefactoring.adtObjectUri.uri}${(0, _1.rangeToString)(renameRefactoring.adtObjectUri.range)}</generic:adtObjectUri> <generic:affectedObjects> ${addAffectedObjects(renameRefactoring.affectedObjects).join("")} </generic:affectedObjects> <generic:transport>${renameRefactoring.transport || transport}</generic:transport> <generic:ignoreSyntaxErrorsAllowed>${renameRefactoring.ignoreSyntaxErrorsAllowed}</generic:ignoreSyntaxErrorsAllowed> <generic:ignoreSyntaxErrors>${renameRefactoring.ignoreSyntaxErrors}</generic:ignoreSyntaxErrors> <generic:userContent/> </generic:genericRefactoring> ${end}`; return bodyXml; }; const extractMethodBody = (proposal) => { const parameters = proposal.parameters .map(p => `<extractmethod:parameter> <extractmethod:id>${(0, utilities_1.encodeEntity)(p.id)}</extractmethod:id> <extractmethod:name>${p.name}</extractmethod:name> <extractmethod:direction>${p.direction}</extractmethod:direction> <extractmethod:byValue>${p.byValue}</extractmethod:byValue> <extractmethod:typeType>${p.typeType}</extractmethod:typeType> <extractmethod:type>${p.type}</extractmethod:type> <extractmethod:userContent>${(0, utilities_1.encodeEntity)(p.userContent)}</extractmethod:userContent> </extractmethod:parameter>`) .join("\n"); const exceptions = proposal.exceptions .map(e => `<extractmethod:exception> <extractmethod:name>${e.name}</extractmethod:name> <extractmethod:resumable>${e.resumable}</extractmethod:resumable> <extractmethod:userContent>${e.userContent}</extractmethod:userContent> </extractmethod:exception>`) .join("\n"); const exc = exceptions.length ? `<extractmethod:exceptions>${exceptions}</extractmethod:exceptions> ` : `<extractmethod:exceptions/>`; const gr = proposal.genericRefactoring; const affected = gr.affectedObjects .map(o => { const deltas = o.textReplaceDeltas.length === 0 ? undefined : o.textReplaceDeltas .map(d => `<generic:textReplaceDelta> <generic:rangeFragment>${d.rangeFragment}</generic:rangeFragment> <generic:contentOld>${(0, utilities_1.encodeEntity)(d.contentOld)}</generic:contentOld> <generic:contentNew>${(0, utilities_1.encodeEntity)(d.contentNew)}</generic:contentNew> </generic:textReplaceDelta>`) .join("\n"); const delta = deltas ? `<generic:textReplaceDeltas>${deltas}</generic:textReplaceDeltas>` : ``; return `<generic:affectedObject adtcore:name="${o.name}" adtcore:parentUri="${o.parentUri}" adtcore:type="${o.type}" adtcore:uri="${o.uri}"> <generic:userContent>${o.userContent}</generic:userContent> ${delta} </generic:affectedObject>`; }) .join("\n"); return `<?xml version="1.0" encoding="ASCII"?> <extractmethod:extractMethodRefactoring xmlns:adtcore="http://www.sap.com/adt/core" xmlns:extractmethod="http://www.sap.com/adt/refactoring/extractmethodrefactoring" xmlns:generic="http://www.sap.com/adt/refactoring/genericrefactoring"> <extractmethod:name>${proposal.name}</extractmethod:name> <extractmethod:isStatic>${proposal.isStatic}</extractmethod:isStatic> <extractmethod:visibility>${proposal.visibility}</extractmethod:visibility> <extractmethod:classBasedExceptions>${proposal.classBasedExceptions}</extractmethod:classBasedExceptions> <extractmethod:parameters> ${parameters} </extractmethod:parameters> ${exc} <extractmethod:content>${(0, utilities_1.encodeEntity)(proposal.content)}</extractmethod:content> <generic:genericRefactoring> <generic:title>${gr.title}</generic:title> <generic:adtObjectUri>${(0, urlparser_1.uriPartsToString)(gr.adtObjectUri)}</generic:adtObjectUri> <generic:affectedObjects> ${affected} </generic:affectedObjects> <generic:transport>${gr.transport}</generic:transport> <generic:ignoreSyntaxErrorsAllowed>${gr.ignoreSyntaxErrorsAllowed}</generic:ignoreSyntaxErrorsAllowed> <generic:ignoreSyntaxErrors>${gr.ignoreSyntaxErrors}</generic:ignoreSyntaxErrors> <generic:userContent>${gr.userContent}</generic:userContent> </generic:genericRefactoring> <extractmethod:className>ZAPIADT_TESTCASE_CLASS1${proposal}</extractmethod:className> <extractmethod:isEventAllowed>${proposal.isEventAllowed}</extractmethod:isEventAllowed> <extractmethod:isEvent>${proposal.isEvent}</extractmethod:isEvent> <extractmethod:userContent>${(0, utilities_1.encodeEntity)(proposal.userContent)}</extractmethod:userContent> <extractmethod:isForTesting>${proposal.isForTesting}</extractmethod:isForTesting> </extractmethod:extractMethodRefactoring>`; }; const parseExtractMethodEval = (body) => { const root = (0, utilities_1.fullParse)(body, { removeNSPrefix: true }).extractMethodRefactoring; const parameters = (0, utilities_1.xmlArray)(root, "parameters", "parameter"); const exceptions = (0, utilities_1.xmlArray)(root, "exceptions", "exception"); const { name, isStatic, visibility, classBasedExceptions, content, className, isEventAllowed, isEvent, userContent } = root; const genericRefactoring = parseGeneric(root.genericRefactoring); const resp = { name, isStatic, visibility, classBasedExceptions, genericRefactoring, content, className, isForTesting: false, isEventAllowed, isEvent, userContent: (0, html_entities_1.decode)(userContent), parameters, exceptions }; return resp; }; async function renamePreview(h, renameRefactoring, transport) { const qs = { step: `preview`, rel: `http://www.sap.com/adt/relations/refactoring/rename` }; const bodyXml = srializeRefactoring(renameRefactoring, true, transport); const headers = { "Content-Type": "application/*", Accept: "application/*" }; const response = await h.request("/sap/bc/adt/refactorings", { method: "POST", qs: qs, body: bodyXml, headers: headers }); const parsed = parseRenameRefactoring(response.body); return { ...parsed, transport: parsed.transport || transport }; } exports.renamePreview = renamePreview; async function renameExecute(h, rename) { const qs = { step: `execute` }; const headers = { "Content-Type": "application/*", Accept: "application/*" }; const body = srializeRefactoring(rename, false); const response = await h.request("/sap/bc/adt/refactorings", { method: "POST", qs: qs, body, headers: headers }); const result = parseRenameRefactoring(response.body); return { ...result, transport: result.transport || rename.transport }; } exports.renameExecute = renameExecute; async function extractMethodEvaluate(h, uri, range) { const qs = { step: `evaluate`, rel: `http://www.sap.com/adt/relations/refactoring/extractmethod`, uri: `${uri}#start=${range.start.line},${range.start.column};end=${range.end.line},${range.end.column}` }; const headers = { "Content-Type": "application/*", Accept: "application/*" }; const opts = { method: "POST", qs, headers }; const response = await h.request("/sap/bc/adt/refactorings", opts); return parseExtractMethodEval(response.body); } exports.extractMethodEvaluate = extractMethodEvaluate; async function extractMethodPreview(h, proposal) { const body = extractMethodBody(proposal); const qs = { step: `preview`, rel: `http://www.sap.com/adt/relations/refactoring/extractmethod` }; const headers = { "Content-Type": "application/*", Accept: "application/*" }; const opts = { method: "POST", qs, headers, body }; const response = await h.request("/sap/bc/adt/refactorings", opts); const raw = (0, utilities_1.fullParse)(response.body, { removeNSPrefix: true }).genericRefactoring; return parseGeneric(raw); } exports.extractMethodPreview = extractMethodPreview; async function extractMethodExecute(h, refactoring) { const body = serializeGenericRefactoring(refactoring); const qs = { step: `execute` }; const headers = { "Content-Type": "application/*", Accept: "application/*" }; const opts = { method: "POST", qs, headers, body }; const response = await h.request("/sap/bc/adt/refactorings", opts); const raw = (0, utilities_1.fullParse)(response.body, { removeNSPrefix: true }).genericRefactoring; return parseGeneric(raw); } exports.extractMethodExecute = extractMethodExecute;