/**
   * Return a List of SA Fields for all the java fields in this class, including all inherited
   * fields. This includes hidden fields. Thus the returned list can contain fields with the same
   * name. Return an empty list if there are no fields. Only designed for use in a debugging system.
   */
  public List getAllFields() {
    // Contains a Field for each field in this class, including immediate
    // fields and inherited fields.
    List allFields = getImmediateFields();

    // transitiveInterfaces contains all interfaces implemented
    // by this class and its superclass chain with no duplicates.

    ObjArray interfaces = getTransitiveInterfaces();
    int n = (int) interfaces.getLength();
    for (int i = 0; i < n; i++) {
      InstanceKlass intf1 = (InstanceKlass) interfaces.getObjAt(i);
      if (Assert.ASSERTS_ENABLED) {
        Assert.that(intf1.isInterface(), "just checking type");
      }
      allFields.addAll(intf1.getImmediateFields());
    }

    // Get all fields in the superclass, recursively.  But, don't
    // include fields in interfaces implemented by superclasses;
    // we already have all those.
    if (!isInterface()) {
      InstanceKlass supr;
      if ((supr = (InstanceKlass) getSuper()) != null) {
        allFields.addAll(supr.getImmediateFields());
      }
    }

    return allFields;
  }
 private static int linearSearch(ObjArray methods, Symbol name, Symbol signature) {
   int len = (int) methods.getLength();
   for (int index = 0; index < len; index++) {
     Method m = (Method) methods.getObjAt(index);
     if (m.getSignature().equals(signature) && m.getName().equals(name)) {
       return index;
     }
   }
   return -1;
 }
 public boolean implementsInterface(Klass k) {
   if (Assert.ASSERTS_ENABLED) {
     Assert.that(k.isInterface(), "should not reach here");
   }
   ObjArray interfaces = getTransitiveInterfaces();
   final int len = (int) interfaces.getLength();
   for (int i = 0; i < len; i++) {
     if (interfaces.getObjAt(i).equals(k)) return true;
   }
   return false;
 }
  /**
   * Return a List containing an SA InstanceKlass for each interface named in this class's
   * 'implements' clause.
   */
  public List getDirectImplementedInterfaces() {
    // Contains an InstanceKlass for each interface in this classes
    // 'implements' clause.

    ObjArray interfaces = getLocalInterfaces();
    int length = (int) interfaces.getLength();
    List directImplementedInterfaces = new ArrayList(length);

    for (int index = 0; index < length; index++) {
      directImplementedInterfaces.add(interfaces.getObjAt(index));
    }

    return directImplementedInterfaces;
  }
 private static Method findMethod(ObjArray methods, Symbol name, Symbol signature) {
   int len = (int) methods.getLength();
   // methods are sorted, so do binary search
   int l = 0;
   int h = len - 1;
   while (l <= h) {
     int mid = (l + h) >> 1;
     Method m = (Method) methods.getObjAt(mid);
     int res = m.getName().fastCompare(name);
     if (res == 0) {
       // found matching name; do linear search to find matching signature
       // first, quick check for common case
       if (m.getSignature().equals(signature)) return m;
       // search downwards through overloaded methods
       int i;
       for (i = mid - 1; i >= l; i--) {
         Method m1 = (Method) methods.getObjAt(i);
         if (!m1.getName().equals(name)) break;
         if (m1.getSignature().equals(signature)) return m1;
       }
       // search upwards
       for (i = mid + 1; i <= h; i++) {
         Method m1 = (Method) methods.getObjAt(i);
         if (!m1.getName().equals(name)) break;
         if (m1.getSignature().equals(signature)) return m1;
       }
       // not found
       if (Assert.ASSERTS_ENABLED) {
         int index = linearSearch(methods, name, signature);
         if (index != -1) {
           throw new DebuggerException("binary search bug: should have found entry " + index);
         }
       }
       return null;
     } else if (res < 0) {
       l = mid + 1;
     } else {
       h = mid - 1;
     }
   }
   if (Assert.ASSERTS_ENABLED) {
     int index = linearSearch(methods, name, signature);
     if (index != -1) {
       throw new DebuggerException("binary search bug: should have found entry " + index);
     }
   }
   return null;
 }
  /**
   * Return a List of SA Methods declared directly in this class/interface. Return an empty list if
   * there are none, or if this isn't a class/ interface.
   */
  public List getImmediateMethods() {
    // Contains a Method for each method declared in this class/interface
    // not including inherited methods.

    ObjArray methods = getMethods();
    int length = (int) methods.getLength();
    Object[] tmp = new Object[length];

    TypeArray methodOrdering = getMethodOrdering();
    if (methodOrdering.getLength() != length) {
      // no ordering info present
      for (int index = 0; index < length; index++) {
        tmp[index] = methods.getObjAt(index);
      }
    } else {
      for (int index = 0; index < length; index++) {
        int originalIndex = getMethodOrdering().getIntAt(index);
        tmp[originalIndex] = methods.getObjAt(index);
      }
    }

    return Arrays.asList(tmp);
  }
 /** Find field in direct superinterfaces. */
 public Field findInterfaceField(Symbol name, Symbol sig) {
   ObjArray interfaces = getLocalInterfaces();
   int n = (int) interfaces.getLength();
   for (int i = 0; i < n; i++) {
     InstanceKlass intf1 = (InstanceKlass) interfaces.getObjAt(i);
     if (Assert.ASSERTS_ENABLED) {
       Assert.that(intf1.isInterface(), "just checking type");
     }
     // search for field in current interface
     Field f = intf1.findLocalField(name, sig);
     if (f != null) {
       if (Assert.ASSERTS_ENABLED) {
         Assert.that(f.getAccessFlagsObj().isStatic(), "interface field must be static");
       }
       return f;
     }
     // search for field in direct superinterfaces
     f = intf1.findInterfaceField(name, sig);
     if (f != null) return f;
   }
   // otherwise field lookup fails
   return null;
 }