Merge "Java 8 in layoutlib-create"

This commit is contained in:
Brian Carlstrom
2016-02-10 03:29:28 +00:00
committed by Gerrit Code Review
26 changed files with 189 additions and 192 deletions

View File

@@ -21,7 +21,5 @@
<processorPath useClasspath="true" /> <processorPath useClasspath="true" />
</profile> </profile>
</annotationProcessing> </annotationProcessing>
<bytecodeTargetLevel target="1.6" />
</component> </component>
</project> </project>

View File

@@ -20,7 +20,7 @@ LOCAL_SRC_FILES := $(call all-java-files-under,src)
LOCAL_JAR_MANIFEST := manifest.txt LOCAL_JAR_MANIFEST := manifest.txt
LOCAL_STATIC_JAVA_LIBRARIES := \ LOCAL_STATIC_JAVA_LIBRARIES := \
asm-4.0 asm-5.0
LOCAL_MODULE := layoutlib_create LOCAL_MODULE := layoutlib_create

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4"> <module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true"> <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="true">
<exclude-output /> <exclude-output />
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
@@ -9,12 +9,12 @@
<sourceFolder url="file://$MODULE_DIR$/tests/mock_data" type="java-test-resource" /> <sourceFolder url="file://$MODULE_DIR$/tests/mock_data" type="java-test-resource" />
<excludeFolder url="file://$MODULE_DIR$/.settings" /> <excludeFolder url="file://$MODULE_DIR$/.settings" />
</content> </content>
<orderEntry type="inheritedJdk" /> <orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module-library"> <orderEntry type="module-library">
<library name="asm-4.0"> <library name="asm-5.0">
<CLASSES> <CLASSES>
<root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/asm/asm-4.0.jar!/" /> <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/asm/asm-5.0.jar!/" />
</CLASSES> </CLASSES>
<JAVADOC /> <JAVADOC />
<SOURCES> <SOURCES>

View File

