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

92.31% Statements 36/39
89.66% Branches 26/29
100% Functions 1/1
92.31% Lines 36/39

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 651x     1x 1x 1x 1x 1x 1x     1x         15x 15x 3x 3x 3x 3x 2x 2x 1x   1x     1x         13x       13x 13x 13x 13x 13x 13x 2x 11x     11x 1x 10x 7x 7x 1x           11x 2x        
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 {Dynamic} from "../expressions/dynamic";
import {ReferenceType} from "../_reference";
import {GenericObjectReferenceType, ObjectReferenceType, VoidType} from "../../types/basic";
import {ClassDefinition} from "../../types";
import {StatementSyntax} from "../_statement_syntax";
 
export class CreateObject implements StatementSyntax {
  public runSyntax(node: StatementNode, scope: CurrentScope, filename: string): void {
    // todo, validate parameters
 
    // CREATE OBJECT, TYPE
    const type = node.findExpressionAfterToken("TYPE");
    if (type && type.get() instanceof Expressions.ClassName) {
      const token = type.getFirstToken();
      const name = token.getStr();
      const found = scope.findClassDefinition(name);
      if (found) {
        scope.addReference(token, found, ReferenceType.ObjectOrientedReference, filename);
        if (found.isAbstract() === true) {
          throw new Error(found.getName() + " is abstract, cannot be instantiated");
        }
      } else Iif (scope.getDDIC().inErrorNamespace(name) === false) {
        scope.addReference(token, undefined, ReferenceType.ObjectOrientedVoidReference, filename, {ooName: name, ooType: "CLAS"});
      } else {
        throw new Error("TYPE \"" + name + "\" not found");
      }
    }
 
    // just recurse
    for (const s of node.findAllExpressions(Expressions.Source)) {
      new Source().runSyntax(s, scope, filename);
    }
 
    let first = true;
    for (const t of node.findAllExpressions(Expressions.Target)) {
      const found = new Target().runSyntax(t, scope, filename);
      Eif (first === true) {
        first = false;
        if (found instanceof VoidType) {
          continue;
        } else Iif (!(found instanceof ObjectReferenceType)
            && !(found instanceof GenericObjectReferenceType)) {
          throw new Error("Target must be a object reference");
        } else if (found instanceof GenericObjectReferenceType && type === undefined) {
          throw new Error("Generic type, cannot be instantiated");
        } else if (found instanceof ObjectReferenceType) {
          const id = found.getIdentifier();
          if (type === undefined && id instanceof ClassDefinition && id.isAbstract() === true) {
            throw new Error(id.getName() + " is abstract, cannot be instantiated");
          }
        }
      }
    }
 
    for (const t of node.findDirectExpressions(Expressions.Dynamic)) {
      new Dynamic().runSyntax(t, scope, filename);
    }
 
  }
}