Path: blob/master/test/jdk/java/lang/constant/ClassDescTest.java
41149 views
/*1* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.lang.invoke.MethodHandles;24import java.lang.constant.ClassDesc;25import java.lang.constant.ConstantDescs;26import java.lang.reflect.Array;27import java.lang.reflect.Field;28import java.lang.reflect.Modifier;29import java.util.Arrays;30import java.util.List;31import java.util.Map;3233import org.testng.annotations.Test;3435import static org.testng.Assert.assertEquals;36import static org.testng.Assert.assertFalse;37import static org.testng.Assert.assertNotEquals;38import static org.testng.Assert.assertNull;39import static org.testng.Assert.assertTrue;40import static org.testng.Assert.fail;4142/**43* @test44* @bug 821551045* @compile ClassDescTest.java46* @run testng ClassDescTest47* @summary unit tests for java.lang.constant.ClassDesc48*/49@Test50public class ClassDescTest extends SymbolicDescTest {5152private void testClassDesc(ClassDesc r) throws ReflectiveOperationException {53testSymbolicDesc(r);5455// Test descriptor accessor, factory, equals56assertEquals(r, ClassDesc.ofDescriptor(r.descriptorString()));5758if (!r.descriptorString().equals("V")) {59assertEquals(r, r.arrayType().componentType());60// Commutativity: array -> resolve -> componentType -> toSymbolic61assertEquals(r, ((Class<?>) r.arrayType().resolveConstantDesc(LOOKUP)).getComponentType().describeConstable().orElseThrow());62// Commutativity: resolve -> array -> toSymbolic -> component type63assertEquals(r, Array.newInstance(((Class<?>) r.resolveConstantDesc(LOOKUP)), 0).getClass().describeConstable().orElseThrow().componentType());64}6566if (r.isArray()) {67assertEquals(r, r.componentType().arrayType());68assertEquals(r, ((Class<?>) r.resolveConstantDesc(LOOKUP)).getComponentType().describeConstable().orElseThrow().arrayType());69assertEquals(r, Array.newInstance(((Class<?>) r.componentType().resolveConstantDesc(LOOKUP)), 0).getClass().describeConstable().orElseThrow());70}71}7273private void testClassDesc(ClassDesc r, Class<?> c) throws ReflectiveOperationException {74testClassDesc(r);7576assertEquals(r.resolveConstantDesc(LOOKUP), c);77assertEquals(c.describeConstable().orElseThrow(), r);78assertEquals(ClassDesc.ofDescriptor(c.descriptorString()), r);79}8081public void testSymbolicDescsConstants() throws ReflectiveOperationException {82int tested = 0;83Field[] fields = ConstantDescs.class.getDeclaredFields();84for (Field f : fields) {85try {86if (f.getType().equals(ClassDesc.class)87&& ((f.getModifiers() & Modifier.STATIC) != 0)88&& ((f.getModifiers() & Modifier.PUBLIC) != 0)) {89ClassDesc cr = (ClassDesc) f.get(null);90Class c = (Class)cr.resolveConstantDesc(MethodHandles.lookup());91testClassDesc(cr, c);92++tested;93}94}95catch (Throwable e) {96System.out.println(e.getMessage());97fail("Error testing field " + f.getName(), e);98}99}100101assertTrue(tested > 0);102}103104public void testPrimitiveClassDesc() throws ReflectiveOperationException {105for (Primitives p : Primitives.values()) {106List<ClassDesc> descs = List.of(ClassDesc.ofDescriptor(p.descriptor),107p.classDesc,108(ClassDesc) p.clazz.describeConstable().orElseThrow());109for (ClassDesc c : descs) {110testClassDesc(c, p.clazz);111assertTrue(c.isPrimitive());112assertEquals(p.descriptor, c.descriptorString());113assertEquals(p.name, c.displayName());114descs.forEach(cc -> assertEquals(c, cc));115if (p != Primitives.VOID) {116testClassDesc(c.arrayType(), p.arrayClass);117assertEquals(c, ((ClassDesc) p.arrayClass.describeConstable().orElseThrow()).componentType());118assertEquals(c, p.classDesc.arrayType().componentType());119}120}121122for (Primitives other : Primitives.values()) {123ClassDesc otherDescr = ClassDesc.ofDescriptor(other.descriptor);124if (p != other)125descs.forEach(c -> assertNotEquals(c, otherDescr));126else127descs.forEach(c -> assertEquals(c, otherDescr));128}129}130}131132public void testSimpleClassDesc() throws ReflectiveOperationException {133134List<ClassDesc> stringClassDescs = Arrays.asList(ClassDesc.ofDescriptor("Ljava/lang/String;"),135ClassDesc.of("java.lang", "String"),136ClassDesc.of("java.lang.String"),137ClassDesc.of("java.lang.String").arrayType().componentType(),138String.class.describeConstable().orElseThrow());139for (ClassDesc r : stringClassDescs) {140testClassDesc(r, String.class);141assertFalse(r.isPrimitive());142assertEquals("Ljava/lang/String;", r.descriptorString());143assertEquals("String", r.displayName());144assertEquals(r.arrayType().resolveConstantDesc(LOOKUP), String[].class);145stringClassDescs.forEach(rr -> assertEquals(r, rr));146}147148testClassDesc(ClassDesc.of("java.lang.String").arrayType(), String[].class);149testClassDesc(ClassDesc.of("java.util.Map").nested("Entry"), Map.Entry.class);150151ClassDesc thisClassDesc = ClassDesc.ofDescriptor("LClassDescTest;");152assertEquals(thisClassDesc, ClassDesc.of("", "ClassDescTest"));153assertEquals(thisClassDesc, ClassDesc.of("ClassDescTest"));154assertEquals(thisClassDesc.displayName(), "ClassDescTest");155testClassDesc(thisClassDesc, ClassDescTest.class);156}157158public void testPackageName() {159assertEquals("com.foo", ClassDesc.of("com.foo.Bar").packageName());160assertEquals("com.foo", ClassDesc.of("com.foo.Bar").nested("Baz").packageName());161assertEquals("", ClassDesc.of("Bar").packageName());162assertEquals("", ClassDesc.of("Bar").nested("Baz").packageName());163assertEquals("", ClassDesc.of("Bar").nested("Baz", "Foo").packageName());164165assertEquals("", ConstantDescs.CD_int.packageName());166assertEquals("", ConstantDescs.CD_int.arrayType().packageName());167assertEquals("", ConstantDescs.CD_String.arrayType().packageName());168assertEquals("", ClassDesc.of("Bar").arrayType().packageName());169}170171private void testBadArrayRank(ClassDesc cr) {172try {173cr.arrayType(-1);174fail("");175} catch (IllegalArgumentException e) {176// good177}178try {179cr.arrayType(0);180fail("");181} catch (IllegalArgumentException e) {182// good183}184}185186public void testArrayClassDesc() throws ReflectiveOperationException {187for (String d : basicDescs) {188ClassDesc a0 = ClassDesc.ofDescriptor(d);189ClassDesc a1 = a0.arrayType();190ClassDesc a2 = a1.arrayType();191192testClassDesc(a0);193testClassDesc(a1);194testClassDesc(a2);195assertFalse(a0.isArray());196assertTrue(a1.isArray());197assertTrue(a2.isArray());198assertFalse(a1.isPrimitive());199assertFalse(a2.isPrimitive());200assertEquals(a0.descriptorString(), d);201assertEquals(a1.descriptorString(), "[" + a0.descriptorString());202assertEquals(a2.descriptorString(), "[[" + a0.descriptorString());203204assertNull(a0.componentType());205assertEquals(a0, a1.componentType());206assertEquals(a1, a2.componentType());207208assertNotEquals(a0, a1);209assertNotEquals(a1, a2);210211assertEquals(a1, ClassDesc.ofDescriptor("[" + d));212assertEquals(a2, ClassDesc.ofDescriptor("[[" + d));213assertEquals(classToDescriptor((Class<?>) a0.resolveConstantDesc(LOOKUP)), a0.descriptorString());214assertEquals(classToDescriptor((Class<?>) a1.resolveConstantDesc(LOOKUP)), a1.descriptorString());215assertEquals(classToDescriptor((Class<?>) a2.resolveConstantDesc(LOOKUP)), a2.descriptorString());216217testBadArrayRank(ConstantDescs.CD_int);218testBadArrayRank(ConstantDescs.CD_String);219testBadArrayRank(ClassDesc.of("Bar"));220}221}222223public void testBadClassDescs() {224List<String> badDescriptors = List.of("II", "I;", "Q", "L", "",225"java.lang.String", "[]", "Ljava/lang/String",226"Ljava.lang.String;", "java/lang/String");227228for (String d : badDescriptors) {229try {230ClassDesc constant = ClassDesc.ofDescriptor(d);231fail(d);232}233catch (IllegalArgumentException e) {234// good235}236}237238List<String> badBinaryNames = List.of("I;", "[]", "Ljava/lang/String",239"Ljava.lang.String;", "java/lang/String");240for (String d : badBinaryNames) {241try {242ClassDesc constant = ClassDesc.of(d);243fail(d);244} catch (IllegalArgumentException e) {245// good246}247}248249for (Primitives p : Primitives.values()) {250testBadNestedClasses(ClassDesc.ofDescriptor(p.descriptor), "any");251testBadNestedClasses(ClassDesc.ofDescriptor(p.descriptor), "any", "other");252}253254ClassDesc stringDesc = ClassDesc.ofDescriptor("Ljava/lang/String;");255ClassDesc stringArrDesc = stringDesc.arrayType(255);256try {257ClassDesc arrGreaterThan255 = stringArrDesc.arrayType();258fail("can't create an array type descriptor with more than 255 dimensions");259} catch (IllegalStateException e) {260// good261}262String descWith255ArrayDims = new String(new char[255]).replace('\0', '[');263try {264ClassDesc arrGreaterThan255 = ClassDesc.ofDescriptor(descWith255ArrayDims + "[Ljava/lang/String;");265fail("can't create an array type descriptor with more than 255 dimensions");266} catch (IllegalArgumentException e) {267// good268}269try {270ClassDesc arrWith255Dims = ClassDesc.ofDescriptor(descWith255ArrayDims + "Ljava/lang/String;");271arrWith255Dims.arrayType(1);272fail("can't create an array type descriptor with more than 255 dimensions");273} catch (IllegalArgumentException e) {274// good275}276}277278private void testBadNestedClasses(ClassDesc cr, String firstNestedName, String... moreNestedNames) {279try {280cr.nested(firstNestedName, moreNestedNames);281fail("");282} catch (IllegalStateException e) {283// good284}285}286287public void testLangClasses() {288Double d = 1.0;289assertEquals(d.resolveConstantDesc(LOOKUP), d);290assertEquals(d.describeConstable().get(), d);291292Integer i = 1;293assertEquals(i.resolveConstantDesc(LOOKUP), i);294assertEquals(i.describeConstable().get(), i);295296Float f = 1.0f;297assertEquals(f.resolveConstantDesc(LOOKUP), f);298assertEquals(f.describeConstable().get(), f);299300Long l = 1L;301assertEquals(l.resolveConstantDesc(LOOKUP), l);302assertEquals(l.describeConstable().get(), l);303304String s = "";305assertEquals(s.resolveConstantDesc(LOOKUP), s);306assertEquals(s.describeConstable().get(), s);307}308309public void testNullNestedClasses() {310ClassDesc cd = ClassDesc.of("Bar");311try {312cd.nested(null);313fail("");314} catch (NullPointerException e) {315// good316}317318try {319cd.nested("good", null);320fail("");321} catch (NullPointerException e) {322// good323}324325try {326cd.nested("good", "goodToo", null);327fail("");328} catch (NullPointerException e) {329// good330}331}332}333334335