All files / src/abap/5_syntax/expressions value_body.ts

97.64% Statements 83/85
94.73% Branches 36/38
100% Functions 1/1
97.64% Lines 83/85

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 851x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 143x 143x 143x 143x 143x 143x 35x 35x 108x 108x 108x 143x 9x 9x 108x 108x 143x 33x 33x 32x 32x 33x 107x 143x 43x 43x 104x 104x 143x 22x 22x 104x 143x 73x 73x 73x 73x 73x     73x 73x 57x 57x 73x 73x 4x 5x 5x 5x 4x 73x 46x 46x 73x 38x 38x 71x 102x 143x 9x 9x 102x 143x 32x 32x 102x 143x 1x 1x 143x 143x 1x
import {ExpressionNode} from "../../nodes";
import {CurrentScope} from "../_current_scope";
import * as Expressions from "../../2_statements/expressions";
import {For} from "./for";
import {Source} from "./source";
import {AbstractType} from "../../types/basic/_abstract_type";
import {Let} from "./let";
import {FieldAssignment} from "./field_assignment";
import {AnyType, TableType, UnknownType, VoidType} from "../../types/basic";
 
export class ValueBody {
  public runSyntax(
    node: ExpressionNode | undefined,
    scope: CurrentScope,
    filename: string,
    targetType: AbstractType | undefined): AbstractType | undefined {
 
    if (node === undefined) {
      return targetType;
    }
 
    let letScoped = false;
    const letNode = node.findDirectExpression(Expressions.Let);
    if (letNode) {
      letScoped = new Let().runSyntax(letNode, scope, filename);
    }
 
    let forScopes = 0;
    for (const forNode of node.findDirectExpressions(Expressions.For) || []) {
      const scoped = new For().runSyntax(forNode, scope, filename);
      if (scoped === true) {
        forScopes++;
      }
    }
 
    for (const s of node.findDirectExpressions(Expressions.FieldAssignment)) {
      new FieldAssignment().runSyntax(s, scope, filename, targetType);
    }
 
    let type: AbstractType | undefined = undefined; // todo, this is only correct if there is a single source in the body
    for (const s of node.findDirectExpressions(Expressions.Source)) {
      type = new Source().runSyntax(s, scope, filename);
    }
 
    for (const foo of node.findDirectExpressions(Expressions.ValueBodyLine)) {
      if (!(targetType instanceof TableType)
          && !(targetType instanceof UnknownType)
          && !(targetType instanceof AnyType)
          && targetType !== undefined
          && !(targetType instanceof VoidType)) {
        throw new Error("Value, not a table type");
      }
      let rowType: AbstractType | undefined = targetType;
      if (targetType instanceof TableType) {
        rowType = targetType.getRowType();
      }
 
      for (const l of foo.findDirectExpressions(Expressions.ValueBodyLines)) {
        for (const s of l.findDirectExpressions(Expressions.Source)) {
// LINES OF ?? todo, pass type,
          new Source().runSyntax(s, scope, filename);
        }
      }
      for (const s of foo.findDirectExpressions(Expressions.FieldAssignment)) {
        new FieldAssignment().runSyntax(s, scope, filename, rowType);
      }
      for (const s of foo.findDirectExpressions(Expressions.Source)) {
        new Source().runSyntax(s, scope, filename, rowType);
      }
    }
 
    if (letScoped === true) {
      scope.pop(node.getLastToken().getEnd());
    }
 
    for (let i = 0; i < forScopes; i++) {
      scope.pop(node.getLastToken().getEnd());
    }
 
    if (targetType?.isGeneric() && type) {
      return type;
    }
    return targetType ? targetType : type;
  }
}