1ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski/* 2ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Copyright (C) 2012 The Android Open Source Project 3ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 4ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 5ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * you may not use this file except in compliance with the License. 6ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * You may obtain a copy of the License at 7ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 8ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 9ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 10ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Unless required by applicable law or agreed to in writing, software 11ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 12ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * See the License for the specific language governing permissions and 14ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * limitations under the License. 15ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 16ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 17ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskipackage com.android.tools.layoutlib.create; 18ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 19ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport com.android.tools.layoutlib.annotations.VisibleForTesting; 20ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport com.android.tools.layoutlib.annotations.VisibleForTesting.Visibility; 21ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 22ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport org.objectweb.asm.AnnotationVisitor; 23ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport org.objectweb.asm.Attribute; 24ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport org.objectweb.asm.ClassReader; 25ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport org.objectweb.asm.ClassVisitor; 26ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport org.objectweb.asm.FieldVisitor; 27ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport org.objectweb.asm.Label; 28ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport org.objectweb.asm.MethodVisitor; 29ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport org.objectweb.asm.Type; 30ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport org.objectweb.asm.signature.SignatureReader; 31ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport org.objectweb.asm.signature.SignatureVisitor; 32ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 33ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.io.IOException; 34ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.util.ArrayList; 35ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.util.Enumeration; 36ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.util.List; 37ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.util.Map; 38ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.util.Map.Entry; 39ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.util.Set; 40ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.util.TreeMap; 41ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.util.TreeSet; 42ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.util.zip.ZipEntry; 43ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.util.zip.ZipFile; 44ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 45ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski/** 46ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Analyzes the input JAR using the ASM java bytecode manipulation library 47ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * to list the classes and their dependencies. A "dependency" is a class 48ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * used by another class. 49ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 50ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskipublic class DependencyFinder { 51ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 52ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // Note: a bunch of stuff has package-level access for unit tests. Consider it private. 53ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 54ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** Output logger. */ 55ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski private final Log mLog; 56ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 57ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 58ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Creates a new analyzer. 59ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 60ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param log The log output. 61ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 62ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public DependencyFinder(Log log) { 63ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mLog = log; 64ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 65ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 66ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 67ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Starts the analysis using parameters from the constructor. 68ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 69ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param osJarPath The input source JARs to parse. 70ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @return A pair: [0]: map { class FQCN => set of FQCN class dependencies }. 71ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * [1]: map { missing class FQCN => set of FQCN class that uses it. } 72ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 73ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public List<Map<String, Set<String>>> findDeps(List<String> osJarPath) throws IOException { 74ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 75ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Map<String, ClassReader> zipClasses = parseZip(osJarPath); 76ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mLog.info("Found %d classes in input JAR%s.", 77ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski zipClasses.size(), 78ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski osJarPath.size() > 1 ? "s" : ""); 79ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 80ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Map<String, Set<String>> deps = findClassesDeps(zipClasses); 81ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 82ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Map<String, Set<String>> missing = findMissingClasses(deps, zipClasses.keySet()); 83ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 84528ddbf71ab1cac494e9a1aa50b9c8b76ba29586Deepanshu Gupta List<Map<String, Set<String>>> result = new ArrayList<>(2); 85ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski result.add(deps); 86ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski result.add(missing); 87ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return result; 88ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 89ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 90ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 91ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Prints dependencies to the current logger, found stuff and missing stuff. 92ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 93ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void printAllDeps(List<Map<String, Set<String>>> result) { 94ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski assert result.size() == 2; 95ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Map<String, Set<String>> deps = result.get(0); 96ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Map<String, Set<String>> missing = result.get(1); 97ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 98ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // Print all dependences found in the format: 99ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // +Found: <FQCN from zip> 100ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // uses: FQCN 101ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 102ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mLog.info("++++++ %d Entries found in source JARs", deps.size()); 103ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mLog.info(""); 104ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 105ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski for (Entry<String, Set<String>> entry : deps.entrySet()) { 106ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mLog.info( "+Found : %s", entry.getKey()); 107ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski for (String dep : entry.getValue()) { 108ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mLog.info(" uses: %s", dep); 109ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 110ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 111ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mLog.info(""); 112ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 113ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 114ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 115ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // Now print all missing dependences in the format: 116ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // -Missing <FQCN>: 117ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // used by: <FQCN> 118ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 119ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mLog.info(""); 120ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mLog.info("------ %d Entries missing from source JARs", missing.size()); 121ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mLog.info(""); 122ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 123ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski for (Entry<String, Set<String>> entry : missing.entrySet()) { 124ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mLog.info( "-Missing : %s", entry.getKey()); 125ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski for (String dep : entry.getValue()) { 126ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mLog.info(" used by: %s", dep); 127ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 128ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 129ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mLog.info(""); 130ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 131ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 132ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 133ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 134ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Prints only a summary of the missing dependencies to the current logger. 135ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 136ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void printMissingDeps(List<Map<String, Set<String>>> result) { 137ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski assert result.size() == 2; 138ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @SuppressWarnings("unused") Map<String, Set<String>> deps = result.get(0); 139ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Map<String, Set<String>> missing = result.get(1); 140ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 141ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski for (String fqcn : missing.keySet()) { 142ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mLog.info("%s", fqcn); 143ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 144ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 145ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 146ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // ---------------- 147ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 148ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 149ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Parses a JAR file and returns a list of all classes founds using a map 150ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * class name => ASM ClassReader. Class names are in the form "android.view.View". 151ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 152ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Map<String,ClassReader> parseZip(List<String> jarPathList) throws IOException { 153528ddbf71ab1cac494e9a1aa50b9c8b76ba29586Deepanshu Gupta TreeMap<String, ClassReader> classes = new TreeMap<>(); 154ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 155ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski for (String jarPath : jarPathList) { 156ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski ZipFile zip = new ZipFile(jarPath); 157ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Enumeration<? extends ZipEntry> entries = zip.entries(); 158ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski ZipEntry entry; 159ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski while (entries.hasMoreElements()) { 160ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski entry = entries.nextElement(); 161ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (entry.getName().endsWith(".class")) { 162ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski ClassReader cr = new ClassReader(zip.getInputStream(entry)); 163ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski String className = classReaderToClassName(cr); 164ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski classes.put(className, cr); 165ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 166ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 167ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 168ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 169ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return classes; 170ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 171ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 172ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 173ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Utility that returns the fully qualified binary class name for a ClassReader. 174ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * E.g. it returns something like android.view.View. 175ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 176ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski static String classReaderToClassName(ClassReader classReader) { 177ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (classReader == null) { 178ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return null; 179ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } else { 180ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return classReader.getClassName().replace('/', '.'); 181ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 182ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 183ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 184ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 185ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Utility that returns the fully qualified binary class name from a path-like FQCN. 186ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * E.g. it returns android.view.View from android/view/View. 187ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 188ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski static String internalToBinaryClassName(String className) { 189ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (className == null) { 190ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return null; 191ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } else { 192ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return className.replace('/', '.'); 193ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 194ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 195ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 196ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 197ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Finds all dependencies for all classes in keepClasses which are also 198ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * listed in zipClasses. Returns a map of all the dependencies found. 199ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 200ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Map<String, Set<String>> findClassesDeps(Map<String, ClassReader> zipClasses) { 201ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 202ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // The dependencies that we'll collect. 203ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // It's a map Class name => uses class names. 204528ddbf71ab1cac494e9a1aa50b9c8b76ba29586Deepanshu Gupta Map<String, Set<String>> dependencyMap = new TreeMap<>(); 205ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 206ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski DependencyVisitor visitor = getVisitor(); 207ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 208ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski int count = 0; 209ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski try { 210ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski for (Entry<String, ClassReader> entry : zipClasses.entrySet()) { 211ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski String name = entry.getKey(); 212ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 213528ddbf71ab1cac494e9a1aa50b9c8b76ba29586Deepanshu Gupta TreeSet<String> set = new TreeSet<>(); 214ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski dependencyMap.put(name, set); 215ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski visitor.setDependencySet(set); 216ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 217ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski ClassReader cr = entry.getValue(); 218ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski cr.accept(visitor, 0 /* flags */); 219ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 220ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski visitor.setDependencySet(null); 221ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 222ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mLog.debugNoln("Visited %d classes\r", ++count); 223ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 224ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } finally { 225ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mLog.debugNoln("\n"); 226ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 227ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 228ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return dependencyMap; 229ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 230ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 231ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 232ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Computes which classes FQCN were found as dependencies that are NOT listed 233ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * in the original JAR classes. 234ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 235ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param deps The map { FQCN => dependencies[] } returned by {@link #findClassesDeps(Map)}. 236ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param zipClasses The set of all classes FQCN found in the JAR files. 237ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @return A map { FQCN not found in the zipClasses => classes using it } 238ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 239ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski private Map<String, Set<String>> findMissingClasses( 240ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Map<String, Set<String>> deps, 241ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Set<String> zipClasses) { 242528ddbf71ab1cac494e9a1aa50b9c8b76ba29586Deepanshu Gupta Map<String, Set<String>> missing = new TreeMap<>(); 243ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 244ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski for (Entry<String, Set<String>> entry : deps.entrySet()) { 245ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski String name = entry.getKey(); 246ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 247ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski for (String dep : entry.getValue()) { 248ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (!zipClasses.contains(dep)) { 249ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // This dependency doesn't exist in the zip classes. 250ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Set<String> set = missing.get(dep); 251ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (set == null) { 252528ddbf71ab1cac494e9a1aa50b9c8b76ba29586Deepanshu Gupta set = new TreeSet<>(); 253ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski missing.put(dep, set); 254ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 255ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski set.add(name); 256ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 257ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 258ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 259ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 260ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 261ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return missing; 262ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 263ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 264ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 265ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // ---------------------------------- 266ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 267ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 268ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Instantiates a new DependencyVisitor. Useful for unit tests. 269ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 270ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @VisibleForTesting(visibility=Visibility.PRIVATE) 271ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski DependencyVisitor getVisitor() { 272ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return new DependencyVisitor(); 273ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 274ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 275ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 276ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Visitor to collect all the type dependencies from a class. 277ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 278ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public class DependencyVisitor extends ClassVisitor { 279ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 280ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski private Set<String> mCurrentDepSet; 281ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 282ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 283ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Creates a new visitor that will find all the dependencies for the visited class. 284ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 285ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public DependencyVisitor() { 286528ddbf71ab1cac494e9a1aa50b9c8b76ba29586Deepanshu Gupta super(Main.ASM_VERSION); 287ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 288ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 289ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 290ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Sets the {@link Set} where to record direct dependencies for this class. 291ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * This will change before each {@link ClassReader#accept(ClassVisitor, int)} call. 292ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 293ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void setDependencySet(Set<String> set) { 294ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mCurrentDepSet = set; 295ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 296ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 297ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 298ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Considers the given class name as a dependency. 299ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 300ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void considerName(String className) { 301ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (className == null) { 302ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return; 303ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 304ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 305ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski className = internalToBinaryClassName(className); 306ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 307ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski try { 308ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // exclude classes that are part of the default JRE (the one executing this program) 3094b45b08eb7e472863701f6d78cc08b817aa8d0f1Deepanshu Gupta // or in java package (we won't be able to load them anyway). 3104b45b08eb7e472863701f6d78cc08b817aa8d0f1Deepanshu Gupta if (className.startsWith("java.") || 3114b45b08eb7e472863701f6d78cc08b817aa8d0f1Deepanshu Gupta getClass().getClassLoader().loadClass(className) != null) { 312ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return; 313ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 314ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } catch (ClassNotFoundException e) { 315ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // ignore 316ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 317ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 318ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // Add it to the dependency set for the currently visited class, as needed. 319ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski assert mCurrentDepSet != null; 320b77a349014d1fade2185a53c2a58edaa4b971dbeDeepanshu Gupta mCurrentDepSet.add(className); 321ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 322ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 323ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 324ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Considers this array of names using considerName(). 325ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 326ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void considerNames(String[] classNames) { 327ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (classNames != null) { 328ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski for (String className : classNames) { 329ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski considerName(className); 330ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 331ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 332ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 333ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 334ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 335ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Considers this signature or type signature by invoking the {@link SignatureVisitor} 336ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * on it. 337ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 338ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void considerSignature(String signature) { 339ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (signature != null) { 340ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski SignatureReader sr = new SignatureReader(signature); 341ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // SignatureReader.accept will call accessType so we don't really have 342ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // to differentiate where the signature comes from. 343ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski sr.accept(new MySignatureVisitor()); 344ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 345ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 346ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 347ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 348ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Considers this {@link Type}. For arrays, the element type is considered. 349ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * If the type is an object, it's internal name is considered. 350ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 351ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void considerType(Type t) { 352ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (t != null) { 353ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (t.getSort() == Type.ARRAY) { 354ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski t = t.getElementType(); 355ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 356ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (t.getSort() == Type.OBJECT) { 357ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski considerName(t.getInternalName()); 358ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 359ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 360ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 361ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 362ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 363ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Considers a descriptor string. The descriptor is converted to a {@link Type} 364ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * and then considerType() is invoked. 365ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 366ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public boolean considerDesc(String desc) { 367ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (desc != null) { 368ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski try { 369ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (desc.length() > 0 && desc.charAt(0) == '(') { 370ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // This is a method descriptor with arguments and a return type. 371ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Type t = Type.getReturnType(desc); 372ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski considerType(t); 373ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 374ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski for (Type arg : Type.getArgumentTypes(desc)) { 375ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski considerType(arg); 376ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 377ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 378ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } else { 379ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Type t = Type.getType(desc); 380ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski considerType(t); 381ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 382ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return true; 383ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } catch (ArrayIndexOutOfBoundsException e) { 384ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // ignore, not a valid type. 385ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 386ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 387ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return false; 388ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 389ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 390ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 391ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // --------------------------------------------------- 392ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // --- ClassVisitor, FieldVisitor 393ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // --------------------------------------------------- 394ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 395ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // Visits a class header 396ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 397ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visit(int version, int access, String name, 398ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski String signature, String superName, String[] interfaces) { 399ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // signature is the signature of this class. May be null if the class is not a generic 400ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // one, and does not extend or implement generic classes or interfaces. 401ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 402ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (signature != null) { 403ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski considerSignature(signature); 404ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 405ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 406ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // superName is the internal of name of the super class (see getInternalName). 407ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // For interfaces, the super class is Object. May be null but only for the Object class. 408ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski considerName(superName); 409ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 410ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // interfaces is the internal names of the class's interfaces (see getInternalName). 411ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // May be null. 412ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski considerNames(interfaces); 413ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 414ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 415ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 416ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 417ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public AnnotationVisitor visitAnnotation(String desc, boolean visible) { 418ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // desc is the class descriptor of the annotation class. 419ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski considerDesc(desc); 420ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return new MyAnnotationVisitor(); 421ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 422ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 423ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 424ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitAttribute(Attribute attr) { 425ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // pass 426ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 427ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 428ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // Visits the end of a class 429ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 430ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitEnd() { 431ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // pass 432ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 433ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 434ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski private class MyFieldVisitor extends FieldVisitor { 435ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 436ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public MyFieldVisitor() { 437528ddbf71ab1cac494e9a1aa50b9c8b76ba29586Deepanshu Gupta super(Main.ASM_VERSION); 438ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 439ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 440ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 441ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public AnnotationVisitor visitAnnotation(String desc, boolean visible) { 442ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // desc is the class descriptor of the annotation class. 443ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski considerDesc(desc); 444ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return new MyAnnotationVisitor(); 445ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 446ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 447ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 448ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitAttribute(Attribute attr) { 449ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // pass 450ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 451ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 452ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // Visits the end of a class 453ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 454ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitEnd() { 455ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // pass 456ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 457ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 458ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 459ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 460ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public FieldVisitor visitField(int access, String name, String desc, 461ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski String signature, Object value) { 462ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // desc is the field's descriptor (see Type). 463ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski considerDesc(desc); 464ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 465ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // signature is the field's signature. May be null if the field's type does not use 466ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // generic types. 467ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski considerSignature(signature); 468ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 469ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return new MyFieldVisitor(); 470ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 471ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 472ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 473ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitInnerClass(String name, String outerName, String innerName, int access) { 474ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // name is the internal name of an inner class (see getInternalName). 475ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // Note: outerName/innerName seems to be null when we're reading the 476ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // _Original_ClassName classes generated by layoutlib_create. 477ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (outerName != null) { 478ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski considerName(name); 479ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 480ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 481ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 482ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 483ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public MethodVisitor visitMethod(int access, String name, String desc, 484ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski String signature, String[] exceptions) { 485ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // desc is the method's descriptor (see Type). 486ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski considerDesc(desc); 487ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // signature is the method's signature. May be null if the method parameters, return 488ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // type and exceptions do not use generic types. 489ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski considerSignature(signature); 490ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 491ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return new MyMethodVisitor(); 492ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 493ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 494ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 495ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitOuterClass(String owner, String name, String desc) { 496ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // pass 497ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 498ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 499ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 500ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitSource(String source, String debug) { 501ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // pass 502ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 503ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 504ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 505ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // --------------------------------------------------- 506ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // --- MethodVisitor 507ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // --------------------------------------------------- 508ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 509ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski private class MyMethodVisitor extends MethodVisitor { 510ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 511ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public MyMethodVisitor() { 512528ddbf71ab1cac494e9a1aa50b9c8b76ba29586Deepanshu Gupta super(Main.ASM_VERSION); 513ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 514ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 515ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 516ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 517ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public AnnotationVisitor visitAnnotationDefault() { 518ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return new MyAnnotationVisitor(); 519ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 520ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 521ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 522ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitCode() { 523ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // pass 524ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 525ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 526ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // field instruction 527ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 528ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitFieldInsn(int opcode, String owner, String name, String desc) { 5292ff4f504c82e35c1f8d3cae79a32b4400a628c28Deepanshu Gupta // owner is the class that declares the field. 5302ff4f504c82e35c1f8d3cae79a32b4400a628c28Deepanshu Gupta considerName(owner); 531ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // desc is the field's descriptor (see Type). 532ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski considerDesc(desc); 533ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 534ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 535ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 536ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitFrame(int type, int local, Object[] local2, int stack, Object[] stack2) { 537ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // pass 538ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 539ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 540ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 541ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitIincInsn(int var, int increment) { 542ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // pass -- an IINC instruction 543ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 544ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 545ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 546ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitInsn(int opcode) { 547ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // pass -- a zero operand instruction 548ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 549ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 550ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 551ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitIntInsn(int opcode, int operand) { 552ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // pass -- a single int operand instruction 553ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 554ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 555ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 556ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitJumpInsn(int opcode, Label label) { 557ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // pass -- a jump instruction 558ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 559ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 560ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 561ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitLabel(Label label) { 562ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // pass -- a label target 563ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 564ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 565ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // instruction to load a constant from the stack 566ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 567ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitLdcInsn(Object cst) { 568ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (cst instanceof Type) { 569ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski considerType((Type) cst); 570ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 571ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 572ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 573ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 574ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitLineNumber(int line, Label start) { 575ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // pass 576ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 577ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 578ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 579ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitLocalVariable(String name, String desc, 580ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski String signature, Label start, Label end, int index) { 581ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // desc is the type descriptor of this local variable. 582ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski considerDesc(desc); 583ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // signature is the type signature of this local variable. May be null if the local 584ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // variable type does not use generic types. 585ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski considerSignature(signature); 586ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 587ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 588ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 589ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { 590ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // pass -- a lookup switch instruction 591ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 592ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 593ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 594ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitMaxs(int maxStack, int maxLocals) { 595ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // pass 596ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 597ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 598ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // instruction that invokes a method 599ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 600528ddbf71ab1cac494e9a1aa50b9c8b76ba29586Deepanshu Gupta public void visitMethodInsn(int opcode, String owner, String name, String desc, 601528ddbf71ab1cac494e9a1aa50b9c8b76ba29586Deepanshu Gupta boolean itf) { 602ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 603ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // owner is the internal name of the method's owner class 604ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (!considerDesc(owner) && owner.indexOf('/') != -1) { 605ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski considerName(owner); 606ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 607ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // desc is the method's descriptor (see Type). 608ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski considerDesc(desc); 609ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 610ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 611ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // instruction multianewarray, whatever that is 612ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 613ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitMultiANewArrayInsn(String desc, int dims) { 614ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 615ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // desc an array type descriptor. 616ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski considerDesc(desc); 617ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 618ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 619ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 620ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, 621ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski boolean visible) { 622ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // desc is the class descriptor of the annotation class. 623ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski considerDesc(desc); 624ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return new MyAnnotationVisitor(); 625ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 626ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 627ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 628ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) { 629ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // pass -- table switch instruction 630ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 631ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 632ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 633ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 634ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { 635ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // type is the internal name of the type of exceptions handled by the handler, 636ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // or null to catch any exceptions (for "finally" blocks). 637ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski considerName(type); 638ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 639ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 640ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // type instruction 641ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 642ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitTypeInsn(int opcode, String type) { 643ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // type is the operand of the instruction to be visited. This operand must be the 644ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // internal name of an object or array class. 645ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski considerName(type); 646ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 647ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 648ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 649ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitVarInsn(int opcode, int var) { 650ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // pass -- local variable instruction 651ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 652ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 653ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 654ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski private class MySignatureVisitor extends SignatureVisitor { 655ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 656ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public MySignatureVisitor() { 657528ddbf71ab1cac494e9a1aa50b9c8b76ba29586Deepanshu Gupta super(Main.ASM_VERSION); 658ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 659ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 660ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // --------------------------------------------------- 661ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // --- SignatureVisitor 662ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // --------------------------------------------------- 663ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 664ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski private String mCurrentSignatureClass = null; 665ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 666ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // Starts the visit of a signature corresponding to a class or interface type 667ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 668ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitClassType(String name) { 669ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mCurrentSignatureClass = name; 670ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski considerName(name); 671ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 672ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 673ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // Visits an inner class 674ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 675ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitInnerClassType(String name) { 676ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (mCurrentSignatureClass != null) { 677ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mCurrentSignatureClass += "$" + name; 678ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski considerName(mCurrentSignatureClass); 679ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 680ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 681ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 682ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 683ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public SignatureVisitor visitArrayType() { 684ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return new MySignatureVisitor(); 685ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 686ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 687ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 688ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitBaseType(char descriptor) { 689ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // pass -- a primitive type, ignored 690ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 691ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 692ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 693ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public SignatureVisitor visitClassBound() { 694ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return new MySignatureVisitor(); 695ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 696ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 697ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 698ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public SignatureVisitor visitExceptionType() { 699ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return new MySignatureVisitor(); 700ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 701ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 702ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 703ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitFormalTypeParameter(String name) { 704ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // pass 705ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 706ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 707ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 708ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public SignatureVisitor visitInterface() { 709ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return new MySignatureVisitor(); 710ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 711ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 712ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 713ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public SignatureVisitor visitInterfaceBound() { 714ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return new MySignatureVisitor(); 715ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 716ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 717ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 718ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public SignatureVisitor visitParameterType() { 719ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return new MySignatureVisitor(); 720ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 721ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 722ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 723ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public SignatureVisitor visitReturnType() { 724ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return new MySignatureVisitor(); 725ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 726ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 727ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 728ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public SignatureVisitor visitSuperclass() { 729ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return new MySignatureVisitor(); 730ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 731ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 732ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 733ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public SignatureVisitor visitTypeArgument(char wildcard) { 734ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return new MySignatureVisitor(); 735ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 736ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 737ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 738ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitTypeVariable(String name) { 739ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // pass 740ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 741ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 742ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 743ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitTypeArgument() { 744ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // pass 745ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 746ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 747ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 748ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 749ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // --------------------------------------------------- 750ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // --- AnnotationVisitor 751ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // --------------------------------------------------- 752ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 753ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski private class MyAnnotationVisitor extends AnnotationVisitor { 754ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 755ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public MyAnnotationVisitor() { 756528ddbf71ab1cac494e9a1aa50b9c8b76ba29586Deepanshu Gupta super(Main.ASM_VERSION); 757ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 758ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 759ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // Visits a primitive value of an annotation 760ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 761ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visit(String name, Object value) { 762ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // value is the actual value, whose type must be Byte, Boolean, Character, Short, 763ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // Integer, Long, Float, Double, String or Type 764ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (value instanceof Type) { 765ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski considerType((Type) value); 766ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 767ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 768ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 769ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 770ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public AnnotationVisitor visitAnnotation(String name, String desc) { 771ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // desc is the class descriptor of the nested annotation class. 772ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski considerDesc(desc); 773ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return new MyAnnotationVisitor(); 774ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 775ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 776ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 777ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public AnnotationVisitor visitArray(String name) { 778ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return new MyAnnotationVisitor(); 779ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 780ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 781ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 782ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitEnum(String name, String desc, String value) { 783ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // desc is the class descriptor of the enumeration class. 784ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski considerDesc(desc); 785ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 786ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 787ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 788ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski} 789