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

92.08% Statements 93/101
83.33% Branches 25/30
100% Functions 1/1
92.08% Lines 93/101

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 98 99 100 1011x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 22x 22x 22x 22x 22x 22x 22x 22x 22x 22x   22x 1x 1x 20x 20x 22x 19x 19x 20x 20x 22x 10x 10x 18x 18x 22x 10x 10x 1x 1x 10x 16x 16x 22x           16x 22x 24x 24x 24x     16x 16x 22x 15x 15x 2x 2x 2x 13x 13x 15x 3x 3x 3x 10x 10x 10x 10x 10x 10x 10x 10x 10x 15x 4x 4x 4x 15x 7x 7x 22x 1x 1x 1x 1x 1x 22x 22x 1x
import * as Expressions from "../../2_statements/expressions";
import {StatementNode} from "../../nodes";
import {CurrentScope} from "../_current_scope";
import {VoidType, TableType, IntegerType} from "../../types/basic";
import {Source} from "../expressions/source";
import {InlineData} from "../expressions/inline_data";
import {Target} from "../expressions/target";
import {FSTarget} from "../expressions/fstarget";
import {ComponentCompareSimple} from "../expressions/component_compare_simple";
import {StatementSyntax} from "../_statement_syntax";
import {AbstractType} from "../../types/basic/_abstract_type";
import {TypeUtils} from "../_type_utils";
 
export class ReadTable implements StatementSyntax {
  public runSyntax(node: StatementNode, scope: CurrentScope, filename: string): void {
 
    const sources = node.findDirectExpressions(Expressions.Source);
 
    let firstSource = node.findDirectExpression(Expressions.SimpleSource2);
    if (firstSource === undefined) {
      firstSource = sources[0];
    }
    const sourceType = firstSource ? new Source().runSyntax(firstSource, scope, filename) : undefined;
 
    if (sourceType === undefined) {
      throw new Error("No source type determined, read table");
    } else if (!(sourceType instanceof TableType) && !(sourceType instanceof VoidType)) {
      throw new Error("Read table, not a table type");
    }
 
    let rowType: AbstractType = sourceType;
    if (rowType instanceof TableType) {
      rowType = rowType.getRowType();
    }
 
    const components = node.findDirectExpression(Expressions.ComponentCompareSimple);
    if (components !== undefined) {
      new ComponentCompareSimple().runSyntax(components, scope, filename, rowType);
    }
 
    const indexSource = node.findExpressionAfterToken("INDEX");
    if (indexSource) {
      const indexType = new Source().runSyntax(indexSource, scope, filename);
      if (TypeUtils.isAssignable(indexType, new IntegerType()) === false) {
        throw new Error("READ TABLE, INDEX must be simple");
      }
    }
 
    const fromSource = node.findExpressionAfterToken("FROM");
    if (fromSource) {
      const fromType = new Source().runSyntax(fromSource, scope, filename);
      if (TypeUtils.isAssignable(fromType, new IntegerType()) === false) {
        throw new Error("READ TABLE, FROM must be simple");
      }
    }
 
    for (const s of sources) {
      if (s === firstSource || s === indexSource || s === fromSource) {
        continue;
      }
      new Source().runSyntax(s, scope, filename);
    }
 
    const target = node.findDirectExpression(Expressions.ReadTableTarget);
    if (target) {
      const inline = target.findFirstExpression(Expressions.InlineData);
      if (inline) {
        new InlineData().runSyntax(inline, scope, filename, rowType);
        return;
      }
 
      const fst = target.findDirectExpression(Expressions.FSTarget);
      if (fst) {
        new FSTarget().runSyntax(fst, scope, filename, rowType);
        return;
      }
/*
      const inlinefs = target.findFirstExpression(Expressions.InlineFS);
      if (inlinefs) {
        new InlineFS().runSyntax(inlinefs, scope, filename, sourceType);
        return;
      }
*/
 
      const t = target.findFirstExpression(Expressions.Target);
      if (t) {
        new Target().runSyntax(t, scope, filename);
        return;
      }
    }
 
    const concat = node.concatTokens().toUpperCase();
    if (target === undefined && concat.includes(" TRANSPORTING NO FIELDS ") === false) {
      // if sourceType is void, assume its with header
      if (sourceType instanceof TableType && sourceType.isWithHeader() === false) {
        throw new Error("READ TABLE, define INTO or TRANSPORTING NO FIELDS");
      }
    }
 
  }
}