⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fieldlocation.java

📁 A framework written in Java for implementing high-level and dynamic languages, compiling them into J
💻 JAVA
字号:
package gnu.kawa.reflect;import gnu.bytecode.*;import gnu.mapping.*;import gnu.mapping.Location;  // As opposed to gnu.bytecode.Location.import gnu.expr.*;public class FieldLocation extends ClassMemberLocation{  Declaration decl;  /** The cached location of the field, if final.   * This is the value of this Location.  Howeve, if INDIRECT_LOCATION is   * set and CONSTANT is cleared, then we need to do an extra indirection. */  Object value;  static final int SETUP_DONE = 1; // FIXME - do we still need this?  /** Flag that indicates that field value has type Location.   * Hence <code>get</code> of this Location requires an extra indirection. */  static final int INDIRECT_LOCATION = 2;  /** The actual value (following any indirection) is constant.   * I.e. if INDIRECT_LOCATION is set, then that Location has isConstant set,   * Otherwise the actual value is a final field. */  static final int CONSTANT = 4;  /** Flag that indicates that the value field has been set.   * If INDIRECT_LOCATION has been set, but not CONSTANT, then   * the <code>value</code> is a Location we need to indirect.   * If CONSTANT is set, then this is the actual (final) value.   * Not set unless at least one of INDIRECT_LOCATION or CONSTANT are set. */  static final int VALUE_SET = 8;  // The PROCEDURE and SYNTAX flags aren't current used by getDeclaration,  // but probably should be, assuming we can count on them.  public static final int PROCEDURE = 16;  public static final int SYNTAX = 32;  /** True if the flags <code>PROCEDURE|SYNTAX|INDIRECT_LOCATION|CONSTANT</code>   * are valid. */  public static final int KIND_FLAGS_SET = 64;  private int flags;  public boolean isIndirectLocation ()  { return (flags & INDIRECT_LOCATION) != 0; }  public void setProcedure ()  {    flags |= PROCEDURE|CONSTANT|KIND_FLAGS_SET;  }  public void setSyntax ()  {    flags |= SYNTAX|CONSTANT|KIND_FLAGS_SET;  }  void setKindFlags ()  {    String fname = getMemberName();    gnu.bytecode.Field fld = getDeclaringClass().getDeclaredField(fname);    int fflags = fld.getModifiers();    Type ftype = fld.getType();    if (ftype.isSubtype(Compilation.typeLocation))      flags |= INDIRECT_LOCATION;    if ((fflags & Access.FINAL) != 0)      {        if ((flags & INDIRECT_LOCATION) == 0)          {            flags |= CONSTANT;            if (ftype.isSubtype(Compilation.typeProcedure))              flags |= PROCEDURE;            if (ftype.isSubtype(ClassType.make("kawa.lang.Syntax")))              flags |= SYNTAX;          }        else          {            Location loc = (Location) getFieldValue();            if (loc instanceof FieldLocation)              {                FieldLocation floc = (FieldLocation) loc;                if ((floc.flags & KIND_FLAGS_SET) == 0)                  floc.setKindFlags();                flags |= (floc.flags & (SYNTAX|PROCEDURE|CONSTANT));                if ((floc.flags & CONSTANT) != 0)                  {                    if ((floc.flags & VALUE_SET) != 0)                      {                        value = floc.value;                        flags |= VALUE_SET;                      }                  }                else                  {                    value = floc;                    flags |= VALUE_SET;                  }              }            else if (loc.isConstant())              {                Object val = loc.get(null);                // if (val == null) ????;                if (val instanceof Procedure)                  flags |= PROCEDURE;                if (val instanceof kawa.lang.Syntax) // FIXME                  flags |= SYNTAX;                flags |= CONSTANT|VALUE_SET;                value = val;              }          }      }    flags |= KIND_FLAGS_SET;  }  public boolean isProcedureOrSyntax ()  {    if ((flags & KIND_FLAGS_SET) == 0)      setKindFlags();    return (flags & (PROCEDURE+SYNTAX)) != 0;  }  public FieldLocation(Object instance, String cname, String fname)  {    super(instance, ClassType.make(cname), fname);  }  public FieldLocation(Object instance, ClassType type, String mname)  {    super(instance, type, mname);  }  public void setDeclaration (Declaration decl)  {    this.decl = decl;  }  public Field getField ()  {    return type.getDeclaredField(mname);  }  /** Get the type of the field. */  public Type getFType ()  {    return type.getDeclaredField(mname).getType();  }  public synchronized Declaration getDeclaration ()  {    if ((flags & KIND_FLAGS_SET) == 0)      setKindFlags();    Declaration d = decl;    if (d == null)      {	String fname = getMemberName();	ClassType t = getDeclaringClass();	gnu.bytecode.Field procField = t.getDeclaredField(fname);	if (procField == null)	  return null;        ModuleInfo info = ModuleInfo.find(t.getName());        ModuleExp mexp = info.getModuleExp();        for (d = mexp.firstDecl();  d != null; d = d.nextDecl())          {            if (d.field != null && d.field.getName().equals(fname))              break;          }        if (d == null)          throw new RuntimeException("no field found for "+this);        decl = d;      }    return d;  }  void setup ()  {    synchronized (this)      {	if ((flags & SETUP_DONE) != 0)	  return;	super.setup();        if ((flags & KIND_FLAGS_SET) == 0)          setKindFlags();        flags |= SETUP_DONE;      }  }  public Object get (Object defaultValue)  {    try      {        setup();      }    catch (Throwable ex)      {        return defaultValue;      }    Object v;    if ((flags & VALUE_SET) != 0)      {        v = value;        if ((flags & CONSTANT) != 0)          return v;      }    else      {	v = getFieldValue();	if ((type.getDeclaredField(mname).getModifiers() & Access.FINAL) != 0)	  {	    flags |= VALUE_SET;	    if ((flags & INDIRECT_LOCATION) == 0)              flags |= CONSTANT;	    value = v;	  }      }    if ((flags & INDIRECT_LOCATION) != 0)      {	Object unb = Location.UNBOUND;	Location loc = (Location) v;	v = loc.get(unb);	if (v == unb)	  return defaultValue;	if (loc.isConstant())	  {	    flags |= CONSTANT;	    value = v;	  }      }    return v;  }  private Object getFieldValue ()  {    super.setup(); // Set rfield, if needed.    try      {	return rfield.get(instance);      }    catch (Throwable ex)      {	throw WrappedException.wrapIfNeeded(ex);      }  }  public void set (Object newValue)  {    setup();    if ((flags & INDIRECT_LOCATION) == 0)      {	try	  {	    rfield.set(instance, newValue);	  }	catch (Throwable ex)	  {	    throw WrappedException.wrapIfNeeded(ex);	  }      }    else      {	Object v;	if ((flags & VALUE_SET) != 0)	  v = value;	else	  {	    flags |= VALUE_SET;	    v = getFieldValue();	    value = v;	  }	((Location) v).set(newValue);      }  }  public boolean isConstant ()  {    if ((flags & KIND_FLAGS_SET) == 0)      setKindFlags();    if ((flags & CONSTANT) != 0)      return true;    if (isIndirectLocation())      {	Object v;	if ((flags & VALUE_SET) != 0)	  v = value;	else	  {            try              {                setup();              }            catch (Throwable ex)              {                return false;              }	    v = getFieldValue();	    flags |= VALUE_SET;	    value = v;	  }	return ((Location) v).isConstant();      }    return false;  }  public boolean isBound ()  {    if ((flags & KIND_FLAGS_SET) == 0)      setKindFlags();    if ((flags & CONSTANT) != 0 || (flags & INDIRECT_LOCATION) == 0)      return true;    Object v;    if ((flags & VALUE_SET) != 0)      v = value;    else      {        try          {            setup();          }        catch (Throwable ex)          {            return false;          }	v = getFieldValue();	flags |= VALUE_SET;	value = v;      }    return ((Location) v).isBound();  }  public static FieldLocation make (Object instance, Declaration decl)  {    gnu.bytecode.Field fld = decl.field;    ClassType ctype = fld.getDeclaringClass();    FieldLocation loc = new FieldLocation(instance, ctype, fld.getName());    loc.setDeclaration(decl);    //maybe setKindFlags();    return loc;  }  public static FieldLocation make (/*Object name,*/ Object instance, String cname, String fldName)  {    return new FieldLocation(/*name,*/ instance, ClassType.make(cname), fldName);  }  public String toString()  {    StringBuffer sbuf = new StringBuffer();    sbuf.append("FieldLocation[");    if (instance != null)      {	sbuf.append(instance);	sbuf.append(' ');      }    sbuf.append(type.getName());    sbuf.append('.');    sbuf.append(mname);    /* DEBGUGGING:    sbuf.append(" #:");    sbuf.append(id);    */    sbuf.append(']');    return sbuf.toString();  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -