1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 package org.codehaus.groovy.ast;
47
48 import java.util.List;
49
50 import org.codehaus.groovy.ast.stmt.BlockStatement;
51 import org.codehaus.groovy.ast.stmt.Statement;
52 import org.objectweb.asm.Opcodes;
53
54 /***
55 * Represents a method declaration
56 *
57 * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
58 * @version $Revision: 1.24 $
59 */
60 public class MethodNode extends AnnotatedNode implements Opcodes {
61
62 private String name;
63 private int modifiers;
64 private ClassNode returnType;
65 private Parameter[] parameters;
66 private boolean hasDefaultValue = false;
67 private Statement code;
68 private boolean dynamicReturnType;
69 private VariableScope variableScope;
70 private ClassNode[] exceptions;
71
72 public MethodNode(String name, int modifiers, ClassNode returnType, Parameter[] parameters, ClassNode[] exceptions, Statement code) {
73 this.name = name;
74 this.modifiers = modifiers;
75 this.parameters = parameters;
76 this.code = code;
77 this.returnType = returnType;
78 if (returnType==null) this.returnType = ClassHelper.OBJECT_TYPE;
79
80 variableScope = new VariableScope();
81 if (parameters != null && parameters.length > 0) {
82 for (int i = 0; i < parameters.length; i++) {
83 Parameter para = parameters[i];
84 if (para.hasInitialExpression()) {
85 this.hasDefaultValue = true;
86 }
87 para.setInStaticContext(isStatic());
88 variableScope.getDeclaredVariables().put(para.getName(),para);
89 }
90 }
91 variableScope.setInStaticContext(isStatic());
92
93 this.exceptions = exceptions;
94 }
95
96 /***
97 * The type descriptor for a method node is a string containing the name of the method, its return type,
98 * and its parameter types in a canonical form. For simplicity, I'm using the format of a Java declaration
99 * without parameter names, and with $dynamic as the type for any dynamically typed values.
100 *
101 * @return
102 */
103
104 public String getTypeDescriptor() {
105 StringBuffer buf = new StringBuffer();
106
107
108 buf.append(returnType.getName());
109
110 buf.append(' ');
111 buf.append(name);
112 buf.append('(');
113 for (int i = 0; i < parameters.length; i++) {
114 if (i > 0) {
115 buf.append(',');
116 }
117 Parameter param = parameters[i];
118 buf.append(param.getType().getName());
119 }
120 buf.append(')');
121 return buf.toString();
122 }
123
124 public boolean isVoidMethod() {
125 return returnType==ClassHelper.VOID_TYPE;
126 }
127
128 public Statement getCode() {
129 return code;
130 }
131
132 public void setCode(Statement code) {
133 this.code = code;
134 }
135
136 public int getModifiers() {
137 return modifiers;
138 }
139
140 public void setModifiers(int modifiers) {
141 this.modifiers = modifiers;
142 }
143
144 public String getName() {
145 return name;
146 }
147
148 public Parameter[] getParameters() {
149 return parameters;
150 }
151
152 public ClassNode getReturnType() {
153 return returnType;
154 }
155
156 public VariableScope getVariableScope() {
157 return variableScope;
158 }
159
160 public void setVariableScope(VariableScope variableScope) {
161 this.variableScope = variableScope;
162 }
163
164 public boolean isDynamicReturnType() {
165 return dynamicReturnType;
166 }
167
168 public boolean isAbstract() {
169 return (modifiers & ACC_ABSTRACT) != 0;
170 }
171
172 public boolean isStatic() {
173 return (modifiers & ACC_STATIC) != 0;
174 }
175
176 public boolean hasDefaultValue() {
177 return this.hasDefaultValue;
178 }
179
180 public String toString() {
181 return super.toString() + "[name: " + name + "]";
182 }
183
184 public void setReturnType(ClassNode returnType) {
185 this.returnType = returnType;
186 }
187
188 public ClassNode[] getExceptions() {
189 return exceptions;
190 }
191
192 public Statement getFirstStatement(){
193 if (code == null) return null;
194 if (code instanceof BlockStatement) {
195 List list = ((BlockStatement) code).getStatements();
196 if (list.size()>0) return (Statement) list.get(0);
197 return null;
198 }
199 return code;
200 }
201 }