visitCall method

  1. @override
dynamic visitCall(
  1. CallExpression node
)

Implementation

@override
visitCall(CallExpression node) {
  dynamic val;
  try {
    dynamic method;
    if (node.callee is NameExpression) {
      if (node.isNew) {
        //a new object is being instantiated
        final dynamic _class = getValue((node.callee as NameExpression).name);
        if (_class == null) {
          throw JSException(node.line ?? -1,
              'Cannot instantiate object of class ${(node.callee as NameExpression).name} No definition found for class in code ${getCode(node)}.',
              recovery: 'Check your syntax and try again.');
        }
        if (!(_class is Invokable)) {
          throw JSException(node.line ?? -1,
              'Cannot instantiate object of class ${(node.callee as NameExpression).name} Class is not invokable in code ${getCode(node)}.',
              recovery: 'Check your syntax and try again.');
        }
        if (_class.methods()['init'] == null) {
          throw JSException(node.line ?? -1,
              'Cannot instantiate object of class ${(node.callee as NameExpression).name} No init method found for class in code ${getCode(node)}. init method is called to construct an instance. It must take List<parms> as argument.',
              recovery: 'Check your syntax and try again.');
        }
        method = _class.methods()['init'];
      } else {
        method = getValue((node.callee as NameExpression).name);
        if (method == null) {
          throw JSException(
              node.line ?? -1, 'No definition found for ${getCode(node)}.',
              recovery: 'Check your syntax and try again.');
        }
      }
      val = executeMethod(method, node.arguments);
    } else if (node.callee is MemberExpression ||
        node.callee is IndexExpression) {
      ObjectPattern? pattern;
      dynamic method;
      MethodExecutor? methodExecutor;
      String? methodName;
      if (node.callee is MemberExpression) {
        pattern = visitMember(node.callee as MemberExpression,
            computeAsPattern: true);
        if (pattern!.obj is MethodExecutor) {
          methodExecutor = pattern!.obj as MethodExecutor;
          methodName = pattern.property;
        } else {
          method = InvokableController.methods(pattern.obj)[pattern.property];
        }
        method = InvokableController.methods(pattern!.obj)[pattern.property];
      } else if (node.callee is IndexExpression) {
        pattern = visitIndex(node.callee as IndexExpression,
            computeAsPattern: true);
        method =
            InvokableController.getProperty(pattern!.obj, pattern.property);
        //old: method = pattern!.obj.getProperty(pattern.property);
      }
      if (method == null) {
        throw JSException(
            node.line ?? -1,
            "cannot compute statement=" +
                node.toString() +
                " "
                    "as no method found for property=" +
                ((pattern != null) ? pattern.property.toString() : ''),
            detailedError: 'Code: ${getCode(node)}');
      }
      try {
        val = executeMethod(method, node.arguments,
            methodName: methodName, executor: methodExecutor);
      } on JSException catch (e) {
        rethrow;
      } catch (e) {
        throw JSException(node.line ?? -1,
            'Error while executing method: ${getCode(node)}. Underlying error:${e.toString()}',
            originalError: e);
      }
    }
  } on JSException catch (e) {
    rethrow;
  } on InvalidPropertyException catch (e) {
    throw JSException(node.line ?? 1, '${e.message}. Code: ${getCode(node)}');
  }
  return val;
}