changeset 50733:acd4969ec1f8 condy-folding

manual merge with jep-334 branch
author vromero
date Thu, 24 May 2018 07:15:23 -0700
parents d72fb500b553 f7d2d1cc9d8c
children 3248898657dc
files src/java.base/share/classes/java/lang/Class.java src/java.base/share/classes/java/lang/Double.java src/java.base/share/classes/java/lang/Enum.java src/java.base/share/classes/java/lang/Float.java src/java.base/share/classes/java/lang/Integer.java src/java.base/share/classes/java/lang/Long.java src/java.base/share/classes/java/lang/String.java src/java.base/share/classes/java/lang/invoke/FieldTypeDescriptor.java src/java.base/share/classes/java/lang/invoke/VarHandle.java src/java.base/share/classes/java/lang/invoke/VarHandles.java src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template src/java.base/share/classes/java/lang/invoke/constant/AsTypeMethodHandleDesc.java src/java.base/share/classes/java/lang/invoke/constant/ClassDesc.java src/java.base/share/classes/java/lang/invoke/constant/Constable.java src/java.base/share/classes/java/lang/invoke/constant/ConstantClassDesc.java src/java.base/share/classes/java/lang/invoke/constant/ConstantDesc.java src/java.base/share/classes/java/lang/invoke/constant/ConstantDescs.java src/java.base/share/classes/java/lang/invoke/constant/ConstantMethodHandleDesc.java src/java.base/share/classes/java/lang/invoke/constant/ConstantUtils.java src/java.base/share/classes/java/lang/invoke/constant/DynamicCallSiteDesc.java src/java.base/share/classes/java/lang/invoke/constant/DynamicConstantDesc.java src/java.base/share/classes/java/lang/invoke/constant/PrimitiveClassDesc.java src/java.base/share/classes/module-info.java test/jdk/java/lang/invoke/constant/ClassRefTest.java
diffstat 25 files changed, 213 insertions(+), 95 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/lang/Class.java	Wed May 23 09:13:50 2018 -0700
+++ b/src/java.base/share/classes/java/lang/Class.java	Thu May 24 07:15:23 2018 -0700
@@ -3879,9 +3879,7 @@
 
     @Override
     public Class<?> componentType() {
-        if (!isArray())
-            throw new IllegalStateException("not an array class");
-        return componentType;
+        return isArray() ? componentType : null;
     }
 
     @Override
--- a/src/java.base/share/classes/java/lang/Double.java	Wed May 23 09:13:50 2018 -0700
+++ b/src/java.base/share/classes/java/lang/Double.java	Thu May 24 07:15:23 2018 -0700
@@ -1077,10 +1077,10 @@
     }
 
     /**
-     * Returns a symbolic constant reference for this instance, which is
-     * the instance itself.
+     * Returns a nominal descriptor for this instance, which is the instance
+     * itself.
      *
-     * @return the {@linkplain Double} instance
+     * @return an {@link Optional} describing the {@linkplain Double} instance
      */
     @Override
     public Optional<ConstantDesc<Double>> describeConstable() {
--- a/src/java.base/share/classes/java/lang/Enum.java	Wed May 23 09:13:50 2018 -0700
+++ b/src/java.base/share/classes/java/lang/Enum.java	Thu May 24 07:15:23 2018 -0700
@@ -206,16 +206,6 @@
         return (zuper == Enum.class) ? (Class<E>)clazz : (Class<E>)zuper;
     }
 
