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.expr;
47
48 import java.lang.reflect.Field;
49 import java.lang.reflect.Method;
50 import java.lang.reflect.Modifier;
51
52 import org.codehaus.groovy.ast.GroovyCodeVisitor;
53 import org.codehaus.groovy.classgen.AsmClassGenerator;
54
55 /***
56 * Represents an attribute access (accessing the field of a class) such as the expression "foo.@bar".
57 *
58 * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
59 * @version $Revision: 1.2 $
60 */
61 public class AttributeExpression extends Expression {
62
63 private Expression objectExpression;
64 private String property;
65 private boolean spreadSafe = false;
66 private boolean safe = false;
67 private boolean isStatic = false;
68
69 private Method getter = null;
70 private Method setter = null;
71
72 private Field field = null;
73 private int access = -1;
74
75 public boolean isStatic() {
76 return isStatic;
77 }
78
79 public AttributeExpression(Expression objectExpression, String property) {
80 this(objectExpression, property, false);
81 }
82
83 public AttributeExpression(Expression objectExpression, String property, boolean safe) {
84 this.objectExpression = objectExpression;
85 this.property = property;
86 this.safe = safe;
87 }
88
89 public void visit(GroovyCodeVisitor visitor) {
90 visitor.visitAttributeExpression(this);
91 }
92
93 public boolean isDynamic() {
94 return true;
95 }
96
97 public Expression transformExpression(ExpressionTransformer transformer) {
98 return this;
99 }
100
101 protected void resolveType(AsmClassGenerator resolver) {
102 objectExpression.resolve(resolver);
103 resolver.resolve(this);
104 }
105
106 public Expression getObjectExpression() {
107 return objectExpression;
108 }
109
110 public String getProperty() {
111 return property;
112 }
113
114 public String getText() {
115 return objectExpression.getText() + "." + property;
116 }
117
118 /***
119 * @return is this a safe navigation, i.e. if true then if the source object is null
120 * then this navigation will return null
121 */
122 public boolean isSafe() {
123 return safe;
124 }
125
126 public boolean isSpreadSafe() {
127 return spreadSafe;
128 }
129
130 public void setSpreadSafe(boolean value) {
131 spreadSafe = value;
132 }
133
134 public String toString() {
135 return super.toString() + "[object: " + objectExpression + " property: " + property + "]";
136 }
137
138 public void setStatic(boolean aStatic) {
139 this.isStatic = aStatic;
140 }
141
142 public void setGetter(Method meth) {
143 Class returntype = meth.getReturnType();
144 Class oldType = getTypeClass();
145 if (oldType != null && oldType != Object.class && oldType != returntype) {
146
147
148
149
150
151
152
153 }
154 else {
155 getter = meth;
156 setTypeClass(returntype);
157 setTypeResolved(true);
158 }
159 }
160
161 public Method getGetter() {
162 return getter;
163 }
164
165 public void setSetter(Method method) {
166 Class paramType = method.getParameterTypes()[0];
167 Class wasType = getTypeClass();
168 if (wasType != null && wasType != Object.class && wasType != paramType) {
169
170
171
172
173
174
175
176 }
177 else {
178 setter = method;
179 setTypeClass(paramType);
180 setTypeResolved(true);
181 }
182 }
183 public Method getSetter() {
184 return setter;
185 }
186
187 public void setField(Field fld) {
188 field = fld;
189 setStatic(Modifier.isStatic(fld.getModifiers()));
190 setTypeClass(fld.getType());
191 }
192 public Field getField() {
193 return field;
194 }
195
196 public void setAccess(int access) {
197 this.access = access;
198 }
199
200 public int getAccess() {
201 return access;
202 }
203 }