1 /* 2 * ProGuard -- shrinking, optimization, obfuscation, and preverification 3 * of Java bytecode. 4 * 5 * Copyright (c) 2002-2009 Eric Lafortune (eric (at) graphics.cornell.edu) 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the Free 9 * Software Foundation; either version 2 of the License, or (at your option) 10 * any later version. 11 * 12 * This program is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15 * more details. 16 * 17 * You should have received a copy of the GNU General Public License along 18 * with this program; if not, write to the Free Software Foundation, Inc., 19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 */ 21 package proguard.obfuscate; 22 23 import proguard.classfile.*; 24 import proguard.classfile.attribute.*; 25 import proguard.classfile.attribute.visitor.AttributeVisitor; 26 import proguard.classfile.constant.*; 27 import proguard.classfile.constant.visitor.ConstantVisitor; 28 import proguard.classfile.util.SimplifiedVisitor; 29 import proguard.classfile.visitor.ClassVisitor; 30 31 /** 32 * This ClassVisitor marks all NameAndType constant pool entries that are 33 * being used in the program classes it visits. 34 * 35 * @see NameAndTypeShrinker 36 * 37 * @author Eric Lafortune 38 */ 39 public class NameAndTypeUsageMarker 40 extends SimplifiedVisitor 41 implements ClassVisitor, 42 ConstantVisitor, 43 AttributeVisitor 44 { 45 // A visitor info flag to indicate the NameAndType constant pool entry is being used. 46 private static final Object USED = new Object(); 47 48 49 // Implementations for ClassVisitor. 50 51 public void visitProgramClass(ProgramClass programClass) 52 { 53 // Mark the NameAndType entries referenced by all other constant pool 54 // entries. 55 programClass.constantPoolEntriesAccept(this); 56 57 // Mark the NameAndType entries referenced by all EnclosingMethod 58 // attributes. 59 programClass.attributesAccept(this); 60 } 61 62 63 // Implementations for ConstantVisitor. 64 65 public void visitAnyConstant(Clazz clazz, Constant constant) {} 66 67 68 public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant) 69 { 70 visitRefConstant(clazz, fieldrefConstant); 71 } 72 73 74 public void visitInterfaceMethodrefConstant(Clazz clazz, InterfaceMethodrefConstant interfaceMethodrefConstant) 75 { 76 visitRefConstant(clazz, interfaceMethodrefConstant); 77 } 78 79 80 public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant) 81 { 82 visitRefConstant(clazz, methodrefConstant); 83 } 84 85 86 private void visitRefConstant(Clazz clazz, RefConstant refConstant) 87 { 88 markNameAndTypeConstant(clazz, refConstant.u2nameAndTypeIndex); 89 } 90 91 92 // Implementations for AttributeVisitor. 93 94 public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} 95 96 97 public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute) 98 { 99 if (enclosingMethodAttribute.u2nameAndTypeIndex != 0) 100 { 101 markNameAndTypeConstant(clazz, enclosingMethodAttribute.u2nameAndTypeIndex); 102 } 103 } 104 105 106 // Small utility methods. 107 108 /** 109 * Marks the given UTF-8 constant pool entry of the given class. 110 */ 111 private void markNameAndTypeConstant(Clazz clazz, int index) 112 { 113 markAsUsed((NameAndTypeConstant)((ProgramClass)clazz).getConstant(index)); 114 } 115 116 117 /** 118 * Marks the given VisitorAccepter as being used. 119 * In this context, the VisitorAccepter will be a NameAndTypeConstant object. 120 */ 121 private static void markAsUsed(VisitorAccepter visitorAccepter) 122 { 123 visitorAccepter.setVisitorInfo(USED); 124 } 125 126 127 /** 128 * Returns whether the given VisitorAccepter has been marked as being used. 129 * In this context, the VisitorAccepter will be a NameAndTypeConstant object. 130 */ 131 static boolean isUsed(VisitorAccepter visitorAccepter) 132 { 133 return visitorAccepter.getVisitorInfo() == USED; 134 } 135 } 136