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 41x 41x 41x 41x 41x     41x 41x 41x 41x 3x 3x 41x 41x 41x 47x 38x 38x 38x 47x 47x 47x 47x 45x 45x 47x 47x 47x 41x 41x 47x 41x 41x 41x 42x 42x 42x 42x 42x 41x 41x     41x 41x 41x 41x 41x 41x 41x 41x 41x 41x 42x 42x 41x 41x 41x 41x     41x 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 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 = new 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 = new Source().runSyntax(source, input, targetType);
      }
 
      const found = new InlineFieldDefinition().runSyntax(i, input, foundType);
      if (found && first === undefined) {
        first = found;
      }
    }
 
    let forScopes = 0;
    for (const forNode of node.findDirectExpressions(Expressions.For) || []) {
      const scoped = new For().runSyntax(forNode, input);
      if (scoped === true) {
        forScopes++;
      }
    }
 
    for (const s of node.findDirectExpressions(Expressions.Source)) {
      new Source().runSyntax(s, input);
    }
 
    for (const s of node.findDirectExpressions(Expressions.ReduceNext)) {
      new 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");
    }
  }
}