Home | History | Annotate | Download | only in editor
      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