All files / src/abap/5_syntax/statements loop.ts

91.83% Statements 90/98
86.53% Branches 45/52
100% Functions 1/1
91.83% Lines 90/98

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 981x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 106x 106x 106x 106x 106x 38x 38x 99x 99x 99x 106x 2x 2x 106x 106x 106x 106x   106x   94x 94x 94x 94x 1x 94x 93x 93x 93x     93x 106x 84x 84x 84x 12x 12x 84x 93x 106x 106x 49x 49x 93x 106x 6x 2x 2x 4x 4x 92x 106x 106x 1x 106x 91x 91x 29x 29x 91x 91x 106x     91x 106x 7x 7x 90x 106x     90x 90x 106x 19x 19x 106x 106x 1x
import * as Expressions from "../../2_statements/expressions";
import {StatementNode} from "../../nodes";
import {CurrentScope} from "../_current_scope";
import {VoidType, TableType, UnknownType, DataReference, AnyType} from "../../types/basic";
import {Target} from "../expressions/target";
import {Source} from "../expressions/source";
import {InlineData} from "../expressions/inline_data";
import {InlineFS} from "../expressions/inline_fs";
import {FSTarget} from "../expressions/fstarget";
import {ComponentCompare} from "../expressions/component_compare";
import {ComponentCond} from "../expressions/component_cond";
import {Dynamic} from "../expressions/dynamic";
import {StatementSyntax} from "../_statement_syntax";
import {LoopGroupBy} from "../expressions/loop_group_by";
 
export class Loop implements StatementSyntax {
  public runSyntax(node: StatementNode, scope: CurrentScope, filename: string): void {
    const loopTarget = node.findDirectExpression(Expressions.LoopTarget);
 
    let target = loopTarget?.findDirectExpression(Expressions.Target);
    const targetType = target ? new Target().runSyntax(target, scope, filename) : undefined;
    if (target === undefined) {
      target = node.findDirectExpression(Expressions.FSTarget);
    }
 
    const sources = node.findDirectExpressions(Expressions.Source);
    let firstSource = node.findDirectExpression(Expressions.SimpleSource2);
    if (firstSource === undefined) {
      firstSource = sources[0];
    }
    let sourceType = firstSource ? new Source().runSyntax(firstSource, scope, filename, targetType) : undefined;
 
    const concat = node.concatTokens().toUpperCase();
    if (sourceType === undefined) {
      throw new Error("No source type determined");
    } else if (sourceType instanceof UnknownType) {
      throw new Error("Loop, not a table type, " + sourceType.getError());
    } else if (sourceType instanceof TableType
        && target === undefined
        && sourceType.isWithHeader() === false
        && node.getChildren().length === 4) {
      throw new Error("Loop, no header line");
    } else if (!(sourceType instanceof TableType)
        && !(sourceType instanceof AnyType)
        && !(sourceType instanceof VoidType)
        && concat.startsWith("LOOP AT GROUP ") === false) {
      throw new Error("Loop, not a table type");
    }
 
    if (sourceType instanceof TableType) {
      const targetConcat = node.findDirectExpression(Expressions.LoopTarget)?.concatTokens().toUpperCase();
      sourceType = sourceType.getRowType();
      if (targetConcat?.startsWith("REFERENCE INTO ")) {
        sourceType = new DataReference(sourceType);
      }
    }
 
    const inline = target?.findDirectExpression(Expressions.InlineData);
    if (inline) {
      new InlineData().runSyntax(inline, scope, filename, sourceType);
    }
 
    for (const s of sources) {
      if (s === firstSource) {
        continue;
      }
      new Source().runSyntax(s, scope, filename);
    }
 
    const inlinefs = target?.findDirectExpression(Expressions.InlineFS);
    if (inlinefs) {
      new InlineFS().runSyntax(inlinefs, scope, filename, sourceType);
    } else {
      const fstarget = loopTarget?.findDirectExpression(Expressions.FSTarget);
      if (fstarget) {
        new FSTarget().runSyntax(fstarget, scope, filename, sourceType);
      }
    }
 
    for (const t of node.findDirectExpressions(Expressions.ComponentCompare)) {
      new ComponentCompare().runSyntax(t, scope, filename);
    }
 
    for (const t of node.findDirectExpressions(Expressions.ComponentCond)) {
      new ComponentCond().runSyntax(t, scope, filename);
    }
 
    for (const t of node.findDirectExpressions(Expressions.Dynamic)) {
      new Dynamic().runSyntax(t, scope, filename);
    }
 
    const group = node.findDirectExpression(Expressions.LoopGroupBy);
    if (group) {
      new LoopGroupBy().runSyntax(group, scope, filename);
    }
 
  }
}