1 /*
2 * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 /*
25 * @test
26 * @bug 8392141
27 * @library /tools/lib
28 * @modules
29 * jdk.compiler/com.sun.tools.javac.api
30 * jdk.compiler/com.sun.tools.javac.main
31 * jdk.incubator.code
32 * @build toolbox.ToolBox toolbox.JavacTask
33 * @run junit TestOrdering
34 */
35
36 import java.net.URL;
37 import java.net.URLClassLoader;
38 import java.nio.file.Files;
39 import java.nio.file.Path;
40 import java.nio.file.Paths;
41 import java.util.function.Supplier;
42
43 import jdk.incubator.code.Op;
44 import org.junit.jupiter.api.Assertions;
45 import toolbox.JavacTask;
46 import toolbox.ToolBox;
47
48 import org.junit.jupiter.api.BeforeEach;
49 import org.junit.jupiter.api.Test;
50 import org.junit.jupiter.api.TestInfo;
51
52 public class TestOrdering {
53
54 Path base;
55 ToolBox tb = new ToolBox();
56
57 @Test
58 void test() throws Exception {
59 Path classes = base.resolve("classes");
60 Files.createDirectories(classes);
61 new JavacTask(tb)
62 .options("-d", classes.toString(), "--add-modules", "jdk.incubator.code", "-XDreflectAll")
63 .sources("""
64 import java.util.function.Supplier;
65
66 abstract class Base<T> {
67 abstract T lazy(Supplier<T> supplier);
68 }
69 """,
70 """
71 import java.util.function.Supplier;
72
73 abstract class A extends Base<String> {
74 @Override
75 final String lazy(Supplier<String> supplier) {
76 return supplier.get();
77 }
78
79 abstract static class Op extends A {}
80
81 Object toB() {
82 return new B.Op() {};
83 }
84 }
85 """,
86 """
87 import java.util.function.Supplier;
88
89 abstract class B extends Base<Integer> {
90 @Override
91 final Integer lazy(Supplier<Integer> supplier) {
92 return supplier.get();
93 }
94
95 abstract static class Op extends B {}
96
97 Object toA() {
98 return new A.Op() {};
99 }
100 }
101 """)
102 .run()
103 .writeAll();
104
105 try (URLClassLoader loader = new URLClassLoader(new URL[] { classes.toUri().toURL() })) {
106 Class<?> clsA = loader.loadClass("A");
107 var methodA = clsA.getDeclaredMethod("lazy", Supplier.class);
108 Assertions.assertEquals("""
109 func @loc="4:9:A.java" @func.source=java.ref:"A::lazy(java.util.function.Supplier<java.lang.String>):java.lang.String" (%0 : java.type:"A", %1 : java.type:"java.util.function.Supplier<java.lang.String>")java.type:"java.lang.String" -> {
110 %2 : Var<java.type:"java.util.function.Supplier<java.lang.String>"> = var %1 @loc="4:9" @"supplier";
111 %3 : java.type:"java.util.function.Supplier<java.lang.String>" = var.load %2 @loc="6:20";
112 %4 : java.type:"java.lang.String" = invoke %3 @loc="6:20" @java.ref:"java.util.function.Supplier::get():java.lang.Object";
113 return %4 @loc="6:13";
114 };""", Op.ofMethod(methodA).orElseThrow().toText());
115 Class<?> clsB = loader.loadClass("B");
116 var methodB = clsB.getDeclaredMethod("lazy", Supplier.class);
117 Assertions.assertEquals("""
118 func @loc="4:9:B.java" @func.source=java.ref:"B::lazy(java.util.function.Supplier<java.lang.Integer>):java.lang.Integer" (%0 : java.type:"B", %1 : java.type:"java.util.function.Supplier<java.lang.Integer>")java.type:"java.lang.Integer" -> {
119 %2 : Var<java.type:"java.util.function.Supplier<java.lang.Integer>"> = var %1 @loc="4:9" @"supplier";
120 %3 : java.type:"java.util.function.Supplier<java.lang.Integer>" = var.load %2 @loc="6:20";
121 %4 : java.type:"java.lang.Integer" = invoke %3 @loc="6:20" @java.ref:"java.util.function.Supplier::get():java.lang.Object";
122 return %4 @loc="6:13";
123 };""", Op.ofMethod(methodB).orElseThrow().toText());
124
125 }
126 }
127
128 @BeforeEach
129 public void setUp(TestInfo info) {
130 base = Paths.get(".")
131 .resolve(info.getTestMethod()
132 .orElseThrow()
133 .getName());
134 }
135 }