1b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/*
2b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ProGuard -- shrinking, optimization, obfuscation, and preverification
3b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *             of Java bytecode.
4b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
52270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom * Copyright (c) 2002-2014 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.optimize.peephole;
22b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
23b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.*;
24b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.attribute.*;
25b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.attribute.annotation.*;
26b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.attribute.annotation.visitor.*;
27b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.attribute.visitor.*;
28b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.constant.*;
29b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.constant.visitor.ConstantVisitor;
302270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstromimport proguard.classfile.editor.*;
312270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstromimport proguard.classfile.util.SimplifiedVisitor;
32b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.visitor.*;
33b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
34b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/**
35b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This ClassVisitor replaces references to classes and class members if the
36b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * classes have targets that are intended to replace them.
37b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
38b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @see VerticalClassMerger
39b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @see ClassReferenceFixer
40b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @see MemberReferenceFixer
41b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @author Eric Lafortune
42b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */
43b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopublic class TargetClassChanger
44b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoextends      SimplifiedVisitor
45b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimplements   ClassVisitor,
46b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato             ConstantVisitor,
47b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato             MemberVisitor,
48b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato             AttributeVisitor,
49b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato             LocalVariableInfoVisitor,
50b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato             LocalVariableTypeInfoVisitor,
51b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato             AnnotationVisitor,
52b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato             ElementValueVisitor
53b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato{
54b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    private static final boolean DEBUG = false;
55b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
56b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
57b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Implementations for ClassVisitor.
58b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
59b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitProgramClass(ProgramClass programClass)
60b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
612270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom        // We're only making changes locally in the class.
622270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom        // Not all other classes may have been retargeted yet.
632270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom
64b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Change the references of the constant pool.
65b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        programClass.constantPoolEntriesAccept(this);
66b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
67b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Change the references of the class members.
68b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        programClass.fieldsAccept(this);
69b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        programClass.methodsAccept(this);
70b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
71b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Change the references of the attributes.
72b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        programClass.attributesAccept(this);
73b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
742270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom        // Remove duplicate interfaces and interface classes that have ended
752270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom        // up pointing to the class itself.
762270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom        boolean[] delete = null;
772270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom        for (int index = 0; index < programClass.u2interfacesCount; index++)
782270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom        {
792270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            Clazz interfaceClass = programClass.getInterface(index);
802270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            if (interfaceClass != null &&
812270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom                (programClass.equals(interfaceClass) ||
822270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom                 containsInterfaceClass(programClass,
832270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom                                        index,
842270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom                                        interfaceClass)))
852270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            {
862270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom                // Lazily create the array.
872270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom                if (delete == null)
882270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom                {
892270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom                    delete = new boolean[programClass.u2interfacesCount];
902270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom                }
912270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom
922270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom                delete[index] = true;
932270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            }
942270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom        }
952270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom
962270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom        if (delete != null)
972270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom        {
982270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            new InterfaceDeleter(delete).visitProgramClass(programClass);
992270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom        }
1002270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom
1012270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom        // Is the class being retargeted?
102b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        Clazz targetClass = ClassMerger.getTargetClass(programClass);
103b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (targetClass != null)
104b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
1052270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            // We're not changing anything special in the superclass and
1062270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            // interface hierarchy of the retargeted class. The shrinking
1072270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            // step will remove the class for us.
1082270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom
109b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Restore the class name. We have to add a new class entry
110b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // to avoid an existing entry with the same name being reused. The
111b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // names have to be fixed later, based on their referenced classes.
112b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            programClass.u2thisClass =
113b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                addNewClassConstant(programClass,
114b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                    programClass.getName(),
115b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                    programClass);
116b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
1172270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            // This class will no longer have any subclasses, because their
1182270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            // subclasses and interfaces will be retargeted.
119b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            programClass.subClasses = null;
120b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
121b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        else
122b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
1232270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            // This class has become the subclass of its possibly new
1242270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            // superclass and of any new interfaces.
125b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            ConstantVisitor subclassAdder =
126b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                new ReferencedClassVisitor(
127b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                new SubclassFilter(programClass,
128b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                new SubclassAdder(programClass)));
129b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
130b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            programClass.superClassConstantAccept(subclassAdder);
131b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            programClass.interfaceConstantsAccept(subclassAdder);
132b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
133b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            // TODO: Maybe restore private method references.
134b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        }
135b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
136b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
137b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
138b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitLibraryClass(LibraryClass libraryClass)
139b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
140b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Change the references of the class members.
141b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        libraryClass.fieldsAccept(this);
142b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        libraryClass.methodsAccept(this);
143b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
144b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
145b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
146b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Implementations for MemberVisitor.
147b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
148b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitProgramField(ProgramClass programClass, ProgramField programField)
149b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
150b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Change the referenced class.
151b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        programField.referencedClass =
152b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            updateReferencedClass(programField.referencedClass);
153b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
154b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Change the references of the attributes.
155b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        programField.attributesAccept(programClass, this);
156b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
157b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
158b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
159b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
160b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
161b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Change the referenced classes.
162b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        updateReferencedClasses(programMethod.referencedClasses);
163b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
164b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Change the references of the attributes.
165b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        programMethod.attributesAccept(programClass, this);
166b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
167b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
168b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
169b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
170b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
171b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Change the referenced class.
172b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        libraryField.referencedClass =
173b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            updateReferencedClass(libraryField.referencedClass);
174b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
175b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
176b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
177b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
178b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
179b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Change the referenced classes.
180b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        updateReferencedClasses(libraryMethod.referencedClasses);
181b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
182b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
183b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
184b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Implementations for ConstantVisitor.
185b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
186b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitAnyConstant(Clazz clazz, Constant constant) {}
187b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
188b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
189b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
190b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
191b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Does the string refer to a class, due to a Class.forName construct?
192b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        Clazz referencedClass    = stringConstant.referencedClass;
193b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        Clazz newReferencedClass = updateReferencedClass(referencedClass);
194b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (referencedClass != newReferencedClass)
195b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
196b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Change the referenced class.
197b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            stringConstant.referencedClass = newReferencedClass;
198b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
199b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Change the referenced class member, if applicable.
200b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            stringConstant.referencedMember =
201b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                updateReferencedMember(stringConstant.referencedMember,
202b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                       stringConstant.getString(clazz),
203b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                       null,
204b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                       newReferencedClass);
205b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
206b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
207b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
208b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
209b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
210b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
211b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        Clazz referencedClass    = refConstant.referencedClass;
212b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        Clazz newReferencedClass = updateReferencedClass(referencedClass);
213b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (referencedClass != newReferencedClass)
214b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
215b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            if (DEBUG)
216b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            {
217b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                System.out.println("TargetClassChanger:");
218b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                System.out.println("  ["+clazz.getName()+"] changing reference from ["+refConstant.referencedClass+"."+refConstant.referencedMember.getName(refConstant.referencedClass)+refConstant.referencedMember.getDescriptor(refConstant.referencedClass)+"]");
219b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            }
220b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
221b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Change the referenced class.
222b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            refConstant.referencedClass  = newReferencedClass;
223b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
224b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Change the referenced class member.
225b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            refConstant.referencedMember =
226b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                updateReferencedMember(refConstant.referencedMember,
227b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                       refConstant.getName(clazz),
228b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                       refConstant.getType(clazz),
229b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                       newReferencedClass);
230b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
231b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            if (DEBUG)
232b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            {
233b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                System.out.println("  ["+clazz.getName()+"]                    to   ["+refConstant.referencedClass+"."+refConstant.referencedMember.getName(refConstant.referencedClass)+refConstant.referencedMember.getDescriptor(refConstant.referencedClass)+"]");
234b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            }
235b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
236b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
237b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
238b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
239b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
240b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
241b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Change the referenced class.
242b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        classConstant.referencedClass =
243b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            updateReferencedClass(classConstant.referencedClass);
244b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
245b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
246b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
247b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Implementations for AttributeVisitor.
248b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
249b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
250b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
251b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
252b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
253b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
254b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Change the references of the attributes.
255b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        codeAttribute.attributesAccept(clazz, method, this);
256b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
257b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
258b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
259b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
260b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
261b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Change the references of the local variables.
262b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
263b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
264b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
265b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
266b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
267b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
268b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Change the references of the local variables.
269b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
270b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
271b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
272b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
273b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)
274b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
275b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Change the referenced classes.
276b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        updateReferencedClasses(signatureAttribute.referencedClasses);
277b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
278b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
279b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
280b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitAnyAnnotationsAttribute(Clazz clazz, AnnotationsAttribute annotationsAttribute)
281b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
282b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Change the references of the annotations.
283b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        annotationsAttribute.annotationsAccept(clazz, this);
284b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
285b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
286b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
287b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitAnyParameterAnnotationsAttribute(Clazz clazz, Method method, ParameterAnnotationsAttribute parameterAnnotationsAttribute)
288b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
289b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Change the references of the annotations.
290b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        parameterAnnotationsAttribute.annotationsAccept(clazz, method, this);
291b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
292b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
293b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
294b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute)
295b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
296b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Change the references of the annotation.
297b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        annotationDefaultAttribute.defaultValueAccept(clazz, this);
298b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
299b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
300b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
3012270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom    // Implementations for LocalVariableInfoVisitor.
302b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
303b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)
304b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
305b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Change the referenced class.
306b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        localVariableInfo.referencedClass =
307b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            updateReferencedClass(localVariableInfo.referencedClass);
308b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
309b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
3102270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom
311b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Implementations for LocalVariableTypeInfoVisitor.
312b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
313b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo)
314b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
315b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Change the referenced classes.
316b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        updateReferencedClasses(localVariableTypeInfo.referencedClasses);
317b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
318b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
3192270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom
320b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Implementations for AnnotationVisitor.
321b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
322b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitAnnotation(Clazz clazz, Annotation annotation)
323b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
324b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Change the referenced classes.
325b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        updateReferencedClasses(annotation.referencedClasses);
326b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
327b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Change the references of the element values.
328b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        annotation.elementValuesAccept(clazz, this);
329b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
330b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
331b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
332b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Implementations for ElementValueVisitor.
333b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
334b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitAnyElementValue(Clazz clazz, Annotation annotation, ElementValue elementValue)
335b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
336b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        Clazz referencedClass    = elementValue.referencedClass;
337b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        Clazz newReferencedClass = updateReferencedClass(referencedClass);
338b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (referencedClass != newReferencedClass)
339b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
340b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Change the referenced annotation class.
341b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            elementValue.referencedClass  = newReferencedClass;
342b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
343b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Change the referenced method.
344b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            elementValue.referencedMethod =
345b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                (Method)updateReferencedMember(elementValue.referencedMethod,
346b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                               elementValue.getMethodName(clazz),
347b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                               null,
348b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                               newReferencedClass);
349b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
350b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
351b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
352b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
353b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue)
354b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
355b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Change the referenced annotation class and method.
356b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        visitAnyElementValue(clazz, annotation, constantElementValue);
357b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
358b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
359b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
360b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue)
361b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
362b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Change the referenced annotation class and method.
363b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        visitAnyElementValue(clazz, annotation, enumConstantElementValue);
364b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
365b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Change the referenced classes.
366b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        updateReferencedClasses(enumConstantElementValue.referencedClasses);
367b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
368b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
369b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
370b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue)
371b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
372b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Change the referenced annotation class and method.
373b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        visitAnyElementValue(clazz, annotation, classElementValue);
374b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
375b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Change the referenced classes.
376b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        updateReferencedClasses(classElementValue.referencedClasses);
377b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
378b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
379b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
380b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue)
381b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
382b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Change the referenced annotation class and method.
383b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        visitAnyElementValue(clazz, annotation, annotationElementValue);
384b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
385b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Change the references of the annotation.
386b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        annotationElementValue.annotationAccept(clazz, this);
387b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
388b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
389b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
390b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue)
391b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
392b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Change the referenced annotation class and method.
393b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        visitAnyElementValue(clazz, annotation, arrayElementValue);
394b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
395b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Change the references of the element values.
396b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        arrayElementValue.elementValuesAccept(clazz, annotation, this);
397b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
398b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
399b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
400b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Small utility methods.
401b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
4022270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom     /**
4032270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom     * Returns whether the given class contains the given interface
4042270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom     * class in its first given number of interfaces.
4052270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom     */
4062270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom    private boolean containsInterfaceClass(Clazz clazz,
4072270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom                                           int   interfaceCount,
4082270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom                                           Clazz interfaceClass)
4092270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom    {
4102270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom        for (int index = 0; index < interfaceCount; index++)
4112270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom        {
4122270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            if (interfaceClass.equals(clazz.getInterface(index)))
4132270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            {
4142270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom                return true;
4152270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            }
4162270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom        }
4172270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom
4182270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom        return false;
4192270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom    }
4202270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom
4212270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom
4222270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom   /**
423b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Updates the retargeted classes in the given array of classes.
424b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
425b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private void updateReferencedClasses(Clazz[] referencedClasses)
426b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
427b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (referencedClasses == null)
428b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
429b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            return;
430b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
431b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
432b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        for (int index = 0; index < referencedClasses.length; index++)
433b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
434b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            referencedClasses[index] =
435b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                updateReferencedClass(referencedClasses[index]);
436b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
437b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
438b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
439b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
440b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
441b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Returns the retargeted class of the given class.
442b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
443b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private Clazz updateReferencedClass(Clazz referencedClass)
444b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
445b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (referencedClass == null)
446b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
447b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            return null;
448b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
449b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
450b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        Clazz targetClazz = ClassMerger.getTargetClass(referencedClass);
451b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return targetClazz != null ?
452b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            targetClazz :
453b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            referencedClass;
454b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
455b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
456b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
457b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
458b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Returns the retargeted class member of the given class member.
459b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
460b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private Member updateReferencedMember(Member referencedMember,
461b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                          String name,
462b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                          String type,
463b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                          Clazz  newReferencedClass)
464b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
465b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (referencedMember == null)
466b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
467b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            return null;
468b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
469b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
470b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return referencedMember instanceof Field ?
471b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            (Member)newReferencedClass.findField(name, type) :
472b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            (Member)newReferencedClass.findMethod(name, type);
473b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
474b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
475b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
476b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
477b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Explicitly adds a new class constant for the given class in the given
478b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * program class.
479b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
480b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private int addNewClassConstant(ProgramClass programClass,
481b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                    String       className,
482b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                    Clazz        referencedClass)
483b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
484b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        ConstantPoolEditor constantPoolEditor =
485b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            new ConstantPoolEditor(programClass);
486b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
487b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        int nameIndex =
488b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            constantPoolEditor.addUtf8Constant(className);
489b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
490b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        int classConstantIndex =
491b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            constantPoolEditor.addConstant(new ClassConstant(nameIndex,
492b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                             referencedClass));
493b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return classConstantIndex;
494b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
495b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato}