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