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) 310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (getClass().getClassLoader().loadClass(className) != null) { 311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } catch (ClassNotFoundException e) { 314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // ignore 315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Add it to the dependency set for the currently visited class, as needed. 318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assert mCurrentDepSet != null; 319d2a411840c58eaee05499bab0190e3f3656e2e84Deepanshu Gupta mCurrentDepSet.add(className); 320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Considers this array of names using considerName(). 324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void considerNames(String[] classNames) { 326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (classNames != null) { 327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (String className : classNames) { 328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerName(className); 329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Considers this signature or type signature by invoking the {@link SignatureVisitor} 335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * on it. 336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void considerSignature(String signature) { 338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (signature != null) { 339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SignatureReader sr = new SignatureReader(signature); 340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // SignatureReader.accept will call accessType so we don't really have 341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // to differentiate where the signature comes from. 342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sr.accept(new MySignatureVisitor()); 343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Considers this {@link Type}. For arrays, the element type is considered. 348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * If the type is an object, it's internal name is considered. 349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void considerType(Type t) { 351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t != null) { 352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t.getSort() == Type.ARRAY) { 353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski t = t.getElementType(); 354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t.getSort() == Type.OBJECT) { 356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerName(t.getInternalName()); 357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Considers a descriptor string. The descriptor is converted to a {@link Type} 363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * and then considerType() is invoked. 364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public boolean considerDesc(String desc) { 366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (desc != null) { 367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski try { 368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (desc.length() > 0 && desc.charAt(0) == '(') { 369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // This is a method descriptor with arguments and a return type. 370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Type t = Type.getReturnType(desc); 371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerType(t); 372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (Type arg : Type.getArgumentTypes(desc)) { 374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerType(arg); 375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Type t = Type.getType(desc); 379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerType(t); 380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } catch (ArrayIndexOutOfBoundsException e) { 383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // ignore, not a valid type. 384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // --------------------------------------------------- 391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // --- ClassVisitor, FieldVisitor 392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // --------------------------------------------------- 393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Visits a class header 395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visit(int version, int access, String name, 397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String signature, String superName, String[] interfaces) { 398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // signature is the signature of this class. May be null if the class is not a generic 399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // one, and does not extend or implement generic classes or interfaces. 400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (signature != null) { 402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerSignature(signature); 403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // superName is the internal of name of the super class (see getInternalName). 406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // For interfaces, the super class is Object. May be null but only for the Object class. 407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerName(superName); 408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // interfaces is the internal names of the class's interfaces (see getInternalName). 410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // May be null. 411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerNames(interfaces); 412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public AnnotationVisitor visitAnnotation(String desc, boolean visible) { 417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // desc is the class descriptor of the annotation class. 418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerDesc(desc); 419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MyAnnotationVisitor(); 420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitAttribute(Attribute attr) { 424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass 425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Visits the end of a class 428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitEnd() { 430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass 431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private class MyFieldVisitor extends FieldVisitor { 434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public MyFieldVisitor() { 436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski super(Opcodes.ASM4); 437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public AnnotationVisitor visitAnnotation(String desc, boolean visible) { 441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // desc is the class descriptor of the annotation class. 442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerDesc(desc); 443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MyAnnotationVisitor(); 444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitAttribute(Attribute attr) { 448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass 449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Visits the end of a class 452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitEnd() { 454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass 455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public FieldVisitor visitField(int access, String name, String desc, 460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String signature, Object value) { 461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // desc is the field's descriptor (see Type). 462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerDesc(desc); 463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // signature is the field's signature. May be null if the field's type does not use 465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // generic types. 466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerSignature(signature); 467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MyFieldVisitor(); 469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitInnerClass(String name, String outerName, String innerName, int access) { 473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // name is the internal name of an inner class (see getInternalName). 474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Note: outerName/innerName seems to be null when we're reading the 475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // _Original_ClassName classes generated by layoutlib_create. 476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outerName != null) { 477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerName(name); 478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public MethodVisitor visitMethod(int access, String name, String desc, 483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String signature, String[] exceptions) { 484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // desc is the method's descriptor (see Type). 485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerDesc(desc); 486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // signature is the method's signature. May be null if the method parameters, return 487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // type and exceptions do not use generic types. 488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerSignature(signature); 489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MyMethodVisitor(); 491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitOuterClass(String owner, String name, String desc) { 495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass 496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitSource(String source, String debug) { 500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass 501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // --------------------------------------------------- 505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // --- MethodVisitor 506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // --------------------------------------------------- 507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private class MyMethodVisitor extends MethodVisitor { 509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public MyMethodVisitor() { 511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski super(Opcodes.ASM4); 512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public AnnotationVisitor visitAnnotationDefault() { 517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MyAnnotationVisitor(); 518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitCode() { 522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass 523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // field instruction 526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitFieldInsn(int opcode, String owner, String name, String desc) { 5284a0f93bd32b8dd9b3c351680ad82e461d5111f38Deepanshu Gupta // owner is the class that declares the field. 5294a0f93bd32b8dd9b3c351680ad82e461d5111f38Deepanshu Gupta considerName(owner); 530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // desc is the field's descriptor (see Type). 531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerDesc(desc); 532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitFrame(int type, int local, Object[] local2, int stack, Object[] stack2) { 536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass 537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitIincInsn(int var, int increment) { 541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass -- an IINC instruction 542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitInsn(int opcode) { 546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass -- a zero operand instruction 547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitIntInsn(int opcode, int operand) { 551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass -- a single int operand instruction 552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitJumpInsn(int opcode, Label label) { 556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass -- a jump instruction 557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitLabel(Label label) { 561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass -- a label target 562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // instruction to load a constant from the stack 565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitLdcInsn(Object cst) { 567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (cst instanceof Type) { 568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerType((Type) cst); 569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitLineNumber(int line, Label start) { 574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass 575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitLocalVariable(String name, String desc, 579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String signature, Label start, Label end, int index) { 580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // desc is the type descriptor of this local variable. 581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerDesc(desc); 582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // signature is the type signature of this local variable. May be null if the local 583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // variable type does not use generic types. 584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerSignature(signature); 585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { 589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass -- a lookup switch instruction 590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitMaxs(int maxStack, int maxLocals) { 594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass 595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // instruction that invokes a method 598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitMethodInsn(int opcode, String owner, String name, String desc) { 600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // owner is the internal name of the method's owner class 602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!considerDesc(owner) && owner.indexOf('/') != -1) { 603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerName(owner); 604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // desc is the method's descriptor (see Type). 606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerDesc(desc); 607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // instruction multianewarray, whatever that is 610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitMultiANewArrayInsn(String desc, int dims) { 612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // desc an array type descriptor. 614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerDesc(desc); 615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, 619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski boolean visible) { 620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // desc is the class descriptor of the annotation class. 621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerDesc(desc); 622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MyAnnotationVisitor(); 623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) { 627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass -- table switch instruction 628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { 633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // type is the internal name of the type of exceptions handled by the handler, 634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // or null to catch any exceptions (for "finally" blocks). 635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerName(type); 636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // type instruction 639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitTypeInsn(int opcode, String type) { 641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // type is the operand of the instruction to be visited. This operand must be the 642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // internal name of an object or array class. 643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerName(type); 644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitVarInsn(int opcode, int var) { 648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass -- local variable instruction 649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private class MySignatureVisitor extends SignatureVisitor { 653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public MySignatureVisitor() { 655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski super(Opcodes.ASM4); 656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 657282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // --------------------------------------------------- 659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // --- SignatureVisitor 660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // --------------------------------------------------- 661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private String mCurrentSignatureClass = null; 663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Starts the visit of a signature corresponding to a class or interface type 665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitClassType(String name) { 667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCurrentSignatureClass = name; 668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerName(name); 669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Visits an inner class 672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitInnerClassType(String name) { 674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mCurrentSignatureClass != null) { 675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCurrentSignatureClass += "$" + name; 676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerName(mCurrentSignatureClass); 677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public SignatureVisitor visitArrayType() { 682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MySignatureVisitor(); 683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitBaseType(char descriptor) { 687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass -- a primitive type, ignored 688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public SignatureVisitor visitClassBound() { 692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MySignatureVisitor(); 693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public SignatureVisitor visitExceptionType() { 697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MySignatureVisitor(); 698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 699282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 700282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitFormalTypeParameter(String name) { 702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass 703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 704282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 705282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 706282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public SignatureVisitor visitInterface() { 707282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MySignatureVisitor(); 708282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public SignatureVisitor visitInterfaceBound() { 712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MySignatureVisitor(); 713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public SignatureVisitor visitParameterType() { 717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MySignatureVisitor(); 718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 720282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public SignatureVisitor visitReturnType() { 722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MySignatureVisitor(); 723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public SignatureVisitor visitSuperclass() { 727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MySignatureVisitor(); 728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public SignatureVisitor visitTypeArgument(char wildcard) { 732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MySignatureVisitor(); 733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitTypeVariable(String name) { 737282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass 738282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 739282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 740282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitTypeArgument() { 742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass 743282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 744282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 745282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 746282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 747282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // --------------------------------------------------- 748282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // --- AnnotationVisitor 749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // --------------------------------------------------- 750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private class MyAnnotationVisitor extends AnnotationVisitor { 752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public MyAnnotationVisitor() { 754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski super(Opcodes.ASM4); 755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 756282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 757282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Visits a primitive value of an annotation 758282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visit(String name, Object value) { 760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // value is the actual value, whose type must be Byte, Boolean, Character, Short, 761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Integer, Long, Float, Double, String or Type 762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value instanceof Type) { 763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerType((Type) value); 764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 767282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 768282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public AnnotationVisitor visitAnnotation(String name, String desc) { 769282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // desc is the class descriptor of the nested annotation class. 770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerDesc(desc); 771282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MyAnnotationVisitor(); 772282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 774282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public AnnotationVisitor visitArray(String name) { 776282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MyAnnotationVisitor(); 777282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 778282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 779282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 780282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitEnum(String name, String desc, String value) { 781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // desc is the class descriptor of the enumeration class. 782282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski considerDesc(desc); 783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 785282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 787