1b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/* 2b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ProGuard -- shrinking, optimization, obfuscation, and preverification 3b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * of Java bytecode. 4b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 5b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) 6b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 7b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This program is free software; you can redistribute it and/or modify it 8b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * under the terms of the GNU General Public License as published by the Free 9b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Software Foundation; either version 2 of the License, or (at your option) 10b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * any later version. 11b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 12b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This program is distributed in the hope that it will be useful, but WITHOUT 13b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * more details. 16b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 17b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * You should have received a copy of the GNU General Public License along 18b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * with this program; if not, write to the Free Software Foundation, Inc., 19b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 21b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopackage proguard.classfile.util; 22b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 23b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.*; 24b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.visitor.*; 25b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 26b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/** 27b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This class provides methods to find class members in a given class or in its 28b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * hierarchy. 29b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 30b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @author Eric Lafortune 31b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 32b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopublic class MemberFinder 33b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoextends SimplifiedVisitor 34b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimplements MemberVisitor 35b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato{ 36b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private static class MemberFoundException extends RuntimeException {} 37b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private static final MemberFoundException MEMBER_FOUND = new MemberFoundException(); 38b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 39b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private Clazz clazz; 40b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private Member member; 41b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 42b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 43b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 44b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Finds the field with the given name and descriptor in the given 45b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * class or its hierarchy. 46b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 47b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public Field findField(Clazz referencingClass, 48b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Clazz clazz, 49b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String name, 50b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String descriptor) 51b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 52b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return (Field)findMember(referencingClass, clazz, name, descriptor, true); 53b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 54b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 55b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 56b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 57b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Finds the method with the given name and descriptor in the given 58b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * class or its hierarchy. 59b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 60b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public Method findMethod(Clazz referencingClass, 61b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Clazz clazz, 62b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String name, 63b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String descriptor) 64b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 65b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return (Method)findMember(referencingClass, clazz, name, descriptor, false); 66b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 67b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 68b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 69b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 70b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Finds the class member with the given name and descriptor in the given 71b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * class or its hierarchy. 72b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 73b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public Member findMember(Clazz referencingClass, 74b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Clazz clazz, 75b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String name, 76b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String descriptor, 77b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato boolean isField) 78b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 79b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Organize a search in the hierarchy of superclasses and interfaces. 80b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // The class member may be in a different class, if the code was 81b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // compiled with "-target 1.2" or higher (the default in JDK 1.4). 82b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato try 83b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 84b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.clazz = null; 85b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.member = null; 86b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato clazz.hierarchyAccept(true, true, true, false, isField ? 87b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato (ClassVisitor)new NamedFieldVisitor(name, descriptor, 88b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato new MemberClassAccessFilter(referencingClass, this)) : 89b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato (ClassVisitor)new NamedMethodVisitor(name, descriptor, 90b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato new MemberClassAccessFilter(referencingClass, this))); 91b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 92b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato catch (MemberFoundException ex) 93b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 94b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // We've found the member we were looking for. 95b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 96b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 97b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return member; 98b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 99b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 100b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 101b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 102b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Returns the corresponding class of the most recently found class 103b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * member. 104b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 105b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public Clazz correspondingClass() 106b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 107b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return clazz; 108b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 109b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 110b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 111b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 112b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Returns whether the given method is overridden anywhere down the class 113b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * hierarchy. 114b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 115b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public boolean isOverriden(Clazz clazz, 116b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Method method) 117b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 118b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String name = method.getName(clazz); 119b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String descriptor = method.getDescriptor(clazz); 120b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 121b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Go looking for the method down the class hierarchy. 122b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato try 123b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 124b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.clazz = null; 125b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.member = null; 126b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 127b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato clazz.hierarchyAccept(false, false, false, true, 128b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato new NamedMethodVisitor(name, descriptor, 129b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato new MemberAccessFilter(0, ClassConstants.INTERNAL_ACC_PRIVATE, this))); 130b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 131b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato catch (MemberFoundException ex) 132b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 133b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // We've found an overriding method. 134b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return true; 135b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 136b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 137b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return false; 138b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 139b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 140b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 141b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 142b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Returns whether the given field is shadowed anywhere down the class 143b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * hierarchy. 144b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 145b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public boolean isShadowed(Clazz clazz, 146b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Field field) 147b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 148b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String name = field.getName(clazz); 149b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String descriptor = field.getDescriptor(clazz); 150b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 151b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Go looking for the field down the class hierarchy. 152b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato try 153b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 154b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.clazz = null; 155b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.member = null; 156b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato clazz.hierarchyAccept(false, false, false, true, 157b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato new NamedFieldVisitor(name, descriptor, 158b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato new MemberAccessFilter(0, ClassConstants.INTERNAL_ACC_PRIVATE, this))); 159b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 160b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato catch (MemberFoundException ex) 161b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 162b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // We've found a shadowing field. 163b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return true; 164b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 165b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 166b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return false; 167b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 168b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 169b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 170b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato// // Implementations for ClassVisitor. 171b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato// 172b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato// private void visitAnyClass(Clazz clazz) 173b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato// { 174b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato// if (member == null) 175b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato// { 176b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato// member = isField ? 177b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato// (Member)clazz.findField(name, descriptor) : 178b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato// (Member)clazz.findMethod(name, descriptor); 179b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato// 180b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato// if (member != null) 181b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato// { 182b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato// this.clazz = clazz; 183b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato// } 184b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato// } 185b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato// } 186b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 187b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 188b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Implementations for MemberVisitor. 189b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 190b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void visitAnyMember(Clazz clazz, Member member) 191b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 192b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.clazz = clazz; 193b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.member = member; 194b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 195b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato throw MEMBER_FOUND; 196b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 197b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato} 198