-    /**
-     * Return a nominal descriptor for this instance, if one can be
-     * constructed.  This object (and any classes needed to construct its
-     * nominal description) must be accessible from the class described by the
-     * {@code lookup} parameter.
-     *
-     * @return An {@link Optional} containing the resulting nominal descriptor,
-     * or an empty {@link Optional} if one cannot be constructed or this object
-     * is not accessible from {@code lookup}
-     */
     @Override
     public final Optional<EnumDesc<E>> describeConstable() {
         return getDeclaringClass()
--- a/src/java.base/share/classes/java/lang/Float.java	Wed May 23 09:13:50 2018 -0700
+++ b/src/java.base/share/classes/java/lang/Float.java	Thu May 24 07:15:23 2018 -0700
@@ -989,10 +989,10 @@
     }
 
     /**
-     * Returns a symbolic constant reference for this instance, which is
-     * the instance itself.
+     * Returns a nominal descriptor for this instance, which is the instance
+     * itself.
      *
-     * @return the {@linkplain Float} instance
+     * @return an {@link Optional} describing the {@linkplain Float} instance
      */
     @Override
     public Optional<ConstantDesc<Float>> describeConstable() {
--- a/src/java.base/share/classes/java/lang/Integer.java	Wed May 23 09:13:50 2018 -0700
+++ b/src/java.base/share/classes/java/lang/Integer.java	Thu May 24 07:15:23 2018 -0700
@@ -1824,10 +1824,10 @@
     }
 
     /**
-     * Returns a symbolic constant reference for this instance, which is
-     * the instance itself.
+     * Returns a nominal descriptor for this instance, which is the instance
+     * itself.
      *
-     * @return the {@linkplain Integer} instance
+     * @return an {@link Optional} describing the {@linkplain Integer} instance
      */
     @Override
     public Optional<ConstantDesc<Integer>> describeConstable() {
--- a/src/java.base/share/classes/java/lang/Long.java	Wed May 23 09:13:50 2018 -0700
+++ b/src/java.base/share/classes/java/lang/Long.java	Thu May 24 07:15:23 2018 -0700
@@ -1970,10 +1970,10 @@
     }
 
     /**
-     * Returns a symbolic constant reference for this instance, which is
-     * the instance itself.
+     * Returns a nominal descriptor for this instance, which is the instance
+     * itself.
      *
-     * @return the {@linkplain Long} instance
+     * @return an {@link Optional} describing the {@linkplain Long} instance
      */
     @Override
     public Optional<ConstantDesc<Long>> describeConstable() {
--- a/src/java.base/share/classes/java/lang/String.java	Wed May 23 09:13:50 2018 -0700
+++ b/src/java.base/share/classes/java/lang/String.java	Thu May 24 07:15:23 2018 -0700
@@ -3280,10 +3280,10 @@
     }
 
     /**
-     * Returns a symbolic constant reference for this instance, which is
-     * the instance itself.
+     * Returns a nominal descriptor for this instance, which is the instance
+     * itself.
      *
-     * @return the {@linkplain String} instance
+     * @return an {@link Optional} describing the {@linkplain String} instance
      */
     @Override
     public Optional<ConstantDesc<String>> describeConstable() {
--- a/src/java.base/share/classes/java/lang/invoke/FieldTypeDescriptor.java	Wed May 23 09:13:50 2018 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/FieldTypeDescriptor.java	Thu May 24 07:15:23 2018 -0700
@@ -20,9 +20,9 @@
 
     /**
      * If this field descriptor describes an array type, return
-     * a descriptor for its component type.
-     * @return the component type
-     * @throws IllegalStateException if this descriptor does not describe an array type
+     * a descriptor for its component type, otherwise return {@code null}.
+     * @return the component type, or {@code null} if this field descriptor does
+     * not describe an array type
      */
     F componentType();
 
--- a/src/java.base/share/classes/java/lang/invoke/VarHandle.java	Wed May 23 09:13:50 2018 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/VarHandle.java	Thu May 24 07:15:23 2018 -0700
@@ -1869,22 +1869,19 @@
                internalEquals(that);
     }
 
-    boolean internalEquals(VarHandle vh) {
-        return true;
-    }
+    abstract boolean internalEquals(VarHandle vh);
 
     @Override
     public final int hashCode() {
         return 31 * accessModeType(AccessMode.GET).hashCode() + internalHashCode();
     }
 
-    int internalHashCode() {
-        return 0;
-    }
+    abstract int internalHashCode();
 
     @Override
     public final String toString() {
         // @@@ defer to concrete type for additional description
+        // see https://bugs.openjdk.java.net/browse/JDK-8199149
         return String.format("VarHandle[varType=%s, cooordType=%s]",
                              varType().getName(),
                              coordinateTypes());
--- a/src/java.base/share/classes/java/lang/invoke/VarHandles.java	Wed May 23 09:13:50 2018 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/VarHandles.java	Thu May 24 07:15:23 2018 -0700
@@ -148,7 +148,7 @@
     }
 
     // Required by instance field handles
