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

85.18% Statements 46/54
68.75% Branches 11/16
100% Functions 1/1
85.18% Lines 46/54

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 541x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 923x 923x 923x 923x 923x 923x 923x 683x 683x 684x 683x 683x 1x 1x 683x 923x 923x 923x 923x         922x 923x 239x 239x 239x 922x 923x 5x         923x 14x 14x 14x 14x 923x 1x
import * as Expressions from "../../2_statements/expressions";
import {StatementNode} from "../../nodes";
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";
import {SyntaxInput, syntaxIssue} from "../_syntax_input";
 
export class Move implements StatementSyntax {
  public runSyntax(node: StatementNode, input: SyntaxInput): 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 ? Target.runSyntax(firstTarget, input) : undefined;
      for (const t of targets) {
        if (t === firstTarget) {
          continue;
        }
        Target.runSyntax(t, input);
      }
    }
 
    const source = node.findDirectExpression(Expressions.Source);
    const sourceType = source ? Source.runSyntax(source, input, targetType) : undefined;
    if (sourceType === undefined) {
      const message = "No source type determined";
      input.issues.push(syntaxIssue(input, node.getFirstToken(), message));
      return;
    }
 
    if (inline) {
      InlineData.runSyntax(inline, input, sourceType);
      targetType = sourceType;
    }
 
    if (node.findDirectTokenByText("?=")) {
      if (new TypeUtils(input.scope).isCastable(sourceType, targetType) === false) {
        const message = "Incompatible types";
        input.issues.push(syntaxIssue(input, node.getFirstToken(), message));
        return;
      }
    } else if (new TypeUtils(input.scope).isAssignableNew(sourceType, targetType, source) === false) {
      const message = "Incompatible types";
      input.issues.push(syntaxIssue(input, node.getFirstToken(), message));
      return;
    }
  }
}