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 }