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

95.83% Statements 46/48
77.77% Branches 14/18
100% Functions 1/1
95.83% Lines 46/48

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 481x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 532x 532x 532x 532x 532x 532x 532x 348x 348x 332x 331x 331x 1x 1x 331x 515x 515x 532x 532x 1x 1x 495x 532x 173x 173x 173x 495x 532x 2x     532x 5x 5x 532x 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 {InlineData} from "../expressions/inline_data";
import {AbstractType} from "../../types/basic/_abstract_type";
import {StatementSyntax} from "../_statement_syntax";
import {TypeUtils} from "../_type_utils";
 
export class Move implements StatementSyntax {
  public runSyntax(node: StatementNode, scope: CurrentScope, filename: string): void {
    const targets = node.findDirectExpressions(Expressions.Target);
    const firstTarget = targets[0];
 
    const inline = firstTarget?.findDirectExpression(Expressions.InlineData);
 
    let targetType: AbstractType | undefined = undefined;
    if (inline === undefined) {
      targetType = firstTarget ? new Target().runSyntax(firstTarget, scope, filename) : undefined;
      for (const t of targets) {
        if (t === firstTarget) {
          continue;
        }
        new Target().runSyntax(t, scope, filename);
      }
    }
 
    const source = node.findDirectExpression(Expressions.Source);
    const sourceType = source ? new Source().runSyntax(source, scope, filename, targetType) : undefined;
    if (sourceType === undefined) {
      throw new Error("No source type determined");
    }
 
    if (inline) {
      new InlineData().runSyntax(inline, scope, filename, sourceType);
      targetType = sourceType;
    }
 
    if (node.findDirectTokenByText("?=")) {
      if (new TypeUtils(scope).isCastable(sourceType, targetType) === false) {
        throw new Error("Incompatible types");
      }
    } else if (new TypeUtils(scope).isAssignable(sourceType, targetType) === false) {
      throw new Error("Incompatible types");
    }
  }
}