--- /dev/null 2019-05-28 09:59:29.644075095 -0400 +++ new/test/jdk/valhalla/valuetypes/InlineConstructorTest.java 2019-06-03 14:39:21.961950487 -0400 @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2019, 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. + * + * 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. + */ + + +/* + * @test + * @summary Test reflection of constructors for inline classes + * @run main/othervm -XX:+EnableValhalla InlineConstructorTest + */ + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InaccessibleObjectException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Arrays; +import java.util.Set; +import java.util.stream.Collectors; + +public class InlineConstructorTest { + + // Target test class + static inline class SimpleInline { + public final int x; + + SimpleInline() { + x = -1; + } + + public SimpleInline(int x) { + this.x = x; + } + } + + private final Class c; + + public static void main(String... args) throws Exception { + testSimpleInlineClass(); + } + + static void testSimpleInlineClass() throws Exception { + InlineConstructorTest test = new InlineConstructorTest(SimpleInline.class); + test.constructor(); + test.constructors("public InlineConstructorTest$SimpleInline(int)", + "InlineConstructorTest$SimpleInline()"); + test.setAccessible(); + test.trySetAccessible(); + test.initFactoryNotMethods(); + } + + InlineConstructorTest(Class type) throws Exception { + String cn = type.getName(); + this.c = Class.forName(cn); + + assertTrue(c.isInlineClass()); + assertEquals(c, type); + } + + void constructor() throws Exception { + Constructor ctor = c.getDeclaredConstructor(); + Object o = ctor.newInstance(); + assertEquals(o.getClass(), c); + } + + // Check that the class has the expected Constructors + void constructors(String... expected) throws Exception { + Constructor[] cons = c.getDeclaredConstructors(); + Set actualSig = + Arrays.stream(cons).map(Constructor::toString).collect(Collectors.toSet()); + Set expectedSig = Set.of(expected); + boolean ok = expectedSig.equals(actualSig); + if (!ok) { + System.out.printf("expected: %s%n", expectedSig); + System.out.printf("declared: %s%n", actualSig); + assertTrue(ok); + } + } + + // Check that the constructor can be set accessible and that the field x can not + void setAccessible() throws Exception { + Constructor ctor = c.getDeclaredConstructor(); + ctor.setAccessible(true); + Field field = c.getField("x"); + try { + field.setAccessible(true); + throw new RuntimeException("InaccessibleObjectException not thrown"); + } catch (InaccessibleObjectException e) { + // IOE is expected + } + } + + // Check that the constructor can be set accessible and that the field x can not + void trySetAccessible() throws Exception { + Constructor ctor = c.getDeclaredConstructor(); + assertTrue(ctor.trySetAccessible()); + Field field = c.getField("x"); + if (field.trySetAccessible()) { + throw new RuntimeException("trySetAccessible should not succeed"); + } + } + + // Check that the class does not have a static method with the name + void initFactoryNotMethods() { + Method[] methods = c.getDeclaredMethods(); + for (Method m : methods) { + if (Modifier.isStatic(m.getModifiers())) { + assertFalse(m.getName().equals("")); + } + } + } + + static void assertEquals(Object o1, Object o2) { + if (o1 == o2 || o1.equals(o2)) + return; + + throw new AssertionError(o1 + " != " + o2); + } + + static void assertTrue(boolean value) { + if (!value) + throw new AssertionError("expected true"); + } + + static void assertFalse(boolean value) { + if (value) + throw new AssertionError("expected false"); + } +}