1 /* 2 * Copyright (c) 2024, 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 import jdk.incubator.code.CodeReflection; 25 26 /* 27 * @test 28 * @summary Smoke test for code reflection with intersection type conversions. 29 * @modules jdk.incubator.code 30 * @build IntersectionTypeTest 31 * @build CodeReflectionTester 32 * @run main CodeReflectionTester IntersectionTypeTest 33 */ 34 35 class IntersectionTypeTest { 36 interface A { 37 Object f_A = 5; 38 void m_A(); 39 } 40 41 interface B { 42 Object f_B = 5; 43 void m_B(); 44 } 45 46 interface C { 47 Object f_C = 5; 48 void m_C(); 49 } 50 51 @CodeReflection 52 @IR(""" 53 func @"test1" (%0 : java.type:"&IntersectionTypeTest::test1(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>)")java.type:"void" -> { 54 %1 : Var<java.type:"&IntersectionTypeTest::test1(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>"> = var %0 @"x"; 55 %2 : java.type:"&IntersectionTypeTest::test1(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>" = var.load %1; 56 invoke %2 @java.ref:"IntersectionTypeTest$A::m_A():void"; 57 %3 : java.type:"&IntersectionTypeTest::test1(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>" = var.load %1; 58 %4 : java.type:"IntersectionTypeTest$B" = cast %3 @java.type:"IntersectionTypeTest$B"; 59 invoke %4 @java.ref:"IntersectionTypeTest$B::m_B():void"; 60 %5 : java.type:"&IntersectionTypeTest::test1(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>" = var.load %1; 61 %6 : java.type:"IntersectionTypeTest$C" = cast %5 @java.type:"IntersectionTypeTest$C"; 62 invoke %6 @java.ref:"IntersectionTypeTest$C::m_C():void"; 63 return; 64 }; 65 """) 66 static <X extends A & B & C> void test1(X x) { 67 x.m_A(); 68 x.m_B(); 69 x.m_C(); 70 } 71 72 // #X<&m<IntersectionTypeTest, test2, func<void, IntersectionTypeTest$A>>, IntersectionTypeTest$A> 73 // #X<&m<IntersectionTypeTest, test2, func<void, IntersectionTypeTest$A>, IntersectionTypeTest$A> 74 @CodeReflection 75 @IR(""" 76 func @"test2" (%0 : java.type:"&IntersectionTypeTest::test2(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>)")java.type:"void" -> { 77 %1 : Var<java.type:"&IntersectionTypeTest::test2(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>)"> = var %0 @"x"; 78 %2 : java.type:"IntersectionTypeTest::test2(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>)" = var.load %1; 79 %3 : java.type:"java.lang.Object" = field.load @java.ref:"IntersectionTypeTest$A::f_A:java.lang.Object"; 80 %4 : Var<java.type:"java.lang.Object"> = var %3 @"oA"; 81 %5 : java.type:"&IntersectionTypeTest::test2(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>)" = var.load %1; 82 %6 : java.type:"java.lang.Object" = field.load @java.ref:"IntersectionTypeTest$B::f_B:java.lang.Object"; 83 %7 : Var<java.type:"java.lang.Object"> = var %6 @"oB"; 84 %8 : java.type:"&IntersectionTypeTest::test2(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>)" = var.load %1; 85 %9 : java.type:"java.lang.Object" = field.load @java.ref:"IntersectionTypeTest$C::f_C:java.lang.Object"; 86 %10 : Var<java.type:"java.lang.Object"> = var %9 @"oC"; 87 return; 88 }; 89 """) 90 static <X extends A & B & C> void test2(X x) { 91 Object oA = x.f_A; 92 Object oB = x.f_B; 93 Object oC = x.f_C; 94 } 95 96 @CodeReflection 97 @IR(""" 98 func @"test3" (%0 : java.type:"&IntersectionTypeTest::test3(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>)")java.type:"void" -> { 99 %1 : Var<java.type:"&IntersectionTypeTest::test3(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>)"> = var %0 @"x"; 100 %2 : java.type:"&IntersectionTypeTest::test3(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>)" = var.load %1; 101 %3 : Var<java.type:"IntersectionTypeTest$A"> = var %2 @"rec$"; 102 %4 : java.type:"java.lang.Runnable" = lambda ()java.type:"void" -> { 103 %5 : java.type:"IntersectionTypeTest$A" = var.load %3; 104 invoke %5 @java.ref:"IntersectionTypeTest$A::m_A():void"; 105 return; 106 }; 107 %6 : Var<java.type:"java.lang.Runnable"> = var %4 @"rA"; 108 %7 : java.type:"&IntersectionTypeTest::test3(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>)" = var.load %1; 109 %8 : java.type:"IntersectionTypeTest$B" = cast %7 @java.type:"IntersectionTypeTest$B"; 110 %9 : Var<java.type:"IntersectionTypeTest$B"> = var %8 @"rec$"; 111 %10 : java.type:"java.lang.Runnable" = lambda ()java.type:"void" -> { 112 %11 : java.type:"IntersectionTypeTest$B" = var.load %9; 113 invoke %11 @java.ref:"IntersectionTypeTest$B::m_B():void"; 114 return; 115 }; 116 %12 : Var<java.type:"java.lang.Runnable"> = var %10 @"rB"; 117 %13 : java.type:"&IntersectionTypeTest::test3(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>)" = var.load %1; 118 %14 : java.type:"IntersectionTypeTest$C" = cast %13 @java.type:"IntersectionTypeTest$C"; 119 %15 : Var<java.type:"IntersectionTypeTest$C"> = var %14 @"rec$"; 120 %16 : java.type:"java.lang.Runnable" = lambda ()java.type:"void" -> { 121 %17 : java.type:"IntersectionTypeTest$C" = var.load %15; 122 invoke %17 @java.ref:"IntersectionTypeTest$C::m_C():void"; 123 return; 124 }; 125 %18 : Var<java.type:"java.lang.Runnable"> = var %16 @"rC"; 126 return; 127 }; 128 """) 129 static <X extends A & B & C> void test3(X x) { 130 Runnable rA = x::m_A; 131 Runnable rB = x::m_B; 132 Runnable rC = x::m_C; 133 } 134 135 static void g_A(A a) { } 136 static void g_B(B a) { } 137 static void g_C(C a) { } 138 139 @CodeReflection 140 @IR(""" 141 func @"test4" (%0 : java.type:"&IntersectionTypeTest::test4(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>)")java.type:"void" -> { 142 %1 : Var<java.type:"&IntersectionTypeTest::test4(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>)"> = var %0 @"x"; 143 %2 : java.type:"&IntersectionTypeTest::test4(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>)" = var.load %1; 144 invoke %2 @java.ref:"IntersectionTypeTest::g_A(IntersectionTypeTest$A):void"; 145 %3 : java.type:"&IntersectionTypeTest::test4(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>)" = var.load %1; 146 %4 : java.type:"IntersectionTypeTest$B" = cast %3 @java.type:"IntersectionTypeTest$B"; 147 invoke %4 @java.ref:"IntersectionTypeTest::g_B(IntersectionTypeTest$B):void"; 148 %5 : java.type:"&IntersectionTypeTest::test4(IntersectionTypeTest$A):void::<X extends IntersectionTypeTest$A>)" = var.load %1; 149 %6 : java.type:"IntersectionTypeTest$C" = cast %5 @java.type:"IntersectionTypeTest$C"; 150 invoke %6 @java.ref:"IntersectionTypeTest::g_C(IntersectionTypeTest$C):void"; 151 return; 152 }; 153 """) 154 static <X extends A & B & C> void test4(X x) { 155 g_A(x); 156 g_B(x); 157 g_C(x); 158 } 159 160 static <X extends A & B & C> X makeIntersection(X x1, X x2) { 161 return null; 162 } 163 164 static class E1 implements A, B, C { 165 @Override 166 public void m_A() { } 167 @Override 168 public void m_B() { } 169 @Override 170 public void m_C() { } 171 } 172 173 static class E2 implements A, B, C { 174 @Override 175 public void m_A() { } 176 @Override 177 public void m_B() { } 178 @Override 179 public void m_C() { } 180 } 181 182 @CodeReflection 183 @IR(""" 184 func @"test5" (%0 : java.type:"IntersectionTypeTest$E1", %1 : java.type:"IntersectionTypeTest$E2")java.type:"void" -> { 185 %2 : Var<java.type:"IntersectionTypeTest$E1"> = var %0 @"e1"; 186 %3 : Var<java.type:"IntersectionTypeTest$E2"> = var %1 @"e2"; 187 %4 : java.type:"IntersectionTypeTest$E1" = var.load %2; 188 %5 : java.type:"IntersectionTypeTest$E2" = var.load %3; 189 %6 : java.type:"IntersectionTypeTest$A" = invoke %4 %5 @java.ref:"IntersectionTypeTest::makeIntersection(IntersectionTypeTest$A, IntersectionTypeTest$A):IntersectionTypeTest$A"; 190 %7 : Var<java.type:"IntersectionTypeTest$A"> = var %6 @"x"; 191 %8 : java.type:"IntersectionTypeTest$A" = var.load %7; 192 invoke %8 @java.ref:"IntersectionTypeTest$A::m_A():void"; 193 %9 : java.type:"IntersectionTypeTest$A" = var.load %7; 194 %10 : java.type:"IntersectionTypeTest$B" = cast %9 @java.type:"IntersectionTypeTest$B"; 195 invoke %10 @java.ref:"IntersectionTypeTest$B::m_B():void"; 196 %11 : java.type:"IntersectionTypeTest$A" = var.load %7; 197 %12 : java.type:"IntersectionTypeTest$C" = cast %11 @java.type:"IntersectionTypeTest$C"; 198 invoke %12 @java.ref:"IntersectionTypeTest$C::m_C():void"; 199 return; 200 }; 201 """) 202 static void test5(E1 e1, E2 e2) { 203 var x = makeIntersection(e1, e2); 204 x.m_A(); 205 x.m_B(); 206 x.m_C(); 207 } 208 209 @CodeReflection 210 @IR(""" 211 func @"test6" (%0 : java.type:"IntersectionTypeTest$E1", %1 : java.type:"IntersectionTypeTest$E2")java.type:"void" -> { 212 %2 : Var<java.type:"IntersectionTypeTest$E1"> = var %0 @"e1"; 213 %3 : Var<java.type:"IntersectionTypeTest$E2"> = var %1 @"e2"; 214 %4 : java.type:"IntersectionTypeTest$E1" = var.load %2; 215 %5 : java.type:"IntersectionTypeTest$E2" = var.load %3; 216 %6 : java.type:"IntersectionTypeTest$A" = invoke %4 %5 @java.ref:"IntersectionTypeTest::makeIntersection(IntersectionTypeTest$A, IntersectionTypeTest$A):IntersectionTypeTest$A"; 217 %7 : Var<java.type:"IntersectionTypeTest$A"> = var %6 @"x"; 218 %8 : java.type:"IntersectionTypeTest$A" = var.load %7; 219 %9 : java.type:"java.lang.Object" = field.load @java.ref:"IntersectionTypeTest$A::f_A:java.lang.Object"; 220 %10 : Var<java.type:"java.lang.Object"> = var %9 @"oA"; 221 %11 : java.type:"IntersectionTypeTest$A" = var.load %7; 222 %12 : java.type:"java.lang.Object" = field.load @java.ref:"IntersectionTypeTest$B::f_B:java.lang.Object"; 223 %13 : Var<java.type:"java.lang.Object"> = var %12 @"oB"; 224 %14 : java.type:"IntersectionTypeTest$A" = var.load %7; 225 %15 : java.type:"java.lang.Object" = field.load @java.ref:"IntersectionTypeTest$C::f_C:java.lang.Object"; 226 %16 : Var<java.type:"java.lang.Object"> = var %15 @"oC"; 227 return; 228 }; 229 """) 230 static void test6(E1 e1, E2 e2) { 231 var x = makeIntersection(e1, e2); 232 Object oA = x.f_A; 233 Object oB = x.f_B; 234 Object oC = x.f_C; 235 } 236 237 @CodeReflection 238 @IR(""" 239 func @"test7" (%0 : java.type:"IntersectionTypeTest$E1", %1 : java.type:"IntersectionTypeTest$E2")java.type:"void" -> { 240 %2 : Var<java.type:"IntersectionTypeTest$E1"> = var %0 @"e1"; 241 %3 : Var<java.type:"IntersectionTypeTest$E2"> = var %1 @"e2"; 242 %4 : java.type:"IntersectionTypeTest$E1" = var.load %2; 243 %5 : java.type:"IntersectionTypeTest$E2" = var.load %3; 244 %6 : java.type:"IntersectionTypeTest$A" = invoke %4 %5 @java.ref:"IntersectionTypeTest::makeIntersection(IntersectionTypeTest$A, IntersectionTypeTest$A):IntersectionTypeTest$A"; 245 %7 : Var<java.type:"IntersectionTypeTest$A"> = var %6 @"x"; 246 %8 : java.type:"IntersectionTypeTest$A" = var.load %7; 247 %9 : Var<java.type:"IntersectionTypeTest$A"> = var %8 @"rec$"; 248 %10 : java.type:"java.lang.Runnable" = lambda ()java.type:"void" -> { 249 %11 : java.type:"IntersectionTypeTest$A" = var.load %9; 250 invoke %11 @java.ref:"IntersectionTypeTest$A::m_A():void"; 251 return; 252 }; 253 %12 : Var<java.type:"java.lang.Runnable"> = var %10 @"rA"; 254 %13 : java.type:"IntersectionTypeTest$A" = var.load %7; 255 %14 : java.type:"IntersectionTypeTest$B" = cast %13 @java.type:"IntersectionTypeTest$B"; 256 %15 : Var<java.type:"IntersectionTypeTest$B"> = var %14 @"rec$"; 257 %16 : java.type:"java.lang.Runnable" = lambda ()java.type:"void" -> { 258 %17 : java.type:"IntersectionTypeTest$B" = var.load %15; 259 invoke %17 @java.ref:"IntersectionTypeTest$B::m_B():void"; 260 return; 261 }; 262 %18 : Var<java.type:"java.lang.Runnable"> = var %16 @"rB"; 263 %19 : java.type:"IntersectionTypeTest$A" = var.load %7; 264 %20 : java.type:"IntersectionTypeTest$C" = cast %19 @java.type:"IntersectionTypeTest$C"; 265 %21 : Var<java.type:"IntersectionTypeTest$C"> = var %20 @"rec$"; 266 %22 : java.type:"java.lang.Runnable" = lambda ()java.type:"void" -> { 267 %23 : java.type:"IntersectionTypeTest$C" = var.load %21; 268 invoke %23 @java.ref:"IntersectionTypeTest$C::m_C():void"; 269 return; 270 }; 271 %24 : Var<java.type:"java.lang.Runnable"> = var %22 @"rC"; 272 return; 273 }; 274 """) 275 static void test7(E1 e1, E2 e2) { 276 var x = makeIntersection(e1, e2); 277 Runnable rA = x::m_A; 278 Runnable rB = x::m_B; 279 Runnable rC = x::m_C; 280 } 281 282 @CodeReflection 283 @IR(""" 284 func @"test8" (%0 : java.type:"IntersectionTypeTest$E1", %1 : java.type:"IntersectionTypeTest$E2")java.type:"void" -> { 285 %2 : Var<java.type:"IntersectionTypeTest$E1"> = var %0 @"e1"; 286 %3 : Var<java.type:"IntersectionTypeTest$E2"> = var %1 @"e2"; 287 %4 : java.type:"IntersectionTypeTest$E1" = var.load %2; 288 %5 : java.type:"IntersectionTypeTest$E2" = var.load %3; 289 %6 : java.type:"IntersectionTypeTest$A" = invoke %4 %5 @java.ref:"IntersectionTypeTest::makeIntersection(IntersectionTypeTest$A, IntersectionTypeTest$A):IntersectionTypeTest$A"; 290 %7 : Var<java.type:"IntersectionTypeTest$A"> = var %6 @"x"; 291 %8 : java.type:"IntersectionTypeTest$A" = var.load %7; 292 invoke %8 @java.ref:"IntersectionTypeTest::g_A(IntersectionTypeTest$A):void"; 293 %9 : java.type:"IntersectionTypeTest$A" = var.load %7; 294 %10 : java.type:"IntersectionTypeTest$B" = cast %9 @java.type:"IntersectionTypeTest$B"; 295 invoke %10 @java.ref:"IntersectionTypeTest::g_B(IntersectionTypeTest$B):void"; 296 %11 : java.type:"IntersectionTypeTest$A" = var.load %7; 297 %12 : java.type:"IntersectionTypeTest$C" = cast %11 @java.type:"IntersectionTypeTest$C"; 298 invoke %12 @java.ref:"IntersectionTypeTest::g_C(IntersectionTypeTest$C):void"; 299 return; 300 }; 301 """) 302 static void test8(E1 e1, E2 e2) { 303 var x = makeIntersection(e1, e2); 304 g_A(x); 305 g_B(x); 306 g_C(x); 307 } 308 }