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.optimize;
22b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
23b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.*;
24b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.attribute.*;
25b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.attribute.annotation.*;
26b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.attribute.visitor.AttributeVisitor;
27b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.editor.ConstantPoolEditor;
28b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.util.*;
29b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.visitor.MemberVisitor;
30b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.optimize.info.*;
31b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.optimize.peephole.VariableShrinker;
32b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
33b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/**
34b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This MemberVisitor removes unused parameters in the descriptors of the
35b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * methods that it visits.
36b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
37b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @see ParameterUsageMarker
38b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @see VariableUsageMarker
39b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @see VariableShrinker
40b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @author Eric Lafortune
41b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */
42b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopublic class MethodDescriptorShrinker
43b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoextends      SimplifiedVisitor
44b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimplements   MemberVisitor,
45b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato             AttributeVisitor
46b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato{
47b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private static final boolean DEBUG = false;
48b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
49b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
50b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private final MemberVisitor extraMemberVisitor;
51b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
52b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
53b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
54b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Creates a new MethodDescriptorShrinker.
55b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
56b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public MethodDescriptorShrinker()
57b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
58b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        this(null);
59b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
60b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
61b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
62b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
63b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Creates a new MethodDescriptorShrinker with an extra visitor.
64b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * @param extraMemberVisitor an optional extra visitor for all methods whose
65b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     *                           parameters have been simplified.
66b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
67b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public MethodDescriptorShrinker(MemberVisitor extraMemberVisitor)
68b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
69b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        this.extraMemberVisitor = extraMemberVisitor;
70b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
71b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
72b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
73b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Implementations for MemberVisitor.
74b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
75b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
76b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
77b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Update the descriptor if it has any unused parameters.
78b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        String descriptor    = programMethod.getDescriptor(programClass);
79b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        String newDescriptor = shrinkDescriptor(programMethod, descriptor);
80b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
81b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (!descriptor.equals(newDescriptor))
82b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
83b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Shrink the signature and parameter annotations.
84b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            programMethod.attributesAccept(programClass, this);
85b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
86b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            String name    = programMethod.getName(programClass);
87b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            String newName = name;
88b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
89b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Append a code, if the method isn't a class instance initializer.
90b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (!name.equals(ClassConstants.INTERNAL_METHOD_NAME_INIT))
91b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
92b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                newName += ClassConstants.SPECIAL_MEMBER_SEPARATOR + Long.toHexString(Math.abs((descriptor).hashCode()));
93b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
94b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
95b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (DEBUG)
96b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
97b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                System.out.println("MethodDescriptorShrinker:");
98b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                System.out.println("  Class file        = "+programClass.getName());
99b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                System.out.println("  Method name       = "+name);
100b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                System.out.println("                   -> "+newName);
101b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                System.out.println("  Method descriptor = "+descriptor);
102b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                System.out.println("                   -> "+newDescriptor);
103b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
104b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
105b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            ConstantPoolEditor constantPoolEditor =
106b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                new ConstantPoolEditor(programClass);
107b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
108b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Update the name, if necessary.
109b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (!newName.equals(name))
110b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
111b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                programMethod.u2nameIndex =
112b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    constantPoolEditor.addUtf8Constant(newName);
113b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
114b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
115b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Update the referenced classes.
116b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            programMethod.referencedClasses =
117b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                shrinkReferencedClasses(programMethod,
118b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                        descriptor,
119b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                        programMethod.referencedClasses);
120b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
121b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Finally, update the descriptor itself.
122b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            programMethod.u2descriptorIndex =
123b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                constantPoolEditor.addUtf8Constant(newDescriptor);
124b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
125b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Visit the method, if required.
126b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (extraMemberVisitor != null)
127b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
128b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                extraMemberVisitor.visitProgramMethod(programClass, programMethod);
129b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
130b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
131b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
132b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
133b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
134b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Implementations for AttributeVisitor.
135b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
136b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
137b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
138b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
139b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitSignatureAttribute(Clazz clazz, Method method, SignatureAttribute signatureAttribute)
140b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
141b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Compute the new signature.
142b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        String signature    = clazz.getString(signatureAttribute.u2signatureIndex);
143b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        String newSignature = shrinkDescriptor(method, signature);
144b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
145b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Update the signature.
146b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        signatureAttribute.u2signatureIndex =
147b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            new ConstantPoolEditor((ProgramClass)clazz).addUtf8Constant(newSignature);
148b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
149b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Update the referenced classes.
150b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        signatureAttribute.referencedClasses =
151b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            shrinkReferencedClasses(method,
152b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                    signature,
153b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                    signatureAttribute.referencedClasses);
154b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
155b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
156b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
157b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void visitAnyParameterAnnotationsAttribute(Clazz clazz, Method method, ParameterAnnotationsAttribute parameterAnnotationsAttribute)
158b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
159b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        int[]          annotationsCounts = parameterAnnotationsAttribute.u2parameterAnnotationsCount;
160b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        Annotation[][] annotations       = parameterAnnotationsAttribute.parameterAnnotations;
161b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
162b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // All parameters of non-static methods are shifted by one in the local
163b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // variable frame.
164b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        int parameterIndex =
165b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            (method.getAccessFlags() & ClassConstants.INTERNAL_ACC_STATIC) != 0 ?
166b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                0 : 1;
167b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
168b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        int annotationIndex    = 0;
169b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        int newAnnotationIndex = 0;
170b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
171b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Go over the parameters.
172b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        String descriptor = method.getDescriptor(clazz);
173b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        InternalTypeEnumeration internalTypeEnumeration =
174b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            new InternalTypeEnumeration(descriptor);
175b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
176b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        while (internalTypeEnumeration.hasMoreTypes())
177b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
178b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            String type = internalTypeEnumeration.nextType();
179b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (ParameterUsageMarker.isParameterUsed(method, parameterIndex))
180b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
181b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                annotationsCounts[newAnnotationIndex] = annotationsCounts[annotationIndex];
182b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                annotations[newAnnotationIndex++]     = annotations[annotationIndex];
183b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
184b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
185b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            annotationIndex++;
186b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
187b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            parameterIndex += ClassUtil.isInternalCategory2Type(type) ? 2 : 1;
188b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
189b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
190b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Update the number of parameters.
191b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        parameterAnnotationsAttribute.u2parametersCount = newAnnotationIndex;
192b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
193b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Clear the unused entries.
194b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        while (newAnnotationIndex < annotationIndex)
195b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
196b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            annotationsCounts[newAnnotationIndex] = 0;
197b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            annotations[newAnnotationIndex++]     = null;
198b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
199b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
200b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
201b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
202b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Small utility methods.
203b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
204b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
205b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Returns a shrunk descriptor or signature of the given method.
206b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
207b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private String shrinkDescriptor(Method method, String descriptor)
208b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
209b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // All parameters of non-static methods are shifted by one in the local
210b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // variable frame.
211b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        int parameterIndex =
212b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            (method.getAccessFlags() & ClassConstants.INTERNAL_ACC_STATIC) != 0 ?
213b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                0 : 1;
214b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
215b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Go over the parameters.
216b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        InternalTypeEnumeration internalTypeEnumeration =
217b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            new InternalTypeEnumeration(descriptor);
218b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
219b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        StringBuffer newDescriptorBuffer = new StringBuffer();
220b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
221b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        newDescriptorBuffer.append(internalTypeEnumeration.formalTypeParameters());
222b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        newDescriptorBuffer.append(ClassConstants.INTERNAL_METHOD_ARGUMENTS_OPEN);
223b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
224b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        while (internalTypeEnumeration.hasMoreTypes())
225b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
226b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            String type = internalTypeEnumeration.nextType();
227b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (ParameterUsageMarker.isParameterUsed(method, parameterIndex))
228b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
229b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                newDescriptorBuffer.append(type);
230b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
231b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            else if (DEBUG)
232b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
233b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                System.out.println("  Deleting parameter #"+parameterIndex+" ["+type+"]");
234b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
235b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
236b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            parameterIndex += ClassUtil.isInternalCategory2Type(type) ? 2 : 1;
237b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
238b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
239b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        newDescriptorBuffer.append(ClassConstants.INTERNAL_METHOD_ARGUMENTS_CLOSE);
240b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        newDescriptorBuffer.append(internalTypeEnumeration.returnType());
241b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
242b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return newDescriptorBuffer.toString();
243b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
244b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
245b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
246b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
247b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Shrinks the array of referenced classes of the given method.
248b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
249b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private Clazz[] shrinkReferencedClasses(Method  method,
250b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                            String  descriptor,
251b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                            Clazz[] referencedClasses)
252b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
253b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (referencedClasses != null)
254b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
255b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // All parameters of non-static methods are shifted by one in the local
256b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // variable frame.
257b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            int parameterIndex =
258b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                (method.getAccessFlags() & ClassConstants.INTERNAL_ACC_STATIC) != 0 ?
259b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    0 : 1;
260b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
261b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            int referencedClassIndex    = 0;
262b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            int newReferencedClassIndex = 0;
263b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
264b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Go over the parameters.
265b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            InternalTypeEnumeration internalTypeEnumeration =
266b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                new InternalTypeEnumeration(descriptor);
267b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
268b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Also look at the formal type parameters.
269b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            String type  = internalTypeEnumeration.formalTypeParameters();
270b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            int    count = new DescriptorClassEnumeration(type).classCount();
271b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            for (int counter = 0; counter < count; counter++)
272b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
273b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                referencedClasses[newReferencedClassIndex++] =
274b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    referencedClasses[referencedClassIndex++];
275b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
276b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
277b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            while (internalTypeEnumeration.hasMoreTypes())
278b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
279b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                // Consider the classes referenced by this parameter type.
280b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                type  = internalTypeEnumeration.nextType();
281b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                count = new DescriptorClassEnumeration(type).classCount();
282b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
283b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                if (ParameterUsageMarker.isParameterUsed(method, parameterIndex))
284b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                {
285b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    // Copy the referenced classes.
286b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    for (int counter = 0; counter < count; counter++)
287b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    {
288b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                        referencedClasses[newReferencedClassIndex++] =
289b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                            referencedClasses[referencedClassIndex++];
290b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    }
291b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                }
292b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                else
293b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                {
294b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    // Skip the referenced classes.
295b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    referencedClassIndex += count;
296b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                }
297b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
298b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                parameterIndex += ClassUtil.isInternalCategory2Type(type) ? 2 : 1;
299b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
300b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
301b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Also look at the return value.
302b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            type  = internalTypeEnumeration.returnType();
303b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            count = new DescriptorClassEnumeration(type).classCount();
304b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            for (int counter = 0; counter < count; counter++)
305b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
306b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                referencedClasses[newReferencedClassIndex++] =
307b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    referencedClasses[referencedClassIndex++];
308b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
309b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
310b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Clear the unused entries.
311b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            while (newReferencedClassIndex < referencedClassIndex)
312b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
313b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                referencedClasses[newReferencedClassIndex++] = null;
314b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
315b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
316b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
317b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return referencedClasses;
318b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
319b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato}
320