Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/src/com/tns/ClassResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public static Class<?> resolveClass(String fullClassName, DexFactory dexFactory,

if (clazz == null)
{
clazz = Class.forName(className);
clazz = Platform.getClassForName(className);
}

return clazz;
Expand Down
2 changes: 1 addition & 1 deletion src/src/com/tns/DexFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ private File getDexFile(String className) throws InvalidClassException
classToProxyFile += "-" + this.dexThumb;
}

String dexFilePath = dexDir + classToProxyFile + ".dex";
String dexFilePath = dexDir + "/" + classToProxyFile + ".dex";
File dexFile = new File(dexFilePath);
if (dexFile.exists())
{
Expand Down
78 changes: 53 additions & 25 deletions src/src/com/tns/MethodResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,23 +108,27 @@ public static String getTypeSignature(Class<?> type)
return array + signature;
}

static String resolveMethodOverload(HashMap<String, Class<?>> classCache, String className, String methodName, Object[] args) throws ClassNotFoundException
static HashMap<Class<?>, MethodFinder> methodOverloadsForClass = new HashMap<Class<?>, MethodFinder>();
static ArrayList<Tuple<Method, Integer>> candidates = new ArrayList<Tuple<Method, Integer>>();

static String resolveMethodOverload(Class<?> clazz, String methodName, Object[] args) throws ClassNotFoundException
{
String methodSig = null;
Class<?> clazz = classCache.get(className);
if (clazz == null)
{
clazz = Class.forName(className);
}
candidates.clear();
int argLength = (args != null) ? args.length : 0;

ArrayList<Tuple<Method, Integer>> candidates = new ArrayList<Tuple<Method, Integer>>();

Class<?> c = clazz;
int iterationIndex = 0;
while (c != null)
{
tryFindMatches(methodName, candidates, args, argLength, c.getDeclaredMethods());
MethodFinder finder = methodOverloadsForClass.get(c);
if (finder == null)
{
finder = new MethodFinder(c);
methodOverloadsForClass.put(c, finder);
}

ArrayList<Method> matchingMethods = finder.getMatchingMethods(methodName);
tryFindMatches(methodName, candidates, args, argLength, matchingMethods);
if (candidates.size() > iterationIndex && candidates.get(iterationIndex).y == 0)
{
// direct matching (distance 0) found
Expand All @@ -139,28 +143,18 @@ static String resolveMethodOverload(HashMap<String, Class<?>> classCache, String
{
if (candidates.size() > 1)
Collections.sort(candidates, distanceComparator);

Method method = candidates.get(0).x;
methodSig = getMethodSignature(method.getReturnType(), method.getParameterTypes());
return getMethodSignature(method.getReturnType(), method.getParameterTypes());
}

return methodSig;
return null;
}

static void tryFindMatches(String methodName, ArrayList<Tuple<Method, Integer>> candidates, Object[] args, int argLength, Method[] methods)
static void tryFindMatches(String methodName, ArrayList<Tuple<Method, Integer>> candidates, Object[] args, int argLength, ArrayList<Method> methods)
{
for (Method method : methods)
{
if (!method.getName().equals(methodName))
{
continue;
}

int modifiers = method.getModifiers();
if (!Modifier.isPublic(modifiers) && !Modifier.isProtected(modifiers))
{
continue;
}

Class<?>[] params = method.getParameterTypes();

boolean success = false;
Expand Down Expand Up @@ -620,4 +614,38 @@ else if (primitiveType.equals(boolean.class))

return success;
}
}

static class MethodFinder {
private Method[] declaredMethods;
private HashMap<String, ArrayList<Method>> matchingMethods = new HashMap<String, ArrayList<Method>>();
public MethodFinder(Class<?> clazz) {
this.declaredMethods = clazz.getDeclaredMethods();
}

public ArrayList<Method> getMatchingMethods(String methodName) {
ArrayList<Method> matches = this.matchingMethods.get(methodName);
if (matches == null) {
matches = new ArrayList<Method>();
for (Method method : this.declaredMethods)
{
if (!method.getName().equals(methodName))
{
continue;
}

int modifiers = method.getModifiers();
if (!Modifier.isPublic(modifiers) && !Modifier.isProtected(modifiers))
{
continue;
}

matches.add(method);
}

matchingMethods.put(methodName, matches);
}

return matches;
}
}
}
21 changes: 19 additions & 2 deletions src/src/com/tns/Platform.java
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,7 @@ private static String[] getTypeMetadata(String className, int index) throws Clas
if (clazz == null)
{
clazz = Class.forName(className);
classCache.put(className, clazz);
}
}

Expand Down Expand Up @@ -750,13 +751,29 @@ static Object[] packageArgs(Object... args)

return packagedArgs;
}

static Class<?> getClassForName(String className) throws ClassNotFoundException {
Class<?> clazz = classCache.get(className);
if (clazz == null)
{
clazz = Class.forName(className);
if (clazz != null) {
classCache.put(className, clazz);
}
}

return clazz;
}

@RuntimeCallable
private static String resolveMethodOverload(String className, String methodName, Object[] args) throws Exception
{
if (logger.isEnabled())
logger.write("resolveMethodOverload: Resolving method " + methodName + " on class " + className);
String res = MethodResolver.resolveMethodOverload(classCache, className, methodName, args);

Class<?> clazz = getClassForName(className);

String res = MethodResolver.resolveMethodOverload(clazz, methodName, args);
if (logger.isEnabled())
logger.write("resolveMethodOverload: method found :" + res);
if (res == null)
Expand Down Expand Up @@ -902,7 +919,7 @@ public static void purgeAllProxies()
@RuntimeCallable
private static Object createArrayHelper(String arrayClassName, int size) throws ClassNotFoundException
{
Class<?> clazz = Class.forName(arrayClassName);
Class<?> clazz = getClassForName(arrayClassName);

Object arr = Array.newInstance(clazz, size);

Expand Down