-    static Field getFieldFromRecieverAndOffset(Class<?> receiverType,
+    static Field getFieldFromReceiverAndOffset(Class<?> receiverType,
                                                long offset,
                                                Class<?> fieldType) {
         for (Field f : receiverType.getDeclaredFields()) {
--- a/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template	Wed May 23 09:13:50 2018 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template	Thu May 24 07:15:23 2018 -0700
@@ -81,7 +81,8 @@
             if (!receiverTypeRef.isPresent() || !fieldTypeRef.isPresent())
                 return Optional.empty();
 
-            String name = VarHandles.getFieldFromRecieverAndOffset(
+            // Reflect on this VarHandle to extract the field name
+            String name = VarHandles.getFieldFromReceiverAndOffset(
                 receiverType, fieldOffset, {#if[Object]?fieldType:$type$.class}).getName();
             return Optional.of(VarHandleDesc.ofField(receiverTypeRef.get(), name, fieldTypeRef.get()));
         }
@@ -365,6 +366,7 @@
             if (!fieldTypeRef.isPresent())
                 return Optional.empty();
 
+            // Reflect on this VarHandle to extract the field name
             var staticField = VarHandles.getStaticFieldFromBaseAndOffset(
                 base, fieldOffset, {#if[Object]?fieldType:$type$.class});
             var receiverTypeRef = staticField.getDeclaringClass().describeConstable();
@@ -638,6 +640,20 @@
         }
 
         @Override
+        final boolean internalEquals(VarHandle vh) {
+            // Equality of access mode types of AccessMode.GET is sufficient for
+            // equality checks
+            return true;
+        }
+
+        @Override
+        final int internalHashCode() {
+            // The hash code of the access mode types of AccessMode.GET is
+            // sufficient for hash code generation
+            return 0;
+        }
+
+        @Override
         public Optional<VarHandleDesc> describeConstable() {
             var arrayTypeRef = {#if[Object]?arrayType:$type$[].class}.describeConstable();
             if (!arrayTypeRef.isPresent())
--- a/src/java.base/share/classes/java/lang/invoke/constant/AsTypeMethodHandleDesc.java	Wed May 23 09:13:50 2018 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/constant/AsTypeMethodHandleDesc.java	Thu May 24 07:15:23 2018 -0700
@@ -77,6 +77,4 @@
     public String toString() {
         return  String.format("%s.asType%s", underlying.toString(), type.displayDescriptor());
     }
-
-    // @@@ canonical support -- detect DCR with BSM=MHR_METHODHANDLEDESC_ASTYPE
 }
--- a/src/java.base/share/classes/java/lang/invoke/constant/ClassDesc.java	Wed May 23 09:13:50 2018 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/constant/ClassDesc.java	Thu May 24 07:15:23 2018 -0700
@@ -58,7 +58,12 @@
                 FieldTypeDescriptor<ClassDesc> {
 
     /**
-     * Create a {@linkplain ClassDesc} given a class name.
+     * Create a {@linkplain ClassDesc} given the name of a class or interface
+     * type, such as {@code "java.lang.String"}.  (To create a descriptor for an
+     * array type, either use {@link #ofDescriptor(String)}
+     * or {@link #arrayType()}; to create a descriptor for a primitive type, use
+     * {@link #ofDescriptor(String)} or use the predefined constants in
+     * {@link ConstantDescs}).
      *
      * @param name the fully qualified (dot-separated) binary class name
      * @return a {@linkplain ClassDesc} describing the desired class
@@ -204,24 +209,22 @@
 
     /**
      * Returns the component type of this {@linkplain ClassDesc}, if it describes
-     * an array type.
+     * an array type, or {@code null} otherwise.
      *
-     * @return a {@linkplain ClassDesc} describing the component type
-     * @throws IllegalStateException if this {@linkplain ClassDesc} does not
-     * describe an array type
+     * @return a {@linkplain ClassDesc} describing the component type, or {@code null}
+     * if this descriptor does not describe an array type
      */
     @Foldable
     default ClassDesc componentType() {
-        if (!isArray())
-            throw new IllegalStateException("not an array");
-        return ClassDesc.ofDescriptor(descriptorString().substring(1));
+        return isArray() ? ClassDesc.ofDescriptor(descriptorString().substring(1)) : null;
     }
 
     /**
      * Returns the package name of this {@linkplain ClassDesc}, if it describes
      * a class or interface type.
      *
-     * @return the package name, or the empty string if no package
+     * @return the package name, or the empty string if the class is in the
+     * default package
      * @throws IllegalStateException if this {@linkplain ClassDesc} does not
      * describe a class or interface type
      */
@@ -257,7 +260,7 @@
     }
 
     /**
-     * Return the descriptor string for this type, as per JVMS 4.3.2
+     * Return a field type descriptor string for this type, as per JVMS 4.3.2
      *
      * @return the descriptor string
      */
--- a/src/java.base/share/classes/java/lang/invoke/constant/Constable.java	Wed May 23 09:13:50 2018 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/constant/Constable.java	Thu May 24 07:15:23 2018 -0700
@@ -36,8 +36,8 @@
  * nominally as a {@link ConstantDesc}.
  *
  * <p>Some constable types have a native representation in the constant pool:
- * ({@link String}, {@link Integer}, {@link Long}, {@link Float},
- * {@link Double}, {@link Class}, {@link MethodType}, and {@link MethodHandle}).
+ * {@link String}, {@link Integer}, {@link Long}, {@link Float},
+ * {@link Double}, {@link Class}, {@link MethodType}, and {@link MethodHandle}.
  * The types {@link String}, {@link Integer}, {@link Long}, {@link Float},
  * and {@link Double} serve as their own nominal descriptors; {@link Class},
  * {@link MethodType}, and {@link MethodHandle} have corresponding nominal
@@ -64,7 +64,7 @@
 public interface Constable<T> {
     /**
      * Return a nominal descriptor for this instance, if one can be
-     * constructed.
+     * constructed, or an empty {@link Optional} if one cannot be.
      *
      * @return An {@link Optional} containing the resulting nominal descriptor,
      * or an empty {@link Optional} if one cannot be constructed.
--- a/src/java.base/share/classes/java/lang/invoke/constant/ConstantClassDesc.java	Wed May 23 09:13:50 2018 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/constant/ConstantClassDesc.java	Thu May 24 07:15:23 2018 -0700
@@ -40,7 +40,7 @@
  * interface, or array type.  A {@linkplain ConstantClassDesc} corresponds to a
  * {@code Constant_Class_info} entry in the constant pool of a classfile.
  */
-public class ConstantClassDesc implements ClassDesc {
+public final class ConstantClassDesc implements ClassDesc {
     private final String descriptor;
 
     /**
--- a/src/java.base/share/classes/java/lang/invoke/constant/ConstantDesc.java	Wed May 23 09:13:50 2018 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/constant/ConstantDesc.java	Thu May 24 07:15:23 2018 -0700
@@ -66,14 +66,18 @@
  * Instead, they should extend {@link DynamicConstantDesc} (as {@link EnumDesc}
  * and {@link VarHandleDesc} do.)
  *
+ * <p>Nominal descriptors should be compared using the
+ * {@link Object#equals(Object)} method. There is no guarantee that any
+ * particular entity will always be represented by the same descriptor instance.
+ *
  * @apiNote In the future, if the Java language permits, {@linkplain ConstantDesc}
  * may become a {@code sealed} interface, which would prohibit subclassing except by
- * explicitly permitted types.  Bytecode libraries can assume that the following
- * is an exhaustive set of direct subtypes: {@link String}, {@link Integer},
- * {@link Long}, {@link Float}, {@link Double}, {@link ClassDesc},
- * {@link MethodTypeDesc}, {@link MethodHandleDesc}, and {@link DynamicConstantDesc};
- * this list may be extended to reflect future changes to the constant pool format
- * as defined in JVMS 4.4.
+ * explicitly permitted types.  Clients can assume that the following
+ * set of concrete subtypes is exhaustive: {@link String}, {@link Integer},
+ * {@link Long}, {@link Float}, {@link Double}, {@link ConstantClassDesc},
+ * {@link ConstantMethodTypeDesc}, {@link ConstantMethodHandleDesc}, and
+ * {@link DynamicConstantDesc}; this list may be extended to reflect future
+ * changes to the constant pool format as defined in JVMS 4.4.
  *
  * @see Constable
  * @see Intrinsics
--- a/src/java.base/share/classes/java/lang/invoke/constant/ConstantDescs.java	Wed May 23 09:13:50 2018 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/constant/ConstantDescs.java	Thu May 24 07:15:23 2018 -0700
@@ -166,60 +166,60 @@
 
     /** {@link ClassDesc} representing {@link ConstantDesc} */
     @Foldable
-    static final ClassDesc CR_ConstantDesc = ClassDesc.of("java.lang.invoke.constant.ConstantDesc");
+    public static final ClassDesc CR_ConstantDesc = ClassDesc.of("java.lang.invoke.constant.ConstantDesc");
 
     /** {@link ClassDesc} representing {@link ClassDesc} */
     @Foldable
-    static final ClassDesc CR_ClassDesc = ClassDesc.of("java.lang.invoke.constant.ClassDesc");
+    public static final ClassDesc CR_ClassDesc = ClassDesc.of("java.lang.invoke.constant.ClassDesc");
 
     /** {@link ClassDesc} representing {@link EnumDesc} */
     @Foldable
-    static final ClassDesc CR_EnumDesc = ClassDesc.of("java.lang.invoke.constant.EnumDesc");
+    public static final ClassDesc CR_EnumDesc = ClassDesc.of("java.lang.invoke.constant.EnumDesc");
 
     /** {@link ClassDesc} representing {@link MethodTypeDesc} */
     @Foldable
-    static final ClassDesc CR_MethodTypeDesc = ClassDesc.of("java.lang.invoke.constant.MethodTypeDesc");
+    public static final ClassDesc CR_MethodTypeDesc = ClassDesc.of("java.lang.invoke.constant.MethodTypeDesc");
 
     /** {@link ClassDesc} representing {@link ConstantMethodTypeDesc} */
     @Foldable
-    static final ClassDesc CR_ConstantMethodTypeDesc = ClassDesc.of("java.lang.invoke.constant.ConstantMethodTypeDesc");
+    public static final ClassDesc CR_ConstantMethodTypeDesc = ClassDesc.of("java.lang.invoke.constant.ConstantMethodTypeDesc");
 
     /** {@link ClassDesc} representing {@link MethodHandleDesc} */
     @Foldable
-    static final ClassDesc CR_MethodHandleDesc = ClassDesc.of("java.lang.invoke.constant.MethodHandleDesc");
+    public static final ClassDesc CR_MethodHandleDesc = ClassDesc.of("java.lang.invoke.constant.MethodHandleDesc");
 
     /** {@link ClassDesc} representing {@link ConstantMethodHandleDesc} */
     @Foldable
-    static final ClassDesc CR_ConstantMethodHandleDesc = ClassDesc.of("java.lang.invoke.constant.ConstantMethodHandleDesc");
+    public static final ClassDesc CR_ConstantMethodHandleDesc = ClassDesc.of("java.lang.invoke.constant.ConstantMethodHandleDesc");
 
     /** {@link ClassDesc} representing {@link VarHandleDesc} */
     @Foldable
-    static final ClassDesc CR_VarHandleDesc = ClassDesc.of("java.lang.invoke.constant.VarHandleDesc");
+    public static final ClassDesc CR_VarHandleDesc = ClassDesc.of("java.lang.invoke.constant.VarHandleDesc");
 
     /** {@link ClassDesc} representing {@link MethodHandleDesc.Kind} */
     @Foldable
-    static final ClassDesc CR_MethodHandleDesc_Kind = CR_MethodHandleDesc.inner("Kind");
+    public static final ClassDesc CR_MethodHandleDesc_Kind = CR_MethodHandleDesc.inner("Kind");
 
     /** {@link ClassDesc} representing {@link DynamicConstantDesc} */
     @Foldable
-    static final ClassDesc CR_DynamicConstantDesc = ClassDesc.of("java.lang.invoke.constant.DynamicConstantDesc");
+    public static final ClassDesc CR_DynamicConstantDesc = ClassDesc.of("java.lang.invoke.constant.DynamicConstantDesc");
 
     /** {@link ClassDesc} representing {@link DynamicCallSiteDesc} */
     @Foldable
-    static final ClassDesc CR_DynamicCallSiteDesc = ClassDesc.of("java.lang.invoke.constant.DynamicCallSiteDesc");
+    public static final ClassDesc CR_DynamicCallSiteDesc = ClassDesc.of("java.lang.invoke.constant.DynamicCallSiteDesc");
 
     /** {@link ClassDesc} representing {@link ConstantBootstraps} */
     @Foldable
-    static final ClassDesc CR_ConstantBootstraps = ClassDesc.of("java.lang.invoke.ConstantBootstraps");
+    public static final ClassDesc CR_ConstantBootstraps = ClassDesc.of("java.lang.invoke.ConstantBootstraps");
 
     // Used by MethodHandleDesc, but initialized here before reference to
     // MethodHandleDesc to avoid static initalization circularities
-    static final ClassDesc[] INDY_BOOTSTRAP_ARGS = {
+    /* non-public */ static final ClassDesc[] INDY_BOOTSTRAP_ARGS = {
             ConstantDescs.CR_MethodHandles_Lookup,
             ConstantDescs.CR_String,
             ConstantDescs.CR_MethodType };
 
-    static final ClassDesc[] CONDY_BOOTSTRAP_ARGS = {
+    /* non-public */ static final ClassDesc[] CONDY_BOOTSTRAP_ARGS = {
             ConstantDescs.CR_MethodHandles_Lookup,
             ConstantDescs.CR_String,
             ConstantDescs.CR_Class };
@@ -308,7 +308,7 @@
             = DynamicConstantDesc.of(ConstantDescs.BSM_NULL_CONSTANT,
                                      ConstantDescs.CR_Object);
 
-    // Used by XxxDesc classes, but need to be hear to avoid bootstrap cycles
+    // Used by XxxDesc classes, but need to be here to avoid bootstrap cycles
     static final ConstantMethodHandleDesc MHR_METHODTYPEDESC_FACTORY
             = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, CR_MethodTypeDesc, "ofDescriptor",
                                   CR_MethodTypeDesc, CR_String);
--- a/src/java.base/share/classes/java/lang/invoke/constant/ConstantMethodHandleDesc.java	Wed May 23 09:13:50 2018 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/constant/ConstantMethodHandleDesc.java	Thu May 24 07:15:23 2018 -0700
@@ -45,7 +45,7 @@
  * {@link MethodHandle}.  A {@linkplain ConstantMethodHandleDesc} corresponds to
  * a {@code Constant_MethodHandle_info} entry in the constant pool of a classfile.
  */
-public class ConstantMethodHandleDesc implements MethodHandleDesc {
+public final class ConstantMethodHandleDesc implements MethodHandleDesc {
 
     private final Kind kind;
     private final ClassDesc owner;
--- a/src/java.base/share/classes/java/lang/invoke/constant/ConstantUtils.java	Wed May 23 09:13:50 2018 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/constant/ConstantUtils.java	Thu May 24 07:15:23 2018 -0700
@@ -33,9 +33,7 @@
 import sun.invoke.util.Wrapper;
 
 /**
- * ConstantUtils
- *
- * @author Brian Goetz
+ * Helper methods for the implementation of {@code java.lang.invoke.constant}.
  */
 class ConstantUtils {
     static final ConstantDesc<?>[] EMPTY_CONSTANTDESC = new ConstantDesc<?>[0];
--- a/src/java.base/share/classes/java/lang/invoke/constant/DynamicCallSiteDesc.java	Wed May 23 09:13:50 2018 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/constant/DynamicCallSiteDesc.java	Thu May 24 07:15:23 2018 -0700
@@ -42,9 +42,11 @@
 /**
  * A <a href="package-summary.html#nominal">nominal descriptor</a> for an
  * {@code invokedynamic} call site.
+ *
+ * <p>Concrete subtypes of {@linkplain DynamicCallSiteDesc} must be
+ * <a href="../doc-files/ValueBased.html">value-based</a>.
  */
-@SuppressWarnings("rawtypes")
-public final class DynamicCallSiteDesc {
+public class DynamicCallSiteDesc {
 
     private final ConstantMethodHandleDesc bootstrapMethod;
     private final ConstantDesc<?>[] bootstrapArgs;
--- a/src/java.base/share/classes/java/lang/invoke/constant/DynamicConstantDesc.java	Wed May 23 09:13:50 2018 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/constant/DynamicConstantDesc.java	Thu May 24 07:15:23 2018 -0700
@@ -477,6 +477,8 @@
         return VarHandleDesc.ofArray((ClassDesc) desc.bootstrapArgs[0]);
     }
 
+    // @@@ To eventually support in canonicalization: DCR with BSM=MHR_METHODHANDLEDESC_ASTYPE becomes AsTypeMHDesc
+
     @Override
     public final boolean equals(Object o) {
         if (this == o) return true;
--- a/src/java.base/share/classes/java/lang/invoke/constant/PrimitiveClassDesc.java	Wed May 23 09:13:50 2018 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/constant/PrimitiveClassDesc.java	Thu May 24 07:15:23 2018 -0700
@@ -32,7 +32,8 @@
 import static java.util.Objects.requireNonNull;
 
 /**
- * PrimitiveClassDesc
+ * A <a href="package-summary.html#nominal">nominal descriptor</a> for the class
+ * constant corresponding to a primitive type (e.g., {@code int.class}).
  */
 final class PrimitiveClassDesc
         extends DynamicConstantDesc<Class<?>> implements ClassDesc {
--- a/src/java.base/share/classes/module-info.java	Wed May 23 09:13:50 2018 -0700
+++ b/src/java.base/share/classes/module-info.java	Thu May 24 07:15:23 2018 -0700
@@ -309,9 +309,9 @@
         jdk.security.auth,
         jdk.security.jgss;
     exports sun.security.util.math to
-        jdk.crypto.ec
+        jdk.crypto.ec;
     exports sun.security.util.math.intpoly to
-        jdk.crypto.ec
+        jdk.crypto.ec;
     exports sun.security.x509 to
         jdk.crypto.ec,
         jdk.crypto.cryptoki,
--- a/test/jdk/java/lang/invoke/constant/ClassRefTest.java	Wed May 23 09:13:50 2018 -0700
+++ b/test/jdk/java/lang/invoke/constant/ClassRefTest.java	Thu May 24 07:15:23 2018 -0700
@@ -38,6 +38,7 @@
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertNotEquals;
+import static org.testng.Assert.assertNull;
 import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
 
@@ -45,7 +46,7 @@
  * @test
  * @compile -XDfolding=false ClassRefTest.java
  * @run testng ClassRefTest
- * @summary unit tests for java.lang.invoke.constant.ClassRef
+ * @summary unit tests for java.lang.invoke.constant.ClassDesc
  */
 @Test
 public class ClassRefTest extends SymbolicRefTest {
@@ -159,8 +160,7 @@
         try {
             cr.packageName();
             fail("");
-        }
-        catch (IllegalStateException e) {
+        } catch (IllegalStateException e) {
             // good
         }
     }
@@ -177,6 +177,15 @@
         testBadPackageName(ClassDesc.of("Bar").arrayType());
     }
 
+    private void testBadArrayRank(ClassDesc cr) {
+        try {
+            cr.arrayType(-1);
+            fail("");
+        } catch (IllegalArgumentException e) {
+            // good
+        }
+    }
+
     public void testArrayClassRef() throws ReflectiveOperationException {
         for (String d : basicDescs) {
             ClassDesc a0 = ClassDesc.ofDescriptor(d);
@@ -195,13 +204,7 @@
             assertEquals(a1.descriptorString(), "[" + a0.descriptorString());
             assertEquals(a2.descriptorString(), "[[" + a0.descriptorString());
 
-            try {
-                assertEquals(a0, a0.componentType());
-                fail("Didn't throw ISE");
-            }
-            catch (IllegalStateException expected) {
-                // succeed
-            }
+            assertNull(a0.componentType());
             assertEquals(a0, a1.componentType());
             assertEquals(a1, a2.componentType());
 
@@ -213,6 +216,10 @@
             assertEquals(classToDescriptor(a0.resolveConstantDesc(LOOKUP)), a0.descriptorString());
             assertEquals(classToDescriptor(a1.resolveConstantDesc(LOOKUP)), a1.descriptorString());
             assertEquals(classToDescriptor(a2.resolveConstantDesc(LOOKUP)), a2.descriptorString());
+
+            testBadArrayRank(ConstantDescs.CR_int);
+            testBadArrayRank(ConstantDescs.CR_String);
+            testBadArrayRank(ClassDesc.of("Bar"));
         }
     }
 
@@ -230,5 +237,20 @@
                 // good
             }
         }
+
+        ClassDesc barDesc = ClassDesc.of("Bar");
+        for (Primitives p : Primitives.values()) {
+            testBadInnerClasses(ClassDesc.ofDescriptor(p.descriptor), "any");
+            testBadInnerClasses(ClassDesc.ofDescriptor(p.descriptor), "any", "other");
+        }
+    }
+
+    private void testBadInnerClasses(ClassDesc cr, String firstInnerName, String... moreInnerNames) {
+        try {
+            cr.inner(firstInnerName, moreInnerNames);
+            fail("");
+        } catch (IllegalStateException e) {
+            // good
+        }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/invoke/constant/TypeDescriptorTest.java	Thu May 24 07:15:23 2018 -0700
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.invoke.FieldTypeDescriptor;
+import java.lang.invoke.constant.ClassDesc;
+
+import org.testng.annotations.Test;
+
+import static java.lang.invoke.constant.ConstantDescs.*;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * @test
+ * @compile -XDfolding=false TypeDescriptorTest.java
+ * @run testng TypeDescriptorTest
+ * @summary unit tests for implementations of java.lang.invoke.TypeDescriptor
+ */
+@Test
+public class TypeDescriptorTest {
+    private<F extends FieldTypeDescriptor<F>> void testArray(F f, boolean isArray, F component, F array) {
+        if (isArray) {
+            assertTrue(f.isArray());
+            assertEquals(f.arrayType(), array);
+            assertEquals(f.componentType(), component);
+        }
+        else {
+            assertFalse(f.isArray());
+            assertEquals(f.arrayType(), array);
+            assertNull(f.componentType());
+        }
+    }
+
+    public void testClass() {
+        testArray(int.class, false, null, int[].class);
+        testArray(int[].class, true, int.class, int[][].class);
+        testArray(int[][].class, true, int[].class, int[][][].class);
+        testArray(String.class, false, null, String[].class);
+        testArray(String[].class, true, String.class, String[][].class);
+        testArray(String[][].class, true, String[].class, String[][][].class);
+
+        assertTrue(int.class.isPrimitive());
+        assertFalse(int[].class.isPrimitive());
+        assertFalse(String.class.isPrimitive());
+        assertFalse(String[].class.isPrimitive());
+    }
+
+    public void testClassDesc() {
+
+        testArray(CR_int, false, null, CR_int.arrayType());
+        testArray(CR_int.arrayType(), true, CR_int, CR_int.arrayType(2));
+        testArray(CR_int.arrayType(2), true, CR_int.arrayType(), CR_int.arrayType(3));
+        testArray(CR_String, false, null, CR_String.arrayType());
+        testArray(CR_String.arrayType(), true, CR_String, CR_String.arrayType(2));
+        testArray(CR_String.arrayType(2), true, CR_String.arrayType(), CR_String.arrayType(3));
+
+        assertTrue(CR_int.isPrimitive());
+        assertFalse(CR_int.arrayType().isPrimitive());
+        assertFalse(CR_String.isPrimitive());
+        assertFalse(CR_String.arrayType().isPrimitive());
+    }
+
+}