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

92.3% Statements 72/78
66.66% Branches 8/12
100% Functions 1/1
92.3% Lines 72/78

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 781x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 42x 42x 42x 42x 42x     42x 42x 42x 42x 3x 3x 42x 42x 42x 48x 39x 39x 39x 48x 48x 48x 48x 46x 46x 48x 48x 48x 42x 42x 48x 42x 42x 42x 43x 43x 43x 43x 43x 42x 42x     42x 42x 42x 42x 42x 42x 42x 42x 42x 42x 43x 43x 42x 42x 42x 42x     42x 1x
import {ExpressionNode} from "../../nodes";
import * as Expressions from "../../2_statements/expressions";
import {For} from "./for";
import {Source} from "./source";
import {AbstractType} from "../../types/basic/_abstract_type";
import {InlineFieldDefinition} from "./inline_field_definition";
import {UnknownType} from "../../types/basic/unknown_type";
import {ReduceNext} from "./reduce_next";
import {Let} from "./let";
import {ScopeType} from "../_scope_type";
import {SyntaxInput} from "../_syntax_input";
 
export class ReduceBody {
  public static runSyntax(
    node: ExpressionNode | undefined,
    input: SyntaxInput,
    targetType: AbstractType | undefined): AbstractType | undefined {
 
    if (node === undefined) {
      return;
    }
 
    let scoped = false;
    const letNode = node.findDirectExpression(Expressions.Let);
    if (letNode) {
      scoped = Let.runSyntax(letNode, input);
    }
 
    let first: AbstractType | undefined = undefined;
    for (const i of node.findDirectExpressions(Expressions.InlineFieldDefinition)) {
      if (scoped === false) {
        input.scope.push(ScopeType.Let, "LET", node.getFirstToken().getStart(), input.filename);
        scoped = true;
      }
 
      let foundType = targetType;
      const source = i.findDirectExpression(Expressions.Source);
      if (source) {
        foundType = Source.runSyntax(source, input, targetType);
      }
 
      const found = InlineFieldDefinition.runSyntax(i, input, foundType);
      if (found && first === undefined) {
        first = found;
      }
    }
 
    let forScopes = 0;
    for (const forNode of node.findDirectExpressions(Expressions.For) || []) {
      const scoped = For.runSyntax(forNode, input);
      if (scoped === true) {
        forScopes++;
      }
    }
 
    for (const s of node.findDirectExpressions(Expressions.Source)) {
      Source.runSyntax(s, input);
    }
 
    for (const s of node.findDirectExpressions(Expressions.ReduceNext)) {
      ReduceNext.runSyntax(s, input);
    }
 
    if (scoped === true) {
      input.scope.pop(node.getLastToken().getEnd());
    }
 
    for (let i = 0; i < forScopes; i++) {
      input.scope.pop(node.getLastToken().getEnd());
    }
 
    if (first) {
      return first;
    } else {
      return new UnknownType("todo, ReduceBody");
    }
  }
}