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

85.29% Statements 58/68
80% Branches 20/25
100% Functions 1/1
85.29% Lines 58/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 118x     118x 118x 118x     118x 118x 118x 118x 70x 56x 56x 2x 2x 56x 68x 118x 24x 1x 1x 23x 24x 22x 22x     22x 25x 8x 8x 8x 25x 24x 1x 1x 23x 23x 24x   24x 1x 1x 24x 17x 24x 7x 7x       118x 1x
import {ExpressionNode} from "../../nodes";
import {CurrentScope} from "../_current_scope";
import {VoidType} from "../../types/basic";
import * as Expressions from "../../2_statements/expressions";
import {IMethodDefinition} from "../../types/_method_definition";
import {MethodParameters} from "./method_parameters";
import {WParenRight, WParenRightW} from "../../1_lexer/tokens";
import {Source} from "./source";
import {AbstractType} from "../../types/basic/_abstract_type";
import {TypeUtils} from "../_type_utils";
 
export class MethodCallParam {
  public runSyntax(node: ExpressionNode, scope: CurrentScope, method: IMethodDefinition | VoidType, filename: string): void {
    if (!(node.get() instanceof Expressions.MethodCallParam)) {
      throw new Error("MethodCallParam, unexpected input");
    }
 
    const children = node.getChildren();
    if (children.length < 2 || children.length > 3) {
      throw new Error("MethodCallParam, unexpected child length");
    }
 
    const child = children[1];
 
    if (child.get() instanceof WParenRight || child.get() instanceof WParenRightW) {
      if (!(method instanceof VoidType)) {
        const required = method.getParameters().getRequiredParameters();
        if (required.length > 0) {
          throw new Error("Parameter \"" + required[0].getName() + "\" must be supplied");
        }
      }
      return;
    } else if (child instanceof ExpressionNode && child.get() instanceof Expressions.Source) {
      if (!(method instanceof VoidType) && method.getParameters().getImporting().length === 0) {
        throw new Error("Method \"" + method.getName() + "\" has no importing parameters");
      }
      let targetType: AbstractType | undefined = undefined;
      if (!(method instanceof VoidType)) {
        const name = method.getParameters().getDefaultImporting();
        if (name === undefined) {
          throw new Error("No default importing parameter");
        }
        for (const i of method.getParameters().getImporting()) {
          if (i.getName().toUpperCase() === name) {
            targetType = i.getType();
            break;
          }
        }
      } else {
        targetType = method;
      }
      const sourceType = new Source().runSyntax(child, scope, filename, targetType);
 
      if (sourceType === undefined) {
        throw new Error("No source type determined, method source");
      } else if (TypeUtils.isAssignable(sourceType, targetType) === false) {
        throw new Error("Method parameter type not compatible");
      }
    } else if (child instanceof ExpressionNode && child.get() instanceof Expressions.ParameterListS) {
      new MethodParameters().checkExporting(child, scope, method, filename);
    } else if (child.get() instanceof Expressions.MethodParameters) {
      new MethodParameters().runSyntax(child, scope, method, filename);
    } else {
//      console.dir(child);
      throw new Error("MethodCallParam, unexpected child");
    }
  }
}