abap-adt-api
Version:
Interface to Abap Developer Tools webservice
354 lines (353 loc) • 17.1 kB
JavaScript
;
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;