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