1 /*
   2  * Copyright (c) 2009, 2016, 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 package jdk.vm.ci.meta;
  24 
  25 import java.lang.reflect.AnnotatedElement;
  26 
  27 import jdk.vm.ci.meta.Assumptions.AssumptionResult;
  28 
  29 /**
  30  * Represents a resolved Java type. Types include primitives, objects, {@code void}, and arrays
  31  * thereof. Types, like fields and methods, are resolved through {@link ConstantPool constant pools}
  32  * .
  33  */
  34 public interface ResolvedJavaType extends JavaType, ModifiersProvider, AnnotatedElement {
  35     /**
  36      * Checks whether this type has a finalizer method.
  37      *
  38      * @return {@code true} if this class has a finalizer
  39      */
  40     boolean hasFinalizer();
  41 
  42     /**
  43      * Checks whether this type has any finalizable subclasses so far. Any decisions based on this
  44      * information require the registration of a dependency, since this information may change.
  45      *
  46      * @return {@code true} if this class has any subclasses with finalizers
  47      */
  48     AssumptionResult<Boolean> hasFinalizableSubclass();
  49 
  50     /**
  51      * Checks whether this type is an interface.
  52      *
  53      * @return {@code true} if this type is an interface
  54      */
  55     boolean isInterface();
  56 
  57     /**
  58      * Checks whether this type is an instance class.
  59      *
  60      * @return {@code true} if this type is an instance class
  61      */
  62     boolean isInstanceClass();
  63 
  64     /**
  65      * Checks whether this type is primitive.
  66      *
  67      * @return {@code true} if this type is primitive
  68      */
  69     boolean isPrimitive();
  70 
  71     /*
  72      * The setting of the final bit for types is a bit confusing since arrays are marked as final.
  73      * This method provides a semantically equivalent test that appropriate for types.
  74      */
  75     default boolean isLeaf() {
  76         return getElementalType().isFinalFlagSet();
  77     }
  78 
  79     /**
  80      * Checks whether this type is initialized. If a type is initialized it implies that it was
  81      * {@link #isLinked() linked} and that the static initializer has run.
  82      *
  83      * @return {@code true} if this type is initialized
  84      */
  85     boolean isInitialized();
  86 
  87     /**
  88      * Initializes this type.
  89      */
  90     void initialize();
  91 
  92     /**
  93      * Checks whether this type is linked and verified. When a type is linked the static initializer
  94      * has not necessarily run. An {@link #isInitialized() initialized} type is always linked.
  95      *
  96      * @return {@code true} if this type is linked
  97      */
  98     boolean isLinked();
  99 
 100     /**
 101      * Determines if this type is either the same as, or is a superclass or superinterface of, the
 102      * type represented by the specified parameter. This method is identical to
 103      * {@link Class#isAssignableFrom(Class)} in terms of the value return for this type.
 104      */
 105     boolean isAssignableFrom(ResolvedJavaType other);
 106 
 107     /**
 108      * Returns the {@link ResolvedJavaType} object representing the host class of this VM anonymous
 109      * class (as opposed to the unrelated concept specified by {@link Class#isAnonymousClass()}) or
 110      * {@code null} if this object does not represent a VM anonymous class.
 111      */
 112     ResolvedJavaType getHostClass();
 113 
 114     /**
 115      * Returns true if this type is exactly the type {@link java.lang.Object}.
 116      */
 117     default boolean isJavaLangObject() {
 118         // Removed assertion due to https://bugs.eclipse.org/bugs/show_bug.cgi?id=434442
 119         return getSuperclass() == null && !isInterface() && getJavaKind() == JavaKind.Object;
 120     }
 121 
 122     /**
 123      * Checks whether the specified object is an instance of this type.
 124      *
 125      * @param obj the object to test
 126      * @return {@code true} if the object is an instance of this type
 127      */
 128     boolean isInstance(JavaConstant obj);
 129 
 130     /**
 131      * Gets the super class of this type. If this type represents either the {@code Object} class,
 132      * an interface, a primitive type, or void, then null is returned. If this object represents an
 133      * array class then the type object representing the {@code Object} class is returned.
 134      */
 135     ResolvedJavaType getSuperclass();
 136 
 137     /**
 138      * Gets the interfaces implemented or extended by this type. This method is analogous to
 139      * {@link Class#getInterfaces()} and as such, only returns the interfaces directly implemented
 140      * or extended by this type.
 141      */
 142     ResolvedJavaType[] getInterfaces();
 143 
 144     /**
 145      * Gets the single implementor of this type. Calling this method on a non-interface type causes
 146      * an exception.
 147      * <p>
 148      * If the compiler uses the result of this method for its compilation, the usage must be guarded
 149      * because the verifier can not guarantee that the assigned type really implements this
 150      * interface. Additionally, class loading can invalidate the result of this method.
 151      *
 152      * @return {@code null} if there is no implementor, the implementor if there is only one, or
 153      *         {@code this} if there are more than one.
 154      */
 155     ResolvedJavaType getSingleImplementor();
 156 
 157     /**
 158      * Walks the class hierarchy upwards and returns the least common class that is a superclass of
 159      * both the current and the given type.
 160      *
 161      * @return the least common type that is a super type of both the current and the given type, or
 162      *         {@code null} if primitive types are involved.
 163      */
 164     ResolvedJavaType findLeastCommonAncestor(ResolvedJavaType otherType);
 165 
 166     /**
 167      * Attempts to get a leaf concrete subclass of this type.
 168      * <p>
 169      * For an {@linkplain #isArray() array} type A, the leaf concrete subclass is A if the
 170      * {@linkplain #getElementalType() elemental} type of A is final (which includes primitive
 171      * types). Otherwise {@code null} is returned for A.
 172      * <p>
 173      * For a non-array type T, the result is the leaf concrete type in the current hierarchy of T.
 174      * <p>
 175      * A runtime may decide not to manage or walk a large hierarchy and so the result is
 176      * conservative. That is, a non-null result is guaranteed to be the leaf concrete class in T's
 177      * hierarchy <b>at the current point in time</b> but a null result does not necessarily imply
 178      * that there is no leaf concrete class in T's hierarchy.
 179      * <p>
 180      * If the compiler uses the result of this method for its compilation, it must register the
 181      * {@link AssumptionResult} in its {@link Assumptions} because dynamic class loading can
 182      * invalidate the result of this method.
 183      *
 184      * @return an {@link AssumptionResult} containing the leaf concrete subclass for this type as
 185      *         described above
 186      */
 187     AssumptionResult<ResolvedJavaType> findLeafConcreteSubtype();
 188 
 189     ResolvedJavaType getComponentType();
 190 
 191     default ResolvedJavaType getElementalType() {
 192         ResolvedJavaType t = this;
 193         while (t.isArray()) {
 194             t = t.getComponentType();
 195         }
 196         return t;
 197     }
 198 
 199     ResolvedJavaType getArrayClass();
 200 
 201     /**
 202      * Resolves the method implementation for virtual dispatches on objects of this dynamic type.
 203      * This resolution process only searches "up" the class hierarchy of this type. A broader search
 204      * that also walks "down" the hierarchy is implemented by
 205      * {@link #findUniqueConcreteMethod(ResolvedJavaMethod)}. For interface types it returns null
 206      * since no concrete object can be an interface.
 207      *
 208      * @param method the method to select the implementation of
 209      * @param callerType the caller or context type used to perform access checks
 210      * @return the link-time resolved method (might be abstract) or {@code null} if it is either a
 211      *         signature polymorphic method or can not be linked.
 212      */
 213     ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method, ResolvedJavaType callerType);
 214 
 215     /**
 216      * A convenience wrapper for {@link #resolveMethod(ResolvedJavaMethod, ResolvedJavaType)} that
 217      * only returns non-abstract methods.
 218      *
 219      * @param method the method to select the implementation of
 220      * @param callerType the caller or context type used to perform access checks
 221      * @return the concrete method that would be selected at runtime, or {@code null} if there is no
 222      *         concrete implementation of {@code method} in this type or any of its superclasses
 223      */
 224     default ResolvedJavaMethod resolveConcreteMethod(ResolvedJavaMethod method, ResolvedJavaType callerType) {
 225         ResolvedJavaMethod resolvedMethod = resolveMethod(method, callerType);
 226         if (resolvedMethod == null || resolvedMethod.isAbstract()) {
 227             return null;
 228         }
 229         return resolvedMethod;
 230     }
 231 
 232     /**
 233      * Given a {@link ResolvedJavaMethod} A, returns a concrete {@link ResolvedJavaMethod} B that is
 234      * the only possible unique target for a virtual call on A(). Returns {@code null} if either no
 235      * such concrete method or more than one such method exists. Returns the method A if A is a
 236      * concrete method that is not overridden.
 237      * <p>
 238      * If the compiler uses the result of this method for its compilation, it must register an
 239      * assumption because dynamic class loading can invalidate the result of this method.
 240      *
 241      * @param method the method A for which a unique concrete target is searched
 242      * @return the unique concrete target or {@code null} if no such target exists or assumptions
 243      *         are not supported by this runtime
 244      */
 245     AssumptionResult<ResolvedJavaMethod> findUniqueConcreteMethod(ResolvedJavaMethod method);
 246 
 247     /**
 248      * Returns the instance fields of this class, including
 249      * {@linkplain ResolvedJavaField#isInternal() internal} fields. A zero-length array is returned
 250      * for array and primitive types. The order of fields returned by this method is stable. That
 251      * is, for a single JVM execution the same order is returned each time this method is called. It
 252      * is also the "natural" order, which means that the JVM would expect the fields in this order
 253      * if no specific order is given.
 254      *
 255      * @param includeSuperclasses if true, then instance fields for the complete hierarchy of this
 256      *            type are included in the result
 257      * @return an array of instance fields
 258      */
 259     ResolvedJavaField[] getInstanceFields(boolean includeSuperclasses);
 260 
 261     /**
 262      * Returns the static fields of this class, including {@linkplain ResolvedJavaField#isInternal()
 263      * internal} fields. A zero-length array is returned for array and primitive types. The order of
 264      * fields returned by this method is stable. That is, for a single JVM execution the same order
 265      * is returned each time this method is called.
 266      */
 267     ResolvedJavaField[] getStaticFields();
 268 
 269     /**
 270      * Returns the instance field of this class (or one of its super classes) at the given offset,
 271      * or {@code null} if there is no such field.
 272      *
 273      * @param offset the offset of the field to look for
 274      * @return the field with the given offset, or {@code null} if there is no such field.
 275      */
 276     ResolvedJavaField findInstanceFieldWithOffset(long offset, JavaKind expectedKind);
 277 
 278     /**
 279      * Returns name of source file of this type.
 280      */
 281     String getSourceFileName();
 282 
 283     /**
 284      * Returns {@code true} if the type is a local type.
 285      */
 286     boolean isLocal();
 287 
 288     /**
 289      * Returns {@code true} if the type is a member type.
 290      */
 291     boolean isMember();
 292 
 293     /**
 294      * Returns the enclosing type of this type, if it exists, or {@code null}.
 295      */
 296     ResolvedJavaType getEnclosingType();
 297 
 298     /**
 299      * Returns an array reflecting all the constructors declared by this type. This method is
 300      * similar to {@link Class#getDeclaredConstructors()} in terms of returned constructors.
 301      */
 302     ResolvedJavaMethod[] getDeclaredConstructors();
 303 
 304     /**
 305      * Returns an array reflecting all the methods declared by this type. This method is similar to
 306      * {@link Class#getDeclaredMethods()} in terms of returned methods.
 307      */
 308     ResolvedJavaMethod[] getDeclaredMethods();
 309 
 310     /**
 311      * Returns the {@code <clinit>} method for this class if there is one.
 312      */
 313     ResolvedJavaMethod getClassInitializer();
 314 
 315     default ResolvedJavaMethod findMethod(String name, Signature signature) {
 316         for (ResolvedJavaMethod method : getDeclaredMethods()) {
 317             if (method.getName().equals(name) && method.getSignature().equals(signature)) {
 318                 return method;
 319             }
 320         }
 321         return null;
 322     }
 323 
 324     /**
 325      * Returns true if this type is {@link Cloneable} and can be safely cloned by creating a normal
 326      * Java allocation and populating it from the fields returned by
 327      * {@link #getInstanceFields(boolean)}. Some types may require special handling by the platform
 328      * so they would to go through the normal {@link Object#clone} path.
 329      */
 330     boolean isCloneableWithAllocation();
 331 }