Source code: openjava/ptree/FieldAccess.java
1 /*
2 * FieldAccess.java 1.0
3 *
4 * Jun 20, 1997
5 * Sep 29, 1997
6 * Oct 10, 1997
7 *
8 * @see openjava.ptree.ParseTree
9 * @version 1.0 last updated: Oct 10, 1997
10 * @author Michiaki Tatsubori
11 */
12 package openjava.ptree;
13
14 import openjava.mop.Environment;
15 import openjava.mop.NoSuchMemberException;
16 import openjava.mop.OJClass;
17 import openjava.mop.OJField;
18 import openjava.ptree.util.ParseTreeVisitor;
19
20 /**
21 * The <code>FieldAccess</code> class represents
22 * a field access like :
23 * <br><blockquote><pre>
24 * f().str
25 * </pre></blockquote><br>
26 * In this field access,
27 * you can get <code>f()</code> by <code>getReferenceExpr()</code>
28 * and can get <code>str</code> by <code>getName()</code> .
29 * <br>
30 * Warning this class may has bugs around the expression.
31 *
32 * @see openjava.ptree.NonLeaf
33 * @see openjava.ptree.Expression
34 */
35 public class FieldAccess extends NonLeaf implements Expression {
36
37 /**
38 * An access to the specified field of the given expression.
39 */
40 public FieldAccess(Expression expr, String name) {
41 super();
42 set(expr, name);
43 }
44
45 /**
46 * An access to the specified static field of the type.
47 */
48 public FieldAccess(TypeName typename, String name) {
49 super();
50 set(typename, name);
51 }
52
53 /**
54 * An access to the specified static field of the type.
55 */
56 public FieldAccess(OJClass clazz, String name) {
57 this(TypeName.forOJClass(clazz), name);
58 }
59
60 /**
61 * An access to the specified field of self.
62 */
63 public FieldAccess(String name) {
64 this((Expression) null, name);
65 }
66
67 FieldAccess() {
68 super();
69 }
70
71 public ParseTree getReference() {
72 return (ParseTree) elementAt(0);
73 }
74
75 public boolean isTypeReference() {
76 return (getReference() instanceof TypeName);
77 }
78
79 /**
80 * Gets the expression accessed.
81 *
82 * @return the expression accessed.
83 */
84 public Expression getReferenceExpr() {
85 if (isTypeReference())
86 return null;
87 return (Expression) getReference();
88 }
89
90 /**
91 * Sets the expression accessed.
92 *
93 * @param expr the expression accessed.
94 */
95 public void setReferenceExpr(Expression expr) {
96 setElementAt(expr, 0);
97 }
98
99 public TypeName getReferenceType() {
100 if (!isTypeReference())
101 return null;
102 return (TypeName) getReference();
103 }
104
105 public void setReferenceType(TypeName typename) {
106 setElementAt(typename, 0);
107 }
108
109 /**
110 * Gets the field name.
111 *
112 * @return the field name.
113 */
114 public String getName() {
115 return (String) elementAt(1);
116 }
117
118 /**
119 * Sets the field name.
120 *
121 * @param name the field name.
122 */
123 public void setName(String name) {
124 setElementAt(name, 1);
125 }
126
127 public void accept(ParseTreeVisitor v) throws ParseTreeException {
128 v.visit(this);
129 }
130
131 public OJClass getType(Environment env) throws Exception {
132 OJClass selftype = env.lookupClass(env.currentClassName());
133
134 Expression refexpr = getReferenceExpr();
135 String name = getName();
136
137 OJClass reftype = null;
138
139 if (refexpr != null) {
140 reftype = refexpr.getType(env);
141 } else {
142 TypeName refname = getReferenceType();
143 if (refname != null) {
144 String qname = env.toQualifiedName(refname.toString());
145 reftype = env.lookupClass(qname);
146 }
147 }
148
149 OJField field = null;
150
151 if (reftype != null)
152 field = pickupField(reftype, name);
153 if (field != null)
154 return field.getType();
155
156 /* try to consult this class and outer classes */
157 if (reftype == null) {
158 OJClass declaring = selftype;
159 while (declaring != null) {
160 field = pickupField(declaring, name);
161 if (field != null)
162 return field.getType();
163
164 /* consult innerclasses */
165 OJClass[] inners = declaring.getDeclaredClasses();
166 for (int i = 0; i < inners.length; ++i) {
167 field = pickupField(inners[i], name);
168 if (field != null)
169 return field.getType();
170 }
171
172 declaring = declaring.getDeclaringClass();
173 }
174 reftype = selftype;
175 }
176
177 NoSuchMemberException e = new NoSuchMemberException(name);
178 field = reftype.resolveException(e, name);
179 return field.getType();
180 }
181
182 private static OJField pickupField(OJClass reftype, String name) {
183 try {
184 return reftype.getField(name, reftype);
185 } catch (NoSuchMemberException e) {
186 return null;
187 }
188 }
189
190 }