1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 2282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Copyright (C) 2012 The Android Open Source Project 3282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 4282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 5282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * you may not use this file except in compliance with the License. 6282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * You may obtain a copy of the License at 7282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 8282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 9282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Unless required by applicable law or agreed to in writing, software 11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 12282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * See the License for the specific language governing permissions and 14282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * limitations under the License. 15282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 16282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 17282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipackage com.android.tools.layoutlib.create; 18282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 19282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.tools.layoutlib.annotations.VisibleForTesting; 20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.tools.layoutlib.annotations.VisibleForTesting.Visibility; 21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport org.objectweb.asm.AnnotationVisitor; 23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport org.objectweb.asm.Attribute; 24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport org.objectweb.asm.ClassReader; 25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport org.objectweb.asm.ClassVisitor; 26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport org.objectweb.asm.FieldVisitor; 27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport org.objectweb.asm.Label; 28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport org.objectweb.asm.MethodVisitor; 29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport org.objectweb.asm.Opcodes; 30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport org.objectweb.asm.Type; 31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport org.objectweb.asm.signature.SignatureReader; 32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport org.objectweb.asm.signature.SignatureVisitor; 33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.io.IOException; 35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.util.ArrayList; 36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.util.Enumeration; 37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.util.List; 38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.util.Map; 39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.util.Map.Entry; 40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.util.Set; 41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.util.TreeMap; 42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.util.TreeSet; 43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.util.zip.ZipEntry; 44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.util.zip.ZipFile; 45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/** 47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Analyzes the input JAR using the ASM java bytecode manipulation library 48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * to list the classes and their dependencies. A "dependency" is a class 49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * used by another class. 50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipublic class DependencyFinder { 52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Note: a bunch of stuff has package-level access for unit tests. Consider it private. 54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** Output logger. */ 56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private final Log mLog; 57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Creates a new analyzer. 60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param log The log output. 62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public DependencyFinder(Log log) { 64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLog = log; 65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Starts the analysis using parameters from the constructor. 69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param osJarPath The input source JARs to parse. 71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @return A pair: [0]: map { class FQCN => set of FQCN class dependencies }. 72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * [1]: map { missing class FQCN => set of FQCN class that uses it. } 73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public List<Map<String, Set<String>>> findDeps(List<String> osJarPath) throws IOException { 75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Map<String, ClassReader> zipClasses = parseZip(osJarPath); 77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLog.info("Found %d classes in input JAR%s.", 78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zipClasses.size(), 79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski osJarPath.size() > 1 ? "s" : ""); 80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Map<String, Set<String>> deps = findClassesDeps(zipClasses); 82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Map<String, Set<String>> missing = findMissingClasses(deps, zipClasses.keySet()); 84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski List<Map<String, Set<String>>> result = new ArrayList<Map<String,Set<String>>>(2); 86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result.add(deps); 87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result.add(missing); 88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return result; 89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Prints dependencies to the current logger, found stuff and missing stuff. 93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void printAllDeps(List<Map<String, Set<String>>> result) { 95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assert result.size() == 2; 96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Map<String, Set<String>> deps = result.get(0); 97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Map<String, Set<String>> missing = result.get(1); 98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Print all dependences found in the format: 100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // +Found: <FQCN from zip> 101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // uses: FQCN 102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLog.info("++++++ %d Entries found in source JARs", deps.size()); 104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLog.info(""); 105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (Entry<String, Set<String>> entry : deps.entrySet()) { 107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLog.info( "+Found : %s", entry.getKey()); 108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (String dep : entry.getValue()) { 109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLog.info(" uses: %s", dep); 110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLog.info(""); 113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Now print all missing dependences in the format: 117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // -Missing <FQCN>: 118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // used by: <FQCN> 119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLog.info(""); 121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLog.info("------ %d Entries missing from source JARs", missing.size()); 122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLog.info(""); 123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (Entry<String, Set<String>> entry : missing.entrySet()) { 125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLog.info( "-Missing : %s", entry.getKey()); 126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (String dep : entry.getValue()) { 127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLog.info(" used by: %s", dep); 128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLog.info(""); 131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Prints only a summary of the missing dependencies to the current logger. 136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void printMissingDeps(List<Map<String, Set<String>>> result) { 138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assert result.size() == 2; 139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @SuppressWarnings("unused") Map<String, Set<String>> deps = result.get(0); 140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Map<String, Set<String>> missing = result.get(1); 141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (String fqcn : missing.keySet()) { 143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLog.info("%s", fqcn); 144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // ---------------- 148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Parses a JAR file and returns a list of all classes founds using a map 151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * class name => ASM ClassReader. Class names are in the form "android.view.View". 152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Map<String,ClassReader> parseZip(List<String> jarPathList) throws IOException { 154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski TreeMap<String, ClassReader> classes = new TreeMap<String, ClassReader>(); 155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (String jarPath : jarPathList) { 157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipFile zip = new ZipFile(jarPath); 158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Enumeration<? extends ZipEntry> entries = zip.entries(); 159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry entry; 160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (entries.hasMoreElements()) { 161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski entry = entries.nextElement(); 162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (entry.getName().endsWith(".class")) { 163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ClassReader cr = new ClassReader(zip.getInputStream(entry)); 164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String className = classReaderToClassName(cr); 165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski classes.put(className, cr); 166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return classes; 171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Utility that returns the fully qualified binary class name for a ClassReader. 175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * E.g. it returns something like android.view.View. 176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski static String classReaderToClassName(ClassReader classReader) { 178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (classReader == null) { 179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return null; 180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return classReader.getClassName().replace('/', '.'); 182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Utility that returns the fully qualified binary class name from a path-like FQCN. 187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * E.g. it returns android.view.View from android/view/View. 188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski static String internalToBinaryClassName(String className) { 190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (className == null) { 191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return null; 192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return className.replace('/', '.'); 194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Finds all dependencies for all classes in keepClasses which are also 199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * listed in zipClasses. Returns a map of all the dependencies found. 200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Map<String, Set<String>> findClassesDeps(Map<String, ClassReader> zipClasses) { 202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // The dependencies that we'll collect. 204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // It's a map Class name => uses class names. 205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Map<String, Set<String>> dependencyMap = new TreeMap<String, Set<String>>(); 206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DependencyVisitor visitor = getVisitor(); 208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int count = 0; 210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski try { 211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (Entry<String, ClassReader> entry : zipClasses.entrySet()) { 212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String name = entry.getKey(); 213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski TreeSet<String> set = new TreeSet<String>(); 215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dependencyMap.put(name, set); 216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski visitor.setDependencySet(set); 217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ClassReader cr = entry.getValue(); 219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski cr.accept(visitor, 0 /* flags */); 220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski visitor.setDependencySet(null); 222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLog.debugNoln("Visited %d classes\r", ++count); 224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } finally { 226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLog.debugNoln("\n"); 227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return dependencyMap; 230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Computes which classes FQCN were found as dependencies that are NOT listed 234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * in the original JAR classes. 235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param deps The map { FQCN => dependencies[] } returned by {@link #findClassesDeps(Map)}. 237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param zipClasses The set of all classes FQCN found in the JAR files. 238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @return A map { FQCN not found in the zipClasses => classes using it } 239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private Map<String, Set<String>> findMissingClasses( 241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Map<String, Set<String>> deps, 242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Set<String> zipClasses) { 243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Map<String, Set<String>> missing = new TreeMap<String, Set<String>>(); 244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (Entry<String, Set<String>> entry : deps.entrySet()) { 246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String name = entry.getKey(); 247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (String dep : entry.getValue()) { 249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!zipClasses.contains(dep)) { 250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // This dependency doesn't exist in the zip classes. 251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Set<String> set = missing.get(dep); 252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (set == null) { 253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski set = new TreeSet<String>(); 254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski missing.put(dep, set); 255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski set.add(name); 257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return missing; 263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // ---------------------------------- 267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Instantiates a new DependencyVisitor. Useful for unit tests. 270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @VisibleForTesting(visibility=Visibility.PRIVATE) 272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DependencyVisitor getVisitor() { 273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new DependencyVisitor(); 274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Visitor to collect all the type dependencies from a class. 278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public class DependencyVisitor extends ClassVisitor { 280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private Set<String> mCurrentDepSet; 282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Creates a new visitor that will find all the dependencies for the visited class. 285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public DependencyVisitor() { 287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski super(Opcodes.ASM4); 288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Sets the {@link Set} where to record direct dependencies for this class. 292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * This will change before each {@link ClassReader#accept(ClassVisitor, int)} call. 293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void setDependencySet(Set<String> set) { 295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCurrentDepSet = set; 296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Considers the given class name as a dependency. 300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void considerName(String className) { 302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (className == null) { 303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski className = internalToBinaryClassName(className); 307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski try { 309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // exclude classes that are part of the default JRE (the one executing this program) 31086caef1892e1ce063e0e880396c8deaa3a6a171dDeepanshu Gupta // or in java package (we won't be able to load them anyway). 31186caef1892e1ce063e0e880396c8deaa3a6a171dDeepanshu Gupta if (className.startsWith("java.") || 31286caef1892e1ce063e0e880396c8deaa3a6a171dDeepanshu Gupta getClass().getClassLoader().loadClass(className) != null) { 313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } catch (ClassNotFoundException e) { 316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // ignore 317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Add it to the dependency set for the currently visited class, as needed. 320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assert mCurrentDepSet != null; 321d2a411840c58eaee05499bab0190e3f3656e2e84Deepanshu Gupta mCurrentDepSet.add(className); 322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Considers this array of names using considerName(). 326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void considerNames(String[] classNames) { 328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (classNames != null) { 329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (String className : classNames) { 330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerName(className); 331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Considers this signature or type signature by invoking the {@link SignatureVisitor} 337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * on it. 338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void considerSignature(String signature) { 340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (signature != null) { 341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SignatureReader sr = new SignatureReader(signature); 342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // SignatureReader.accept will call accessType so we don't really have 343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // to differentiate where the signature comes from. 344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sr.accept(new MySignatureVisitor()); 345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Considers this {@link Type}. For arrays, the element type is considered. 350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * If the type is an object, it's internal name is considered. 351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void considerType(Type t) { 353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t != null) { 354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t.getSort() == Type.ARRAY) { 355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski t = t.getElementType(); 356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t.getSort() == Type.OBJECT) { 358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerName(t.getInternalName()); 359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Considers a descriptor string. The descriptor is converted to a {@link Type} 365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * and then considerType() is invoked. 366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public boolean considerDesc(String desc) { 368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (desc != null) { 369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski try { 370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (desc.length() > 0 && desc.charAt(0) == '(') { 371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // This is a method descriptor with arguments and a return type. 372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Type t = Type.getReturnType(desc); 373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerType(t); 374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (Type arg : Type.getArgumentTypes(desc)) { 376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerType(arg); 377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Type t = Type.getType(desc); 381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerType(t); 382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } catch (ArrayIndexOutOfBoundsException e) { 385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // ignore, not a valid type. 386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // --------------------------------------------------- 393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // --- ClassVisitor, FieldVisitor 394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // --------------------------------------------------- 395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Visits a class header 397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visit(int version, int access, String name, 399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String signature, String superName, String[] interfaces) { 400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // signature is the signature of this class. May be null if the class is not a generic 401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // one, and does not extend or implement generic classes or interfaces. 402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (signature != null) { 404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerSignature(signature); 405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // superName is the internal of name of the super class (see getInternalName). 408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // For interfaces, the super class is Object. May be null but only for the Object class. 409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerName(superName); 410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // interfaces is the internal names of the class's interfaces (see getInternalName). 412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // May be null. 413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerNames(interfaces); 414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public AnnotationVisitor visitAnnotation(String desc, boolean visible) { 419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // desc is the class descriptor of the annotation class. 420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerDesc(desc); 421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MyAnnotationVisitor(); 422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitAttribute(Attribute attr) { 426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass 427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Visits the end of a class 430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitEnd() { 432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass 433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private class MyFieldVisitor extends FieldVisitor { 436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public MyFieldVisitor() { 438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski super(Opcodes.ASM4); 439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public AnnotationVisitor visitAnnotation(String desc, boolean visible) { 443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // desc is the class descriptor of the annotation class. 444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerDesc(desc); 445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MyAnnotationVisitor(); 446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitAttribute(Attribute attr) { 450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass 451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Visits the end of a class 454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitEnd() { 456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass 457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public FieldVisitor visitField(int access, String name, String desc, 462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String signature, Object value) { 463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // desc is the field's descriptor (see Type). 464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerDesc(desc); 465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // signature is the field's signature. May be null if the field's type does not use 467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // generic types. 468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerSignature(signature); 469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MyFieldVisitor(); 471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitInnerClass(String name, String outerName, String innerName, int access) { 475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // name is the internal name of an inner class (see getInternalName). 476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Note: outerName/innerName seems to be null when we're reading the 477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // _Original_ClassName classes generated by layoutlib_create. 478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outerName != null) { 479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerName(name); 480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public MethodVisitor visitMethod(int access, String name, String desc, 485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String signature, String[] exceptions) { 486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // desc is the method's descriptor (see Type). 487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerDesc(desc); 488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // signature is the method's signature. May be null if the method parameters, return 489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // type and exceptions do not use generic types. 490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerSignature(signature); 491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MyMethodVisitor(); 493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitOuterClass(String owner, String name, String desc) { 497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass 498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitSource(String source, String debug) { 502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass 503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // --------------------------------------------------- 507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // --- MethodVisitor 508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // --------------------------------------------------- 509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private class MyMethodVisitor extends MethodVisitor { 511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public MyMethodVisitor() { 513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski super(Opcodes.ASM4); 514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public AnnotationVisitor visitAnnotationDefault() { 519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MyAnnotationVisitor(); 520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitCode() { 524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass 525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // field instruction 528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitFieldInsn(int opcode, String owner, String name, String desc) { 5304a0f93bd32b8dd9b3c351680ad82e461d5111f38Deepanshu Gupta // owner is the class that declares the field. 5314a0f93bd32b8dd9b3c351680ad82e461d5111f38Deepanshu Gupta considerName(owner); 532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // desc is the field's descriptor (see Type). 533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerDesc(desc); 534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitFrame(int type, int local, Object[] local2, int stack, Object[] stack2) { 538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass 539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitIincInsn(int var, int increment) { 543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass -- an IINC instruction 544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitInsn(int opcode) { 548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass -- a zero operand instruction 549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitIntInsn(int opcode, int operand) { 553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass -- a single int operand instruction 554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitJumpInsn(int opcode, Label label) { 558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass -- a jump instruction 559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitLabel(Label label) { 563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass -- a label target 564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // instruction to load a constant from the stack 567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitLdcInsn(Object cst) { 569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (cst instanceof Type) { 570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerType((Type) cst); 571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitLineNumber(int line, Label start) { 576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass 577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitLocalVariable(String name, String desc, 581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String signature, Label start, Label end, int index) { 582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // desc is the type descriptor of this local variable. 583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerDesc(desc); 584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // signature is the type signature of this local variable. May be null if the local 585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // variable type does not use generic types. 586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerSignature(signature); 587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { 591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass -- a lookup switch instruction 592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitMaxs(int maxStack, int maxLocals) { 596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass 597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // instruction that invokes a method 600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitMethodInsn(int opcode, String owner, String name, String desc) { 602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // owner is the internal name of the method's owner class 604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!considerDesc(owner) && owner.indexOf('/') != -1) { 605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerName(owner); 606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // desc is the method's descriptor (see Type). 608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerDesc(desc); 609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // instruction multianewarray, whatever that is 612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitMultiANewArrayInsn(String desc, int dims) { 614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // desc an array type descriptor. 616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerDesc(desc); 617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, 621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski boolean visible) { 622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // desc is the class descriptor of the annotation class. 623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerDesc(desc); 624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MyAnnotationVisitor(); 625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) { 629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass -- table switch instruction 630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { 635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // type is the internal name of the type of exceptions handled by the handler, 636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // or null to catch any exceptions (for "finally" blocks). 637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerName(type); 638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // type instruction 641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitTypeInsn(int opcode, String type) { 643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // type is the operand of the instruction to be visited. This operand must be the 644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // internal name of an object or array class. 645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerName(type); 646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitVarInsn(int opcode, int var) { 650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass -- local variable instruction 651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private class MySignatureVisitor extends SignatureVisitor { 655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public MySignatureVisitor() { 657282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski super(Opcodes.ASM4); 658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // --------------------------------------------------- 661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // --- SignatureVisitor 662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // --------------------------------------------------- 663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private String mCurrentSignatureClass = null; 665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Starts the visit of a signature corresponding to a class or interface type 667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitClassType(String name) { 669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCurrentSignatureClass = name; 670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerName(name); 671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Visits an inner class 674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitInnerClassType(String name) { 676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mCurrentSignatureClass != null) { 677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCurrentSignatureClass += "$" + name; 678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerName(mCurrentSignatureClass); 679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public SignatureVisitor visitArrayType() { 684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MySignatureVisitor(); 685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitBaseType(char descriptor) { 689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass -- a primitive type, ignored 690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public SignatureVisitor visitClassBound() { 694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MySignatureVisitor(); 695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public SignatureVisitor visitExceptionType() { 699282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MySignatureVisitor(); 700282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitFormalTypeParameter(String name) { 704282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass 705282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 706282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 707282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 708282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public SignatureVisitor visitInterface() { 709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MySignatureVisitor(); 710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public SignatureVisitor visitInterfaceBound() { 714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MySignatureVisitor(); 715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public SignatureVisitor visitParameterType() { 719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MySignatureVisitor(); 720282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public SignatureVisitor visitReturnType() { 724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MySignatureVisitor(); 725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public SignatureVisitor visitSuperclass() { 729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MySignatureVisitor(); 730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public SignatureVisitor visitTypeArgument(char wildcard) { 734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MySignatureVisitor(); 735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 737282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 738282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitTypeVariable(String name) { 739282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass 740282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 743282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitTypeArgument() { 744282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass 745282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 746282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 747282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 748282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // --------------------------------------------------- 750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // --- AnnotationVisitor 751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // --------------------------------------------------- 752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private class MyAnnotationVisitor extends AnnotationVisitor { 754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public MyAnnotationVisitor() { 756282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski super(Opcodes.ASM4); 757282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 758282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Visits a primitive value of an annotation 760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visit(String name, Object value) { 762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // value is the actual value, whose type must be Byte, Boolean, Character, Short, 763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Integer, Long, Float, Double, String or Type 764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value instanceof Type) { 765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerType((Type) value); 766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 767282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 768282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 769282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public AnnotationVisitor visitAnnotation(String name, String desc) { 771282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // desc is the class descriptor of the nested annotation class. 772282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerDesc(desc); 773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MyAnnotationVisitor(); 774282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 776282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 777282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public AnnotationVisitor visitArray(String name) { 778282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MyAnnotationVisitor(); 779282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 780282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 782282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitEnum(String name, String desc, String value) { 783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // desc is the class descriptor of the enumeration class. 784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerDesc(desc); 785282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 789