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.classfile.editor; 22 23 import proguard.classfile.*; 24 import proguard.classfile.constant.*; 25 import proguard.classfile.constant.visitor.ConstantVisitor; 26 27 /** 28 * This ConstantVisitor adds all constants that it visits to the constant pool 29 * of a given target class. 30 * 31 * @author Eric Lafortune 32 */ 33 public class ConstantAdder 34 implements ConstantVisitor 35 { 36 private final ConstantPoolEditor constantPoolEditor; 37 38 private int constantIndex; 39 40 41 /** 42 * Creates a new ConstantAdder that will copy constants into the given 43 * target class. 44 */ 45 public ConstantAdder(ProgramClass targetClass) 46 { 47 constantPoolEditor = new ConstantPoolEditor(targetClass); 48 } 49 50 51 /** 52 * Adds a copy of the specified constant in the given class and returns 53 * its index. If the specified index is 0, the returned value is 0 too. 54 */ 55 public int addConstant(Clazz clazz, int constantIndex) 56 { 57 clazz.constantPoolEntryAccept(constantIndex, this); 58 59 return this.constantIndex; 60 } 61 62 63 /** 64 * Adds a copy of the given constant in the given class and returns 65 * its index. 66 */ 67 public int addConstant(Clazz clazz, Constant constant) 68 { 69 constant.accept(clazz, this); 70 71 return this.constantIndex; 72 } 73 74 75 /** 76 * Returns the index of the most recently created constant in the constant 77 * pool of the target class. 78 */ 79 public int getConstantIndex() 80 { 81 return constantIndex; 82 } 83 84 85 // Implementations for ConstantVisitor. 86 87 public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant) 88 { 89 constantIndex = 90 constantPoolEditor.addIntegerConstant(integerConstant.getValue()); 91 } 92 93 94 public void visitLongConstant(Clazz clazz, LongConstant longConstant) 95 { 96 constantIndex = 97 constantPoolEditor.addLongConstant(longConstant.getValue()); 98 } 99 100 101 public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant) 102 { 103 constantIndex = 104 constantPoolEditor.addFloatConstant(floatConstant.getValue()); 105 } 106 107 108 public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant) 109 { 110 constantIndex = 111 constantPoolEditor.addDoubleConstant(doubleConstant.getValue()); 112 } 113 114 115 public void visitStringConstant(Clazz clazz, StringConstant stringConstant) 116 { 117 constantIndex = 118 constantPoolEditor.addStringConstant(stringConstant.getString(clazz), 119 stringConstant.referencedClass, 120 stringConstant.referencedMember); 121 } 122 123 124 public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant) 125 { 126 constantIndex = 127 constantPoolEditor.addUtf8Constant(utf8Constant.getString()); 128 } 129 130 131 public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant) 132 { 133 // First add the referenced class constant, with its own referenced class. 134 clazz.constantPoolEntryAccept(fieldrefConstant.u2classIndex, this); 135 136 // Then add the actual field reference constant, with its referenced 137 // class and class member. 138 constantIndex = 139 constantPoolEditor.addFieldrefConstant(constantIndex, 140 fieldrefConstant.getName(clazz), 141 fieldrefConstant.getType(clazz), 142 fieldrefConstant.referencedClass, 143 fieldrefConstant.referencedMember); 144 } 145 146 147 public void visitInterfaceMethodrefConstant(Clazz clazz, InterfaceMethodrefConstant interfaceMethodrefConstant) 148 { 149 // First add the referenced class constant, with its own referenced class. 150 clazz.constantPoolEntryAccept(interfaceMethodrefConstant.u2classIndex, this); 151 152 // Then add the actual interface method reference constant, with its 153 // referenced class and class member. 154 constantIndex = 155 constantPoolEditor.addInterfaceMethodrefConstant(constantIndex, 156 interfaceMethodrefConstant.getName(clazz), 157 interfaceMethodrefConstant.getType(clazz), 158 interfaceMethodrefConstant.referencedClass, 159 interfaceMethodrefConstant.referencedMember); 160 } 161 162 163 public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant) 164 { 165 // First add the referenced class constant, with its own referenced class. 166 clazz.constantPoolEntryAccept(methodrefConstant.u2classIndex, this); 167 168 // Then add the actual method reference constant, with its referenced 169 // class and class member. 170 constantIndex = 171 constantPoolEditor.addMethodrefConstant(constantIndex, 172 methodrefConstant.getName(clazz), 173 methodrefConstant.getType(clazz), 174 methodrefConstant.referencedClass, 175 methodrefConstant.referencedMember); 176 } 177 178 179 public void visitClassConstant(Clazz clazz, ClassConstant classConstant) 180 { 181 // Add the class constant, with its referenced class.. 182 constantIndex = 183 constantPoolEditor.addClassConstant(classConstant.getName(clazz), 184 classConstant.referencedClass); 185 } 186 187 188 public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant) 189 { 190 constantIndex = 191 constantPoolEditor.addNameAndTypeConstant(nameAndTypeConstant.getName(clazz), 192 nameAndTypeConstant.getType(clazz)); 193 } 194 } 195