PageRenderTime 54ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/src/sys/java/fan/sys/Field.java

https://bitbucket.org/bedlaczech/fan-1.0
Java | 167 lines | 107 code | 29 blank | 31 comment | 28 complexity | 8cc53d930a75fe6608d97f035edf6dfc MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  1. //
  2. // Copyright (c) 2006, Brian Frank and Andy Frank
  3. // Licensed under the Academic Free License version 3.0
  4. //
  5. // History:
  6. // 4 Jan 06 Brian Frank Creation
  7. //
  8. package fan.sys;
  9. import java.util.Iterator;
  10. import java.util.Map.Entry;
  11. import fanx.fcode.*;
  12. /**
  13. * Field is a slot which "stores" a value.
  14. */
  15. public class Field
  16. extends Slot
  17. {
  18. //////////////////////////////////////////////////////////////////////////
  19. // Factories
  20. //////////////////////////////////////////////////////////////////////////
  21. public static Func makeSetFunc(final Map map)
  22. {
  23. return new Func.Indirect1()
  24. {
  25. public Object call(Object obj)
  26. {
  27. Iterator it = map.pairsIterator();
  28. while (it.hasNext())
  29. {
  30. Entry entry = (Entry)it.next();
  31. Field field = (Field)entry.getKey();
  32. Object val = entry.getValue();
  33. field.set(obj, val, obj != inCtor);
  34. }
  35. return null;
  36. }
  37. };
  38. }
  39. //////////////////////////////////////////////////////////////////////////
  40. // Java Constructor
  41. //////////////////////////////////////////////////////////////////////////
  42. public Field(Type parent, String name, int flags, Facets facets, int lineNum, Type type)
  43. {
  44. super(parent, name, flags, facets, lineNum);
  45. this.type = type;
  46. }
  47. //////////////////////////////////////////////////////////////////////////
  48. // Signature
  49. //////////////////////////////////////////////////////////////////////////
  50. public Type typeof() { return Sys.FieldType; }
  51. public Type type() { return type; }
  52. public String signature() { return type.toStr() + " " + name; }
  53. public Object trap(String name, List args)
  54. {
  55. // private undocumented access
  56. if (name.equals("getter")) return getter;
  57. if (name.equals("setter")) return setter;
  58. return super.trap(name, args);
  59. }
  60. //////////////////////////////////////////////////////////////////////////
  61. // Reflection
  62. //////////////////////////////////////////////////////////////////////////
  63. public Object get() { return get(null); }
  64. public Object get(Object instance)
  65. {
  66. parent.finish();
  67. if (getter != null)
  68. {
  69. return getter.invoke(instance, Method.noArgs);
  70. }
  71. try
  72. {
  73. // if JavaType handle slot resolution
  74. if (parent.isJava()) return JavaType.get(this, instance);
  75. return reflect.get(instance);
  76. }
  77. catch (Exception e)
  78. {
  79. if (reflect == null)
  80. throw Err.make("Field not mapped to java.lang.reflect correctly " + qname());
  81. throw Err.make(e);
  82. }
  83. }
  84. public void set(Object instance, Object value)
  85. {
  86. set(instance, value, true);
  87. }
  88. public void set(Object instance, Object value, boolean checkConst)
  89. {
  90. parent.finish();
  91. // check const
  92. if ((flags & FConst.Const) != 0)
  93. {
  94. if (checkConst)
  95. throw ReadonlyErr.make("Cannot set const field " + qname());
  96. else if (value != null && !isImmutable(value))
  97. throw ReadonlyErr.make("Cannot set const field " + qname() + " with mutable value");
  98. }
  99. // check static
  100. if ((flags & FConst.Static) != 0 && !parent.isJava())
  101. throw ReadonlyErr.make("Cannot set static field " + qname());
  102. // check generic type (the Java runtime will check non-generics)
  103. if (type.isGenericInstance() && value != null)
  104. {
  105. if (!typeof(value).is(type.toNonNullable()))
  106. throw ArgErr.make("Wrong type for field " + qname() + ": " + type + " != " + typeof(value));
  107. }
  108. if (setter != null)
  109. {
  110. setter.invoke(instance, new Object[] { value });
  111. return;
  112. }
  113. try
  114. {
  115. // if JavaType handle slot resolution
  116. if (parent.isJava()) { JavaType.set(this, instance, value); return; }
  117. reflect.set(instance, value);
  118. }
  119. catch (IllegalArgumentException e)
  120. {
  121. throw ArgErr.make(e);
  122. }
  123. catch (Exception e)
  124. {
  125. if (reflect == null)
  126. throw Err.make("Field not mapped to java.lang.reflect correctly");
  127. throw Err.make(e);
  128. }
  129. }
  130. //////////////////////////////////////////////////////////////////////////
  131. // Fields
  132. //////////////////////////////////////////////////////////////////////////
  133. Type type;
  134. Method getter;
  135. Method setter;
  136. java.lang.reflect.Field reflect;
  137. Method overload; // if overloaded by method in JavaType
  138. }