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

88% Statements 44/50
66.66% Branches 12/18
100% Functions 1/1
88% Lines 44/50

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 501x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 4x 4x 4x 4x 4x 4x 3x 1x 3x 2x 2x 4x 1x 1x 1x     1x 3x 4x 7x 7x 7x 1x     1x 1x 1x 6x 7x 7x     7x 3x 3x 1x
import * as Expressions from "../../2_statements/expressions";
import {StatementNode} from "../../nodes";
import {CurrentScope} from "../_current_scope";
import {Source} from "../expressions/source";
import {Target} from "../expressions/target";
import {StringType, TableType, UnknownType, VoidType, XStringType} from "../../types/basic";
import {InlineData} from "../expressions/inline_data";
import {StatementSyntax} from "../_statement_syntax";
import {TypeUtils} from "../_type_utils";
 
export class Concatenate implements StatementSyntax {
  public runSyntax(node: StatementNode, scope: CurrentScope, filename: string): void {
    const byteMode = node.findDirectTokenByText("BYTE") !== undefined;
    let linesMode = node.findDirectTokenByText("LINES") !== undefined;
 
    const target = node.findFirstExpression(Expressions.Target);
    const inline = target?.findDirectExpression(Expressions.InlineData);
    if (inline) {
      if (byteMode) {
        new InlineData().runSyntax(inline, scope, filename, new XStringType());
      } else {
        new InlineData().runSyntax(inline, scope, filename, StringType.get());
      }
    } else if (target) {
      const type = new Target().runSyntax(target, scope, filename);
      const compatible = byteMode ? new TypeUtils(scope).isHexLike(type) : new TypeUtils(scope).isCharLike(type);
      if (compatible === false) {
        throw new Error("Target type not compatible");
      }
    }
 
    for (const s of node.findDirectExpressions(Expressions.Source)) {
      const type = new Source().runSyntax(s, scope, filename);
 
      if (linesMode) {
        if (!(type instanceof UnknownType) && !(type instanceof VoidType) && !(type instanceof TableType)) {
          throw new Error("Source must be an internal table");
        }
        linesMode = false;
        continue;
      }
 
      const compatible = byteMode ? new TypeUtils(scope).isHexLike(type) : new TypeUtils(scope).isCharLike(type);
      if (compatible === false) {
        throw new Error("Source type not compatible");
      }
    }
 
  }
}