OpenJDK / amber / amber
changeset 50728:a064652a444f jep-334
Minor updates based on CSR and spec review; add tests for FieldTypeDescriptor methods
line wrap: on
line diff
--- a/src/java.base/share/classes/java/lang/Class.java Wed May 23 07:17:14 2018 -0700 +++ b/src/java.base/share/classes/java/lang/Class.java Wed May 23 13:24:31 2018 -0400 @@ -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 07:17:14 2018 -0700 +++ b/src/java.base/share/classes/java/lang/Double.java Wed May 23 13:24:31 2018 -0400 @@ -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 07:17:14 2018 -0700 +++ b/src/java.base/share/classes/java/lang/Enum.java Wed May 23 13:24:31 2018 -0400 @@ -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 07:17:14 2018 -0700 +++ b/src/java.base/share/classes/java/lang/Float.java Wed May 23 13:24:31 2018 -0400 @@ -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 07:17:14 2018 -0700 +++ b/src/java.base/share/classes/java/lang/Integer.java Wed May 23 13:24:31 2018 -0400 @@ -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 07:17:14 2018 -0700 +++ b/src/java.base/share/classes/java/lang/Long.java Wed May 23 13:24:31 2018 -0400 @@ -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 07:17:14 2018 -0700 +++ b/src/java.base/share/classes/java/lang/String.java Wed May 23 13:24:31 2018 -0400 @@ -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 07:17:14 2018 -0700 +++ b/src/java.base/share/classes/java/lang/invoke/FieldTypeDescriptor.java Wed May 23 13:24:31 2018 -0400 @@ -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/VarHandles.java Wed May 23 07:17:14 2018 -0700 +++ b/src/java.base/share/classes/java/lang/invoke/VarHandles.java Wed May 23 13:24:31 2018 -0400 @@ -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 07:17:14 2018 -0700 +++ b/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template Wed May 23 13:24:31 2018 -0400 @@ -81,7 +81,7 @@ if (!receiverTypeRef.isPresent() || !fieldTypeRef.isPresent()) return Optional.empty(); - String name = VarHandles.getFieldFromRecieverAndOffset( + String name = VarHandles.getFieldFromReceiverAndOffset( receiverType, fieldOffset, {#if[Object]?fieldType:$type$.class}).getName(); return Optional.of(VarHandleDesc.ofField(receiverTypeRef.get(), name, fieldTypeRef.get())); }
--- a/src/java.base/share/classes/java/lang/invoke/constant/ClassDesc.java Wed May 23 07:17:14 2018 -0700 +++ b/src/java.base/share/classes/java/lang/invoke/constant/ClassDesc.java Wed May 23 13:24:31 2018 -0400 @@ -57,7 +57,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 @@ -196,23 +201,21 @@ /** * 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 */ 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 */
--- a/src/java.base/share/classes/java/lang/invoke/constant/Constable.java Wed May 23 07:17:14 2018 -0700 +++ b/src/java.base/share/classes/java/lang/invoke/constant/Constable.java Wed May 23 13:24:31 2018 -0400 @@ -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 07:17:14 2018 -0700 +++ b/src/java.base/share/classes/java/lang/invoke/constant/ConstantClassDesc.java Wed May 23 13:24:31 2018 -0400 @@ -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 07:17:14 2018 -0700 +++ b/src/java.base/share/classes/java/lang/invoke/constant/ConstantDesc.java Wed May 23 13:24:31 2018 -0400 @@ -65,6 +65,10 @@ * 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
--- a/src/java.base/share/classes/java/lang/invoke/constant/ConstantMethodHandleDesc.java Wed May 23 07:17:14 2018 -0700 +++ b/src/java.base/share/classes/java/lang/invoke/constant/ConstantMethodHandleDesc.java Wed May 23 13:24:31 2018 -0400 @@ -43,7 +43,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 07:17:14 2018 -0700 +++ b/src/java.base/share/classes/java/lang/invoke/constant/ConstantUtils.java Wed May 23 13:24:31 2018 -0400 @@ -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 07:17:14 2018 -0700 +++ b/src/java.base/share/classes/java/lang/invoke/constant/DynamicCallSiteDesc.java Wed May 23 13:24:31 2018 -0400 @@ -40,9 +40,12 @@ /** * 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/test/jdk/java/lang/invoke/constant/ClassRefTest.java Wed May 23 07:17:14 2018 -0700 +++ b/test/jdk/java/lang/invoke/constant/ClassRefTest.java Wed May 23 13:24:31 2018 -0400 @@ -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; @@ -195,13 +196,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());
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/invoke/constant/TypeDescriptorTest.java Wed May 23 13:24:31 2018 -0400 @@ -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()); + } + +}