AsmAnalyzer.java revision 9066cfe9886ac131c34d59ed0e2d287b0e3c0087
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.tools.layoutlib.create;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.objectweb.asm.AnnotationVisitor;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.objectweb.asm.Attribute;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.objectweb.asm.ClassReader;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.objectweb.asm.ClassVisitor;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.objectweb.asm.FieldVisitor;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.objectweb.asm.Label;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.objectweb.asm.MethodVisitor;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.objectweb.asm.Type;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.objectweb.asm.signature.SignatureReader;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.objectweb.asm.signature.SignatureVisitor;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Enumeration;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List;
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Map;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.TreeMap;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Map.Entry;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.regex.Pattern;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.zip.ZipEntry;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.zip.ZipFile;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Analyzes the input JAR using the ASM java bytecode manipulation library
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to list the desired classes and their dependencies.
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class AsmAnalyzer {
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Note: a bunch of stuff has package-level access for unit tests. Consider it private.
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Output logger. */
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final Log mLog;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** The input source JAR to parse. */
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final List<String> mOsSourceJar;
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** The generator to fill with the class list and dependency list. */
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final AsmGenerator mGen;
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Keep all classes that derive from these one (these included). */
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final String[] mDeriveFrom;
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Glob patterns of classes to keep, e.g. "com.foo.*" */
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final String[] mIncludeGlobs;
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Creates a new analyzer.
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param log The log output.
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param osJarPath The input source JARs to parse.
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param gen The generator to fill with the class list and dependency list.
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param deriveFrom Keep all classes that derive from these one (these included).
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param includeGlobs Glob patterns of classes to keep, e.g. "com.foo.*"
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *        ("*" does not matches dots whilst "**" does, "." and "$" are interpreted as-is)
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public AsmAnalyzer(Log log, List<String> osJarPath, AsmGenerator gen,
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String[] deriveFrom, String[] includeGlobs) {
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLog = log;
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mGen = gen;
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOsSourceJar = osJarPath != null ? osJarPath : new ArrayList<String>();
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDeriveFrom = deriveFrom != null ? deriveFrom : new String[0];
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIncludeGlobs = includeGlobs != null ? includeGlobs : new String[0];
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Starts the analysis using parameters from the constructor.
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Fills the generator with classes & dependencies found.
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void analyze() throws IOException, LogAbortException {
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AsmAnalyzer visitor = this;
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Map<String, ClassReader> zipClasses = parseZip(mOsSourceJar);
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLog.info("Found %d classes in input JAR%s.", zipClasses.size(),
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mOsSourceJar.size() > 1 ? "s" : "");
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Map<String, ClassReader> found = findIncludes(zipClasses);
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Map<String, ClassReader> deps = findDeps(zipClasses, found);
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mGen != null) {
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mGen.setKeep(found);
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mGen.setDeps(deps);
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Parses a JAR file and returns a list of all classes founds using a map
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * class name => ASM ClassReader. Class names are in the form "android.view.View".
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Map<String,ClassReader> parseZip(List<String> jarPathList) throws IOException {
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TreeMap<String, ClassReader> classes = new TreeMap<String, ClassReader>();
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (String jarPath : jarPathList) {
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ZipFile zip = new ZipFile(jarPath);
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Enumeration<? extends ZipEntry> entries = zip.entries();
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ZipEntry entry;
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            while (entries.hasMoreElements()) {
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                entry = entries.nextElement();
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (entry.getName().endsWith(".class")) {
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ClassReader cr = new ClassReader(zip.getInputStream(entry));
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String className = classReaderToClassName(cr);
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    classes.put(className, cr);
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return classes;
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Utility that returns the fully qualified binary class name for a ClassReader.
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * E.g. it returns something like android.view.View.
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static String classReaderToClassName(ClassReader classReader) {
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (classReader == null) {
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return classReader.getClassName().replace('/', '.');
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Utility that returns the fully qualified binary class name from a path-like FQCN.
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * E.g. it returns android.view.View from android/view/View.
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static String internalToBinaryClassName(String className) {
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (className == null) {
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return className.replace('/', '.');
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Process the "includes" arrays.
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p/>
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This updates the in_out_found map.
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Map<String, ClassReader> findIncludes(Map<String, ClassReader> zipClasses)
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throws LogAbortException {
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TreeMap<String, ClassReader> found = new TreeMap<String, ClassReader>();
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLog.debug("Find classes to include.");
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (String s : mIncludeGlobs) {
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            findGlobs(s, zipClasses, found);
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (String s : mDeriveFrom) {
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            findClassesDerivingFrom(s, zipClasses, found);
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return found;
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Uses ASM to find the class reader for the given FQCN class name.
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If found, insert it in the in_out_found map.
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the class reader object.
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ClassReader findClass(String className, Map<String, ClassReader> zipClasses,
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Map<String, ClassReader> inOutFound) throws LogAbortException {
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ClassReader classReader = zipClasses.get(className);
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (classReader == null) {
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new LogAbortException("Class %s not found by ASM in %s",
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    className, mOsSourceJar);
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        inOutFound.put(className, classReader);
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return classReader;
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Insert in the inOutFound map all classes found in zipClasses that match the
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * given glob pattern.
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p/>
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The glob pattern is not a regexp. It only accepts the "*" keyword to mean
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * "anything but a period". The "." and "$" characters match themselves.
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The "**" keyword means everything including ".".
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p/>
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Examples:
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <ul>
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <li>com.foo.* matches all classes in the package com.foo but NOT sub-packages.
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <li>com.foo*.*$Event matches all internal Event classes in a com.foo*.* class.
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </ul>
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void findGlobs(String globPattern, Map<String, ClassReader> zipClasses,
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Map<String, ClassReader> inOutFound) throws LogAbortException {
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // transforms the glob pattern in a regexp:
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // - escape "." with "\."
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // - replace "*" by "[^.]*"
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // - escape "$" with "\$"
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // - add end-of-line match $
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        globPattern = globPattern.replaceAll("\\$", "\\\\\\$");
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        globPattern = globPattern.replaceAll("\\.", "\\\\.");
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // prevent ** from being altered by the next rule, then process the * rule and finally
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // the real ** rule (which is now @)
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        globPattern = globPattern.replaceAll("\\*\\*", "@");
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        globPattern = globPattern.replaceAll("\\*", "[^.]*");
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        globPattern = globPattern.replaceAll("@", ".*");
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        globPattern += "$";
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Pattern regexp = Pattern.compile(globPattern);
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (Entry<String, ClassReader> entry : zipClasses.entrySet()) {
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String class_name = entry.getKey();
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (regexp.matcher(class_name).matches()) {
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                findClass(class_name, zipClasses, inOutFound);
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Checks all the classes defined in the JarClassName instance and uses BCEL to
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * determine if they are derived from the given FQCN super class name.
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Inserts the super class and all the class objects found in the map.
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void findClassesDerivingFrom(String super_name, Map<String, ClassReader> zipClasses,
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Map<String, ClassReader> inOutFound) throws LogAbortException {
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ClassReader super_clazz = findClass(super_name, zipClasses, inOutFound);
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (Entry<String, ClassReader> entry : zipClasses.entrySet()) {
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String className = entry.getKey();
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (super_name.equals(className)) {
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ClassReader classReader = entry.getValue();
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ClassReader parent_cr = classReader;
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            while (parent_cr != null) {
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String parent_name = internalToBinaryClassName(parent_cr.getSuperName());
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (parent_name == null) {
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // not found
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (super_name.equals(parent_name)) {
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    inOutFound.put(className, classReader);
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                parent_cr = zipClasses.get(parent_name);
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Instantiates a new DependencyVisitor. Useful for unit tests.
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DependencyVisitor getVisitor(Map<String, ClassReader> zipClasses,
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Map<String, ClassReader> inKeep,
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Map<String, ClassReader> outKeep,
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Map<String, ClassReader> inDeps,
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Map<String, ClassReader> outDeps) {
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return new DependencyVisitor(zipClasses, inKeep, outKeep, inDeps, outDeps);
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Finds all dependencies for all classes in keepClasses which are also
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * listed in zipClasses. Returns a map of all the dependencies found.
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Map<String, ClassReader> findDeps(Map<String, ClassReader> zipClasses,
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Map<String, ClassReader> inOutKeepClasses) {
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TreeMap<String, ClassReader> deps = new TreeMap<String, ClassReader>();
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TreeMap<String, ClassReader> new_deps = new TreeMap<String, ClassReader>();
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TreeMap<String, ClassReader> new_keep = new TreeMap<String, ClassReader>();
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TreeMap<String, ClassReader> temp = new TreeMap<String, ClassReader>();
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DependencyVisitor visitor = getVisitor(zipClasses,
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                inOutKeepClasses, new_keep,
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                deps, new_deps);
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (ClassReader cr : inOutKeepClasses.values()) {
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            cr.accept(visitor, 0 /* flags */);
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (new_deps.size() > 0 || new_keep.size() > 0) {
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            deps.putAll(new_deps);
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            inOutKeepClasses.putAll(new_keep);
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            temp.clear();
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            temp.putAll(new_deps);
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            temp.putAll(new_keep);
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            new_deps.clear();
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            new_keep.clear();
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mLog.debug("Found %1$d to keep, %2$d dependencies.",
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    inOutKeepClasses.size(), deps.size());
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (ClassReader cr : temp.values()) {
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                cr.accept(visitor, 0 /* flags */);
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLog.info("Found %1$d classes to keep, %2$d class dependencies.",
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                inOutKeepClasses.size(), deps.size());
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return deps;
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // ----------------------------------
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Visitor to collect all the type dependencies from a class.
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public class DependencyVisitor
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        implements ClassVisitor, FieldVisitor, MethodVisitor, SignatureVisitor, AnnotationVisitor {
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /** All classes found in the source JAR. */
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private final Map<String, ClassReader> mZipClasses;
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /** Classes from which dependencies are to be found. */
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private final Map<String, ClassReader> mInKeep;
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /** Dependencies already known. */
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private final Map<String, ClassReader> mInDeps;
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /** New dependencies found by this visitor. */
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private final Map<String, ClassReader> mOutDeps;
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /** New classes to keep as-is found by this visitor. */
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private final Map<String, ClassReader> mOutKeep;
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Creates a new visitor that will find all the dependencies for the visited class.
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Types which are already in the zipClasses, keepClasses or inDeps are not marked.
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * New dependencies are marked in outDeps.
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param zipClasses All classes found in the source JAR.
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param inKeep Classes from which dependencies are to be found.
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param inDeps Dependencies already known.
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param outDeps New dependencies found by this visitor.
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public DependencyVisitor(Map<String, ClassReader> zipClasses,
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Map<String, ClassReader> inKeep,
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Map<String, ClassReader> outKeep,
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Map<String,ClassReader> inDeps,
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Map<String,ClassReader> outDeps) {
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mZipClasses = zipClasses;
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mInKeep = inKeep;
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mOutKeep = outKeep;
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mInDeps = inDeps;
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mOutDeps = outDeps;
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Considers the given class name as a dependency.
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * If it does, add to the mOutDeps map.
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void considerName(String className) {
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (className == null) {
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            className = internalToBinaryClassName(className);
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // exclude classes that have already been found
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mInKeep.containsKey(className) ||
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mOutKeep.containsKey(className) ||
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mInDeps.containsKey(className) ||
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mOutDeps.containsKey(className)) {
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // exclude classes that are not part of the JAR file being examined
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ClassReader cr = mZipClasses.get(className);
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (cr == null) {
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // exclude classes that are part of the default JRE (the one executing this program)
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (getClass().getClassLoader().loadClass(className) != null) {
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return;
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (ClassNotFoundException e) {
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // ignore
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // accept this class:
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // - android classes are added to dependencies
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // - non-android classes are added to the list of classes to keep as-is (they don't need
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //   to be stubbed).
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (className.indexOf("android") >= 0) {  // TODO make configurable
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mOutDeps.put(className, cr);
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mOutKeep.put(className, cr);
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Considers this array of names using considerName().
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void considerNames(String[] classNames) {
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (classNames != null) {
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (String className : classNames) {
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    considerName(className);
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Considers this signature or type signature by invoking the {@link SignatureVisitor}
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * on it.
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void considerSignature(String signature) {
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (signature != null) {
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SignatureReader sr = new SignatureReader(signature);
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // SignatureReader.accept will call accessType so we don't really have
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // to differentiate where the signature comes from.
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sr.accept(this);
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Considers this {@link Type}. For arrays, the element type is considered.
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * If the type is an object, it's internal name is considered.
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void considerType(Type t) {
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (t != null) {
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (t.getSort() == Type.ARRAY) {
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    t = t.getElementType();
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (t.getSort() == Type.OBJECT) {
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    considerName(t.getInternalName());
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Considers a descriptor string. The descriptor is converted to a {@link Type}
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * and then considerType() is invoked.
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void considerDesc(String desc) {
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (desc != null) {
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Type t = Type.getType(desc);
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    considerType(t);
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (ArrayIndexOutOfBoundsException e) {
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // ignore, not a valid type.
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // ---------------------------------------------------
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // --- ClassVisitor, FieldVisitor
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // ---------------------------------------------------
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Visits a class header
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visit(int version, int access, String name,
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String signature, String superName, String[] interfaces) {
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // signature is the signature of this class. May be null if the class is not a generic
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // one, and does not extend or implement generic classes or interfaces.
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (signature != null) {
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                considerSignature(signature);
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // superName is the internal of name of the super class (see getInternalName).
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // For interfaces, the super class is Object. May be null but only for the Object class.
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            considerName(superName);
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // interfaces is the internal names of the class's interfaces (see getInternalName).
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // May be null.
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            considerNames(interfaces);
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // desc is the class descriptor of the annotation class.
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            considerDesc(desc);
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return this; // return this to visit annotion values
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visitAttribute(Attribute attr) {
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // pass
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Visits the end of a class
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visitEnd() {
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // pass
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public FieldVisitor visitField(int access, String name, String desc,
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String signature, Object value) {
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // desc is the field's descriptor (see Type).
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            considerDesc(desc);
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // signature is the field's signature. May be null if the field's type does not use
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // generic types.
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            considerSignature(signature);
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return this; // a visitor to visit field annotations and attributes
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visitInnerClass(String name, String outerName, String innerName, int access) {
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // name is the internal name of an inner class (see getInternalName).
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            considerName(name);
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public MethodVisitor visitMethod(int access, String name, String desc,
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String signature, String[] exceptions) {
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // desc is the method's descriptor (see Type).
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            considerDesc(desc);
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // signature is the method's signature. May be null if the method parameters, return
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // type and exceptions do not use generic types.
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            considerSignature(signature);
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return this; // returns this to visit the method
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visitOuterClass(String owner, String name, String desc) {
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // pass
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visitSource(String source, String debug) {
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // pass
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // ---------------------------------------------------
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // --- MethodVisitor
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // ---------------------------------------------------
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public AnnotationVisitor visitAnnotationDefault() {
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return this; // returns this to visit the default value
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visitCode() {
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // pass
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // field instruction
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visitFieldInsn(int opcode, String owner, String name, String desc) {
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // name is the field's name.
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            considerName(name);
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // desc is the field's descriptor (see Type).
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            considerDesc(desc);
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visitFrame(int type, int local, Object[] local2, int stack, Object[] stack2) {
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // pass
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visitIincInsn(int var, int increment) {
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // pass -- an IINC instruction
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visitInsn(int opcode) {
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // pass -- a zero operand instruction
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visitIntInsn(int opcode, int operand) {
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // pass -- a single int operand instruction
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visitJumpInsn(int opcode, Label label) {
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // pass -- a jump instruction
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visitLabel(Label label) {
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // pass -- a label target
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // instruction to load a constant from the stack
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visitLdcInsn(Object cst) {
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (cst instanceof Type) {
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                considerType((Type) cst);
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visitLineNumber(int line, Label start) {
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // pass
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visitLocalVariable(String name, String desc,
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String signature, Label start, Label end, int index) {
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // desc is the type descriptor of this local variable.
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            considerDesc(desc);
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // signature is the type signature of this local variable. May be null if the local
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // variable type does not use generic types.
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            considerSignature(signature);
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // pass -- a lookup switch instruction
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visitMaxs(int maxStack, int maxLocals) {
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // pass
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // instruction that invokes a method
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visitMethodInsn(int opcode, String owner, String name, String desc) {
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // owner is the internal name of the method's owner class
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            considerName(owner);
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // desc is the method's descriptor (see Type).
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            considerDesc(desc);
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // instruction multianewarray, whatever that is
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visitMultiANewArrayInsn(String desc, int dims) {
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // desc an array type descriptor.
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            considerDesc(desc);
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public AnnotationVisitor visitParameterAnnotation(int parameter, String desc,
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                boolean visible) {
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // desc is the class descriptor of the annotation class.
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            considerDesc(desc);
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return this; // return this to visit annotation values
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) {
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // pass -- table switch instruction
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // type is the internal name of the type of exceptions handled by the handler,
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // or null to catch any exceptions (for "finally" blocks).
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            considerName(type);
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // type instruction
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visitTypeInsn(int opcode, String type) {
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // type is the operand of the instruction to be visited. This operand must be the
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // internal name of an object or array class.
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            considerName(type);
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visitVarInsn(int opcode, int var) {
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // pass -- local variable instruction
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // ---------------------------------------------------
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // --- SignatureVisitor
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // ---------------------------------------------------
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private String mCurrentSignatureClass = null;
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Starts the visit of a signature corresponding to a class or interface type
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visitClassType(String name) {
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCurrentSignatureClass = name;
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            considerName(name);
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Visits an inner class
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visitInnerClassType(String name) {
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mCurrentSignatureClass != null) {
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mCurrentSignatureClass += "$" + name;
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                considerName(mCurrentSignatureClass);
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public SignatureVisitor visitArrayType() {
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return this; // returns this to visit the signature of the array element type
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visitBaseType(char descriptor) {
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // pass -- a primitive type, ignored
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public SignatureVisitor visitClassBound() {
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return this; // returns this to visit the signature of the class bound
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public SignatureVisitor visitExceptionType() {
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return this; // return this to visit the signature of the exception type.
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visitFormalTypeParameter(String name) {
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // pass
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public SignatureVisitor visitInterface() {
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return this; // returns this to visit the signature of the interface type
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public SignatureVisitor visitInterfaceBound() {
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return this; // returns this to visit the signature of the interface bound
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public SignatureVisitor visitParameterType() {
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return this; // returns this to visit the signature of the parameter type
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public SignatureVisitor visitReturnType() {
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return this; // returns this to visit the signature of the return type
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public SignatureVisitor visitSuperclass() {
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return this; // returns this to visit the signature of the super class type
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public SignatureVisitor visitTypeArgument(char wildcard) {
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return this; // returns this to visit the signature of the type argument
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visitTypeVariable(String name) {
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // pass
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visitTypeArgument() {
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // pass
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // ---------------------------------------------------
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // --- AnnotationVisitor
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // ---------------------------------------------------
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Visits a primitive value of an annotation
7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visit(String name, Object value) {
7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // value is the actual value, whose type must be Byte, Boolean, Character, Short,
7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Integer, Long, Float, Double, String or Type
7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (value instanceof Type) {
7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                considerType((Type) value);
7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public AnnotationVisitor visitAnnotation(String name, String desc) {
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // desc is the class descriptor of the nested annotation class.
7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            considerDesc(desc);
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return this; // returns this to visit the actual nested annotation value
7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public AnnotationVisitor visitArray(String name) {
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return this; // returns this to visit the actual array value elements
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void visitEnum(String name, String desc, String value) {
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // desc is the class descriptor of the enumeration class.
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            considerDesc(desc);
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
752