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

96.96% Statements 64/66
61.9% Branches 26/42
100% Functions 1/1
96.96% Lines 64/66

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 661x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 32x 32x 32x 32x 32x 32x 32x 32x 32x 4x 4x 4x     4x 32x 28x 28x 32x 32x 32x 8x 8x 8x 1x 1x 8x 31x 32x 9x 9x 32x 10x 10x 31x 31x 31x 31x 7x 31x 24x 24x 31x 30x 32x 26x 25x 25x 1x 1x 30x 30x 1x
import * as Expressions from "../../2_statements/expressions";
import {ExpressionNode, StatementNode} from "../../nodes";
import {CurrentScope} from "../_current_scope";
import {Source} from "../expressions/source";
import {FSTarget} from "../expressions/fstarget";
import {AnyType, CharacterType, VoidType} from "../../types/basic";
import {StatementSyntax} from "../_statement_syntax";
import {AbstractType} from "../../types/basic/_abstract_type";
import {Dynamic} from "../expressions/dynamic";
import {TypeUtils} from "../_type_utils";
 
export class Assign implements StatementSyntax {
  public runSyntax(node: StatementNode, scope: CurrentScope, filename: string): void {
    const assignSource = node.findDirectExpression(Expressions.AssignSource);
    const sources: ExpressionNode[] = assignSource?.findDirectExpressionsMulti([Expressions.Source, Expressions.SimpleSource3]) || [];
    const theSource = sources[sources.length - 1];
 
    let sourceType: AbstractType | undefined = undefined;
    const firstAssign = assignSource?.getChildren()[0];
    const secondAssign = assignSource?.getChildren()[1];
    const thirdAssign = assignSource?.getChildren()[2];
    if (secondAssign?.concatTokens() === "=>" && firstAssign && thirdAssign?.get() instanceof Expressions.Dynamic) {
      const name = firstAssign.concatTokens();
      const found = scope.findClassDefinition(name) || scope.findVariable(name);
      if (found === undefined && scope.getDDIC().inErrorNamespace(name) && name.startsWith("(") === false) {
        throw new Error(name + " not found, dynamic");
      }
      sourceType = new VoidType("Dynamic");
    } else {
      sourceType = new Source().runSyntax(theSource, scope, filename);
    }
 
    if (assignSource?.getChildren().length === 5
        && assignSource?.getFirstChild()?.concatTokens().toUpperCase() === "COMPONENT") {
      const componentSource = sources[sources.length - 2];
      const componentType = new Source().runSyntax(componentSource, scope, filename);
      if (new TypeUtils(scope).isAssignable(componentType, new CharacterType(30)) === false) {
        throw new Error("component name must be charlike");
      }
    }
 
    if (sourceType === undefined || assignSource?.findDirectExpression(Expressions.Dynamic)) {
      sourceType = new AnyType();
    }
    for (const d of assignSource?.findAllExpressions(Expressions.Dynamic) || []) {
      new Dynamic().runSyntax(d, scope, filename);
    }
 
    const target = node.findDirectExpression(Expressions.FSTarget);
    if (target) {
      if (assignSource?.getFirstChild()?.concatTokens().toUpperCase() === "COMPONENT") {
        new FSTarget().runSyntax(target, scope, filename, new AnyType());
      } else {
        new FSTarget().runSyntax(target, scope, filename, sourceType);
      }
    }
 
    for (const s of node.findAllExpressions(Expressions.Source)) {
      if (s === theSource) {
        continue;
      }
      new Source().runSyntax(s, scope, filename);
    }
 
  }
}