All files / src/abap/5_syntax/expressions method_source.ts

94.11% Statements 64/68
87.5% Branches 14/16
100% Functions 1/1
94.11% Lines 64/68

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 681x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 18x 18x 18x 18x 18x 18x 18x 3x 18x 10x 8x 8x 2x 2x 8x 7x 7x 7x 7x 2x 2x 5x 5x 5x 5x 5x 5x 10x 2x 2x     13x 3x 3x     6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 1x 1x
import * as Expressions from "../../2_statements/expressions";
import {ExpressionNode} from "../../nodes";
import {CurrentScope} from "../_current_scope";
import {Dynamic} from "./dynamic";
import {MethodCallChain} from "./method_call_chain";
import {ObjectReferenceType, VoidType} from "../../types/basic";
import {ClassDefinition} from "../../types";
import {IReferenceExtras, ReferenceType} from "../_reference";
import {ObjectOriented} from "../_object_oriented";
import {Identifier} from "../../4_file_information/_identifier";
import {IMethodDefinition} from "../../types/_method_definition";
 
export class MethodSource {
 
  public runSyntax(node: ExpressionNode, scope: CurrentScope, filename: string): IMethodDefinition | VoidType | undefined {
 
// todo, rewrite the context finding, and/or restructure the expression?
    const context = new MethodCallChain().runSyntax(node, scope, filename);
 
    const last = node.getLastChild();
    const first = node.getFirstChild();
    if (first instanceof ExpressionNode && first.get() instanceof Expressions.Dynamic) {
      new Dynamic().runSyntax(first!, scope, filename);
    } else if (last instanceof ExpressionNode && last.get() instanceof Expressions.MethodName) {
      if (context instanceof ObjectReferenceType) {
        let id: Identifier | undefined = context.getIdentifier();
        if (!(id instanceof ClassDefinition)) {
          id = scope.findObjectDefinition(id.getName());
        }
        if (id instanceof ClassDefinition) { // todo || id instanceof InterfaceDefinition) {
          const methodName = last.concatTokens().toUpperCase();
          const helper = new ObjectOriented(scope);
          const {method: foundMethod} = helper.searchMethodName(id, methodName);
          if (foundMethod === undefined && methodName !== "CONSTRUCTOR") {
            throw new Error(`MethodSource, method not found \"${methodName}\"`);
          }
          const extra: IReferenceExtras = {
            ooName: id.getName(),
            ooType: "CLAS"};
          scope.addReference(last.getFirstToken(), foundMethod, ReferenceType.MethodReference, filename, extra);
          return foundMethod;
        }
      } else if (context instanceof VoidType) {
        return context;
      } else {
        throw new Error("MethodSource, not a object reference, " + node.concatTokens());
      }
    } else if (last instanceof ExpressionNode && last.get() instanceof Expressions.Dynamic) {
      new Dynamic().runSyntax(last!, scope, filename);
    } else {
      throw new Error("MethodSource, unexpected node");
    }
 
    /*
    const chain = node.findDirectExpression(Expressions.FieldChain);
    if (chain) {
      new FieldChain().runSyntax(chain, scope, filename, ReferenceType.DataReadReference);
    }
 
    for (const d of node.findAllExpressions(Expressions.Dynamic)) {
      new Dynamic().runSyntax(d, scope, filename);
    }
    */
 
    return undefined;
  }
 
}