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