UNPKG

@abaplint/transpiler

Version:
137 lines • 7.18 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AssignTranspiler = void 0; /* eslint-disable max-len */ const abaplint = require("@abaplint/core"); const expressions_1 = require("../expressions"); const chunk_1 = require("../chunk"); class AssignTranspiler { tableExpressionSafeSource(node, code) { if (node?.findFirstExpression(abaplint.Expressions.TableExpression) === undefined) { return code; } return `(await (async () => { try { return ${code}; } catch (error) { if (abap.isLineNotFound(error)) { return undefined; } throw error; } })())`; } transpile(node, traversal) { const assignSource = node.findDirectExpression(abaplint.Expressions.AssignSource); const sourceExpressions = assignSource?.findDirectExpressionsMulti([abaplint.Expressions.Source, abaplint.Expressions.SimpleSource3]) || []; const sources = sourceExpressions.map(e => this.tableExpressionSafeSource(e, new expressions_1.SourceTranspiler(false).transpile(e, traversal).getCode())); let fsTarget = node.findDirectExpression(abaplint.Expressions.FSTarget); if (fsTarget?.getFirstChild()?.get() instanceof abaplint.Expressions.InlineFS) { fsTarget = fsTarget.findFirstExpression(abaplint.Expressions.TargetFieldSymbol); } const fs = new expressions_1.FieldSymbolTranspiler().transpile(fsTarget, traversal).getCode(); const options = []; const concat = node.concatTokens().toUpperCase(); if (concat.startsWith("ASSIGN COMPONENT ")) { options.push("component: " + sources.shift()); } options.push("target: " + fs); if (sources.length !== 0 && assignSource?.findDirectExpression(abaplint.Expressions.Dynamic) === undefined) { // Check for struct-(var) pattern: dynamic component access via FieldLength after - const sourceExprForCheck = sourceExpressions[0]; const fieldChainForCheck = sourceExprForCheck?.findFirstExpression(abaplint.Expressions.FieldChain); const fcChildren = fieldChainForCheck?.getChildren() ?? []; const lastFC = fcChildren[fcChildren.length - 1]; const prevFC = fcChildren[fcChildren.length - 2]; const isStructDynField = fieldChainForCheck !== undefined && lastFC instanceof abaplint.Nodes.ExpressionNode && lastFC.get() instanceof abaplint.Expressions.FieldLength && prevFC instanceof abaplint.Nodes.TokenNode && prevFC.getFirstToken().getStr() === "-"; if (isStructDynField) { const componentCode = new expressions_1.FieldLengthTranspiler().transpile(lastFC, traversal).getCode(); const fullSource = sources.pop(); // Strip trailing .get().getOffset(...) to recover the base structure variable const getOffsetIdx = fullSource.lastIndexOf(".get().getOffset("); const baseSourceCode = getOffsetIdx >= 0 ? fullSource.substring(0, getOffsetIdx) : fullSource; options.push("component: " + componentCode); options.push("source: " + baseSourceCode); } else { options.push("source: " + sources.pop()); } } else { let dynamicName = ""; for (const c of assignSource?.getChildren() || []) { if (c instanceof abaplint.Nodes.ExpressionNode && c.get() instanceof abaplint.Expressions.Dynamic && c.findFirstExpression(abaplint.Expressions.ConstantString)) { if (dynamicName !== "") { dynamicName += " + "; } dynamicName += c.findFirstExpression(abaplint.Expressions.ConstantString)?.getFirstToken().getStr(); } else if (c instanceof abaplint.Nodes.ExpressionNode && c.get() instanceof abaplint.Expressions.Dynamic && c.findDirectExpression(abaplint.Expressions.FieldChain)) { if (dynamicName !== "") { dynamicName += " + "; } dynamicName += new expressions_1.FieldChainTranspiler(true).transpile(c.findDirectExpression(abaplint.Expressions.FieldChain), traversal).getCode(); } else if (c.concatTokens() === "(" || c.concatTokens() === ")") { continue; } else if (c.concatTokens() === "=>" || c.concatTokens() === "->") { dynamicName += " + '" + c.concatTokens() + "'"; } else { if (dynamicName !== "") { dynamicName += " + "; } dynamicName += "'" + c.concatTokens() + "'"; } } options.push(`dynamicName: ` + dynamicName); // dynamicSource is the first part of the dynamic part const first = assignSource?.getFirstChild(); if (first?.get() instanceof abaplint.Expressions.Dynamic && first instanceof abaplint.Nodes.ExpressionNode) { const firstFirst = first.getChildren()[1]; if (firstFirst?.get() instanceof abaplint.Expressions.Constant) { const s = firstFirst.getFirstToken().getStr().toLowerCase().match(/\w+/)?.toString(); options.push(`dynamicSource: (() => { try { return ${s}; } catch {} try { return this.${s}; } catch {} })()`); } else if (firstFirst?.get() instanceof abaplint.Expressions.FieldChain && firstFirst instanceof abaplint.Nodes.ExpressionNode) { const code = new expressions_1.FieldChainTranspiler(true).transpile(firstFirst, traversal).getCode(); options.push(`dynamicSource: (() => { const name = ${code}.toLowerCase().replace(/[~\\/]/g, "$").match(/[\\w\\$\\/]+/)[0]; try { return eval(name); } catch {} try { return eval("this." + name); } catch {} })()`); } } else if (first?.get() instanceof abaplint.Expressions.Source && first instanceof abaplint.Nodes.ExpressionNode) { // const name = first.concatTokens().toLowerCase(); const name = new expressions_1.SourceTranspiler().transpile(first, traversal).getCode(); options.push(`dynamicSource: (() => { try { return ${name}; } catch {} try { return this.${name}; } catch {} })()`); } } if (concat.endsWith(" CASTING.") || concat.includes(" CASTING TYPE ")) { options.push("casting: true"); } const ret = new chunk_1.Chunk().append("abap.statements.assign({", node, traversal) .appendString(options.join(", ")) .append("});", node.getLastToken(), traversal); return ret; } } exports.AssignTranspiler = AssignTranspiler; //# sourceMappingURL=assign.js.map