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

📄 slotget.java

📁 A framework written in Java for implementing high-level and dynamic languages, compiling them into J
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package gnu.kawa.reflect;import gnu.mapping.*;import gnu.expr.*;import gnu.bytecode.*;import gnu.lists.FString;import gnu.kawa.lispexpr.LangPrimType;public class SlotGet extends Procedure2  implements HasSetter, CanInline, Inlineable{  static Class[] noClasses = { };  /** True if this is a "static-field" operation. */  boolean isStatic;  Procedure setter;  public static final SlotGet field    = new SlotGet("field", false, SlotSet.set$Mnfield$Ex);  public static final SlotGet slotRef    = new SlotGet("slot-ref", false, SlotSet.set$Mnfield$Ex);  public static final SlotGet staticField    = new SlotGet("static-field", true, SlotSet.set$Mnstatic$Mnfield$Ex);  public SlotGet(String name, boolean isStatic)  {    super(name);    this.isStatic = isStatic;  }  public SlotGet(String name, boolean isStatic, Procedure setter)  {    super(name);    this.isStatic = isStatic;    this.setter = setter;  }  public static Object field(Object obj, String fname)  {    return field.apply2(obj, fname);  }  public static Object staticField(Object obj, String fname)  {    return staticField.apply2(obj, fname);  }  public Object apply2 (Object arg1, Object arg2)  {    String name, fname;    String getName = null, isName = null;    if (arg2 instanceof gnu.bytecode.Field)      {        fname = ((gnu.bytecode.Field) arg2).getName();        name = Compilation.demangleName(fname, true);      }    else if (arg2 instanceof gnu.bytecode.Method)      {        String mname = ((gnu.bytecode.Method) arg2).getName();        name = Compilation.demangleName(mname, false);        if (mname.startsWith("get"))          getName = mname;        else if (mname.startsWith("is"))          isName = mname;        fname = null;      }    else if (! (arg2 instanceof String) && ! (arg2 instanceof FString))      throw new WrongType(this, 2, arg2, "string");    else      {        name = arg2.toString();        fname = gnu.expr.Compilation.mangleNameIfNeeded(name);      }    // "intern" fname if it is "class" or "length":    if ("class".equals(fname))      fname = "class";    else if ("length".equals(fname))      fname = "length";    return getSlotValue(isStatic, arg1, name, fname, getName, isName,                         Language.getDefaultLanguage());  }  /** The actual gets of finding the field value.   * The compiler emits calls to this method if the field name is literals   * but the actual field is not known at compile time.   * This speeds lookup a bit.   */  public static Object  getSlotValue (boolean isStatic, Object obj, String name, String fname,                String getName, String isName, Language language)  {    Class clas = isStatic ? coerceToClass(obj) : obj.getClass();    if (fname == "length" && clas.isArray())      {	int length = java.lang.reflect.Array.getLength(obj);	return language.coerceToObject(length);      }    if (fname == "class")      return clas;    boolean illegalAccess = false;    if (fname != null)      {        java.lang.reflect.Field field;        try          {            field = clas.getField(fname);          }        catch (Exception ex)          {            field = null;          }        if (field != null)          {            if (isStatic                && (field.getModifiers() & java.lang.reflect.Modifier.STATIC) == 0)              throw new RuntimeException("cannot access non-static field '"                                         + fname + '\'');            try              {                return language.coerceToObject(field.getType(), field.get(obj));              }            catch (IllegalAccessException ex)              {                illegalAccess = true;              }            catch (Exception ex)              {                ex.printStackTrace();  // FIXME?              }          }      }    // Try looking for a method "getFname" or "isFname" instead:    try      {        String mname = null;        java.lang.reflect.Method getmethod = null;                try {          mname = getName != null ? getName            : ClassExp.slotToMethodName("get", name);          getmethod = clas.getMethod(mname, noClasses);        } catch (Exception getEx) {          mname = isName != null ? isName            : ClassExp.slotToMethodName("is", name);          getmethod = clas.getMethod(mname, noClasses);        }        if (isStatic            && (getmethod.getModifiers() & java.lang.reflect.Modifier.STATIC) == 0)          throw new RuntimeException("cannot call non-static getter method '"                                     + mname + '\'');        Object result = getmethod.invoke(obj, Values.noArgs);        result = language.coerceToObject(getmethod.getReturnType(), result);        return result;      }    catch (java.lang.reflect.InvocationTargetException ex)      {        throw WrappedException.wrapIfNeeded(ex.getTargetException());      }    catch (IllegalAccessException ex)      {        illegalAccess = true;      }    catch (java.lang.NoSuchMethodException ex)      {      }    if (illegalAccess)      throw new RuntimeException("illegal access for field "+fname);    else      throw new RuntimeException ("no such field "+fname                                  +" in "+clas.getName());  }  static Class coerceToClass(Object obj)  {    if (obj instanceof Class)      return (Class) obj;    if (obj instanceof gnu.bytecode.Type)      return ((gnu.bytecode.Type) obj).getReflectClass();    throw new RuntimeException("argument is neither Class nor Type");  }  public void setN (Object[] args)  {    int nargs = args.length;    if (nargs != 3)      throw new WrongArguments(getSetter(), nargs);    set2(args[0], args[1], args[2]);  }  public void set2 (Object obj, Object name, Object value)  {    SlotSet.apply(isStatic, obj, (String) name, value);  }  /** Get a named property - field or 'get' accessor method.   * @param clas the class type declaring the property.   * @param name the source (unmangled) name of the property.   */  public static Member  lookupMember (ClassType clas, String name, ClassType caller)  {    gnu.bytecode.Field field      = clas.getField(Compilation.mangleNameIfNeeded(name), -1);    if (field != null)      {        if (caller == null)          caller = Type.pointer_type;        if (caller.isAccessible(field.getDeclaringClass(),                                field.getModifiers()))          return field;      }    // Try looking for a method "getFname" instead:    String getname = ClassExp.slotToMethodName("get", name);    gnu.bytecode.Method method = clas.getMethod(getname, Type.typeArray0);    if (method == null)      return field;    else      return method;  }  public Expression inline (ApplyExp exp, ExpWalker walker)  {    Compilation comp = walker.getCompilation();    Language language = comp.getLanguage();    Type type;    Expression[] args = exp.getArgs();    Expression arg0 = args[0];    Expression arg1 = args[1];    String name = null;    if (arg1 instanceof QuoteExp)      {        Object val1 = ((QuoteExp) arg1).getValue();        if (val1 instanceof String

⌨️ 快捷键说明

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