KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > polyglot > types > reflect > Method


1 package polyglot.types.reflect;
2
3 import polyglot.types.*;
4 import java.util.*;
5 import java.io.*;
6
7 /**
8  * Method represents a method in a Java classfile. A method's name and
9  * value (the types of its parameters and its return type) are modeled
10  * as indices into it class's constant pool. A method has modifiers
11  * that determine whether it is public, private, static, final, etc.
12  * Methods have a number of attributes such as their Code and any
13  * Exceptions they may throw.
14  *
15  * @see polyglot.types.reflect Code
16  * @see polyglot.types.reflect Exceptions
17  *
18  * @author Nate Nystrom
19  * (<a HREF="mailto:nystrom@cs.purdue.edu">nystrom@cs.purdue.edu</a>)
20  */

21 class Method
22 {
23   ClassFile clazz;
24   int modifiers;
25   int name;
26   int type;
27   Attribute[] attrs;
28   Exceptions exceptions;
29   boolean synthetic;
30
31   /**
32    * Constructor. Read a method from a class file.
33    *
34    * @param in
35    * The data stream of the class file.
36    * @param clazz
37    * The class file containing the method.
38    * @exception IOException
39    * If an error occurs while reading.
40    */

41   Method(DataInputStream in, ClassFile clazz) throws IOException
42   {
43     this.clazz = clazz;
44
45     modifiers = in.readUnsignedShort();
46
47     name = in.readUnsignedShort();
48     type = in.readUnsignedShort();
49
50     int numAttributes = in.readUnsignedShort();
51
52     attrs = new Attribute[numAttributes];
53
54     for (int i = 0; i < numAttributes; i++) {
55       int nameIndex = in.readUnsignedShort();
56       int length = in.readInt();
57
58       Constant name = clazz.constants[nameIndex];
59
60       if (name != null) {
61         if ("Exceptions".equals(name.value())) {
62           exceptions = new Exceptions(clazz, in, nameIndex, length);
63           attrs[i] = exceptions;
64         }
65         if ("Synthetic".equals(name.value())) {
66           synthetic = true;
67         }
68       }
69
70       if (attrs[i] == null) {
71         long n = in.skip(length);
72         if (n != length) {
73           throw new EOFException();
74         }
75       }
76     }
77   }
78
79   boolean isSynthetic() {
80     return synthetic;
81   }
82
83   String JavaDoc name() {
84     return (String JavaDoc) clazz.constants[this.name].value();
85   }
86
87   MethodInstance methodInstance(TypeSystem ts, ClassType ct) {
88     String JavaDoc name = (String JavaDoc) clazz.constants[this.name].value();
89     String JavaDoc type = (String JavaDoc) clazz.constants[this.type].value();
90
91     if (type.charAt(0) != '(') {
92         throw new ClassFormatError JavaDoc("Bad method type descriptor.");
93     }
94
95     int index = type.indexOf(')', 1);
96     List argTypes = clazz.typeListForString(ts, type.substring(1, index));
97     Type returnType = clazz.typeForString(ts, type.substring(index+1));
98
99     List excTypes = new ArrayList();
100
101     if (exceptions != null) {
102         for (int i = 0; i < exceptions.exceptions.length; i++) {
103             String JavaDoc s = clazz.classNameCP(exceptions.exceptions[i]);
104             excTypes.add(clazz.quietTypeForName(ts, s));
105         }
106     }
107
108     return ts.methodInstance(ct.position(), ct,
109                              ts.flagsForBits(modifiers), returnType, name,
110                              argTypes, excTypes);
111   }
112
113   ConstructorInstance constructorInstance(TypeSystem ts, ClassType ct,
114                                           Field[] fields) {
115     // Get a method instance for the <init> method.
116
MethodInstance mi = methodInstance(ts, ct);
117
118     List formals = mi.formalTypes();
119
120     if (ct.isInnerClass()) {
121         // If an inner class, the first argument may be a reference to an
122
// enclosing class used to initialize a synthetic field.
123

124         // Count the number of synthetic fields.
125
int numSynthetic = 0;
126
127         for (int i = 0; i < fields.length; i++) {
128             if (fields[i].isSynthetic()) {
129                 numSynthetic++;
130             }
131         }
132
133         // Ignore a number of parameters equal to the number of synthetic
134
// fields.
135
if (numSynthetic <= formals.size()) {
136             formals = formals.subList(numSynthetic, formals.size());
137         }
138     }
139
140     return ts.constructorInstance(mi.position(), ct,
141                                   mi.flags(), formals,
142                                   mi.throwTypes());
143   }
144 }
145
Popular Tags