@abaplint/core
Version:
abaplint - Core API
143 lines • 7.92 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Loop = void 0;
const Expressions = require("../../2_statements/expressions");
const basic_1 = require("../../types/basic");
const target_1 = require("../expressions/target");
const source_1 = require("../expressions/source");
const inline_data_1 = require("../expressions/inline_data");
const inline_fs_1 = require("../expressions/inline_fs");
const fstarget_1 = require("../expressions/fstarget");
const component_cond_1 = require("../expressions/component_cond");
const dynamic_1 = require("../expressions/dynamic");
const loop_group_by_1 = require("../expressions/loop_group_by");
const _syntax_input_1 = require("../_syntax_input");
const version_1 = require("../../../version");
class Loop {
runSyntax(node, input) {
var _a, _b;
const loopTarget = node.findDirectExpression(Expressions.LoopTarget);
let target = loopTarget === null || loopTarget === void 0 ? void 0 : loopTarget.findDirectExpression(Expressions.Target);
const targetType = target ? target_1.Target.runSyntax(target, input) : undefined;
if (target === undefined) {
target = node.findDirectExpression(Expressions.FSTarget);
}
const write = (loopTarget === null || loopTarget === void 0 ? void 0 : loopTarget.findDirectTokenByText("ASSIGNING")) !== undefined;
const sources = node.findDirectExpressions(Expressions.Source);
let firstSource = (_a = node.findDirectExpression(Expressions.LoopSource)) === null || _a === void 0 ? void 0 : _a.getFirstChild();
if (firstSource === undefined) {
firstSource = sources[0];
}
let sourceType = firstSource ? source_1.Source.runSyntax(firstSource, input, targetType, write) : undefined;
let rowType = undefined;
const concat = node.concatTokens().toUpperCase();
if (sourceType === undefined) {
// if its a dynpro table control loop, then dont issue error
if (concat !== "LOOP.") {
const message = "No source type determined";
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
}
}
else if (sourceType instanceof basic_1.UnknownType) {
const message = "Loop, not a table type, " + sourceType.getError();
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
sourceType = basic_1.VoidType.get("Loop, not a table type");
}
else if (sourceType instanceof basic_1.TableType
&& target === undefined
&& sourceType.isWithHeader() === false
&& node.getChildren().length === 4) {
const message = "Loop, no header line";
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
}
else if (!(sourceType instanceof basic_1.TableType)
&& !(sourceType instanceof basic_1.AnyType)
&& !(sourceType instanceof basic_1.DataType)
&& !(sourceType instanceof basic_1.VoidType)
&& concat.startsWith("LOOP AT GROUP ") === false) {
const message = "Loop, not a table type";
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
}
else if (loopTarget === undefined
&& sourceType instanceof basic_1.TableType
&& sourceType.isWithHeader() === false) {
const message = "Loop, no header";
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
}
const targetConcat = loopTarget === null || loopTarget === void 0 ? void 0 : loopTarget.concatTokens().toUpperCase();
const topType = sourceType; // todo: refactor topType vs sourceType vs rowType
if (sourceType instanceof basic_1.TableType) {
rowType = sourceType.getRowType();
sourceType = rowType;
if (targetConcat === null || targetConcat === void 0 ? void 0 : targetConcat.startsWith("REFERENCE INTO ")) {
sourceType = new basic_1.DataReference(sourceType);
}
}
const cond = node.findDirectExpression(Expressions.ComponentCond);
if (cond !== undefined) {
component_cond_1.ComponentCond.runSyntax(cond, input, rowType);
}
if (targetConcat
&& targetConcat.startsWith("TRANSPORTING ")
&& node.findDirectTokenByText("WHERE") === undefined) {
const message = "Loop, TRANSPORTING NO FIELDS only with WHERE";
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
return;
}
if (node.findDirectTokenByText("USING") !== undefined
&& cond !== undefined
&& topType instanceof basic_1.TableType) {
// https://github.com/abap2xlsx/abap2xlsx/issues/1341
const keyName = node.findExpressionAfterToken("KEY");
let key = undefined;
if ((keyName === null || keyName === void 0 ? void 0 : keyName.get()) instanceof Expressions.SimpleName) {
// it might be dynamic, in that case we cannot check anything
key = (_b = topType.getOptions().secondary) === null || _b === void 0 ? void 0 : _b.find(k => k.name.toUpperCase() === keyName.getFirstToken().getStr().toUpperCase());
if (key === undefined) {
const message = "Key " + (keyName === null || keyName === void 0 ? void 0 : keyName.concatTokens()) + " not found in table type";
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
return;
}
if (input.scope.getRegistry().getConfig().getVersion() <= version_1.Version.v740sp02) {
const compares = cond.findAllExpressionsRecursive(Expressions.ComponentCompare).map(c => c.concatTokens().toUpperCase());
for (const keyField of key.keyFields) {
if (compares.find(c => c === keyField.toUpperCase() + " IS INITIAL") !== undefined) {
const message = "Loop, key check with IS INITIAL cannot optimized before 7.40 SP02";
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
return;
}
}
}
}
}
const inline = target === null || target === void 0 ? void 0 : target.findDirectExpression(Expressions.InlineData);
if (inline) {
inline_data_1.InlineData.runSyntax(inline, input, sourceType);
}
for (const s of sources) {
if (s === firstSource) {
continue;
}
source_1.Source.runSyntax(s, input);
}
const inlinefs = target === null || target === void 0 ? void 0 : target.findDirectExpression(Expressions.InlineFS);
if (inlinefs) {
inline_fs_1.InlineFS.runSyntax(inlinefs, input, sourceType);
}
else {
const fstarget = loopTarget === null || loopTarget === void 0 ? void 0 : loopTarget.findDirectExpression(Expressions.FSTarget);
if (fstarget) {
fstarget_1.FSTarget.runSyntax(fstarget, input, sourceType);
}
}
for (const t of node.findDirectExpressions(Expressions.Dynamic)) {
dynamic_1.Dynamic.runSyntax(t, input);
}
const group = node.findDirectExpression(Expressions.LoopGroupBy);
if (group) {
loop_group_by_1.LoopGroupBy.runSyntax(group, input);
}
}
}
exports.Loop = Loop;
//# sourceMappingURL=loop.js.map