dynamic noSuchMethod(Invocation invocation)

Invoked when a non-existent method or property is accessed.

Classes can override noSuchMethod to provide custom behavior.

If a value is returned, it becomes the result of the original invocation.

The default behavior is to throw a NoSuchMethodError.

Source

dynamic noSuchMethod(Invocation invocation) {
  if (invocation.isMethod) {
    List<_JavaMethod> overloads = _clazz._methods[invocation.memberName];
    if (overloads == null)
      throw new JavaError('Method ${invocation.memberName} not found');

    _JavaMethod method = _findMatchingMethod(overloads, invocation.positionalArguments);
    List args = _convertArgumentsToJava(invocation.positionalArguments, method);

    if (method.returnType == _JavaPrimitive.jvoid) {
      return _object.callVoidMethod(method.methodId, args);
    } else if (method.returnType == _JavaPrimitive.jboolean) {
      return _object.callBooleanMethod(method.methodId, args);
    } else if (method.returnType == _JavaPrimitive.jbyte) {
      return _object.callByteMethod(method.methodId, args);
    } else if (method.returnType == _JavaPrimitive.jchar) {
      return _object.callCharMethod(method.methodId, args);
    } else if (method.returnType == _JavaPrimitive.jshort) {
      return _object.callShortMethod(method.methodId, args);
    } else if (method.returnType == _JavaPrimitive.jint) {
      return _object.callIntMethod(method.methodId, args);
    } else if (method.returnType == _JavaPrimitive.jlong) {
      return _object.callLongMethod(method.methodId, args);
    } else if (method.returnType == _JavaPrimitive.jfloat) {
      return _object.callFloatMethod(method.methodId, args);
    } else if (method.returnType == _JavaPrimitive.jdouble) {
      return _object.callDoubleMethod(method.methodId, args);
    } else {
      return _javaObjectToDart(
          _object.callObjectMethod(method.methodId, args));
    }
  }

  if (invocation.isGetter) {
    _JavaField field = _clazz._fields[invocation.memberName];
    if (field == null)
      throw new JavaError('Field ${invocation.memberName} not found');

    if (field.type == _JavaPrimitive.jboolean) {
      return _object.getBooleanField(field.fieldId);
    } else if (field.type == _JavaPrimitive.jbyte) {
      return _object.getByteField(field.fieldId);
    } else if (field.type == _JavaPrimitive.jchar) {
      return _object.getCharField(field.fieldId);
    } else if (field.type == _JavaPrimitive.jshort) {
      return _object.getShortField(field.fieldId);
    } else if (field.type == _JavaPrimitive.jint) {
      return _object.getIntField(field.fieldId);
    } else if (field.type == _JavaPrimitive.jlong) {
      return _object.getLongField(field.fieldId);
    } else if (field.type == _JavaPrimitive.jfloat) {
      return _object.getFloatField(field.fieldId);
    } else if (field.type == _JavaPrimitive.jdouble) {
      return _object.getDoubleField(field.fieldId);
    } else {
      return _javaObjectToDart(_object.getObjectField(field.fieldId));
    }
  }

  if (invocation.isSetter) {
    _JavaField field = _clazz._fields[invocation.memberName];
    if (field == null)
      throw new JavaError('Field ${invocation.memberName} not found');

    dynamic value = invocation.positionalArguments[0];

    if (field.type == _JavaPrimitive.jboolean) {
      _object.setBooleanField(field.fieldId, value);
    } else if (field.type == _JavaPrimitive.jbyte) {
      _object.setByteField(field.fieldId, value);
    } else if (field.type == _JavaPrimitive.jchar) {
      _object.setCharField(field.fieldId, value);
    } else if (field.type == _JavaPrimitive.jshort) {
      _object.setShortField(field.fieldId, value);
    } else if (field.type == _JavaPrimitive.jint) {
      _object.setIntField(field.fieldId, value);
    } else if (field.type == _JavaPrimitive.jlong) {
      _object.setLongField(field.fieldId, value);
    } else if (field.type == _JavaPrimitive.jfloat) {
      _object.setFloatField(field.fieldId, value);
    } else if (field.type == _JavaPrimitive.jdouble) {
      _object.setDoubleField(field.fieldId, value);
    } else {
      _object.setObjectField(field.fieldId, _dartObjectToJava(value, field.type));
    }

    return null;
  }

  throw new JavaError('Unable to access ${invocation.memberName}');
}