UNPKG

@abaplint/transpiler

Version:
142 lines 6.82 kB
"use strict"; 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"); 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 = ""; let pre = ""; let post = ""; const nameToken = methodSource.getLastChild()?.getFirstToken(); const m = nameToken ? traversal.findMethodReference(nameToken, traversal.findCurrentScopeByToken(nameToken)) : undefined; const methodCallBody = node.findDirectExpression(abaplint.Expressions.MethodCallBody); if (methodCallBody) { if (methodCallBody.findDirectTokenByText("EXCEPTION")) { return new chunk_1.Chunk(`throw new Error("EXCEPTION-TABLE not supported, todo");`); } if (methodCallBody.findDirectTokenByText("PARAMETER")) { const source = traversal.traverse(methodCallBody.findDirectExpression(abaplint.Expressions.Source)).getCode(); pre = 'await abap.parametersCall('; body = ", " + source + ")"; } else { body = new expressions_1.MethodCallBodyTranspiler(m?.def).transpile(methodCallBody, traversal).getCode(); body = "(" + body + ")"; } } 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 (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"); } } } } if (body === "") { body = "()"; } 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, let value = e.findFirstExpression(abaplint.Expressions.Integer)?.getFirstToken().getStr().toUpperCase(); if (value === undefined) { continue; } while (value.substring(0, 1) === "0" && value.length > 1) { // remove leading zeros value = value.substring(1); } 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