@@ -21,7 +21,6 @@ import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor; import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Label; import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
import org.objectweb.asm.signature.SignatureReader; import org.objectweb.asm.signature.SignatureReader;
import org.objectweb.asm.signature.SignatureVisitor; import org.objectweb.asm.signature.SignatureVisitor;
@@ -44,7 +43,7 @@ public abstract class AbstractClassAdapter extends ClassVisitor {
abstract String renameInternalType(String name); abstract String renameInternalType(String name);
public AbstractClassAdapter(ClassVisitor cv) { public AbstractClassAdapter(ClassVisitor cv) {
super(Opcodes.ASM4, cv); super(Main.ASM_VERSION, cv);
} }
/** /**
@@ -239,7 +238,7 @@ public abstract class AbstractClassAdapter extends ClassVisitor {
* The names must be full qualified internal ASM names (e.g. com/blah/MyClass$InnerClass). * The names must be full qualified internal ASM names (e.g. com/blah/MyClass$InnerClass).
*/ */
public RenameMethodAdapter(MethodVisitor mv) { public RenameMethodAdapter(MethodVisitor mv) {
super(Opcodes.ASM4, mv); super(Main.ASM_VERSION, mv);
} }
@Override @Override
@@ -276,7 +275,8 @@ public abstract class AbstractClassAdapter extends ClassVisitor {
} }
@Override @Override
public void visitMethodInsn(int opcode, String owner, String name, String desc) { public void visitMethodInsn(int opcode, String owner, String name, String desc,
boolean itf) {
// The owner sometimes turns out to be a type descriptor. We try to detect it and fix. // The owner sometimes turns out to be a type descriptor. We try to detect it and fix.
if (owner.indexOf(';') > 0) { if (owner.indexOf(';') > 0) {
owner = renameTypeDesc(owner); owner = renameTypeDesc(owner);
@@ -285,7 +285,7 @@ public abstract class AbstractClassAdapter extends ClassVisitor {
} }
desc = renameMethodDesc(desc); desc = renameMethodDesc(desc);
super.visitMethodInsn(opcode, owner, name, desc); super.visitMethodInsn(opcode, owner, name, desc, itf);
} }
@Override @Override
@@ -330,7 +330,7 @@ public abstract class AbstractClassAdapter extends ClassVisitor {
private final SignatureVisitor mSv; private final SignatureVisitor mSv;
public RenameSignatureAdapter(SignatureVisitor sv) { public RenameSignatureAdapter(SignatureVisitor sv) {
super(Opcodes.ASM4); super(Main.ASM_VERSION);
mSv = sv; mSv = sv;
} }

View File

@@ -23,7 +23,6 @@ import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor; import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Label; import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
import org.objectweb.asm.signature.SignatureReader; import org.objectweb.asm.signature.SignatureReader;
import org.objectweb.asm.signature.SignatureVisitor; import org.objectweb.asm.signature.SignatureVisitor;
@@ -65,7 +64,7 @@ public class AsmAnalyzer {
/** Glob patterns of files to keep as is. */ /** Glob patterns of files to keep as is. */
private final String[] mIncludeFileGlobs; private final String[] mIncludeFileGlobs;
/** Internal names of classes that contain method calls that need to be rewritten. */ /** Internal names of classes that contain method calls that need to be rewritten. */
private final Set<String> mReplaceMethodCallClasses = new HashSet<String>(); private final Set<String> mReplaceMethodCallClasses = new HashSet<>();
/** /**
* Creates a new analyzer. * Creates a new analyzer.
@@ -97,8 +96,8 @@ public class AsmAnalyzer {
*/ */
public void analyze() throws IOException, LogAbortException { public void analyze() throws IOException, LogAbortException {
TreeMap<String, ClassReader> zipClasses = new TreeMap<String, ClassReader>(); TreeMap<String, ClassReader> zipClasses = new TreeMap<>();
Map<String, InputStream> filesFound = new TreeMap<String, InputStream>(); Map<String, InputStream> filesFound = new TreeMap<>();
parseZip(mOsSourceJar, zipClasses, filesFound); parseZip(mOsSourceJar, zipClasses, filesFound);
mLog.info("Found %d classes in input JAR%s.", zipClasses.size(), mLog.info("Found %d classes in input JAR%s.", zipClasses.size(),
@@ -189,7 +188,7 @@ public class AsmAnalyzer {
*/ */
Map<String, ClassReader> findIncludes(Map<String, ClassReader> zipClasses) Map<String, ClassReader> findIncludes(Map<String, ClassReader> zipClasses)
throws LogAbortException { throws LogAbortException {
TreeMap<String, ClassReader> found = new TreeMap<String, ClassReader>(); TreeMap<String, ClassReader> found = new TreeMap<>();
mLog.debug("Find classes to include."); mLog.debug("Find classes to include.");
@@ -318,10 +317,10 @@ public class AsmAnalyzer {
Map<String, ClassReader> findDeps(Map<String, ClassReader> zipClasses, Map<String, ClassReader> findDeps(Map<String, ClassReader> zipClasses,
Map<String, ClassReader> inOutKeepClasses) { Map<String, ClassReader> inOutKeepClasses) {
TreeMap<String, ClassReader> deps = new TreeMap<String, ClassReader>(); TreeMap<String, ClassReader> deps = new TreeMap<>();
TreeMap<String, ClassReader> new_deps = new TreeMap<String, ClassReader>(); TreeMap<String, ClassReader> new_deps = new TreeMap<>();
TreeMap<String, ClassReader> new_keep = new TreeMap<String, ClassReader>(); TreeMap<String, ClassReader> new_keep = new TreeMap<>();
TreeMap<String, ClassReader> temp = new TreeMap<String, ClassReader>(); TreeMap<String, ClassReader> temp = new TreeMap<>();
DependencyVisitor visitor = getVisitor(zipClasses, DependencyVisitor visitor = getVisitor(zipClasses,
inOutKeepClasses, new_keep, inOutKeepClasses, new_keep,
@@ -399,7 +398,7 @@ public class AsmAnalyzer {
Map<String, ClassReader> outKeep, Map<String, ClassReader> outKeep,
Map<String,ClassReader> inDeps, Map<String,ClassReader> inDeps,
Map<String,ClassReader> outDeps) { Map<String,ClassReader> outDeps) {
super(Opcodes.ASM4); super(Main.ASM_VERSION);
mZipClasses = zipClasses; mZipClasses = zipClasses;
mInKeep = inKeep; mInKeep = inKeep;
mOutKeep = outKeep; mOutKeep = outKeep;
@@ -557,7 +556,7 @@ public class AsmAnalyzer {
private class MyFieldVisitor extends FieldVisitor { private class MyFieldVisitor extends FieldVisitor {
public MyFieldVisitor() { public MyFieldVisitor() {
super(Opcodes.ASM4); super(Main.ASM_VERSION);
} }
@Override @Override
@@ -630,7 +629,7 @@ public class AsmAnalyzer {
private String mOwnerClass; private String mOwnerClass;
public MyMethodVisitor(String ownerClass) { public MyMethodVisitor(String ownerClass) {
super(Opcodes.ASM4); super(Main.ASM_VERSION);
mOwnerClass = ownerClass; mOwnerClass = ownerClass;
} }
@@ -719,7 +718,8 @@ public class AsmAnalyzer {
// instruction that invokes a method // instruction that invokes a method
@Override @Override
public void visitMethodInsn(int opcode, String owner, String name, String desc) { public void visitMethodInsn(int opcode, String owner, String name, String desc,
boolean itf) {
// owner is the internal name of the method's owner class // owner is the internal name of the method's owner class
considerName(owner); considerName(owner);
@@ -779,7 +779,7 @@ public class AsmAnalyzer {
private class MySignatureVisitor extends SignatureVisitor { private class MySignatureVisitor extends SignatureVisitor {
public MySignatureVisitor() { public MySignatureVisitor() {
super(Opcodes.ASM4); super(Main.ASM_VERSION);
} }
// --------------------------------------------------- // ---------------------------------------------------
@@ -878,7 +878,7 @@ public class AsmAnalyzer {
private class MyAnnotationVisitor extends AnnotationVisitor { private class MyAnnotationVisitor extends AnnotationVisitor {
public MyAnnotationVisitor() { public MyAnnotationVisitor() {
super(Opcodes.ASM4); super(Main.ASM_VERSION);
} }
// Visits a primitive value of an annotation // Visits a primitive value of an annotation

View File

@@ -91,7 +91,7 @@ public class AsmGenerator {
mLog = log; mLog = log;
mOsDestJar = osDestJar; mOsDestJar = osDestJar;
ArrayList<Class<?>> injectedClasses = ArrayList<Class<?>> injectedClasses =
new ArrayList<Class<?>>(Arrays.asList(createInfo.getInjectedClasses())); new ArrayList<>(Arrays.asList(createInfo.getInjectedClasses()));
// Search for and add anonymous inner classes also. // Search for and add anonymous inner classes also.
ListIterator<Class<?>> iter = injectedClasses.listIterator(); ListIterator<Class<?>> iter = injectedClasses.listIterator();
while (iter.hasNext()) { while (iter.hasNext()) {
@@ -107,25 +107,25 @@ public class AsmGenerator {
} }
} }
mInjectClasses = injectedClasses.toArray(new Class<?>[0]); mInjectClasses = injectedClasses.toArray(new Class<?>[0]);
mStubMethods = new HashSet<String>(Arrays.asList(createInfo.getOverriddenMethods())); mStubMethods = new HashSet<>(Arrays.asList(createInfo.getOverriddenMethods()));
// Create the map/set of methods to change to delegates // Create the map/set of methods to change to delegates
mDelegateMethods = new HashMap<String, Set<String>>(); mDelegateMethods = new HashMap<>();
addToMap(createInfo.getDelegateMethods(), mDelegateMethods); addToMap(createInfo.getDelegateMethods(), mDelegateMethods);
for (String className : createInfo.getDelegateClassNatives()) { for (String className : createInfo.getDelegateClassNatives()) {
className = binaryToInternalClassName(className); className = binaryToInternalClassName(className);
Set<String> methods = mDelegateMethods.get(className); Set<String> methods = mDelegateMethods.get(className);
if (methods == null) { if (methods == null) {
methods = new HashSet<String>(); methods = new HashSet<>();
mDelegateMethods.put(className, methods); mDelegateMethods.put(className, methods);
} }
methods.add(DelegateClassAdapter.ALL_NATIVES); methods.add(DelegateClassAdapter.ALL_NATIVES);
} }
// Create the map of classes to rename. // Create the map of classes to rename.
mRenameClasses = new HashMap<String, String>(); mRenameClasses = new HashMap<>();
mClassesNotRenamed = new HashSet<String>(); mClassesNotRenamed = new HashSet<>();
String[] renameClasses = createInfo.getRenamedClasses(); String[] renameClasses = createInfo.getRenamedClasses();
int n = renameClasses.length; int n = renameClasses.length;
for (int i = 0; i < n; i += 2) { for (int i = 0; i < n; i += 2) {
@@ -138,7 +138,7 @@ public class AsmGenerator {
} }
// Create a map of classes to be refactored. // Create a map of classes to be refactored.
mRefactorClasses = new HashMap<String, String>(); mRefactorClasses = new HashMap<>();
String[] refactorClasses = createInfo.getJavaPkgClasses(); String[] refactorClasses = createInfo.getJavaPkgClasses();
n = refactorClasses.length; n = refactorClasses.length;
for (int i = 0; i < n; i += 2) { for (int i = 0; i < n; i += 2) {
@@ -149,7 +149,7 @@ public class AsmGenerator {
} }
// create the map of renamed class -> return type of method to delete. // create the map of renamed class -> return type of method to delete.
mDeleteReturns = new HashMap<String, Set<String>>(); mDeleteReturns = new HashMap<>();
String[] deleteReturns = createInfo.getDeleteReturns(); String[] deleteReturns = createInfo.getDeleteReturns();
Set<String> returnTypes = null; Set<String> returnTypes = null;
String renamedClass = null; String renamedClass = null;
@@ -172,12 +172,12 @@ public class AsmGenerator {
// just a standard return type, we add it to the list. // just a standard return type, we add it to the list.
if (returnTypes == null) { if (returnTypes == null) {
returnTypes = new HashSet<String>(); returnTypes = new HashSet<>();
} }
returnTypes.add(binaryToInternalClassName(className)); returnTypes.add(binaryToInternalClassName(className));
} }
mPromotedFields = new HashMap<String, Set<String>>(); mPromotedFields = new HashMap<>();
addToMap(createInfo.getPromotedFields(), mPromotedFields); addToMap(createInfo.getPromotedFields(), mPromotedFields);
mInjectedMethodsMap = createInfo.getInjectedMethodsMap(); mInjectedMethodsMap = createInfo.getInjectedMethodsMap();
@@ -197,7 +197,7 @@ public class AsmGenerator {
String methodOrFieldName = entry.substring(pos + 1); String methodOrFieldName = entry.substring(pos + 1);
Set<String> set = map.get(className); Set<String> set = map.get(className);
if (set == null) { if (set == null) {
set = new HashSet<String>(); set = new HashSet<>();
map.put(className, set); map.put(className, set);
} }
set.add(methodOrFieldName); set.add(methodOrFieldName);
@@ -247,7 +247,7 @@ public class AsmGenerator {
/** Generates the final JAR */ /** Generates the final JAR */
public void generate() throws IOException { public void generate() throws IOException {
TreeMap<String, byte[]> all = new TreeMap<String, byte[]>(); TreeMap<String, byte[]> all = new TreeMap<>();
for (Class<?> clazz : mInjectClasses) { for (Class<?> clazz : mInjectClasses) {
String name = classToEntryPath(clazz); String name = classToEntryPath(clazz);
@@ -314,7 +314,7 @@ public class AsmGenerator {
* e.g. for the input "android.view.View" it returns "android/view/View.class" * e.g. for the input "android.view.View" it returns "android/view/View.class"
*/ */
String classNameToEntryPath(String className) { String classNameToEntryPath(String className) {
return className.replaceAll("\\.", "/").concat(".class"); return className.replace('.', '/').concat(".class");
} }
/** /**

View File

@@ -31,7 +31,7 @@ import org.objectweb.asm.Opcodes;
*/ */
public class ClassHasNativeVisitor extends ClassVisitor { public class ClassHasNativeVisitor extends ClassVisitor {
public ClassHasNativeVisitor() { public ClassHasNativeVisitor() {
super(Opcodes.ASM4); super(Main.ASM_VERSION);
} }
private boolean mHasNativeMethods = false; private boolean mHasNativeMethods = false;

View File

@@ -111,7 +111,7 @@ public final class CreateInfo implements ICreateInfo {
public Set<String> getExcludedClasses() { public Set<String> getExcludedClasses() {
String[] refactoredClasses = getJavaPkgClasses(); String[] refactoredClasses = getJavaPkgClasses();
int count = refactoredClasses.length / 2 + EXCLUDED_CLASSES.length; int count = refactoredClasses.length / 2 + EXCLUDED_CLASSES.length;
Set<String> excludedClasses = new HashSet<String>(count); Set<String> excludedClasses = new HashSet<>(count);
for (int i = 0; i < refactoredClasses.length; i+=2) { for (int i = 0; i < refactoredClasses.length; i+=2) {
excludedClasses.add(refactoredClasses[i]); excludedClasses.add(refactoredClasses[i]);
} }

View File

@@ -58,7 +58,7 @@ public class DelegateClassAdapter extends ClassVisitor {
ClassVisitor cv, ClassVisitor cv,
String className, String className,
Set<String> delegateMethods) { Set<String> delegateMethods) {
super(Opcodes.ASM4, cv); super(Main.ASM_VERSION, cv);
mLog = log; mLog = log;
mClassName = className; mClassName = className;
mDelegateMethods = delegateMethods; mDelegateMethods = delegateMethods;

View File

@@ -121,7 +121,7 @@ class DelegateMethodAdapter extends MethodVisitor {
String methodName, String methodName,
String desc, String desc,
boolean isStatic) { boolean isStatic) {
super(Opcodes.ASM4); super(Main.ASM_VERSION);
mLog = log; mLog = log;
mOrgWriter = mvOriginal; mOrgWriter = mvOriginal;
mDelWriter = mvDelegate; mDelWriter = mvDelegate;
@@ -184,7 +184,7 @@ class DelegateMethodAdapter extends MethodVisitor {
mDelWriter.visitLineNumber((Integer) p[0], (Label) p[1]); mDelWriter.visitLineNumber((Integer) p[0], (Label) p[1]);
} }
ArrayList<Type> paramTypes = new ArrayList<Type>(); ArrayList<Type> paramTypes = new ArrayList<>();
String delegateClassName = mClassName + DELEGATE_SUFFIX; String delegateClassName = mClassName + DELEGATE_SUFFIX;
boolean pushedArg0 = false; boolean pushedArg0 = false;
int maxStack = 0; int maxStack = 0;
@@ -249,7 +249,8 @@ class DelegateMethodAdapter extends MethodVisitor {
mDelWriter.visitMethodInsn(Opcodes.INVOKESTATIC, mDelWriter.visitMethodInsn(Opcodes.INVOKESTATIC,
delegateClassName, delegateClassName,
mMethodName, mMethodName,
desc); desc,
false);
Type returnType = Type.getReturnType(mDesc); Type returnType = Type.getReturnType(mDesc);
mDelWriter.visitInsn(returnType.getOpcode(Opcodes.IRETURN)); mDelWriter.visitInsn(returnType.getOpcode(Opcodes.IRETURN));
@@ -367,9 +368,9 @@ class DelegateMethodAdapter extends MethodVisitor {
} }
@Override @Override
public void visitMethodInsn(int opcode, String owner, String name, String desc) { public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
if (mOrgWriter != null) { if (mOrgWriter != null) {
mOrgWriter.visitMethodInsn(opcode, owner, name, desc); mOrgWriter.visitMethodInsn(opcode, owner, name, desc, itf);
} }
} }

View File

@@ -26,7 +26,6 @@ import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor; import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Label; import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
import org.objectweb.asm.signature.SignatureReader; import org.objectweb.asm.signature.SignatureReader;
import org.objectweb.asm.signature.SignatureVisitor; import org.objectweb.asm.signature.SignatureVisitor;
@@ -82,7 +81,7 @@ public class DependencyFinder {
Map<String, Set<String>> missing = findMissingClasses(deps, zipClasses.keySet()); Map<String, Set<String>> missing = findMissingClasses(deps, zipClasses.keySet());
List<Map<String, Set<String>>> result = new ArrayList<Map<String,Set<String>>>(2); List<Map<String, Set<String>>> result = new ArrayList<>(2);
result.add(deps); result.add(deps);
result.add(missing); result.add(missing);
return result; return result;
@@ -151,7 +150,7 @@ public class DependencyFinder {
* class name => ASM ClassReader. Class names are in the form "android.view.View". * class name => ASM ClassReader. Class names are in the form "android.view.View".
*/ */
Map<String,ClassReader> parseZip(List<String> jarPathList) throws IOException { Map<String,ClassReader> parseZip(List<String> jarPathList) throws IOException {
TreeMap<String, ClassReader> classes = new TreeMap<String, ClassReader>(); TreeMap<String, ClassReader> classes = new TreeMap<>();
for (String jarPath : jarPathList) { for (String jarPath : jarPathList) {
ZipFile zip = new ZipFile(jarPath); ZipFile zip = new ZipFile(jarPath);
@@ -202,7 +201,7 @@ public class DependencyFinder {
// The dependencies that we'll collect. // The dependencies that we'll collect.
// It's a map Class name => uses class names. // It's a map Class name => uses class names.
Map<String, Set<String>> dependencyMap = new TreeMap<String, Set<String>>(); Map<String, Set<String>> dependencyMap = new TreeMap<>();
DependencyVisitor visitor = getVisitor(); DependencyVisitor visitor = getVisitor();
@@ -211,7 +210,7 @@ public class DependencyFinder {
for (Entry<String, ClassReader> entry : zipClasses.entrySet()) { for (Entry<String, ClassReader> entry : zipClasses.entrySet()) {
String name = entry.getKey(); String name = entry.getKey();
TreeSet<String> set = new TreeSet<String>(); TreeSet<String> set = new TreeSet<>();
dependencyMap.put(name, set); dependencyMap.put(name, set);
visitor.setDependencySet(set); visitor.setDependencySet(set);
@@ -240,7 +239,7 @@ public class DependencyFinder {
private Map<String, Set<String>> findMissingClasses( private Map<String, Set<String>> findMissingClasses(
Map<String, Set<String>> deps, Map<String, Set<String>> deps,
Set<String> zipClasses) { Set<String> zipClasses) {
Map<String, Set<String>> missing = new TreeMap<String, Set<String>>(); Map<String, Set<String>> missing = new TreeMap<>();
for (Entry<String, Set<String>> entry : deps.entrySet()) { for (Entry<String, Set<String>> entry : deps.entrySet()) {
String name = entry.getKey(); String name = entry.getKey();
@@ -250,7 +249,7 @@ public class DependencyFinder {
// This dependency doesn't exist in the zip classes. // This dependency doesn't exist in the zip classes.
Set<String> set = missing.get(dep); Set<String> set = missing.get(dep);
if (set == null) { if (set == null) {
set = new TreeSet<String>(); set = new TreeSet<>();
missing.put(dep, set); missing.put(dep, set);
} }
set.add(name); set.add(name);
@@ -284,7 +283,7 @@ public class DependencyFinder {
* Creates a new visitor that will find all the dependencies for the visited class. * Creates a new visitor that will find all the dependencies for the visited class.
*/ */
public DependencyVisitor() { public DependencyVisitor() {
super(Opcodes.ASM4); super(Main.ASM_VERSION);
} }
/** /**
@@ -435,7 +434,7 @@ public class DependencyFinder {
private class MyFieldVisitor extends FieldVisitor { private class MyFieldVisitor extends FieldVisitor {
public MyFieldVisitor() { public MyFieldVisitor() {
super(Opcodes.ASM4); super(Main.ASM_VERSION);
} }
@Override @Override
@@ -510,7 +509,7 @@ public class DependencyFinder {
private class MyMethodVisitor extends MethodVisitor { private class MyMethodVisitor extends MethodVisitor {
public MyMethodVisitor() { public MyMethodVisitor() {
super(Opcodes.ASM4); super(Main.ASM_VERSION);
} }
@@ -598,7 +597,8 @@ public class DependencyFinder {
// instruction that invokes a method // instruction that invokes a method
@Override @Override
public void visitMethodInsn(int opcode, String owner, String name, String desc) { public void visitMethodInsn(int opcode, String owner, String name, String desc,
boolean itf) {
// owner is the internal name of the method's owner class // owner is the internal name of the method's owner class
if (!considerDesc(owner) && owner.indexOf('/') != -1) { if (!considerDesc(owner) && owner.indexOf('/') != -1) {
@@ -654,7 +654,7 @@ public class DependencyFinder {
private class MySignatureVisitor extends SignatureVisitor { private class MySignatureVisitor extends SignatureVisitor {
public MySignatureVisitor() { public MySignatureVisitor() {
super(Opcodes.ASM4); super(Main.ASM_VERSION);
} }
// --------------------------------------------------- // ---------------------------------------------------
@@ -753,7 +753,7 @@ public class DependencyFinder {
private class MyAnnotationVisitor extends AnnotationVisitor { private class MyAnnotationVisitor extends AnnotationVisitor {
public MyAnnotationVisitor() { public MyAnnotationVisitor() {
super(Opcodes.ASM4); super(Main.ASM_VERSION);
} }
// Visits a primitive value of an annotation // Visits a primitive value of an annotation

View File

@@ -42,9 +42,9 @@ public class InjectMethodRunnables {
mv.visitCode(); mv.visitCode();
mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass",
"()Ljava/lang/Class;"); "()Ljava/lang/Class;", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getClassLoader", mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getClassLoader",
"()Ljava/lang/ClassLoader;"); "()Ljava/lang/ClassLoader;", false);
mv.visitInsn(ARETURN); mv.visitInsn(ARETURN);
mv.visitMaxs(1, 1); mv.visitMaxs(1, 1);
mv.visitEnd(); mv.visitEnd();

View File

@@ -19,7 +19,6 @@ package com.android.tools.layoutlib.create;
import com.android.tools.layoutlib.create.ICreateInfo.InjectMethodRunnable; import com.android.tools.layoutlib.create.ICreateInfo.InjectMethodRunnable;
import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Opcodes;
/** /**
* Injects methods into some classes. * Injects methods into some classes.
@@ -29,7 +28,7 @@ public class InjectMethodsAdapter extends ClassVisitor {
private final ICreateInfo.InjectMethodRunnable mRunnable; private final ICreateInfo.InjectMethodRunnable mRunnable;
public InjectMethodsAdapter(ClassVisitor cv, InjectMethodRunnable runnable) { public InjectMethodsAdapter(ClassVisitor cv, InjectMethodRunnable runnable) {
super(Opcodes.ASM4, cv); super(Main.ASM_VERSION, cv);
mRunnable = runnable; mRunnable = runnable;
} }

View File

@@ -16,6 +16,8 @@
package com.android.tools.layoutlib.create; package com.android.tools.layoutlib.create;
import org.objectweb.asm.Opcodes;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -52,13 +54,15 @@ public class Main {
public boolean listOnlyMissingDeps = false; public boolean listOnlyMissingDeps = false;
} }
public static final int ASM_VERSION = Opcodes.ASM5;
public static final Options sOptions = new Options(); public static final Options sOptions = new Options();
public static void main(String[] args) { public static void main(String[] args) {
Log log = new Log(); Log log = new Log();
ArrayList<String> osJarPath = new ArrayList<String>(); ArrayList<String> osJarPath = new ArrayList<>();
String[] osDestJar = { null }; String[] osDestJar = { null };
if (!processArgs(log, args, osJarPath, osDestJar)) { if (!processArgs(log, args, osJarPath, osDestJar)) {

View File

@@ -36,41 +36,40 @@ public interface MethodListener {
* @param isNative True if the method was a native method. * @param isNative True if the method was a native method.
* @param caller The calling object. Null for static methods, "this" for instance methods. * @param caller The calling object. Null for static methods, "this" for instance methods.
*/ */
public void onInvokeV(String signature, boolean isNative, Object caller); void onInvokeV(String signature, boolean isNative, Object caller);
/** /**
* Same as {@link #onInvokeV(String, boolean, Object)} but returns an integer or similar. * Same as {@link #onInvokeV(String, boolean, Object)} but returns an integer or similar.
* @see #onInvokeV(String, boolean, Object) * @see #onInvokeV(String, boolean, Object)
* @return an integer, or a boolean, or a short or a byte. * @return an integer, or a boolean, or a short or a byte.
*/ */
public int onInvokeI(String signature, boolean isNative, Object caller); int onInvokeI(String signature, boolean isNative, Object caller);
/** /**
* Same as {@link #onInvokeV(String, boolean, Object)} but returns a long. * Same as {@link #onInvokeV(String, boolean, Object)} but returns a long.
* @see #onInvokeV(String, boolean, Object) * @see #onInvokeV(String, boolean, Object)
* @return a long. * @return a long.
*/ */
public long onInvokeL(String signature, boolean isNative, Object caller); long onInvokeL(String signature, boolean isNative, Object caller);
/** /**
* Same as {@link #onInvokeV(String, boolean, Object)} but returns a float. * Same as {@link #onInvokeV(String, boolean, Object)} but returns a float.
* @see #onInvokeV(String, boolean, Object) * @see #onInvokeV(String, boolean, Object)
* @return a float. * @return a float.
*/ */
public float onInvokeF(String signature, boolean isNative, Object caller); float onInvokeF(String signature, boolean isNative, Object caller);
/** /**
* Same as {@link #onInvokeV(String, boolean, Object)} but returns a double. * Same as {@link #onInvokeV(String, boolean, Object)} but returns a double.
* @see #onInvokeV(String, boolean, Object) * @see #onInvokeV(String, boolean, Object)
* @return a double. * @return a double.
*/ */
public double onInvokeD(String signature, boolean isNative, Object caller); double onInvokeD(String signature, boolean isNative, Object caller);
/** /**
* Same as {@link #onInvokeV(String, boolean, Object)} but returns an object. * Same as {@link #onInvokeV(String, boolean, Object)} but returns an object.
* @see #onInvokeV(String, boolean, Object) * @see #onInvokeV(String, boolean, Object)
* @return an object. * @return an object.
*/ */
public Object onInvokeA(String signature, boolean isNative, Object caller); Object onInvokeA(String signature, boolean isNative, Object caller);
} }

View File

@@ -28,7 +28,7 @@ import java.util.HashMap;
public final class OverrideMethod { public final class OverrideMethod {
/** Map of method overridden. */ /** Map of method overridden. */
private static HashMap<String, MethodListener> sMethods = new HashMap<String, MethodListener>(); private static HashMap<String, MethodListener> sMethods = new HashMap<>();
/** Default listener for all method not listed in sMethods. Nothing if null. */ /** Default listener for all method not listed in sMethods. Nothing if null. */
private static MethodListener sDefaultListener = null; private static MethodListener sDefaultListener = null;

View File

@@ -24,7 +24,6 @@ import java.util.Set;
import static org.objectweb.asm.Opcodes.ACC_PRIVATE; import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
import static org.objectweb.asm.Opcodes.ACC_PROTECTED; import static org.objectweb.asm.Opcodes.ACC_PROTECTED;
import static org.objectweb.asm.Opcodes.ACC_PUBLIC; import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
import static org.objectweb.asm.Opcodes.ASM4;
/** /**
* Promotes given fields to public visibility. * Promotes given fields to public visibility.
@@ -35,7 +34,7 @@ public class PromoteFieldClassAdapter extends ClassVisitor {
private static final int ACC_NOT_PUBLIC = ~(ACC_PRIVATE | ACC_PROTECTED); private static final int ACC_NOT_PUBLIC = ~(ACC_PRIVATE | ACC_PROTECTED);
public PromoteFieldClassAdapter(ClassVisitor cv, Set<String> fieldNames) { public PromoteFieldClassAdapter(ClassVisitor cv, Set<String> fieldNames) {
super(ASM4, cv); super(Main.ASM_VERSION, cv);
mFieldNames = fieldNames; mFieldNames = fieldNames;
} }

View File

@@ -43,11 +43,11 @@ public class ReplaceMethodCallsAdapter extends ClassVisitor {
* Descriptors for specialized versions {@link System#arraycopy} that are not present on the * Descriptors for specialized versions {@link System#arraycopy} that are not present on the
* Desktop VM. * Desktop VM.
*/ */
private static Set<String> ARRAYCOPY_DESCRIPTORS = new HashSet<String>(Arrays.asList( private static Set<String> ARRAYCOPY_DESCRIPTORS = new HashSet<>(Arrays.asList(
"([CI[CII)V", "([BI[BII)V", "([SI[SII)V", "([II[III)V", "([CI[CII)V", "([BI[BII)V", "([SI[SII)V", "([II[III)V",
"([JI[JII)V", "([FI[FII)V", "([DI[DII)V", "([ZI[ZII)V")); "([JI[JII)V", "([FI[FII)V", "([DI[DII)V", "([ZI[ZII)V"));
private static final List<MethodReplacer> METHOD_REPLACERS = new ArrayList<MethodReplacer>(5); private static final List<MethodReplacer> METHOD_REPLACERS = new ArrayList<>(5);
private static final String ANDROID_LOCALE_CLASS = private static final String ANDROID_LOCALE_CLASS =
"com/android/layoutlib/bridge/android/AndroidLocale"; "com/android/layoutlib/bridge/android/AndroidLocale";
@@ -206,7 +206,7 @@ public class ReplaceMethodCallsAdapter extends ClassVisitor {
private final String mOriginalClassName; private final String mOriginalClassName;
public ReplaceMethodCallsAdapter(ClassVisitor cv, String originalClassName) { public ReplaceMethodCallsAdapter(ClassVisitor cv, String originalClassName) {
super(Opcodes.ASM4, cv); super(Main.ASM_VERSION, cv);
mOriginalClassName = originalClassName; mOriginalClassName = originalClassName;
} }
@@ -219,11 +219,12 @@ public class ReplaceMethodCallsAdapter extends ClassVisitor {
private class MyMethodVisitor extends MethodVisitor { private class MyMethodVisitor extends MethodVisitor {
public MyMethodVisitor(MethodVisitor mv) { public MyMethodVisitor(MethodVisitor mv) {
super(Opcodes.ASM4, mv); super(Main.ASM_VERSION, mv);
} }
@Override @Override
public void visitMethodInsn(int opcode, String owner, String name, String desc) { public void visitMethodInsn(int opcode, String owner, String name, String desc,
boolean itf) {
for (MethodReplacer replacer : METHOD_REPLACERS) { for (MethodReplacer replacer : METHOD_REPLACERS) {
if (replacer.isNeeded(owner, name, desc, mOriginalClassName)) { if (replacer.isNeeded(owner, name, desc, mOriginalClassName)) {
MethodInformation mi = new MethodInformation(opcode, owner, name, desc); MethodInformation mi = new MethodInformation(opcode, owner, name, desc);
@@ -235,7 +236,7 @@ public class ReplaceMethodCallsAdapter extends ClassVisitor {
break; break;
} }
} }
super.visitMethodInsn(opcode, owner, name, desc); super.visitMethodInsn(opcode, owner, name, desc, itf);
} }
} }

View File

@@ -50,7 +50,7 @@ class StubMethodAdapter extends MethodVisitor {
public StubMethodAdapter(MethodVisitor mv, String methodName, Type returnType, public StubMethodAdapter(MethodVisitor mv, String methodName, Type returnType,
String invokeSignature, boolean isStatic, boolean isNative) { String invokeSignature, boolean isStatic, boolean isNative) {
super(Opcodes.ASM4); super(Main.ASM_VERSION);
mParentVisitor = mv; mParentVisitor = mv;
mReturnType = returnType; mReturnType = returnType;
mInvokeSignature = invokeSignature; mInvokeSignature = invokeSignature;
@@ -82,7 +82,8 @@ class StubMethodAdapter extends MethodVisitor {
mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
"com/android/tools/layoutlib/create/OverrideMethod", "com/android/tools/layoutlib/create/OverrideMethod",
"invokeV", "invokeV",
"(Ljava/lang/String;ZLjava/lang/Object;)V"); "(Ljava/lang/String;ZLjava/lang/Object;)V",
false);
mParentVisitor.visitInsn(Opcodes.RETURN); mParentVisitor.visitInsn(Opcodes.RETURN);
break; break;
case Type.BOOLEAN: case Type.BOOLEAN:
@@ -93,7 +94,8 @@ class StubMethodAdapter extends MethodVisitor {
mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
"com/android/tools/layoutlib/create/OverrideMethod", "com/android/tools/layoutlib/create/OverrideMethod",
"invokeI", "invokeI",
"(Ljava/lang/String;ZLjava/lang/Object;)I"); "(Ljava/lang/String;ZLjava/lang/Object;)I",
false);
switch(sort) { switch(sort) {
case Type.BOOLEAN: case Type.BOOLEAN:
Label l1 = new Label(); Label l1 = new Label();
@@ -119,21 +121,24 @@ class StubMethodAdapter extends MethodVisitor {
mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
"com/android/tools/layoutlib/create/OverrideMethod", "com/android/tools/layoutlib/create/OverrideMethod",
"invokeL", "invokeL",
"(Ljava/lang/String;ZLjava/lang/Object;)J"); "(Ljava/lang/String;ZLjava/lang/Object;)J",
false);
mParentVisitor.visitInsn(Opcodes.LRETURN); mParentVisitor.visitInsn(Opcodes.LRETURN);
break; break;
case Type.FLOAT: case Type.FLOAT:
mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
"com/android/tools/layoutlib/create/OverrideMethod", "com/android/tools/layoutlib/create/OverrideMethod",
"invokeF", "invokeF",
"(Ljava/lang/String;ZLjava/lang/Object;)F"); "(Ljava/lang/String;ZLjava/lang/Object;)F",
false);
mParentVisitor.visitInsn(Opcodes.FRETURN); mParentVisitor.visitInsn(Opcodes.FRETURN);
break; break;
case Type.DOUBLE: case Type.DOUBLE:
mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
"com/android/tools/layoutlib/create/OverrideMethod", "com/android/tools/layoutlib/create/OverrideMethod",
"invokeD", "invokeD",
"(Ljava/lang/String;ZLjava/lang/Object;)D"); "(Ljava/lang/String;ZLjava/lang/Object;)D",
false);
mParentVisitor.visitInsn(Opcodes.DRETURN); mParentVisitor.visitInsn(Opcodes.DRETURN);
break; break;
case Type.ARRAY: case Type.ARRAY:
@@ -141,7 +146,8 @@ class StubMethodAdapter extends MethodVisitor {
mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
"com/android/tools/layoutlib/create/OverrideMethod", "com/android/tools/layoutlib/create/OverrideMethod",
"invokeA", "invokeA",
"(Ljava/lang/String;ZLjava/lang/Object;)Ljava/lang/Object;"); "(Ljava/lang/String;ZLjava/lang/Object;)Ljava/lang/Object;",
false);
mParentVisitor.visitTypeInsn(Opcodes.CHECKCAST, mReturnType.getInternalName()); mParentVisitor.visitTypeInsn(Opcodes.CHECKCAST, mReturnType.getInternalName());
mParentVisitor.visitInsn(Opcodes.ARETURN); mParentVisitor.visitInsn(Opcodes.ARETURN);
break; break;
@@ -282,9 +288,9 @@ class StubMethodAdapter extends MethodVisitor {
} }
@Override @Override
public void visitMethodInsn(int opcode, String owner, String name, String desc) { public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
if (mIsInitMethod) { if (mIsInitMethod) {
mParentVisitor.visitMethodInsn(opcode, owner, name, desc); mParentVisitor.visitMethodInsn(opcode, owner, name, desc, itf);
} }
} }

View File

@@ -49,7 +49,7 @@ class TransformClassAdapter extends ClassVisitor {
public TransformClassAdapter(Log logger, Set<String> stubMethods, public TransformClassAdapter(Log logger, Set<String> stubMethods,
Set<String> deleteReturns, String className, ClassVisitor cv, Set<String> deleteReturns, String className, ClassVisitor cv,
boolean stubNativesOnly) { boolean stubNativesOnly) {
super(Opcodes.ASM4, cv); super(Main.ASM_VERSION, cv);
mLog = logger; mLog = logger;
mStubMethods = stubMethods; mStubMethods = stubMethods;
mClassName = className; mClassName = className;

View File

@@ -28,4 +28,5 @@ public interface AutoCloseable {
/** /**
* Closes the object and release any system resources it holds. * Closes the object and release any system resources it holds.
*/ */
void close() throws Exception; } void close() throws Exception;
}

View File

@@ -24,7 +24,7 @@ LOCAL_MODULE := layoutlib-create-tests
LOCAL_MODULE_TAGS := optional LOCAL_MODULE_TAGS := optional
LOCAL_JAVA_LIBRARIES := layoutlib_create junit LOCAL_JAVA_LIBRARIES := layoutlib_create junit
LOCAL_STATIC_JAVA_LIBRARIES := asm-4.0 LOCAL_STATIC_JAVA_LIBRARIES := asm-5.0
include $(BUILD_HOST_JAVA_LIBRARY) include $(BUILD_HOST_JAVA_LIBRARY)

View File

@@ -17,13 +17,8 @@
package com.android.tools.layoutlib.create; package com.android.tools.layoutlib.create;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import com.android.tools.layoutlib.create.AsmAnalyzer.DependencyVisitor; import com.android.tools.layoutlib.create.AsmAnalyzer.DependencyVisitor;
import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassReader;
@@ -32,11 +27,15 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.Collections;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
/** /**
* Unit tests for some methods of {@link AsmAnalyzer}. * Unit tests for some methods of {@link AsmAnalyzer}.
*/ */
@@ -51,26 +50,22 @@ public class AsmAnalyzerTest {
mLog = new MockLog(); mLog = new MockLog();
URL url = this.getClass().getClassLoader().getResource("data/mock_android.jar"); URL url = this.getClass().getClassLoader().getResource("data/mock_android.jar");
mOsJarPath = new ArrayList<String>(); mOsJarPath = new ArrayList<>();
//noinspection ConstantConditions
mOsJarPath.add(url.getFile()); mOsJarPath.add(url.getFile());
Set<String> excludeClasses = new HashSet<String>(1); Set<String> excludeClasses = Collections.singleton("java.lang.JavaClass");
excludeClasses.add("java.lang.JavaClass");
String[] includeFiles = new String[]{"mock_android/data/data*"}; String[] includeFiles = new String[]{"mock_android/data/data*"};
mAa = new AsmAnalyzer(mLog, mOsJarPath, null /* gen */, null /* deriveFrom */, mAa = new AsmAnalyzer(mLog, mOsJarPath, null /* gen */, null /* deriveFrom */,
null /* includeGlobs */, excludeClasses, includeFiles); null /* includeGlobs */, excludeClasses, includeFiles);
} }
@After
public void tearDown() throws Exception {
}
@Test @Test
public void testParseZip() throws IOException { public void testParseZip() throws IOException {
Map<String, ClassReader> map = new TreeMap<String, ClassReader>(); Map<String, ClassReader> map = new TreeMap<>();
Map<String, InputStream> filesFound = new TreeMap<String, InputStream>(); Map<String, InputStream> filesFound = new TreeMap<>();
mAa.parseZip(mOsJarPath, map, filesFound); mAa.parseZip(mOsJarPath, map, filesFound);
@@ -101,11 +96,11 @@ public class AsmAnalyzerTest {
@Test @Test
public void testFindClass() throws IOException, LogAbortException { public void testFindClass() throws IOException, LogAbortException {
Map<String, ClassReader> zipClasses = new TreeMap<String, ClassReader>(); Map<String, ClassReader> zipClasses = new TreeMap<>();
Map<String, InputStream> filesFound = new TreeMap<String, InputStream>(); Map<String, InputStream> filesFound = new TreeMap<>();
mAa.parseZip(mOsJarPath, zipClasses, filesFound); mAa.parseZip(mOsJarPath, zipClasses, filesFound);
TreeMap<String, ClassReader> found = new TreeMap<String, ClassReader>(); TreeMap<String, ClassReader> found = new TreeMap<>();
ClassReader cr = mAa.findClass("mock_android.view.ViewGroup$LayoutParams", ClassReader cr = mAa.findClass("mock_android.view.ViewGroup$LayoutParams",
zipClasses, found); zipClasses, found);
@@ -120,11 +115,11 @@ public class AsmAnalyzerTest {
@Test @Test
public void testFindGlobs() throws IOException, LogAbortException { public void testFindGlobs() throws IOException, LogAbortException {
Map<String, ClassReader> zipClasses = new TreeMap<String, ClassReader>(); Map<String, ClassReader> zipClasses = new TreeMap<>();
Map<String, InputStream> filesFound = new TreeMap<String, InputStream>(); Map<String, InputStream> filesFound = new TreeMap<>();
mAa.parseZip(mOsJarPath, zipClasses, filesFound); mAa.parseZip(mOsJarPath, zipClasses, filesFound);
TreeMap<String, ClassReader> found = new TreeMap<String, ClassReader>(); TreeMap<String, ClassReader> found = new TreeMap<>();
// this matches classes, a package match returns nothing // this matches classes, a package match returns nothing
found.clear(); found.clear();
@@ -183,11 +178,11 @@ public class AsmAnalyzerTest {
@Test @Test
public void testFindClassesDerivingFrom() throws LogAbortException, IOException { public void testFindClassesDerivingFrom() throws LogAbortException, IOException {
Map<String, ClassReader> zipClasses = new TreeMap<String, ClassReader>(); Map<String, ClassReader> zipClasses = new TreeMap<>();
Map<String, InputStream> filesFound = new TreeMap<String, InputStream>(); Map<String, InputStream> filesFound = new TreeMap<>();
mAa.parseZip(mOsJarPath, zipClasses, filesFound); mAa.parseZip(mOsJarPath, zipClasses, filesFound);
TreeMap<String, ClassReader> found = new TreeMap<String, ClassReader>(); TreeMap<String, ClassReader> found = new TreeMap<>();
mAa.findClassesDerivingFrom("mock_android.view.View", zipClasses, found); mAa.findClassesDerivingFrom("mock_android.view.View", zipClasses, found);
@@ -209,14 +204,14 @@ public class AsmAnalyzerTest {
@Test @Test
public void testDependencyVisitor() throws IOException, LogAbortException { public void testDependencyVisitor() throws IOException, LogAbortException {
Map<String, ClassReader> zipClasses = new TreeMap<String, ClassReader>(); Map<String, ClassReader> zipClasses = new TreeMap<>();
Map<String, InputStream> filesFound = new TreeMap<String, InputStream>(); Map<String, InputStream> filesFound = new TreeMap<>();
mAa.parseZip(mOsJarPath, zipClasses, filesFound); mAa.parseZip(mOsJarPath, zipClasses, filesFound);
TreeMap<String, ClassReader> keep = new TreeMap<String, ClassReader>(); TreeMap<String, ClassReader> keep = new TreeMap<>();
TreeMap<String, ClassReader> new_keep = new TreeMap<String, ClassReader>(); TreeMap<String, ClassReader> new_keep = new TreeMap<>();
TreeMap<String, ClassReader> in_deps = new TreeMap<String, ClassReader>(); TreeMap<String, ClassReader> in_deps = new TreeMap<>();
TreeMap<String, ClassReader> out_deps = new TreeMap<String, ClassReader>(); TreeMap<String, ClassReader> out_deps = new TreeMap<>();
ClassReader cr = mAa.findClass("mock_android.widget.LinearLayout", zipClasses, keep); ClassReader cr = mAa.findClass("mock_android.widget.LinearLayout", zipClasses, keep);
DependencyVisitor visitor = mAa.getVisitor(zipClasses, keep, new_keep, in_deps, out_deps); DependencyVisitor visitor = mAa.getVisitor(zipClasses, keep, new_keep, in_deps, out_deps);

View File

@@ -18,12 +18,6 @@
package com.android.tools.layoutlib.create; package com.android.tools.layoutlib.create;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@@ -31,7 +25,6 @@ import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor; import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
@@ -44,7 +37,6 @@ import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@@ -52,11 +44,18 @@ import java.util.TreeMap;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
/** /**
* Unit tests for some methods of {@link AsmGenerator}. * Unit tests for some methods of {@link AsmGenerator}.
*/ */
public class AsmGeneratorTest { public class AsmGeneratorTest {
private static final String[] EMPTY_STRING_ARRAY = new String[0];
private MockLog mLog; private MockLog mLog;
private ArrayList<String> mOsJarPath; private ArrayList<String> mOsJarPath;
private String mOsDestJar; private String mOsDestJar;
@@ -70,7 +69,8 @@ public class AsmGeneratorTest {
mLog = new MockLog(); mLog = new MockLog();
URL url = this.getClass().getClassLoader().getResource("data/mock_android.jar"); URL url = this.getClass().getClassLoader().getResource("data/mock_android.jar");
mOsJarPath = new ArrayList<String>(); mOsJarPath = new ArrayList<>();
//noinspection ConstantConditions
mOsJarPath.add(url.getFile()); mOsJarPath.add(url.getFile());
mTempFile = File.createTempFile("mock", ".jar"); mTempFile = File.createTempFile("mock", ".jar");
@@ -98,18 +98,18 @@ public class AsmGeneratorTest {
@Override @Override
public String[] getDelegateMethods() { public String[] getDelegateMethods() {
return new String[0]; return EMPTY_STRING_ARRAY;
} }
@Override @Override
public String[] getDelegateClassNatives() { public String[] getDelegateClassNatives() {
return new String[0]; return EMPTY_STRING_ARRAY;
} }
@Override @Override
public String[] getOverriddenMethods() { public String[] getOverriddenMethods() {
// methods to force override // methods to force override
return new String[0]; return EMPTY_STRING_ARRAY;
} }
@Override @Override
@@ -123,7 +123,7 @@ public class AsmGeneratorTest {
@Override @Override
public String[] getJavaPkgClasses() { public String[] getJavaPkgClasses() {
return new String[0]; return EMPTY_STRING_ARRAY;
} }
@Override @Override
@@ -134,17 +134,17 @@ public class AsmGeneratorTest {
@Override @Override
public String[] getDeleteReturns() { public String[] getDeleteReturns() {
// methods deleted from their return type. // methods deleted from their return type.
return new String[0]; return EMPTY_STRING_ARRAY;
} }
@Override @Override
public String[] getPromotedFields() { public String[] getPromotedFields() {
return new String[0]; return EMPTY_STRING_ARRAY;
} }
@Override @Override
public Map<String, InjectMethodRunnable> getInjectedMethodsMap() { public Map<String, InjectMethodRunnable> getInjectedMethodsMap() {
return new HashMap<String, InjectMethodRunnable>(0); return Collections.emptyMap();
} }
}; };
@@ -155,7 +155,7 @@ public class AsmGeneratorTest {
new String[] { // include classes new String[] { // include classes
"**" "**"
}, },
new HashSet<String>(0) /* excluded classes */, Collections.<String>emptySet() /* excluded classes */,
new String[]{} /* include files */); new String[]{} /* include files */);
aa.analyze(); aa.analyze();
agen.generate(); agen.generate();
@@ -178,24 +178,24 @@ public class AsmGeneratorTest {
@Override @Override
public String[] getDelegateMethods() { public String[] getDelegateMethods() {
return new String[0]; return EMPTY_STRING_ARRAY;
} }
@Override @Override
public String[] getDelegateClassNatives() { public String[] getDelegateClassNatives() {
return new String[0]; return EMPTY_STRING_ARRAY;
} }
@Override @Override
public String[] getOverriddenMethods() { public String[] getOverriddenMethods() {
// methods to force override // methods to force override
return new String[0]; return EMPTY_STRING_ARRAY;
} }
@Override @Override
public String[] getRenamedClasses() { public String[] getRenamedClasses() {
// classes to rename (so that we can replace them) // classes to rename (so that we can replace them)
return new String[0]; return EMPTY_STRING_ARRAY;
} }
@Override @Override
@@ -214,17 +214,17 @@ public class AsmGeneratorTest {
@Override @Override
public String[] getDeleteReturns() { public String[] getDeleteReturns() {
// methods deleted from their return type. // methods deleted from their return type.
return new String[0]; return EMPTY_STRING_ARRAY;
} }
@Override @Override
public String[] getPromotedFields() { public String[] getPromotedFields() {
return new String[0]; return EMPTY_STRING_ARRAY;
} }
@Override @Override
public Map<String, InjectMethodRunnable> getInjectedMethodsMap() { public Map<String, InjectMethodRunnable> getInjectedMethodsMap() {
return new HashMap<String, InjectMethodRunnable>(0); return Collections.emptyMap();
} }
}; };
@@ -235,14 +235,14 @@ public class AsmGeneratorTest {
new String[] { // include classes new String[] { // include classes
"**" "**"
}, },
new HashSet<String>(1), Collections.<String>emptySet(),
new String[] { /* include files */ new String[] { /* include files */
"mock_android/data/data*" "mock_android/data/data*"
}); });
aa.analyze(); aa.analyze();
agen.generate(); agen.generate();
Map<String, ClassReader> output = new TreeMap<String, ClassReader>(); Map<String, ClassReader> output = new TreeMap<>();
Map<String, InputStream> filesFound = new TreeMap<String, InputStream>(); Map<String, InputStream> filesFound = new TreeMap<>();
parseZip(mOsDestJar, output, filesFound); parseZip(mOsDestJar, output, filesFound);
boolean injectedClassFound = false; boolean injectedClassFound = false;
for (ClassReader cr: output.values()) { for (ClassReader cr: output.values()) {
@@ -265,35 +265,35 @@ public class AsmGeneratorTest {
@Override @Override
public String[] getDelegateMethods() { public String[] getDelegateMethods() {
return new String[0]; return EMPTY_STRING_ARRAY;
} }
@Override @Override
public String[] getDelegateClassNatives() { public String[] getDelegateClassNatives() {
return new String[0]; return EMPTY_STRING_ARRAY;
} }
@Override @Override
public String[] getOverriddenMethods() { public String[] getOverriddenMethods() {
// methods to force override // methods to force override
return new String[0]; return EMPTY_STRING_ARRAY;
} }
@Override @Override
public String[] getRenamedClasses() { public String[] getRenamedClasses() {
// classes to rename (so that we can replace them) // classes to rename (so that we can replace them)
return new String[0]; return EMPTY_STRING_ARRAY;
} }
@Override @Override
public String[] getJavaPkgClasses() { public String[] getJavaPkgClasses() {
// classes to refactor (so that we can replace them) // classes to refactor (so that we can replace them)
return new String[0]; return EMPTY_STRING_ARRAY;
} }
@Override @Override
public Set<String> getExcludedClasses() { public Set<String> getExcludedClasses() {
Set<String> set = new HashSet<String>(2); Set<String> set = new HashSet<>(2);
set.add("mock_android.dummy.InnerTest"); set.add("mock_android.dummy.InnerTest");
set.add("java.lang.JavaClass"); set.add("java.lang.JavaClass");
return set; return set;
@@ -302,17 +302,17 @@ public class AsmGeneratorTest {
@Override @Override
public String[] getDeleteReturns() { public String[] getDeleteReturns() {
// methods deleted from their return type. // methods deleted from their return type.
return new String[0]; return EMPTY_STRING_ARRAY;
} }
@Override @Override
public String[] getPromotedFields() { public String[] getPromotedFields() {
return new String[0]; return EMPTY_STRING_ARRAY;
} }
@Override @Override
public Map<String, InjectMethodRunnable> getInjectedMethodsMap() { public Map<String, InjectMethodRunnable> getInjectedMethodsMap() {
return new HashMap<String, InjectMethodRunnable>(0); return Collections.emptyMap();
} }
}; };
@@ -329,8 +329,8 @@ public class AsmGeneratorTest {
}); });
aa.analyze(); aa.analyze();
agen.generate(); agen.generate();
Map<String, ClassReader> output = new TreeMap<String, ClassReader>(); Map<String, ClassReader> output = new TreeMap<>();
Map<String, InputStream> filesFound = new TreeMap<String, InputStream>(); Map<String, InputStream> filesFound = new TreeMap<>();
parseZip(mOsDestJar, output, filesFound); parseZip(mOsDestJar, output, filesFound);
for (String s : output.keySet()) { for (String s : output.keySet()) {
assertFalse(excludedClasses.contains(s)); assertFalse(excludedClasses.contains(s));
@@ -351,55 +351,52 @@ public class AsmGeneratorTest {
@Override @Override
public String[] getDelegateMethods() { public String[] getDelegateMethods() {
return new String[0]; return EMPTY_STRING_ARRAY;
} }
@Override @Override
public String[] getDelegateClassNatives() { public String[] getDelegateClassNatives() {
return new String[0]; return EMPTY_STRING_ARRAY;
} }
@Override @Override
public String[] getOverriddenMethods() { public String[] getOverriddenMethods() {
// methods to force override // methods to force override
return new String[0]; return EMPTY_STRING_ARRAY;
} }
@Override @Override
public String[] getRenamedClasses() { public String[] getRenamedClasses() {
// classes to rename (so that we can replace them) // classes to rename (so that we can replace them)
return new String[0]; return EMPTY_STRING_ARRAY;
} }
@Override @Override
public String[] getJavaPkgClasses() { public String[] getJavaPkgClasses() {
// classes to refactor (so that we can replace them) // classes to refactor (so that we can replace them)
return new String[0]; return EMPTY_STRING_ARRAY;
} }
@Override @Override
public Set<String> getExcludedClasses() { public Set<String> getExcludedClasses() {
return new HashSet<String>(0); return Collections.emptySet();
} }
@Override @Override
public String[] getDeleteReturns() { public String[] getDeleteReturns() {
// methods deleted from their return type. // methods deleted from their return type.
return new String[0]; return EMPTY_STRING_ARRAY;
} }
@Override @Override
public String[] getPromotedFields() { public String[] getPromotedFields() {
return new String[0]; return EMPTY_STRING_ARRAY;
} }
@Override @Override
public Map<String, InjectMethodRunnable> getInjectedMethodsMap() { public Map<String, InjectMethodRunnable> getInjectedMethodsMap() {
HashMap<String, InjectMethodRunnable> map = return Collections.singletonMap("mock_android.util.EmptyArray",
new HashMap<String, InjectMethodRunnable>(1);
map.put("mock_android.util.EmptyArray",
InjectMethodRunnables.CONTEXT_GET_FRAMEWORK_CLASS_LOADER); InjectMethodRunnables.CONTEXT_GET_FRAMEWORK_CLASS_LOADER);
return map;
} }
}; };
@@ -415,8 +412,8 @@ public class AsmGeneratorTest {
}); });
aa.analyze(); aa.analyze();
agen.generate(); agen.generate();
Map<String, ClassReader> output = new TreeMap<String, ClassReader>(); Map<String, ClassReader> output = new TreeMap<>();
Map<String, InputStream> filesFound = new TreeMap<String, InputStream>(); Map<String, InputStream> filesFound = new TreeMap<>();
parseZip(mOsDestJar, output, filesFound); parseZip(mOsDestJar, output, filesFound);
final String modifiedClass = "mock_android.util.EmptyArray"; final String modifiedClass = "mock_android.util.EmptyArray";
final String modifiedClassPath = modifiedClass.replace('.', '/').concat(".class"); final String modifiedClassPath = modifiedClass.replace('.', '/').concat(".class");
@@ -424,11 +421,8 @@ public class AsmGeneratorTest {
ZipEntry entry = zipFile.getEntry(modifiedClassPath); ZipEntry entry = zipFile.getEntry(modifiedClassPath);
assertNotNull(entry); assertNotNull(entry);
final byte[] bytes; final byte[] bytes;
final InputStream inputStream = zipFile.getInputStream(entry); try (InputStream inputStream = zipFile.getInputStream(entry)) {
try {
bytes = getByteArray(inputStream); bytes = getByteArray(inputStream);
} finally {
inputStream.close();
} }
ClassLoader classLoader = new ClassLoader(getClass().getClassLoader()) { ClassLoader classLoader = new ClassLoader(getClass().getClassLoader()) {
@Override @Override
@@ -489,7 +483,7 @@ public class AsmGeneratorTest {
boolean mInjectedClassFound = false; boolean mInjectedClassFound = false;
TestClassVisitor() { TestClassVisitor() {
super(Opcodes.ASM4); super(Main.ASM_VERSION);
} }
@Override @Override
@@ -514,7 +508,7 @@ public class AsmGeneratorTest {
public MethodVisitor visitMethod(int access, String name, String desc, public MethodVisitor visitMethod(int access, String name, String desc,
String signature, String[] exceptions) { String signature, String[] exceptions) {
MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
return new MethodVisitor(Opcodes.ASM4, mv) { return new MethodVisitor(Main.ASM_VERSION, mv) {
@Override @Override
public void visitFieldInsn(int opcode, String owner, String name, public void visitFieldInsn(int opcode, String owner, String name,
@@ -540,10 +534,10 @@ public class AsmGeneratorTest {
@Override @Override
public void visitMethodInsn(int opcode, String owner, String name, public void visitMethodInsn(int opcode, String owner, String name,
String desc) { String desc, boolean itf) {
assertTrue(!getBase(owner).equals(JAVA_CLASS_NAME)); assertTrue(!getBase(owner).equals(JAVA_CLASS_NAME));
assertTrue(testType(Type.getType(desc))); assertTrue(testType(Type.getType(desc)));
super.visitMethodInsn(opcode, owner, name, desc); super.visitMethodInsn(opcode, owner, name, desc, itf);
} }
}; };

View File

@@ -60,7 +60,7 @@ public class ClassHasNativeVisitorTest {
* Overrides {@link ClassHasNativeVisitor} to collec the name of the native methods found. * Overrides {@link ClassHasNativeVisitor} to collec the name of the native methods found.
*/ */
private static class MockClassHasNativeVisitor extends ClassHasNativeVisitor { private static class MockClassHasNativeVisitor extends ClassHasNativeVisitor {
private ArrayList<String> mMethodsFound = new ArrayList<String>(); private ArrayList<String> mMethodsFound = new ArrayList<>();
public String[] getMethodsFound() { public String[] getMethodsFound() {
return mMethodsFound.toArray(new String[mMethodsFound.size()]); return mMethodsFound.toArray(new String[mMethodsFound.size()]);

View File

@@ -85,7 +85,7 @@ public class DelegateClassAdapterTest {
// Now process it but tell the delegate to not modify any method // Now process it but tell the delegate to not modify any method
ClassWriter cw = new ClassWriter(0 /*flags*/); ClassWriter cw = new ClassWriter(0 /*flags*/);
HashSet<String> delegateMethods = new HashSet<String>(); HashSet<String> delegateMethods = new HashSet<>();
String internalClassName = NATIVE_CLASS_NAME.replace('.', '/'); String internalClassName = NATIVE_CLASS_NAME.replace('.', '/');
DelegateClassAdapter cv = new DelegateClassAdapter( DelegateClassAdapter cv = new DelegateClassAdapter(
mLog, cw, internalClassName, delegateMethods); mLog, cw, internalClassName, delegateMethods);
@@ -149,7 +149,7 @@ public class DelegateClassAdapterTest {
String internalClassName = NATIVE_CLASS_NAME.replace('.', '/'); String internalClassName = NATIVE_CLASS_NAME.replace('.', '/');
HashSet<String> delegateMethods = new HashSet<String>(); HashSet<String> delegateMethods = new HashSet<>();
delegateMethods.add("<init>"); delegateMethods.add("<init>");
DelegateClassAdapter cv = new DelegateClassAdapter( DelegateClassAdapter cv = new DelegateClassAdapter(
mLog, cw, internalClassName, delegateMethods); mLog, cw, internalClassName, delegateMethods);
@@ -163,7 +163,7 @@ public class DelegateClassAdapterTest {
ClassWriter cw = new ClassWriter(0 /*flags*/); ClassWriter cw = new ClassWriter(0 /*flags*/);
String internalClassName = NATIVE_CLASS_NAME.replace('.', '/'); String internalClassName = NATIVE_CLASS_NAME.replace('.', '/');
HashSet<String> delegateMethods = new HashSet<String>(); HashSet<String> delegateMethods = new HashSet<>();
delegateMethods.add(DelegateClassAdapter.ALL_NATIVES); delegateMethods.add(DelegateClassAdapter.ALL_NATIVES);
DelegateClassAdapter cv = new DelegateClassAdapter( DelegateClassAdapter cv = new DelegateClassAdapter(
mLog, cw, internalClassName, delegateMethods); mLog, cw, internalClassName, delegateMethods);
@@ -214,7 +214,7 @@ public class DelegateClassAdapterTest {
@Test @Test
public void testDelegateInner() throws Throwable { public void testDelegateInner() throws Throwable {
// We'll delegate the "get" method of both the inner and outer class. // We'll delegate the "get" method of both the inner and outer class.
HashSet<String> delegateMethods = new HashSet<String>(); HashSet<String> delegateMethods = new HashSet<>();
delegateMethods.add("get"); delegateMethods.add("get");
delegateMethods.add("privateMethod"); delegateMethods.add("privateMethod");
@@ -309,7 +309,7 @@ public class DelegateClassAdapterTest {
*/ */
private abstract class ClassLoader2 extends ClassLoader { private abstract class ClassLoader2 extends ClassLoader {
private final Map<String, byte[]> mClassDefs = new HashMap<String, byte[]>(); private final Map<String, byte[]> mClassDefs = new HashMap<>();
public ClassLoader2() { public ClassLoader2() {
super(null); super(null);