rev 5684 : 4990369: visibleMethods() and methodsByName() return wrong visible methods
Reviewed-by:

   1 /*
   2  * Copyright (c) 2002, 2004, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 package sun.jvm.hotspot.jdi;
  26 
  27 import java.util.ArrayList;
  28 import java.util.List;
  29 import java.util.Map;
  30 import java.util.Set;
  31 
  32 import sun.jvm.hotspot.oops.ArrayKlass;
  33 import sun.jvm.hotspot.oops.Instance;
  34 import sun.jvm.hotspot.oops.InstanceKlass;


  35 import sun.jvm.hotspot.oops.Klass;
  36 import sun.jvm.hotspot.oops.ObjArrayKlass;
  37 import sun.jvm.hotspot.oops.Symbol;
  38 import sun.jvm.hotspot.oops.TypeArrayKlass;
  39 
  40 import com.sun.jdi.ArrayReference;
  41 import com.sun.jdi.ArrayType;
  42 import com.sun.jdi.ClassLoaderReference;
  43 import com.sun.jdi.ClassNotLoadedException;
  44 import com.sun.jdi.InterfaceType;
  45 import com.sun.jdi.Method;
  46 import com.sun.jdi.PrimitiveType;
  47 import com.sun.jdi.ReferenceType;
  48 import com.sun.jdi.Type;
  49 import com.sun.jdi.VirtualMachine;
  50 
  51 public class ArrayTypeImpl extends ReferenceTypeImpl implements ArrayType {
  52   protected ArrayTypeImpl(VirtualMachine aVm, ArrayKlass aRef) {
  53         super(aVm, aRef);
  54     }
  55 
  56     public ArrayReference newInstance(int length) {
  57         vm.throwNotReadOnlyException("ArrayType.newInstance(int)");
  58         return null;
  59     }
  60 
  61     public String componentSignature() {
  62         return signature().substring(1); // Just skip the leading '['
  63     }
  64 
  65     public String componentTypeName() {
  66         JNITypeParser parser = new JNITypeParser(componentSignature());
  67         return parser.typeName();
  68     }
  69 
  70     public ClassLoaderReference classLoader() {
  71         if (ref() instanceof TypeArrayKlass) {
  72             // primitive array klasses are loaded by bootstrap loader
  73             return null;
  74         } else {
  75             Klass bottomKlass = ((ObjArrayKlass)ref()).getBottomKlass();
  76             if (bottomKlass instanceof TypeArrayKlass) {
  77                 // multidimensional primitive array klasses are loaded by bootstrap loader
  78                 return null;
  79             } else {
  80                 // class loader of any other obj array klass is same as the loader
  81                 // that loaded the bottom InstanceKlass
  82                 Instance xx = (Instance)(((InstanceKlass) bottomKlass).getClassLoader());
  83                 return vm.classLoaderMirror(xx);
  84             }
  85         }
  86     }
  87 
  88     @Override
  89     void addVisibleMethods(Map<String, Method> methodMap, Set<InterfaceType> handledInterfaces) {
  90         // arrays don't have methods
  91     }
  92 
  93     List getAllMethods() {
  94         // arrays don't have methods
  95         // JLS says arrays have methods of java.lang.Object. But
  96         // JVMDI-JDI returns zero size list. We do the same here
  97         // for consistency.
  98         return new ArrayList(0);
  99     }
 100 
 101     /*
 102      * Find the type object, if any, of a component type of this array.
 103      * The component type does not have to be immediate; e.g. this method
 104      * can be used to find the component Foo of Foo[][].
 105      */
 106     public Type componentType() throws ClassNotLoadedException {
 107         ArrayKlass k = (ArrayKlass) ref();
 108         if (k instanceof ObjArrayKlass) {
 109             Klass elementKlass = ((ObjArrayKlass)k).getElementKlass();
 110             if (elementKlass == null) {
 111                 throw new ClassNotLoadedException(componentSignature());
 112             } else {
 113                 return vm.referenceType(elementKlass);
 114             }
 115         } else {
 116             // It's a primitive type
 117             return vm.primitiveTypeMirror(signature().charAt(1));
 118         }
 119     }
 120 
 121     static boolean isComponentAssignable(Type destination, Type source) {
 122         if (source instanceof PrimitiveType) {
 123             // Assignment of primitive arrays requires identical
 124             // component types.
 125             return source.equals(destination);
 126         } else {
 127            if (destination instanceof PrimitiveType) {
 128                 return false;
 129             }
 130 
 131             ReferenceTypeImpl refSource = (ReferenceTypeImpl)source;
 132             ReferenceTypeImpl refDestination = (ReferenceTypeImpl)destination;
 133             // Assignment of object arrays requires availability
 134             // of widening conversion of component types
 135             return refSource.isAssignableTo(refDestination);
 136         }
 137     }
 138 
 139 
 140     /*
 141     * Return true if an instance of the  given reference type
 142     * can be assigned to a variable of this type
 143     */
 144     boolean isAssignableTo(ReferenceType destType) {
 145         if (destType instanceof ArrayType) {
 146             try {
 147                 Type destComponentType = ((ArrayType)destType).componentType();
 148                 return isComponentAssignable(destComponentType, componentType());
 149             } catch (ClassNotLoadedException e) {
 150                 // One or both component types has not yet been
 151                 // loaded => can't assign
 152                 return false;
 153             }
 154         } else {
 155             Symbol typeName = ((ReferenceTypeImpl)destType).typeNameAsSymbol();
 156             if (destType instanceof InterfaceType) {
 157                 // Every array type implements java.io.Serializable and
 158                 // java.lang.Cloneable. fixme in JVMDI-JDI, includes only
 159                 // Cloneable but not Serializable.
 160                 return typeName.equals(vm.javaLangCloneable()) ||
 161                        typeName.equals(vm.javaIoSerializable());
 162             } else {
 163                 // Only valid ClassType assignee is Object
 164                 return typeName.equals(vm.javaLangObject());
 165             }
 166         }
 167     }
 168 
 169     List inheritedTypes() {
 170         // arrays are derived from java.lang.Object and
 171         // B[] is derived from A[] if B is derived from A.
 172         // But JVMDI-JDI returns zero sized list and we do the
 173         // same for consistency.
 174         return new ArrayList(0);
 175     }
 176 
 177     int getModifiers() {
 178         /*
 179          * For object arrays, the return values for Interface
 180          * Accessible.isPrivate(), Accessible.isProtected(),
 181          * etc... are the same as would be returned for the
 182          * component type.  Fetch the modifier bits from the
 183          * component type and use those.
 184          *
 185          * For primitive arrays, the modifiers are always
 186          *   VMModifiers.FINAL | VMModifiers.PUBLIC
 187          *
 188          * Reference com.sun.jdi.Accessible.java.
 189          */
 190         try {
 191             Type t = componentType();
 192             if (t instanceof PrimitiveType) {
 193                 return VMModifiers.FINAL | VMModifiers.PUBLIC;
 194             } else {
 195                 ReferenceType rt = (ReferenceType)t;
 196                 return rt.modifiers();
 197             }
 198         } catch (ClassNotLoadedException cnle) {
 199             cnle.printStackTrace();
 200         }
 201         return -1;
 202     }
 203 
 204     public String toString() {
 205        return "array class " + name() + " (" + loaderString() + ")";
 206     }
 207 
 208     /*
 209      * Save a pointless trip over the wire for these methods
 210      * which have undefined results for arrays.
 211      */
 212     public boolean isPrepared() { return true; }
 213     public boolean isVerified() { return true; }
 214     public boolean isInitialized() { return true; }
 215     public boolean failedToInitialize() { return false; }
 216     public boolean isAbstract() { return false; }
 217 
 218     /*
 219      * Defined always to be true for arrays
 220      */
 221     public boolean isFinal() { return true; }
 222 }
--- EOF ---