KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jbet > Descriptor


1 /*
2  * JBET - Java Binary Enhancement Tool
3  * Copyright (c) 2003 Networks Associates Technology, Inc.
4  *
5  * This software was developed under DARPA/SPAWAR contract
6  * N66001-00-C-8602 "SPMA" as part of the
7  * DARPA OASIS research program.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */

30
31 package jbet;
32 import java.util.*;
33
34 /**
35  * An instance of this class describes the number and type of the
36  * parameters of the method described by the instance, and the method's
37  * return type.
38  *
39  * This file contains fields that hold the types of the parameters and
40  * the return type (if any) of the method that is described by an instance
41  * of this class. This file also includes code that:
42  * 1) initializes the fields
43  * 2) TBD
44  *
45  * $Id: Descriptor.java,v 1.9 2003/09/09 17:31:53 areisse Exp $
46  *
47  * @author Larry D'Anna
48  * @version 0.1
49  * @since JDK 1.1.8
50  */

51
52 public final class Descriptor {
53
54     public Type [] args = null; // The types of the method's parameters
55
public Type ret = null; // The return type of the method
56

57     String JavaDoc stringCache = null; // If not null then this string holds
58
// "( type of param0, type of param1, ...) ret type"
59

60     public static final Descriptor Void = new Descriptor ("()V");
61     public static final Descriptor returnInt = new Descriptor ("()I");
62     
63     // Constructors
64

65     public Descriptor (Type p1, Type r) {
66     ret = r;
67     args = new Type [1];
68     args[0] = p1;
69     }
70
71     public Descriptor (Type r) {
72     ret = r;
73     args = new Type [0];
74     }
75
76     public Descriptor () { }
77
78
79     /**
80      * Construct a new Descriptor based on a template
81      * @see MethodInfo.relocate and Snippit.relocate
82      *
83      * @param d the template method Descriptor.
84      * @return the new Descriptor.
85      */

86     public Descriptor (Descriptor d) {
87     ret = new Type (d.ret);
88     args = new Type [ d.args.length ];
89     for (int i = 0; i < args.length; i++)
90         args[i] = new Type( d.args[i] );
91     }
92
93     /**
94      * A constructor for Descriptor (describing a method M).
95      *
96      * @param str the params of M in "(typeof param0, typeof param1, ...) ret type" format
97      * @return the new Descriptor.
98      */

99     public Descriptor (String JavaDoc str) throws ParseException {
100     stringCache = str;
101     Vector argvec = new Vector();
102     
103     if (str.length() < 3)
104         throw new ParseException ("method descriptor too short");
105     if (str.charAt(0) != '(')
106         throw new ParseException ("method descriptor doesn't start with \"(\"");
107
108     int i;
109     for (i = 1; str.charAt(i) != ')';) {
110         if (i >= str.length())
111         throw new ParseException ("unexpected end of string");
112         Type t = new Type();
113         i += t.parse(str, i);
114         argvec.addElement(t);
115     }
116     i++;
117     ret = new Type();
118     ret.parse(str, i);
119     
120     args = new Type [ argvec.size() ];
121     argvec.copyInto (args);
122
123     }
124
125     /**
126      * Relocate all of the type references used by this descriptor
127      *
128      * @param subs A table of string substitution pairs.
129      * @see ClassRep.relocate
130      */

131     public void relocate(Hashtable subs) {
132     ret.relocate(subs);
133     for (int i = 0; i < args.length; i++)
134         args[i].relocate(subs);
135     }
136
137     /**
138      * Relocate a copy of the current descriptor (the current descriptor
139      * is unchanged).
140      * @see MethodInfo.relocate and Snippit.relocate
141      *
142      * @param subs a table of string substitution pairs.
143      * @return the new (relocated) Descriptor.
144      */

145     public Descriptor relocate_new(Hashtable subs) {
146     Descriptor d = new Descriptor(this);
147     d.relocate(subs);
148     return d;
149     }
150
151
152     int numArgs() { return args.length; }
153
154     /**
155      * for invokeinterface
156      *
157      * @return the number of words needed to store the method's parameters
158      */

159     public int count() {
160     int ret = 1;
161     for (int i = 0; i < args.length; i++)
162         ret += args[i].count();
163     return ret;
164     }
165         
166
167     /**
168      * Convert the internal representation of the types associated
169      * with the method to a string stored in Descriptor.stringCache
170      *
171      * @return a string depicting the types of the (refering) method
172      */

173     public String JavaDoc toString() {
174     if (stringCache == null) {
175         StringBuffer JavaDoc out = new StringBuffer JavaDoc();
176         out.append ('(');
177         for (int i = 0; i < args.length; i++)
178         out.append ( args[i].toString() );
179         out.append (')');
180         out.append (ret.toString());
181         stringCache = out.toString();
182     }
183     return stringCache;
184     }
185  
186     /**
187      * Test if the descriptor argument has the same (argument / return) types
188      * as the (calling) descriptor.
189      *
190      * @param o a method descriptor (return false otherwise)
191      * @return true two descriptors have the same (argument / return) types, false otherwise
192      */

193     public boolean equals(Object JavaDoc o) {
194     if (o instanceof String JavaDoc)
195         return toString().equals(o);
196     if (! (o instanceof Descriptor))
197         return false;
198     Descriptor d = (Descriptor) o ;
199     if (args.length != d.args.length)
200         return false;
201     for (int i = 0; i < args.length; i++)
202         if (! args[i].equals( d.args[i] ) )
203         return false;
204     if (! ret.equals( d.ret ) )
205         return false;
206     return true;
207     }
208
209     /**
210      * Implements hashCode for Descriptor by calculating a hash of the return
211      * type and the parameters of the method in that order.
212      *
213      * @return the value hash(ret) * 101^(n+1) + hash(param0) * 101^(n) + ... + hash(paramn)
214      */

215     public int hashCode() {
216     int hash = ret.hashCode();
217     for (int i = 0; i < args.length; i++)
218         hash = hash * 101 + args[i].hashCode();
219     return hash;
220     }
221
222     // what goes in a java source file to declare this type. The return type is not considered, since that goes before the method name
223
public String JavaDoc declaration () {
224     StringBuffer JavaDoc out = new StringBuffer JavaDoc ("(");
225
226     for (int i = 0; i < args.length; i++) {
227         out.append (args[i].declaration());
228         out.append (" arg");
229         out.append (i);
230         if (i != args.length - 1)
231         out.append (", ");
232     }
233
234     out.append (")");
235     return out.toString();
236     }
237 }
238
239
240
241
Popular Tags