Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

74
LINES

< > TinyBrain | #1000630 - call function(s) for reflective calls (e.g. to hotwired objects) - TODO: cache

JavaX fragment (include)

static Object call(Object o) {
  return callFunction(o);
}

// varargs assignment fixer for a single string array argument
static Object call(Object o, String method, String[] arg) {
  return call(o, method, new Object[] {arg});
}

static Object call(Object o, String method, Object... args) ctex {
  if (o == null) null;
  if (o instanceof Class) {
    Method m = call_findStaticMethod((Class) o, method, args, false);
    m.setAccessible(true);
    return invokeMethod(m, null, args);
  /*} else if (o instanceof DynamicMethods) {
    ret ((DynamicMethods) o)._dynCall(method, args);*/
  } else {
    Method m = call_findMethod(o, method, args, false);
    m.setAccessible(true);
    return invokeMethod(m, o, args);
  }
}

static Method call_findStaticMethod(Class c, String method, Object[] args, boolean debug) {
  Class _c = c;
  while (c != null) {
    for (Method m : c.getDeclaredMethods()) {
      if (debug)
        System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");;
      if (!m.getName().equals(method)) {
        if (debug) System.out.println("Method name mismatch: " + method);
        continue;
      }

      if ((m.getModifiers() & java.lang.reflect.Modifier.STATIC) == 0 || !call_checkArgs(m, args, debug))
        continue;

      return m;
    }
    c = c.getSuperclass();
  }
  throw new RuntimeException("Method '" + method + "' (static) with " + args.length + " parameter(s) not found in " + _c.getName());
}

static Method call_findMethod(Object o, String method, Object[] args, boolean debug) {
  Class c = o.getClass();
  while (c != null) {
    for (Method m : c.getDeclaredMethods()) {
      if (debug)
        System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");;
      if (m.getName().equals(method) && call_checkArgs(m, args, debug))
        return m;
    }
    c = c.getSuperclass();
  }
  throw new RuntimeException("Method '" + method + "' (non-static) with " + args.length + " parameter(s) not found in " + o.getClass().getName());
}

static bool call_checkArgs(Method m, Object[] args, boolean debug) {
  Class<?>[] types = m.getParameterTypes();
  if (types.length != args.length) {
    if (debug)
      System.out.println("Bad parameter length: " + args.length + " vs " + types.length);
    return false;
  }
  for (int i = 0; i < types.length; i++)
    if (!(args[i] == null || isInstanceX(types[i], args[i]))) {
      if (debug)
        System.out.println("Bad parameter " + i + ": " + args[i] + " vs " + types[i]);
      return false;
    }
  return true;
}

Author comment

Began life as a copy of #2000497

Now safer

download  show line numbers  debug dex   

Travelled to 6 computer(s): cfunsshuasjs, ddnzoavkxhuk, gwrvuhgaqvyk, mqqgnosmbjvj, onxytkatvevr, tvejysmllsmz

Comments [hide]

ID Author/Program Comment Date
797 #1000604 (pitcher) 2015-08-20 15:28:24

add comment

Snippet ID: #1000630
Snippet name: call function(s) for reflective calls (e.g. to hotwired objects) - TODO: cache
Eternal ID of this version: #1000630/12
Text MD5: c2417630a0e2a025f98cac5f2e12b396
Author: stefan
Category:
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2018-06-21 23:31:16
Source code size: 2693 bytes / 74 lines
Pitched / IR pitched: No / No
Views / Downloads: 427 / 9759
Version history: 11 change(s)
Referenced in: [show]