16c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll/* 26c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll * Copyright (C) 2009 The Android Open Source Project 36c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll * 46c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll * Licensed under the Apache License, Version 2.0 (the "License"); 56c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll * you may not use this file except in compliance with the License. 66c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll * You may obtain a copy of the License at 76c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll * 86c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll * http://www.apache.org/licenses/LICENSE-2.0 96c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll * 106c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll * Unless required by applicable law or agreed to in writing, software 116c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll * distributed under the License is distributed on an "AS IS" BASIS, 126c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll * See the License for the specific language governing permissions and 146c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll * limitations under the License. 156c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll */ 166c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll 176c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Mollpackage com.android.mkstubs; 186c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll 198252cdea30a5a22ae8b2235d7dee2fdd02ba5ccdRaphaelimport com.android.mkstubs.Main.Logger; 208252cdea30a5a22ae8b2235d7dee2fdd02ba5ccdRaphael 216c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Mollimport org.objectweb.asm.AnnotationVisitor; 226c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Mollimport org.objectweb.asm.Attribute; 236c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Mollimport org.objectweb.asm.ClassVisitor; 246c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Mollimport org.objectweb.asm.FieldVisitor; 256c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Mollimport org.objectweb.asm.MethodVisitor; 266c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Mollimport org.objectweb.asm.Opcodes; 276c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll 286c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll/** 298f17caaa8be3e790f0ee26fa5b009b12c56a16d7Raphael Moll * A class visitor that filters out all members (fields, methods and inner classes) that are 30c3c97d1db391f4e400343fd69be11c8b1f951ff3Xavier Ducrohet * either private, default-access or rejected by the {@link Filter}. 316c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll */ 327fb8be5c6ab69d547a49da88093c57acc3694309Tor Norbyeclass FilterClassAdapter extends ClassVisitor { 336c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll 348252cdea30a5a22ae8b2235d7dee2fdd02ba5ccdRaphael private final Logger mLog; 350cb5e26dab4d6c62f7e1ac5a6ddd509ba3ee8c8cRaphael Moll private final Filter mFilter; 360cb5e26dab4d6c62f7e1ac5a6ddd509ba3ee8c8cRaphael Moll private String mClassName; 376c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll 388252cdea30a5a22ae8b2235d7dee2fdd02ba5ccdRaphael public FilterClassAdapter(ClassVisitor writer, Filter filter, Logger log) { 397fb8be5c6ab69d547a49da88093c57acc3694309Tor Norbye super(Opcodes.ASM4, writer); 400cb5e26dab4d6c62f7e1ac5a6ddd509ba3ee8c8cRaphael Moll mFilter = filter; 418252cdea30a5a22ae8b2235d7dee2fdd02ba5ccdRaphael mLog = log; 426c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll } 436c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll 446c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll @Override 456c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll public void visit(int version, int access, String name, String signature, 466c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll String superName, String[] interfaces) { 476c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll 480cb5e26dab4d6c62f7e1ac5a6ddd509ba3ee8c8cRaphael Moll mClassName = name; 496c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll super.visit(version, access, name, signature, superName, interfaces); 506c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll } 516c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll 526c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll @Override 536c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll public void visitEnd() { 546c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll super.visitEnd(); 556c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll } 56c3c97d1db391f4e400343fd69be11c8b1f951ff3Xavier Ducrohet 576c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll /** 586c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll * Visits a field. 59c3c97d1db391f4e400343fd69be11c8b1f951ff3Xavier Ducrohet * 606c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll * {@inheritDoc} 61c3c97d1db391f4e400343fd69be11c8b1f951ff3Xavier Ducrohet * 626c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll * Examples: 636c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll * name = mArg 646c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll * desc = Ljava/Lang/String; 656c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll * signature = null (not a template) or template type 666c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll */ 676c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll @Override 686c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll public FieldVisitor visitField(int access, String name, String desc, 696c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll String signature, Object value) { 70c3c97d1db391f4e400343fd69be11c8b1f951ff3Xavier Ducrohet // only accept public/protected fields 71c3c97d1db391f4e400343fd69be11c8b1f951ff3Xavier Ducrohet if ((access & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED)) == 0) { 726c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll return null; 736c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll } 74c3c97d1db391f4e400343fd69be11c8b1f951ff3Xavier Ducrohet 750cb5e26dab4d6c62f7e1ac5a6ddd509ba3ee8c8cRaphael Moll // filter on field name 760cb5e26dab4d6c62f7e1ac5a6ddd509ba3ee8c8cRaphael Moll String filterName = String.format("%s#%s", mClassName, name); 770cb5e26dab4d6c62f7e1ac5a6ddd509ba3ee8c8cRaphael Moll 780cb5e26dab4d6c62f7e1ac5a6ddd509ba3ee8c8cRaphael Moll if (!mFilter.accept(filterName)) { 798252cdea30a5a22ae8b2235d7dee2fdd02ba5ccdRaphael mLog.debug("- Remove field " + filterName); 800cb5e26dab4d6c62f7e1ac5a6ddd509ba3ee8c8cRaphael Moll return null; 810cb5e26dab4d6c62f7e1ac5a6ddd509ba3ee8c8cRaphael Moll } 82c3c97d1db391f4e400343fd69be11c8b1f951ff3Xavier Ducrohet 830cb5e26dab4d6c62f7e1ac5a6ddd509ba3ee8c8cRaphael Moll // TODO we should produce an error if a filtered desc/signature is being used. 846c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll 856c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll return super.visitField(access, name, desc, signature, value); 866c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll } 876c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll 886c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll /** 896c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll * Visits a method. 90c3c97d1db391f4e400343fd69be11c8b1f951ff3Xavier Ducrohet * 916c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll * {@inheritDoc} 92c3c97d1db391f4e400343fd69be11c8b1f951ff3Xavier Ducrohet * 936c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll * Examples: 946c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll * name = <init> 956c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll * desc = ()V 966c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll * signature = null (not a template) or template type 976c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll */ 986c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll @Override 996c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll public MethodVisitor visitMethod(int access, String name, String desc, 1006c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll String signature, String[] exceptions) { 1016c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll 102c3c97d1db391f4e400343fd69be11c8b1f951ff3Xavier Ducrohet // only accept public/protected methods 103c3c97d1db391f4e400343fd69be11c8b1f951ff3Xavier Ducrohet if ((access & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED)) == 0) { 1046c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll return null; 1056c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll } 106c3c97d1db391f4e400343fd69be11c8b1f951ff3Xavier Ducrohet 1070cb5e26dab4d6c62f7e1ac5a6ddd509ba3ee8c8cRaphael Moll // filter on method name using the non-generic descriptor 1080cb5e26dab4d6c62f7e1ac5a6ddd509ba3ee8c8cRaphael Moll String filterName = String.format("%s#%s%s", mClassName, name, desc); 1096c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll 1100cb5e26dab4d6c62f7e1ac5a6ddd509ba3ee8c8cRaphael Moll if (!mFilter.accept(filterName)) { 1118252cdea30a5a22ae8b2235d7dee2fdd02ba5ccdRaphael mLog.debug("- Remove method " + filterName); 1120cb5e26dab4d6c62f7e1ac5a6ddd509ba3ee8c8cRaphael Moll return null; 1130cb5e26dab4d6c62f7e1ac5a6ddd509ba3ee8c8cRaphael Moll } 1140cb5e26dab4d6c62f7e1ac5a6ddd509ba3ee8c8cRaphael Moll 1150cb5e26dab4d6c62f7e1ac5a6ddd509ba3ee8c8cRaphael Moll // filter on method name using the generic signature 1160cb5e26dab4d6c62f7e1ac5a6ddd509ba3ee8c8cRaphael Moll if (signature != null) { 1170cb5e26dab4d6c62f7e1ac5a6ddd509ba3ee8c8cRaphael Moll filterName = String.format("%s#%s%s", mClassName, name, signature); 118c3c97d1db391f4e400343fd69be11c8b1f951ff3Xavier Ducrohet 1190cb5e26dab4d6c62f7e1ac5a6ddd509ba3ee8c8cRaphael Moll if (!mFilter.accept(filterName)) { 1208252cdea30a5a22ae8b2235d7dee2fdd02ba5ccdRaphael mLog.debug("- Remove method " + filterName); 1210cb5e26dab4d6c62f7e1ac5a6ddd509ba3ee8c8cRaphael Moll return null; 1220cb5e26dab4d6c62f7e1ac5a6ddd509ba3ee8c8cRaphael Moll } 1230cb5e26dab4d6c62f7e1ac5a6ddd509ba3ee8c8cRaphael Moll } 1240cb5e26dab4d6c62f7e1ac5a6ddd509ba3ee8c8cRaphael Moll 1250cb5e26dab4d6c62f7e1ac5a6ddd509ba3ee8c8cRaphael Moll // TODO we should produce an error if a filtered desc/signature/exception is being used. 1266c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll 1276c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll return super.visitMethod(access, name, desc, signature, exceptions); 1286c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll } 1296c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll 1306c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll @Override 1316c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll public AnnotationVisitor visitAnnotation(String desc, boolean visible) { 132c3c97d1db391f4e400343fd69be11c8b1f951ff3Xavier Ducrohet 1330cb5e26dab4d6c62f7e1ac5a6ddd509ba3ee8c8cRaphael Moll // TODO produce an error if a filtered annotation type is being used 1346c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll return super.visitAnnotation(desc, visible); 1356c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll } 1366c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll 1376c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll @Override 1386c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll public void visitAttribute(Attribute attr) { 1396c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll // pass 1406c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll } 1416c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll 1426c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll @Override 1436c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll public void visitInnerClass(String name, String outerName, String innerName, int access) { 1446c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll 145c3c97d1db391f4e400343fd69be11c8b1f951ff3Xavier Ducrohet // only accept public/protected inner classes 146c3c97d1db391f4e400343fd69be11c8b1f951ff3Xavier Ducrohet if ((access & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED)) == 0) { 1476c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll return; 1486c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll } 1496c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll 1500cb5e26dab4d6c62f7e1ac5a6ddd509ba3ee8c8cRaphael Moll // filter on name 1510cb5e26dab4d6c62f7e1ac5a6ddd509ba3ee8c8cRaphael Moll if (!mFilter.accept(name)) { 1520cb5e26dab4d6c62f7e1ac5a6ddd509ba3ee8c8cRaphael Moll return; 1530cb5e26dab4d6c62f7e1ac5a6ddd509ba3ee8c8cRaphael Moll } 1546c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll 1556c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll super.visitInnerClass(name, outerName, innerName, access); 1566c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll } 1576c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll 1586c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll @Override 1596c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll public void visitOuterClass(String owner, String name, String desc) { 1600cb5e26dab4d6c62f7e1ac5a6ddd509ba3ee8c8cRaphael Moll // pass 1616c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll } 1626c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll 1636c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll @Override 1646c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll public void visitSource(String source, String debug) { 1656c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll // pass 1666c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll } 1676c0d467cc25692bf3a9eb36d2d88b895aa18a18dRaphael Moll} 168