am cc5e69e4: Inject anonymous inner classes of injected classes [DO NOT MERGE]

* commit 'cc5e69e4fed8bb797dc3f83c1de32eaf4a52f324':
  Inject anonymous inner classes of injected classes [DO NOT MERGE]
This commit is contained in:
Deepanshu Gupta
2015-08-26 05:55:02 +00:00
committed by Android Git Automerger
4 changed files with 32 additions and 11 deletions

View File

@@ -24,9 +24,11 @@ import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.ListIterator;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
@@ -86,7 +88,23 @@ public class AsmGenerator {
public AsmGenerator(Log log, String osDestJar, ICreateInfo createInfo) { public AsmGenerator(Log log, String osDestJar, ICreateInfo createInfo) {
mLog = log; mLog = log;
mOsDestJar = osDestJar; mOsDestJar = osDestJar;
mInjectClasses = createInfo.getInjectedClasses(); ArrayList<Class<?>> injectedClasses =
new ArrayList<Class<?>>(Arrays.asList(createInfo.getInjectedClasses()));
// Search for and add anonymous inner classes also.
ListIterator<Class<?>> iter = injectedClasses.listIterator();
while (iter.hasNext()) {
Class<?> clazz = iter.next();
try {
int i = 1;
while(i < 100) {
iter.add(Class.forName(clazz.getName() + "$" + i));
i++;
}
} catch (ClassNotFoundException ignored) {
// Expected.
}
}
mInjectClasses = injectedClasses.toArray(new Class<?>[0]);
mStubMethods = new HashSet<String>(Arrays.asList(createInfo.getOverriddenMethods())); mStubMethods = new HashSet<String>(Arrays.asList(createInfo.getOverriddenMethods()));
// Create the map/set of methods to change to delegates // Create the map/set of methods to change to delegates
@@ -290,13 +308,7 @@ public class AsmGenerator {
* e.g. it returns something like "com/foo/OuterClass$InnerClass1$InnerClass2.class" * e.g. it returns something like "com/foo/OuterClass$InnerClass1$InnerClass2.class"
*/ */
private String classToEntryPath(Class<?> clazz) { private String classToEntryPath(Class<?> clazz) {
String name = ""; return classNameToEntryPath(clazz.getName());
Class<?> parent;
while ((parent = clazz.getEnclosingClass()) != null) {
name = "$" + clazz.getSimpleName() + name;
clazz = parent;
}
return classNameToEntryPath(clazz.getCanonicalName() + name);
} }
/** /**

View File

@@ -136,6 +136,8 @@ public final class CreateInfo implements ICreateInfo {
ICreateInfo.class, ICreateInfo.class,
CreateInfo.class, CreateInfo.class,
LayoutlibDelegate.class, LayoutlibDelegate.class,
InjectMethodRunnable.class,
InjectMethodRunnables.class,
/* Java package classes */ /* Java package classes */
AutoCloseable.class, AutoCloseable.class,
Objects.class, Objects.class,
@@ -304,4 +306,3 @@ public final class CreateInfo implements ICreateInfo {
InjectMethodRunnables.CONTEXT_GET_FRAMEWORK_CLASS_LOADER); InjectMethodRunnables.CONTEXT_GET_FRAMEWORK_CLASS_LOADER);
}}; }};
} }

View File

@@ -85,6 +85,12 @@ public interface ICreateInfo {
Map<String, InjectMethodRunnable> getInjectedMethodsMap(); Map<String, InjectMethodRunnable> getInjectedMethodsMap();
abstract class InjectMethodRunnable { abstract class InjectMethodRunnable {
public abstract void generateMethods(ClassVisitor cv); /**
* @param cv Must be {@link ClassVisitor}. However, the param type is object so that when
* loading the class, ClassVisitor is not loaded. This is because when injecting
* CreateInfo in LayoutLib (see {@link #getInjectedClasses()}, we don't want to inject
* asm classes also, but still keep CreateInfo loadable.
*/
public abstract void generateMethods(Object cv);
} }
} }

View File

@@ -30,7 +30,9 @@ public class InjectMethodRunnables {
public static final ICreateInfo.InjectMethodRunnable CONTEXT_GET_FRAMEWORK_CLASS_LOADER public static final ICreateInfo.InjectMethodRunnable CONTEXT_GET_FRAMEWORK_CLASS_LOADER
= new InjectMethodRunnable() { = new InjectMethodRunnable() {
@Override @Override
public void generateMethods(ClassVisitor cv) { public void generateMethods(Object classVisitor) {
assert classVisitor instanceof ClassVisitor;
ClassVisitor cv = (ClassVisitor) classVisitor;
// generated by compiling the class: // generated by compiling the class:
// class foo { public ClassLoader getFrameworkClassLoader() { return getClass().getClassLoader(); } } // class foo { public ClassLoader getFrameworkClassLoader() { return getClass().getClassLoader(); } }
// and then running ASMifier on it: // and then running ASMifier on it: