@abaplint/transpiler
Version:
126 lines • 6.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.CallTranspiler = void 0;
const abaplint = require("@abaplint/core");
const chunk_1 = require("../chunk");
const expressions_1 = require("../expressions");
const feature_flags_1 = require("../feature_flags");
class CallTranspiler {
transpile(node, traversal) {
const chain = node.findDirectExpression(abaplint.Expressions.MethodCallChain);
if (chain) {
let pre = "";
let post = "";
const receiving = chain.findFirstExpression(abaplint.Expressions.MethodParameters)?.findDirectExpression(abaplint.Expressions.ParameterT)?.findDirectExpression(abaplint.Expressions.Target);
if (receiving) {
pre = traversal.traverse(receiving).getCode() + ".set(";
post = ")";
}
post += ";";
const exceptions = node.findFirstExpression(abaplint.Expressions.ParameterListExceptions);
if (exceptions) {
const build = CallTranspiler.buildExceptions(exceptions);
pre = build.pre + pre;
post += build.post;
}
const chainChunk = traversal.traverse(chain);
let chainCode = chainChunk.getCode();
if (chainCode.startsWith("await super.constructor(")) {
// semantics of constructors in JS vs ABAP is different, so the "constructor_" has been introduced,
chainCode = chainCode.replace("await super.constructor(", "await super.constructor_(");
}
return new chunk_1.Chunk()
.appendString(pre)
.appendString(chainCode)
.append(post, node.getLastToken(), traversal);
}
const methodSource = node.findDirectExpression(abaplint.Expressions.MethodSource);
if (methodSource) {
let body = "";
const nameToken = methodSource.getLastChild()?.getFirstToken();
const m = nameToken ? traversal.findMethodReference(nameToken, traversal.findCurrentScopeByToken(nameToken)) : undefined;
const methodCallBody = node.findDirectExpression(abaplint.Expressions.MethodCallBody);
if (methodCallBody) {
body = new expressions_1.MethodCallBodyTranspiler(m?.def).transpile(methodCallBody, traversal).getCode();
}
let pre = "";
let post = "";
const receiving = node.findFirstExpression(abaplint.Expressions.MethodParameters)?.findExpressionAfterToken("RECEIVING");
if (receiving) {
const target = traversal.traverse(receiving.findDirectExpression(abaplint.Expressions.Target));
pre = target.getCode() + ".set(";
post = ")";
}
const exceptions = node.findFirstExpression(abaplint.Expressions.ParameterListExceptions);
if (exceptions) {
const build = CallTranspiler.buildExceptions(exceptions);
pre = build.pre + pre;
post += build.post;
}
let ms = new expressions_1.MethodSourceTranspiler(pre).transpile(methodSource, traversal).getCode();
if (ms === "await super.get().constructor") {
// semantics of constructors in JS vs ABAP is different, so the "constructor_" has been introduced,
ms = "await super.constructor_";
}
else if (ms.startsWith("await super.get()")) {
ms = ms.replace("await super.get()", "await super");
}
if (nameToken) {
const scope = traversal.findCurrentScopeByToken(nameToken);
if (feature_flags_1.FEATURE_FLAGS.private === true
&& m?.def.getVisibility() === abaplint.Visibility.Private
&& m.def.isStatic() === false) {
const id = scope?.getParent()?.getParent()?.getIdentifier();
if (id?.stype === abaplint.ScopeType.ClassImplementation
&& m.def.getClassName().toUpperCase() === id.sname.toUpperCase()) {
ms = ms.replace("await this.me.get().", "await this.");
ms = ms.replace("await this.", "await this.#");
}
else {
if (ms.includes(".get().")) {
let last = ms.split(".");
last = last[last.length - 1];
ms = ms.replace(".get()." + last, ".get().FRIENDS_ACCESS['" + last + "']");
}
else {
throw new Error("CallTranspiler, todo, refactor CALL");
}
}
}
}
return new chunk_1.Chunk().appendString(ms).appendString("(" + body + ")" + post + ";");
}
throw new Error("CallTranspiler, todo");
}
static buildExceptions(node) {
let pre = "";
let post = "";
pre = "try {\n" + pre;
post += `\nabap.builtin.sy.get().subrc.set(0);
} catch (e) {
if (e.classic) {
switch (e.classic.toUpperCase()) {\n`;
for (const e of node.findAllExpressions(abaplint.Expressions.ParameterException)) {
const name = e.getFirstToken().getStr().toUpperCase();
// todo, also handle SimpleChain,
const value = e.findFirstExpression(abaplint.Expressions.Integer)?.getFirstToken().getStr().toUpperCase();
if (value === undefined) {
continue;
}
if (name === "OTHERS") {
post += `default: abap.builtin.sy.get().subrc.set(${value}); break;\n`;
}
else {
post += `case "${name}": abap.builtin.sy.get().subrc.set(${value}); break;\n`;
}
}
post += ` }
} else {
throw e;
}
}`;
return { pre, post };
}
}
exports.CallTranspiler = CallTranspiler;
//# sourceMappingURL=call.js.map