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