Path: blob/master/test/jdk/java/lang/constant/CondyDescTest.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.Enum.EnumDesc;24import java.lang.constant.MethodTypeDesc;25import java.lang.invoke.MethodHandle;26import java.lang.invoke.MethodHandles;27import java.lang.invoke.VarHandle;28import java.lang.invoke.VarHandle.VarHandleDesc;29import java.lang.constant.ClassDesc;30import java.lang.constant.ConstantDesc;31import java.lang.constant.ConstantDescs;32import java.lang.constant.DirectMethodHandleDesc;33import java.lang.constant.DynamicConstantDesc;34import java.lang.constant.MethodHandleDesc;3536import org.testng.annotations.Test;3738import static java.lang.constant.ConstantDescs.CD_MethodHandle;39import static java.lang.constant.ConstantDescs.CD_Object;40import static java.lang.constant.ConstantDescs.CD_String;41import static java.lang.constant.ConstantDescs.CD_VarHandle;42import static java.lang.constant.ConstantDescs.CD_int;43import static org.testng.Assert.assertEquals;44import static org.testng.Assert.assertFalse;45import static org.testng.Assert.assertNotEquals;46import static org.testng.Assert.assertNotSame;47import static org.testng.Assert.assertNull;48import static org.testng.Assert.assertSame;49import static org.testng.Assert.assertTrue;5051/**52* @test53* @compile CondyDescTest.java54* @run testng CondyDescTest55* @summary unit tests for java.lang.constant.CondyDescTest56*/57@Test58public class CondyDescTest extends SymbolicDescTest {59private final static ConstantDesc[] EMPTY_ARGS = new ConstantDesc[0];60private final static ClassDesc CD_ConstantBootstraps = ClassDesc.of("java.lang.invoke.ConstantBootstraps");6162private static<T> void testDCR(DynamicConstantDesc<T> r, T c) throws ReflectiveOperationException {63assertEquals(r, DynamicConstantDesc.ofNamed(r.bootstrapMethod(), r.constantName(), r.constantType(), r.bootstrapArgs()));64assertEquals(r.resolveConstantDesc(LOOKUP), c);65}6667private void testVarHandleDesc(DynamicConstantDesc<VarHandle> r, VarHandle vh) throws ReflectiveOperationException {68testSymbolicDesc(r);69assertEquals(vh.describeConstable().orElseThrow(), r);70}7172private static<E extends Enum<E>> void testEnumDesc(EnumDesc<E> r, E e) throws ReflectiveOperationException {73testSymbolicDesc(r);7475assertEquals(r, EnumDesc.of(r.constantType(), r.constantName()));76assertEquals(r.resolveConstantDesc(LOOKUP), e);77}7879public void testNullConstant() throws ReflectiveOperationException {80DynamicConstantDesc<?> r = (DynamicConstantDesc<?>) ConstantDescs.NULL;81assertEquals(r, DynamicConstantDesc.ofNamed(r.bootstrapMethod(), r.constantName(), r.constantType(), r.bootstrapArgs()));82assertNull(r.resolveConstantDesc(LOOKUP));83}8485static String concatBSM(MethodHandles.Lookup lookup, String name, Class<?> type, String a, String b) {86return a + b;87}8889public void testDynamicConstant() throws ReflectiveOperationException {90DirectMethodHandleDesc bsmDesc = ConstantDescs.ofConstantBootstrap(ClassDesc.of("CondyDescTest"), "concatBSM",91CD_String, CD_String, CD_String);92DynamicConstantDesc<String> r = DynamicConstantDesc.of(bsmDesc, "foo", "bar");93testDCR(r, "foobar");94}9596public void testNested() throws Throwable {97DirectMethodHandleDesc invoker = ConstantDescs.ofConstantBootstrap(CD_ConstantBootstraps, "invoke", CD_Object, CD_MethodHandle, CD_Object.arrayType());98DirectMethodHandleDesc format = MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.STATIC, CD_String, "format",99MethodTypeDesc.of(CD_String, CD_String, CD_Object.arrayType()));100101String s = (String) ((MethodHandle) invoker.resolveConstantDesc(LOOKUP))102.invoke(LOOKUP, "", String.class,103format.resolveConstantDesc(LOOKUP), "%s%s", "moo", "cow");104assertEquals(s, "moocow");105106DynamicConstantDesc<String> desc = DynamicConstantDesc.of(invoker, format, "%s%s", "moo", "cow");107testDCR(desc, "moocow");108109DynamicConstantDesc<String> desc2 = DynamicConstantDesc.of(invoker, format, "%s%s", desc, "cow");110testDCR(desc2, "moocowcow");111}112113enum MyEnum { A, B, C }114115public void testEnumDesc() throws ReflectiveOperationException {116ClassDesc enumClass = ClassDesc.of("CondyDescTest").nested("MyEnum");117118testEnumDesc(EnumDesc.of(enumClass, "A"), MyEnum.A);119testEnumDesc(EnumDesc.of(enumClass, "B"), MyEnum.B);120testEnumDesc(EnumDesc.of(enumClass, "C"), MyEnum.C);121122DynamicConstantDesc<MyEnum> denum = DynamicConstantDesc.ofNamed(ConstantDescs.BSM_ENUM_CONSTANT, "A", enumClass, EMPTY_ARGS);123assertEquals(MyEnum.A, denum.resolveConstantDesc(LOOKUP));124125EnumDesc<MyEnum> enumDesc = (EnumDesc<MyEnum>)DynamicConstantDesc.<MyEnum>ofCanonical(ConstantDescs.BSM_ENUM_CONSTANT, "A", enumClass, EMPTY_ARGS);126assertEquals(MyEnum.A, enumDesc.resolveConstantDesc(LOOKUP));127}128129static class MyClass {130static int sf;131int f;132}133134public void testVarHandles() throws ReflectiveOperationException {135ClassDesc testClass = ClassDesc.of("CondyDescTest").nested("MyClass");136MyClass instance = new MyClass();137138// static varHandle139VarHandleDesc vhc = VarHandleDesc.ofStaticField(testClass, "sf", CD_int);140VarHandle varHandle = LOOKUP.findStaticVarHandle(MyClass.class, "sf", int.class);141testVarHandleDesc(vhc, varHandle);142143assertEquals(varHandle.varType(), int.class);144varHandle.set(8);145assertEquals(8, (int) varHandle.get());146assertEquals(MyClass.sf, 8);147148// static varHandle149vhc = VarHandleDesc.ofField(testClass, "f", CD_int);150varHandle = LOOKUP.findVarHandle(MyClass.class, "f", int.class);151testVarHandleDesc(vhc, varHandle);152153assertEquals(varHandle.varType(), int.class);154varHandle.set(instance, 9);155assertEquals(9, (int) varHandle.get(instance));156assertEquals(instance.f, 9);157158vhc = VarHandleDesc.ofArray(CD_int.arrayType());159varHandle = MethodHandles.arrayElementVarHandle(int[].class);160testVarHandleDesc(vhc, varHandle);161162int[] ints = new int[3];163varHandle.set(ints, 0, 1);164varHandle.set(ints, 1, 2);165varHandle.set(ints, 2, 3);166167assertEquals(1, varHandle.get(ints, 0));168assertEquals(2, varHandle.get(ints, 1));169assertEquals(3, varHandle.get(ints, 2));170assertEquals(1, ints[0]);171assertEquals(2, ints[1]);172assertEquals(3, ints[2]);173174// static var handle obtained using the DynamicConstantDesc175DynamicConstantDesc<VarHandle> dcd = DynamicConstantDesc.ofNamed(ConstantDescs.BSM_VARHANDLE_STATIC_FIELD, "sf", CD_VarHandle, new ConstantDesc[] {testClass, CD_int });176VarHandle vh = dcd.resolveConstantDesc(LOOKUP);177testVarHandleDesc(dcd, vh);178179VarHandleDesc vhd = (VarHandleDesc) DynamicConstantDesc.ofCanonical(ConstantDescs.BSM_VARHANDLE_STATIC_FIELD, "sf", CD_VarHandle, new ConstantDesc[] {testClass, CD_int });180vh = vhd.resolveConstantDesc(LOOKUP);181testVarHandleDesc(vhd, vh);182183dcd = DynamicConstantDesc.ofNamed(ConstantDescs.BSM_VARHANDLE_FIELD, "f", CD_VarHandle, new ConstantDesc[] {testClass, CD_int });184vh = dcd.resolveConstantDesc(LOOKUP);185testVarHandleDesc(dcd, vh);186187vhd = (VarHandleDesc) DynamicConstantDesc.ofCanonical(ConstantDescs.BSM_VARHANDLE_FIELD, "f", CD_VarHandle, new ConstantDesc[] {testClass, CD_int });188vh = vhd.resolveConstantDesc(LOOKUP);189testVarHandleDesc(vhd, vh);190191dcd = DynamicConstantDesc.ofNamed(ConstantDescs.BSM_VARHANDLE_ARRAY, "_", CD_VarHandle, new ConstantDesc[] {CD_int.arrayType() });192vh = dcd.resolveConstantDesc(LOOKUP);193testVarHandleDesc(dcd, vh);194195vhd = (VarHandleDesc)DynamicConstantDesc.ofCanonical(ConstantDescs.BSM_VARHANDLE_ARRAY, "_", CD_VarHandle, new ConstantDesc[] {CD_int.arrayType() });196vh = vhd.resolveConstantDesc(LOOKUP);197testVarHandleDesc(vhd, vh);198}199200private<T> void assertLifted(ConstantDesc prototype,201DynamicConstantDesc<T> nonCanonical,202ConstantDesc canonical) {203Class<?> clazz = prototype.getClass();204205assertNotSame(canonical, nonCanonical);206assertTrue(clazz.isAssignableFrom(canonical.getClass()));207assertFalse(clazz.isAssignableFrom(nonCanonical.getClass()));208assertEquals(prototype, canonical);209assertEquals(canonical, prototype);210if (prototype instanceof DynamicConstantDesc) {211assertEquals(canonical, nonCanonical);212assertEquals(nonCanonical, canonical);213assertEquals(prototype, nonCanonical);214assertEquals(nonCanonical, prototype);215}216}217218public void testLifting() {219DynamicConstantDesc<Object> unliftedNull = DynamicConstantDesc.ofNamed(ConstantDescs.BSM_NULL_CONSTANT, "_", CD_Object, EMPTY_ARGS);220assertEquals(ConstantDescs.NULL, unliftedNull);221assertNotSame(ConstantDescs.NULL, unliftedNull);222assertSame(ConstantDescs.NULL, DynamicConstantDesc.ofCanonical(ConstantDescs.BSM_NULL_CONSTANT, "_", CD_Object, EMPTY_ARGS));223assertSame(ConstantDescs.NULL, DynamicConstantDesc.ofCanonical(ConstantDescs.BSM_NULL_CONSTANT, "_", CD_String, EMPTY_ARGS));224assertSame(ConstantDescs.NULL, DynamicConstantDesc.ofCanonical(ConstantDescs.BSM_NULL_CONSTANT, "wahoo", CD_Object, EMPTY_ARGS));225226assertLifted(CD_int,227DynamicConstantDesc.ofNamed(ConstantDescs.BSM_PRIMITIVE_CLASS, "I", ConstantDescs.CD_Class, EMPTY_ARGS),228DynamicConstantDesc.ofCanonical(ConstantDescs.BSM_PRIMITIVE_CLASS, "I", ConstantDescs.CD_Class, EMPTY_ARGS));229230ClassDesc enumClass = ClassDesc.of("CondyDescTest").nested("MyEnum");231assertLifted(EnumDesc.of(enumClass, "A"),232DynamicConstantDesc.ofNamed(ConstantDescs.BSM_ENUM_CONSTANT, "A", enumClass, EMPTY_ARGS),233DynamicConstantDesc.<MyEnum>ofCanonical(ConstantDescs.BSM_ENUM_CONSTANT, "A", enumClass, EMPTY_ARGS));234235236ClassDesc testClass = ClassDesc.of("CondyDescTest").nested("MyClass");237238assertLifted(VarHandleDesc.ofStaticField(testClass, "sf", CD_int),239DynamicConstantDesc.ofNamed(ConstantDescs.BSM_VARHANDLE_STATIC_FIELD, "sf", CD_VarHandle, new ConstantDesc[] {testClass, CD_int }),240DynamicConstantDesc.ofCanonical(ConstantDescs.BSM_VARHANDLE_STATIC_FIELD, "sf", CD_VarHandle, new ConstantDesc[] {testClass, CD_int }));241assertLifted(VarHandleDesc.ofField(testClass, "f", CD_int),242DynamicConstantDesc.ofNamed(ConstantDescs.BSM_VARHANDLE_FIELD, "f", CD_VarHandle, new ConstantDesc[] {testClass, CD_int }),243DynamicConstantDesc.ofCanonical(ConstantDescs.BSM_VARHANDLE_FIELD, "f", CD_VarHandle, new ConstantDesc[] {testClass, CD_int }));244245assertLifted(VarHandleDesc.ofArray(CD_int.arrayType()),246DynamicConstantDesc.ofNamed(ConstantDescs.BSM_VARHANDLE_ARRAY, "_", CD_VarHandle, new ConstantDesc[] {CD_int.arrayType() }),247DynamicConstantDesc.ofCanonical(ConstantDescs.BSM_VARHANDLE_ARRAY, "_", CD_VarHandle, new ConstantDesc[] {CD_int.arrayType() }));248}249}250251252