@abaplint/transpiler
Version:
119 lines • 5.44 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.LoopTranspiler = void 0;
const abaplint = require("@abaplint/core");
const unique_identifier_1 = require("../unique_identifier");
const expressions_1 = require("../expressions");
const chunk_1 = require("../chunk");
class LoopTranspiler {
constructor(options) {
this.unique = "";
this.injectFrom = undefined;
this.skipInto = undefined;
this.injectFrom = options?.injectFrom;
this.skipInto = options?.skipInto;
}
getTarget() {
return this.unique;
}
transpile(node, traversal) {
if (!(node.get() instanceof abaplint.Statements.Loop)) {
throw new Error("LoopTranspiler, unexpected node");
}
const source = traversal.traverse(node.findDirectExpression(abaplint.Expressions.SimpleSource2)).getCode();
this.unique = unique_identifier_1.UniqueIdentifier.get();
let target = "";
const into = node.findDirectExpression(abaplint.Expressions.LoopTarget)?.findDirectExpression(abaplint.Expressions.Target);
if (into && this.skipInto !== true) {
const concat = node.concatTokens().toUpperCase();
const t = traversal.traverse(into).getCode();
const scope = traversal.findCurrentScopeByToken(node.getFirstToken());
const typ = traversal.determineType(node, scope);
if (concat.includes(" REFERENCE INTO ")) {
// target is assumed to be a data reference
target = t + ".assign(" + this.unique + ");";
}
else if (typ instanceof abaplint.BasicTypes.DataReference) {
// row type and target is assumed to be data references
target = t + ".assign(" + this.unique + ".getPointer());";
}
else {
target = t + ".set(" + this.unique + ");";
}
}
else if (this.skipInto !== true) {
const assigning = node.findFirstExpression(abaplint.Expressions.FSTarget)?.findFirstExpression(abaplint.Expressions.FieldSymbol);
if (assigning) {
target = traversal.traverse(assigning).getCode() + ".assign(" + this.unique + ");";
}
}
const extra = [];
const fromNode = node.findExpressionAfterToken("FROM");
if (fromNode) {
const from = new expressions_1.SourceTranspiler().transpile(fromNode, traversal).getCode();
extra.push("from: " + from);
}
else if (this.injectFrom) {
extra.push("from: " + this.injectFrom);
}
const toNode = node.findExpressionAfterToken("TO");
if (toNode) {
const to = new expressions_1.SourceTranspiler().transpile(toNode, traversal).getCode();
extra.push("to: " + to);
}
const keyNode = node.findExpressionAfterToken("KEY");
if (keyNode) {
if (keyNode.get() instanceof abaplint.Expressions.Dynamic) {
const children = keyNode.getChildren();
if (children[1] instanceof abaplint.Nodes.ExpressionNode
&& children[1].get() instanceof abaplint.Expressions.FieldChain) {
const t = new expressions_1.FieldChainTranspiler(true).transpile(children[1], traversal);
extra.push(`usingKey: ${t.getCode()}`);
}
else {
extra.push(`usingKey: ${keyNode.concatTokens()}`);
}
}
else {
extra.push(`usingKey: "${keyNode.concatTokens()}"`);
}
}
const whereNode = node.findDirectExpression(abaplint.Expressions.ComponentCond);
if (whereNode) {
const where = traversal.traverse(whereNode).getCode();
// todo, evil workaround removing "await",
extra.push("where: async " + where);
}
const topEquals = {};
for (const compare of whereNode?.findDirectExpressions(abaplint.Expressions.ComponentCompare) || []) {
const op = compare.findDirectExpression(abaplint.Expressions.CompareOperator)?.concatTokens().toUpperCase();
if (op !== "=" && op !== "EQ") {
continue;
}
else if (compare.findDirectTokenByText("NOT")) {
continue;
}
const simple = compare.findDirectExpression(abaplint.Expressions.ComponentChainSimple);
if (simple?.getChildren().length !== 1) {
continue;
}
const tchain = traversal.traverse(simple);
const tsource = traversal.traverse(compare.findDirectExpression(abaplint.Expressions.Source));
topEquals[tchain.getCode()] = tsource.getCode();
}
if (Object.keys(topEquals).length > 0) {
const fields = [];
for (const n in topEquals) {
fields.push(`"${n}": ` + topEquals[n]);
}
extra.push("topEquals: {" + fields.join(",") + "}");
}
let concat = "";
if (extra.length > 0) {
concat = ",{" + extra.join(",") + "}";
}
return new chunk_1.Chunk(`for await (const ${this.unique} of abap.statements.loop(${source}${concat})) {\n${target}`);
}
}
exports.LoopTranspiler = LoopTranspiler;
//# sourceMappingURL=loop.js.map