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

94.28% Statements 66/70
60.97% Branches 25/41
100% Functions 1/1
94.28% Lines 66/70

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 701x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 33x 33x 33x 33x 33x 33x 33x 33x 33x 4x 4x 4x         4x 33x 29x 29x 33x 33x 33x 8x 8x 8x 1x 1x 1x 1x 8x 32x 33x 9x 9x 33x 10x 10x 32x 32x 32x 32x 7x 32x 25x 25x 32x 32x 33x 28x 27x 27x 1x 1x 32x 32x 1x
import * as Expressions from "../../2_statements/expressions";
import {ExpressionNode, StatementNode} from "../../nodes";
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";
import {SyntaxInput, syntaxIssue} from "../_syntax_input";
 
export class Assign implements StatementSyntax {
  public runSyntax(node: StatementNode, input: SyntaxInput): 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 = input.scope.findClassDefinition(name) || input.scope.findVariable(name);
      if (found === undefined && input.scope.getDDIC().inErrorNamespace(name) && name.startsWith("(") === false) {
        const message = name + " not found, dynamic";
        input.issues.push(syntaxIssue(input, node.getFirstToken(), message));
        return;
      }
      sourceType = new VoidType("Dynamic");
    } else {
      sourceType = new Source().runSyntax(theSource, input);
    }
 
    if (assignSource?.getChildren().length === 5
        && assignSource?.getFirstChild()?.concatTokens().toUpperCase() === "COMPONENT") {
      const componentSource = sources[sources.length - 2];
      const componentType = new Source().runSyntax(componentSource, input);
      if (new TypeUtils(input.scope).isAssignable(componentType, new CharacterType(30)) === false) {
        const message = "component name must be charlike";
        input.issues.push(syntaxIssue(input, node.getFirstToken(), message));
        return;
      }
    }
 
    if (sourceType === undefined || assignSource?.findDirectExpression(Expressions.Dynamic)) {
      sourceType = new AnyType();
    }
    for (const d of assignSource?.findAllExpressions(Expressions.Dynamic) || []) {
      new Dynamic().runSyntax(d, input);
    }
 
    const target = node.findDirectExpression(Expressions.FSTarget);
    if (target) {
      if (assignSource?.getFirstChild()?.concatTokens().toUpperCase() === "COMPONENT") {
        new FSTarget().runSyntax(target, input, new AnyType());
      } else {
        new FSTarget().runSyntax(target, input, sourceType);
      }
    }
 
    for (const s of node.findAllExpressions(Expressions.Source)) {
      if (s === theSource) {
        continue;
      }
      new Source().runSyntax(s, input);
    }
 
  }
}