14306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll/* 24306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * Copyright (C) 2012 The Android Open Source Project 34306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * 44306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * Licensed under the Apache License, Version 2.0 (the "License"); 54306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * you may not use this file except in compliance with the License. 64306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * You may obtain a copy of the License at 74306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * 84306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * http://www.apache.org/licenses/LICENSE-2.0 94306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * 104306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * Unless required by applicable law or agreed to in writing, software 114306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * distributed under the License is distributed on an "AS IS" BASIS, 124306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * See the License for the specific language governing permissions and 144306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * limitations under the License. 154306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll */ 164306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 174306096a4351030cab4ea413b5e87460b60a84bfRaphael Mollpackage com.android.tools.layoutlib.create; 184306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 194306096a4351030cab4ea413b5e87460b60a84bfRaphael Mollimport com.android.tools.layoutlib.annotations.VisibleForTesting; 204306096a4351030cab4ea413b5e87460b60a84bfRaphael Mollimport com.android.tools.layoutlib.annotations.VisibleForTesting.Visibility; 214306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 224306096a4351030cab4ea413b5e87460b60a84bfRaphael Mollimport org.objectweb.asm.AnnotationVisitor; 234306096a4351030cab4ea413b5e87460b60a84bfRaphael Mollimport org.objectweb.asm.Attribute; 244306096a4351030cab4ea413b5e87460b60a84bfRaphael Mollimport org.objectweb.asm.ClassReader; 254306096a4351030cab4ea413b5e87460b60a84bfRaphael Mollimport org.objectweb.asm.ClassVisitor; 264306096a4351030cab4ea413b5e87460b60a84bfRaphael Mollimport org.objectweb.asm.FieldVisitor; 274306096a4351030cab4ea413b5e87460b60a84bfRaphael Mollimport org.objectweb.asm.Label; 284306096a4351030cab4ea413b5e87460b60a84bfRaphael Mollimport org.objectweb.asm.MethodVisitor; 29bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Mollimport org.objectweb.asm.Opcodes; 304306096a4351030cab4ea413b5e87460b60a84bfRaphael Mollimport org.objectweb.asm.Type; 314306096a4351030cab4ea413b5e87460b60a84bfRaphael Mollimport org.objectweb.asm.signature.SignatureReader; 324306096a4351030cab4ea413b5e87460b60a84bfRaphael Mollimport org.objectweb.asm.signature.SignatureVisitor; 334306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 344306096a4351030cab4ea413b5e87460b60a84bfRaphael Mollimport java.io.IOException; 354306096a4351030cab4ea413b5e87460b60a84bfRaphael Mollimport java.util.ArrayList; 364306096a4351030cab4ea413b5e87460b60a84bfRaphael Mollimport java.util.Enumeration; 374306096a4351030cab4ea413b5e87460b60a84bfRaphael Mollimport java.util.List; 384306096a4351030cab4ea413b5e87460b60a84bfRaphael Mollimport java.util.Map; 394306096a4351030cab4ea413b5e87460b60a84bfRaphael Mollimport java.util.Map.Entry; 404306096a4351030cab4ea413b5e87460b60a84bfRaphael Mollimport java.util.Set; 414306096a4351030cab4ea413b5e87460b60a84bfRaphael Mollimport java.util.TreeMap; 424306096a4351030cab4ea413b5e87460b60a84bfRaphael Mollimport java.util.TreeSet; 434306096a4351030cab4ea413b5e87460b60a84bfRaphael Mollimport java.util.zip.ZipEntry; 444306096a4351030cab4ea413b5e87460b60a84bfRaphael Mollimport java.util.zip.ZipFile; 454306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 464306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll/** 474306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * Analyzes the input JAR using the ASM java bytecode manipulation library 484306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * to list the classes and their dependencies. A "dependency" is a class 494306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * used by another class. 504306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll */ 514306096a4351030cab4ea413b5e87460b60a84bfRaphael Mollpublic class DependencyFinder { 524306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 534306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // Note: a bunch of stuff has package-level access for unit tests. Consider it private. 544306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 554306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll /** Output logger. */ 564306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll private final Log mLog; 574306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 584306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll /** 594306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * Creates a new analyzer. 604306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * 614306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * @param log The log output. 624306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll */ 634306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll public DependencyFinder(Log log) { 644306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll mLog = log; 654306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 664306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 674306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll /** 684306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * Starts the analysis using parameters from the constructor. 694306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * 704306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * @param osJarPath The input source JARs to parse. 714306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * @return A pair: [0]: map { class FQCN => set of FQCN class dependencies }. 724306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * [1]: map { missing class FQCN => set of FQCN class that uses it. } 734306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll */ 744306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll public List<Map<String, Set<String>>> findDeps(List<String> osJarPath) throws IOException { 754306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 764306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll Map<String, ClassReader> zipClasses = parseZip(osJarPath); 774306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll mLog.info("Found %d classes in input JAR%s.", 784306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll zipClasses.size(), 794306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll osJarPath.size() > 1 ? "s" : ""); 804306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 814306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll Map<String, Set<String>> deps = findClassesDeps(zipClasses); 824306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 834306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll Map<String, Set<String>> missing = findMissingClasses(deps, zipClasses.keySet()); 844306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 854306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll List<Map<String, Set<String>>> result = new ArrayList<Map<String,Set<String>>>(2); 864306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll result.add(deps); 874306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll result.add(missing); 884306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll return result; 894306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 904306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 914306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll /** 924306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * Prints dependencies to the current logger, found stuff and missing stuff. 934306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll */ 944306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll public void printAllDeps(List<Map<String, Set<String>>> result) { 954306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll assert result.size() == 2; 964306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll Map<String, Set<String>> deps = result.get(0); 974306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll Map<String, Set<String>> missing = result.get(1); 984306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 994306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // Print all dependences found in the format: 1004306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // +Found: <FQCN from zip> 1014306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // uses: FQCN 1024306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 1034306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll mLog.info("++++++ %d Entries found in source JARs", deps.size()); 1044306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll mLog.info(""); 1054306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 1064306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll for (Entry<String, Set<String>> entry : deps.entrySet()) { 1074306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll mLog.info( "+Found : %s", entry.getKey()); 1084306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll for (String dep : entry.getValue()) { 1094306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll mLog.info(" uses: %s", dep); 1104306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 1114306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 1124306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll mLog.info(""); 1134306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 1144306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 1154306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 1164306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // Now print all missing dependences in the format: 1174306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // -Missing <FQCN>: 1184306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // used by: <FQCN> 1194306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 1204306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll mLog.info(""); 1214306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll mLog.info("------ %d Entries missing from source JARs", missing.size()); 1224306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll mLog.info(""); 1234306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 1244306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll for (Entry<String, Set<String>> entry : missing.entrySet()) { 1254306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll mLog.info( "-Missing : %s", entry.getKey()); 1264306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll for (String dep : entry.getValue()) { 1274306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll mLog.info(" used by: %s", dep); 1284306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 1294306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 1304306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll mLog.info(""); 1314306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 1324306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 1334306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 1344306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll /** 1354306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * Prints only a summary of the missing dependencies to the current logger. 1364306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll */ 1374306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll public void printMissingDeps(List<Map<String, Set<String>>> result) { 1384306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll assert result.size() == 2; 1394306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll @SuppressWarnings("unused") Map<String, Set<String>> deps = result.get(0); 1404306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll Map<String, Set<String>> missing = result.get(1); 1414306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 1424306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll for (String fqcn : missing.keySet()) { 1434306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll mLog.info("%s", fqcn); 1444306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 1454306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 1464306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 1474306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // ---------------- 1484306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 1494306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll /** 1504306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * Parses a JAR file and returns a list of all classes founds using a map 1514306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * class name => ASM ClassReader. Class names are in the form "android.view.View". 1524306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll */ 1534306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll Map<String,ClassReader> parseZip(List<String> jarPathList) throws IOException { 1544306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll TreeMap<String, ClassReader> classes = new TreeMap<String, ClassReader>(); 1554306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 1564306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll for (String jarPath : jarPathList) { 1574306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll ZipFile zip = new ZipFile(jarPath); 1584306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll Enumeration<? extends ZipEntry> entries = zip.entries(); 1594306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll ZipEntry entry; 1604306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll while (entries.hasMoreElements()) { 1614306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll entry = entries.nextElement(); 1624306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll if (entry.getName().endsWith(".class")) { 1634306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll ClassReader cr = new ClassReader(zip.getInputStream(entry)); 1644306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll String className = classReaderToClassName(cr); 1654306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll classes.put(className, cr); 1664306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 1674306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 1684306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 1694306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 1704306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll return classes; 1714306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 1724306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 1734306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll /** 1744306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * Utility that returns the fully qualified binary class name for a ClassReader. 1754306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * E.g. it returns something like android.view.View. 1764306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll */ 1774306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll static String classReaderToClassName(ClassReader classReader) { 1784306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll if (classReader == null) { 1794306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll return null; 1804306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } else { 1814306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll return classReader.getClassName().replace('/', '.'); 1824306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 1834306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 1844306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 1854306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll /** 1864306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * Utility that returns the fully qualified binary class name from a path-like FQCN. 1874306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * E.g. it returns android.view.View from android/view/View. 1884306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll */ 1894306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll static String internalToBinaryClassName(String className) { 1904306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll if (className == null) { 1914306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll return null; 1924306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } else { 1934306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll return className.replace('/', '.'); 1944306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 1954306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 1964306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 1974306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll /** 1984306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * Finds all dependencies for all classes in keepClasses which are also 1994306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * listed in zipClasses. Returns a map of all the dependencies found. 2004306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll */ 2014306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll Map<String, Set<String>> findClassesDeps(Map<String, ClassReader> zipClasses) { 2024306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 2034306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // The dependencies that we'll collect. 2044306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // It's a map Class name => uses class names. 2054306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll Map<String, Set<String>> dependencyMap = new TreeMap<String, Set<String>>(); 2064306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 2074306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll DependencyVisitor visitor = getVisitor(); 2084306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 2094306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll int count = 0; 2104306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll try { 2114306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll for (Entry<String, ClassReader> entry : zipClasses.entrySet()) { 2124306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll String name = entry.getKey(); 2134306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 2144306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll TreeSet<String> set = new TreeSet<String>(); 2154306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll dependencyMap.put(name, set); 2164306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll visitor.setDependencySet(set); 2174306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 2184306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll ClassReader cr = entry.getValue(); 2194306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll cr.accept(visitor, 0 /* flags */); 2204306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 2214306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll visitor.setDependencySet(null); 2224306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 2234306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll mLog.debugNoln("Visited %d classes\r", ++count); 2244306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 2254306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } finally { 2264306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll mLog.debugNoln("\n"); 2274306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 2284306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 2294306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll return dependencyMap; 2304306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 2314306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 2324306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll /** 2334306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * Computes which classes FQCN were found as dependencies that are NOT listed 2344306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * in the original JAR classes. 2354306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * 2364306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * @param deps The map { FQCN => dependencies[] } returned by {@link #findClassesDeps(Map)}. 2374306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * @param zipClasses The set of all classes FQCN found in the JAR files. 2384306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * @return A map { FQCN not found in the zipClasses => classes using it } 2394306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll */ 2404306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll private Map<String, Set<String>> findMissingClasses( 2414306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll Map<String, Set<String>> deps, 2424306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll Set<String> zipClasses) { 2434306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll Map<String, Set<String>> missing = new TreeMap<String, Set<String>>(); 2444306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 2454306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll for (Entry<String, Set<String>> entry : deps.entrySet()) { 2464306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll String name = entry.getKey(); 2474306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 2484306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll for (String dep : entry.getValue()) { 2494306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll if (!zipClasses.contains(dep)) { 2504306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // This dependency doesn't exist in the zip classes. 2514306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll Set<String> set = missing.get(dep); 2524306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll if (set == null) { 2534306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll set = new TreeSet<String>(); 2544306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll missing.put(dep, set); 2554306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 2564306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll set.add(name); 2574306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 2584306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 2594306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 2604306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 2614306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 2624306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll return missing; 2634306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 2644306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 2654306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 2664306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // ---------------------------------- 2674306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 2684306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll /** 2694306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * Instantiates a new DependencyVisitor. Useful for unit tests. 2704306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll */ 2714306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll @VisibleForTesting(visibility=Visibility.PRIVATE) 2724306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll DependencyVisitor getVisitor() { 2734306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll return new DependencyVisitor(); 2744306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 2754306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 2764306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll /** 2774306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * Visitor to collect all the type dependencies from a class. 2784306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll */ 279bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public class DependencyVisitor extends ClassVisitor { 2804306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 2814306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll private Set<String> mCurrentDepSet; 2824306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 2834306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll /** 2844306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * Creates a new visitor that will find all the dependencies for the visited class. 2854306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll */ 2864306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll public DependencyVisitor() { 287bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll super(Opcodes.ASM4); 2884306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 2894306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 2904306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll /** 2914306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * Sets the {@link Set} where to record direct dependencies for this class. 2924306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * This will change before each {@link ClassReader#accept(ClassVisitor, int)} call. 2934306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll */ 2944306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll public void setDependencySet(Set<String> set) { 2954306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll mCurrentDepSet = set; 2964306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 2974306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 2984306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll /** 2994306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * Considers the given class name as a dependency. 3004306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll */ 3014306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll public void considerName(String className) { 3024306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll if (className == null) { 3034306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll return; 3044306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 3054306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 3064306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll className = internalToBinaryClassName(className); 3074306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 3084306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll try { 3094306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // exclude classes that are part of the default JRE (the one executing this program) 3104306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll if (getClass().getClassLoader().loadClass(className) != null) { 3114306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll return; 3124306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 3134306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } catch (ClassNotFoundException e) { 3144306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // ignore 3154306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 3164306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 3174306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // Add it to the dependency set for the currently visited class, as needed. 3184306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll assert mCurrentDepSet != null; 3194306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll if (mCurrentDepSet != null) { 3204306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll mCurrentDepSet.add(className); 3214306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 3224306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 3234306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 3244306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll /** 3254306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * Considers this array of names using considerName(). 3264306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll */ 3274306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll public void considerNames(String[] classNames) { 3284306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll if (classNames != null) { 3294306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll for (String className : classNames) { 3304306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll considerName(className); 3314306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 3324306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 3334306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 3344306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 3354306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll /** 3364306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * Considers this signature or type signature by invoking the {@link SignatureVisitor} 3374306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * on it. 3384306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll */ 3394306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll public void considerSignature(String signature) { 3404306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll if (signature != null) { 3414306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll SignatureReader sr = new SignatureReader(signature); 3424306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // SignatureReader.accept will call accessType so we don't really have 3434306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // to differentiate where the signature comes from. 344bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll sr.accept(new MySignatureVisitor()); 3454306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 3464306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 3474306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 3484306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll /** 3494306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * Considers this {@link Type}. For arrays, the element type is considered. 3504306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * If the type is an object, it's internal name is considered. 3514306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll */ 3524306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll public void considerType(Type t) { 3534306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll if (t != null) { 3544306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll if (t.getSort() == Type.ARRAY) { 3554306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll t = t.getElementType(); 3564306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 3574306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll if (t.getSort() == Type.OBJECT) { 3584306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll considerName(t.getInternalName()); 3594306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 3604306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 3614306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 3624306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 3634306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll /** 3644306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * Considers a descriptor string. The descriptor is converted to a {@link Type} 3654306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll * and then considerType() is invoked. 3664306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll */ 3674306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll public boolean considerDesc(String desc) { 3684306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll if (desc != null) { 3694306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll try { 3704306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll if (desc.length() > 0 && desc.charAt(0) == '(') { 3714306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // This is a method descriptor with arguments and a return type. 3724306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll Type t = Type.getReturnType(desc); 3734306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll considerType(t); 3744306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 3754306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll for (Type arg : Type.getArgumentTypes(desc)) { 3764306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll considerType(arg); 3774306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 3784306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 3794306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } else { 3804306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll Type t = Type.getType(desc); 3814306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll considerType(t); 3824306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 3834306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll return true; 3844306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } catch (ArrayIndexOutOfBoundsException e) { 3854306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // ignore, not a valid type. 3864306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 3874306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 3884306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll return false; 3894306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 3904306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 3914306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 3924306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // --------------------------------------------------- 3934306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // --- ClassVisitor, FieldVisitor 3944306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // --------------------------------------------------- 3954306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 3964306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // Visits a class header 397bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 3984306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll public void visit(int version, int access, String name, 3994306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll String signature, String superName, String[] interfaces) { 4004306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // signature is the signature of this class. May be null if the class is not a generic 4014306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // one, and does not extend or implement generic classes or interfaces. 4024306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 4034306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll if (signature != null) { 4044306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll considerSignature(signature); 4054306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 4064306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 4074306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // superName is the internal of name of the super class (see getInternalName). 4084306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // For interfaces, the super class is Object. May be null but only for the Object class. 4094306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll considerName(superName); 4104306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 4114306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // interfaces is the internal names of the class's interfaces (see getInternalName). 4124306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // May be null. 4134306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll considerNames(interfaces); 4144306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 4154306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 416bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll 417bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 4184306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll public AnnotationVisitor visitAnnotation(String desc, boolean visible) { 4194306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // desc is the class descriptor of the annotation class. 4204306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll considerDesc(desc); 421bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll return new MyAnnotationVisitor(); 4224306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 4234306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 424bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 4254306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll public void visitAttribute(Attribute attr) { 4264306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // pass 4274306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 4284306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 4294306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // Visits the end of a class 430bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 4314306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll public void visitEnd() { 4324306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // pass 4334306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 4344306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 435bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll private class MyFieldVisitor extends FieldVisitor { 436bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll 437bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public MyFieldVisitor() { 438bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll super(Opcodes.ASM4); 439bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 440bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll 441bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 442bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public AnnotationVisitor visitAnnotation(String desc, boolean visible) { 443bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // desc is the class descriptor of the annotation class. 444bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll considerDesc(desc); 445bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll return new MyAnnotationVisitor(); 446bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 447bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll 448bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 449bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public void visitAttribute(Attribute attr) { 450bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // pass 451bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 452bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll 453bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // Visits the end of a class 454bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 455bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public void visitEnd() { 456bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // pass 457bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 458bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 459bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll 460bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 4614306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll public FieldVisitor visitField(int access, String name, String desc, 4624306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll String signature, Object value) { 4634306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // desc is the field's descriptor (see Type). 4644306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll considerDesc(desc); 4654306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 4664306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // signature is the field's signature. May be null if the field's type does not use 4674306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // generic types. 4684306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll considerSignature(signature); 4694306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 470bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll return new MyFieldVisitor(); 4714306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 4724306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 473bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 4744306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll public void visitInnerClass(String name, String outerName, String innerName, int access) { 4754306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // name is the internal name of an inner class (see getInternalName). 4764306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // Note: outerName/innerName seems to be null when we're reading the 4774306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // _Original_ClassName classes generated by layoutlib_create. 4784306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll if (outerName != null) { 4794306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll considerName(name); 4804306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 4814306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 4824306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 483bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 4844306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll public MethodVisitor visitMethod(int access, String name, String desc, 4854306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll String signature, String[] exceptions) { 4864306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // desc is the method's descriptor (see Type). 4874306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll considerDesc(desc); 4884306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // signature is the method's signature. May be null if the method parameters, return 4894306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // type and exceptions do not use generic types. 4904306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll considerSignature(signature); 4914306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 492bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll return new MyMethodVisitor(); 4934306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 4944306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 495bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 4964306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll public void visitOuterClass(String owner, String name, String desc) { 4974306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // pass 4984306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 4994306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 500bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 5014306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll public void visitSource(String source, String debug) { 5024306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // pass 5034306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 5044306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 5054306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 5064306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // --------------------------------------------------- 5074306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // --- MethodVisitor 5084306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // --------------------------------------------------- 5094306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 510bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll private class MyMethodVisitor extends MethodVisitor { 5114306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 512bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public MyMethodVisitor() { 513bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll super(Opcodes.ASM4); 514bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 5154306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 5164306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 517bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 518bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public AnnotationVisitor visitAnnotationDefault() { 519bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll return new MyAnnotationVisitor(); 520bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 5214306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 522bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 523bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public void visitCode() { 524bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // pass 525bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 5264306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 527bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // field instruction 528bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 529bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public void visitFieldInsn(int opcode, String owner, String name, String desc) { 530bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // name is the field's name. 531bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // desc is the field's descriptor (see Type). 532bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll considerDesc(desc); 533bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 5344306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 535bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 536bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public void visitFrame(int type, int local, Object[] local2, int stack, Object[] stack2) { 537bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // pass 538bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 5394306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 540bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 541bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public void visitIincInsn(int var, int increment) { 542bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // pass -- an IINC instruction 543bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 5444306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 545bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 546bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public void visitInsn(int opcode) { 547bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // pass -- a zero operand instruction 548bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 5494306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 550bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 551bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public void visitIntInsn(int opcode, int operand) { 552bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // pass -- a single int operand instruction 553bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 5544306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 555bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 556bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public void visitJumpInsn(int opcode, Label label) { 557bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // pass -- a jump instruction 5584306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 5594306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 560bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 561bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public void visitLabel(Label label) { 562bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // pass -- a label target 563bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 5644306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 565bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // instruction to load a constant from the stack 566bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 567bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public void visitLdcInsn(Object cst) { 568bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll if (cst instanceof Type) { 569bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll considerType((Type) cst); 570bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 571bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 5724306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 573bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 574bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public void visitLineNumber(int line, Label start) { 575bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // pass 576bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 5774306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 578bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 579bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public void visitLocalVariable(String name, String desc, 580bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll String signature, Label start, Label end, int index) { 581bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // desc is the type descriptor of this local variable. 582bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll considerDesc(desc); 583bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // signature is the type signature of this local variable. May be null if the local 584bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // variable type does not use generic types. 585bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll considerSignature(signature); 586bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 5874306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 588bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 589bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { 590bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // pass -- a lookup switch instruction 591bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 5924306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 593bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 594bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public void visitMaxs(int maxStack, int maxLocals) { 595bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // pass 5964306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 5974306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 598bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // instruction that invokes a method 599bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 600bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public void visitMethodInsn(int opcode, String owner, String name, String desc) { 6014306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 602bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // owner is the internal name of the method's owner class 603bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll if (!considerDesc(owner) && owner.indexOf('/') != -1) { 604bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll considerName(owner); 605bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 606bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // desc is the method's descriptor (see Type). 607bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll considerDesc(desc); 608bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 6094306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 610bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // instruction multianewarray, whatever that is 611bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 612bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public void visitMultiANewArrayInsn(String desc, int dims) { 6134306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 614bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // desc an array type descriptor. 615bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll considerDesc(desc); 616bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 6174306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 618bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 619bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, 620bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll boolean visible) { 621bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // desc is the class descriptor of the annotation class. 622bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll considerDesc(desc); 623bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll return new MyAnnotationVisitor(); 624bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 6254306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 626bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 627bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) { 628bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // pass -- table switch instruction 629bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll 630bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 6314306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 632bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 633bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { 634bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // type is the internal name of the type of exceptions handled by the handler, 635bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // or null to catch any exceptions (for "finally" blocks). 6364306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll considerName(type); 6374306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 6384306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 639bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // type instruction 640bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 641bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public void visitTypeInsn(int opcode, String type) { 642bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // type is the operand of the instruction to be visited. This operand must be the 643bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // internal name of an object or array class. 644bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll considerName(type); 645bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 646bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll 647bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 648bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public void visitVarInsn(int opcode, int var) { 649bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // pass -- local variable instruction 650bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 6514306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 6524306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 653bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll private class MySignatureVisitor extends SignatureVisitor { 6544306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 655bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public MySignatureVisitor() { 656bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll super(Opcodes.ASM4); 657bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 6584306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 659bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // --------------------------------------------------- 660bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // --- SignatureVisitor 661bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // --------------------------------------------------- 6624306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 663bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll private String mCurrentSignatureClass = null; 6644306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 665bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // Starts the visit of a signature corresponding to a class or interface type 666bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 667bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public void visitClassType(String name) { 668bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll mCurrentSignatureClass = name; 669bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll considerName(name); 6704306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 6714306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 672bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // Visits an inner class 673bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 674bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public void visitInnerClassType(String name) { 675bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll if (mCurrentSignatureClass != null) { 676bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll mCurrentSignatureClass += "$" + name; 677bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll considerName(mCurrentSignatureClass); 678bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 679bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 6804306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 681bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 682bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public SignatureVisitor visitArrayType() { 683bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll return new MySignatureVisitor(); 684bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 6854306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 686bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 687bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public void visitBaseType(char descriptor) { 688bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // pass -- a primitive type, ignored 689bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 6904306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 691bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 692bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public SignatureVisitor visitClassBound() { 693bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll return new MySignatureVisitor(); 694bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 6954306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 696bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 697bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public SignatureVisitor visitExceptionType() { 698bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll return new MySignatureVisitor(); 699bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 7004306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 701bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 702bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public void visitFormalTypeParameter(String name) { 703bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // pass 704bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 7054306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 706bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 707bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public SignatureVisitor visitInterface() { 708bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll return new MySignatureVisitor(); 709bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 7104306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 711bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 712bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public SignatureVisitor visitInterfaceBound() { 713bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll return new MySignatureVisitor(); 714bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 7154306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 716bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 717bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public SignatureVisitor visitParameterType() { 718bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll return new MySignatureVisitor(); 719bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 7204306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 721bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 722bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public SignatureVisitor visitReturnType() { 723bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll return new MySignatureVisitor(); 724bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 7254306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 726bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 727bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public SignatureVisitor visitSuperclass() { 728bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll return new MySignatureVisitor(); 729bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 7304306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 731bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 732bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public SignatureVisitor visitTypeArgument(char wildcard) { 733bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll return new MySignatureVisitor(); 734bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 7354306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 736bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 737bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public void visitTypeVariable(String name) { 738bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // pass 739bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 740bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll 741bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 742bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public void visitTypeArgument() { 743bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // pass 744bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 7454306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 7464306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 7474306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 7484306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // --------------------------------------------------- 7494306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // --- AnnotationVisitor 7504306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll // --------------------------------------------------- 7514306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 752bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll private class MyAnnotationVisitor extends AnnotationVisitor { 7534306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 754bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public MyAnnotationVisitor() { 755bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll super(Opcodes.ASM4); 7564306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 7574306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 758bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // Visits a primitive value of an annotation 759bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 760bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public void visit(String name, Object value) { 761bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // value is the actual value, whose type must be Byte, Boolean, Character, Short, 762bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // Integer, Long, Float, Double, String or Type 763bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll if (value instanceof Type) { 764bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll considerType((Type) value); 765bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 766bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 7674306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 768bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 769bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public AnnotationVisitor visitAnnotation(String name, String desc) { 770bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // desc is the class descriptor of the nested annotation class. 771bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll considerDesc(desc); 772bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll return new MyAnnotationVisitor(); 773bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 7744306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll 775bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 776bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public AnnotationVisitor visitArray(String name) { 777bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll return new MyAnnotationVisitor(); 778bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 779bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll 780bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll @Override 781bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll public void visitEnum(String name, String desc, String value) { 782bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll // desc is the class descriptor of the enumeration class. 783bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll considerDesc(desc); 784bce1011dd2a371c587d2e39ad8c3d446b63049d0Raphael Moll } 7854306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 7864306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll } 7874306096a4351030cab4ea413b5e87460b60a84bfRaphael Moll} 788