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

92.66% Statements 101/109
84.37% Branches 27/32
100% Functions 1/1
92.66% Lines 101/109

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 101 102 103 104 105 106 107 108 1091x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 38x 38x 38x 38x 38x 38x 38x 38x 38x 38x   38x 1x 1x 37x 37x 38x 34x 34x 37x 37x 38x 22x 22x 35x 35x 38x 15x 15x 1x 1x 15x 33x 33x 38x           33x 38x 46x 46x 46x     33x 33x 38x 32x 2x 2x 32x 32x 32x 5x 5x 5x 27x 27x 32x 12x 12x 12x 15x 15x 15x 15x 15x 15x 15x 15x 15x 32x 7x 7x 7x 1x 1x 5x 5x 5x 32x 9x 38x 1x 1x 1x 1x 1x 38x 38x 1x
import * as Expressions from "../../2_statements/expressions";
import {StatementNode} from "../../nodes";
import {CurrentScope} from "../_current_scope";
import {VoidType, TableType, IntegerType, DataReference} 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 concat = node.concatTokens().toUpperCase();
    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 (new TypeUtils(scope).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 (new TypeUtils(scope).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) {
      if (concat.includes(" REFERENCE INTO ")) {
        rowType = new DataReference(rowType);
      }
 
      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) {
        const targetType = new Target().runSyntax(t, scope, filename);
 
        if (new TypeUtils(scope).isAssignable(rowType, targetType) === false) {
          throw new Error("Incompatible types");
        }
 
        return;
      }
    }
 
    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");
      }
    }
 
  }
}