/* * FieldAccess.java 1.0 * * Jun 20, 1997 * Sep 29, 1997 * Oct 10, 1997 * * @see io.devnulllabs.openjava.ptree.ParseTree * @version 1.0 last updated: Oct 10, 1997 * @author Michiaki Tatsubori */ package io.devnulllabs.openjava.ptree; import io.devnulllabs.openjava.mop.Environment; import io.devnulllabs.openjava.mop.NoSuchMemberException; import io.devnulllabs.openjava.mop.OJClass; import io.devnulllabs.openjava.mop.OJField; import io.devnulllabs.openjava.ptree.util.ParseTreeVisitor; /** * The FieldAccess class represents * a field access like : *
 *     f().str
 * 

* In this field access, * you can get f() by getReferenceExpr() * and can get str by getName() . *
* Warning this class may has bugs around the expression. * * @see io.devnulllabs.openjava.ptree.NonLeaf * @see io.devnulllabs.openjava.ptree.Expression */ public class FieldAccess extends NonLeaf implements Expression { /** * An access to the specified field of the given expression. */ public FieldAccess(Expression expr, String name) { super(); set(expr, name); } /** * An access to the specified static field of the type. */ public FieldAccess(TypeName typename, String name) { super(); set(typename, name); } /** * An access to the specified static field of the type. */ public FieldAccess(OJClass clazz, String name) { this(TypeName.forOJClass(clazz), name); } /** * An access to the specified field of self. */ public FieldAccess(String name) { this((Expression) null, name); } FieldAccess() { super(); } public ParseTree getReference() { return (ParseTree) elementAt(0); } public boolean isTypeReference() { return (getReference() instanceof TypeName); } /** * Gets the expression accessed. * * @return the expression accessed. */ public Expression getReferenceExpr() { if (isTypeReference()) return null; return (Expression) getReference(); } /** * Sets the expression accessed. * * @param expr the expression accessed. */ public void setReferenceExpr(Expression expr) { setElementAt(expr, 0); } public TypeName getReferenceType() { if (!isTypeReference()) return null; return (TypeName) getReference(); } public void setReferenceType(TypeName typename) { setElementAt(typename, 0); } /** * Gets the field name. * * @return the field name. */ public String getName() { return (String) elementAt(1); } /** * Sets the field name. * * @param name the field name. */ public void setName(String name) { setElementAt(name, 1); } public void accept(ParseTreeVisitor v) throws ParseTreeException { v.visit(this); } public OJClass getType(Environment env) throws Exception { OJClass selftype = env.lookupClass(env.currentClassName()); Expression refexpr = getReferenceExpr(); String name = getName(); OJClass reftype = null; if (refexpr != null) { reftype = refexpr.getType(env); } else { TypeName refname = getReferenceType(); if (refname != null) { String qname = env.toQualifiedName(refname.toString()); reftype = env.lookupClass(qname); } } OJField field = null; if (reftype != null) field = pickupField(reftype, name); if (field != null) return field.getType(); /* try to consult this class and outer classes */ if (reftype == null) { OJClass declaring = selftype; while (declaring != null) { field = pickupField(declaring, name); if (field != null) return field.getType(); /* consult innerclasses */ OJClass[] inners = declaring.getDeclaredClasses(); for (int i = 0; i < inners.length; ++i) { field = pickupField(inners[i], name); if (field != null) return field.getType(); } declaring = declaring.getDeclaringClass(); } reftype = selftype; } NoSuchMemberException e = new NoSuchMemberException(name); field = reftype.resolveException(e, name); return field.getType(); } private static OJField pickupField(OJClass reftype, String name) { try { return reftype.getField(name, reftype); } catch (NoSuchMemberException e) { return null; } } }