Thu, 11 Jul 2013 14:07:39 +0100
8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
8020010: Move lambda bridge creation from metafactory and VM to compiler
Summary: langtools/javac component of the bridge support and MethodType vs. MethodHandle changes.
Reviewed-by: jjg, vromero, briangoetz, forax
Contributed-by: robert.field@oracle.com
rfield@1422 | 1 | /* |
katleman@1448 | 2 | * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. |
rfield@1422 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
rfield@1422 | 4 | * |
rfield@1422 | 5 | * This code is free software; you can redistribute it and/or modify it |
rfield@1422 | 6 | * under the terms of the GNU General Public License version 2 only, as |
rfield@1422 | 7 | * published by the Free Software Foundation. Oracle designates this |
rfield@1422 | 8 | * particular file as subject to the "Classpath" exception as provided |
rfield@1422 | 9 | * by Oracle in the LICENSE file that accompanied this code. |
rfield@1422 | 10 | * |
rfield@1422 | 11 | * This code is distributed in the hope that it will be useful, but WITHOUT |
rfield@1422 | 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
rfield@1422 | 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
rfield@1422 | 14 | * version 2 for more details (a copy is included in the LICENSE file that |
rfield@1422 | 15 | * accompanied this code). |
rfield@1422 | 16 | * |
rfield@1422 | 17 | * You should have received a copy of the GNU General Public License version |
rfield@1422 | 18 | * 2 along with this work; if not, write to the Free Software Foundation, |
rfield@1422 | 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
rfield@1422 | 20 | * |
rfield@1422 | 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
rfield@1422 | 22 | * or visit www.oracle.com if you need additional information or have any |
rfield@1422 | 23 | * questions. |
rfield@1422 | 24 | */ |
rfield@1422 | 25 | |
rfield@1422 | 26 | package org.openjdk.tests.vm; |
rfield@1422 | 27 | |
rfield@1422 | 28 | import java.lang.reflect.*; |
rfield@1422 | 29 | import java.util.*; |
rfield@1422 | 30 | import java.io.File; |
rfield@1422 | 31 | import java.io.IOException; |
rfield@1422 | 32 | |
rfield@1422 | 33 | import org.testng.annotations.Test; |
rfield@1422 | 34 | import org.openjdk.tests.separate.*; |
rfield@1422 | 35 | import org.openjdk.tests.separate.Compiler; |
rfield@1422 | 36 | |
rfield@1422 | 37 | import static org.testng.Assert.*; |
rfield@1422 | 38 | import static org.openjdk.tests.separate.SourceModel.*; |
rfield@1422 | 39 | import static org.openjdk.tests.separate.SourceModel.Class; |
rfield@1422 | 40 | |
rfield@1422 | 41 | @Test(groups = "vm") |
rfield@1422 | 42 | public class DefaultMethodsTest extends TestHarness { |
rfield@1422 | 43 | public DefaultMethodsTest() { |
rfield@1422 | 44 | super(false, false); |
rfield@1422 | 45 | } |
rfield@1422 | 46 | |
rfield@1422 | 47 | /** |
rfield@1422 | 48 | * class C { public int m() { return 22; } } |
rfield@1422 | 49 | * |
rfield@1422 | 50 | * TEST: C c = new C(); c.m() == 22 |
rfield@1422 | 51 | */ |
rfield@1422 | 52 | public void testHarnessInvokeVirtual() { |
rfield@1422 | 53 | Class C = new Class("C", ConcreteMethod.std("22")); |
rfield@1422 | 54 | assertInvokeVirtualEquals(22, C); |
rfield@1422 | 55 | } |
rfield@1422 | 56 | |
rfield@1422 | 57 | /** |
rfield@1422 | 58 | * interface I { int m(); } |
rfield@1422 | 59 | * class C implements I { public int m() { return 33; } } |
rfield@1422 | 60 | * |
rfield@1422 | 61 | * TEST: I i = new C(); i.m() == 33; |
rfield@1422 | 62 | */ |
rfield@1422 | 63 | public void testHarnessInvokeInterface() { |
rfield@1422 | 64 | Interface I = new Interface("I", AbstractMethod.std()); |
rfield@1422 | 65 | Class C = new Class("C", I, ConcreteMethod.std("33")); |
rfield@1422 | 66 | assertInvokeInterfaceEquals(33, C, I); |
rfield@1422 | 67 | } |
rfield@1422 | 68 | |
rfield@1422 | 69 | /** |
rfield@1422 | 70 | * class C {} |
rfield@1422 | 71 | * |
rfield@1422 | 72 | * TEST: C c = new C(); c.m() throws NoSuchMethod |
rfield@1422 | 73 | */ |
rfield@1422 | 74 | public void testHarnessThrows() { |
rfield@1422 | 75 | Class C = new Class("C"); |
rfield@1422 | 76 | assertThrows(NoSuchMethodError.class, C); |
rfield@1422 | 77 | } |
rfield@1422 | 78 | |
rfield@1422 | 79 | /** |
rfield@1422 | 80 | * interface I { int m() default { return 44; } } |
rfield@1422 | 81 | * class C implements I {} |
rfield@1422 | 82 | * |
rfield@1422 | 83 | * TEST: C c = new C(); c.m() == 44; |
rfield@1422 | 84 | * TEST: I i = new C(); i.m() == 44; |
rfield@1422 | 85 | */ |
rfield@1422 | 86 | public void testBasicDefault() { |
rfield@1422 | 87 | Interface I = new Interface("I", DefaultMethod.std("44")); |
rfield@1422 | 88 | Class C = new Class("C", I); |
rfield@1422 | 89 | |
rfield@1422 | 90 | assertInvokeVirtualEquals(44, C); |
rfield@1422 | 91 | assertInvokeInterfaceEquals(44, C, I); |
rfield@1422 | 92 | } |
rfield@1422 | 93 | |
rfield@1422 | 94 | /** |
rfield@1422 | 95 | * interface I { default int m() { return 44; } } |
rfield@1422 | 96 | * interface J extends I {} |
rfield@1422 | 97 | * interface K extends J {} |
rfield@1422 | 98 | * class C implements K {} |
rfield@1422 | 99 | * |
rfield@1422 | 100 | * TEST: C c = new C(); c.m() == 44; |
rfield@1422 | 101 | * TEST: I i = new C(); i.m() == 44; |
rfield@1422 | 102 | */ |
rfield@1422 | 103 | public void testFarDefault() { |
rfield@1422 | 104 | Interface I = new Interface("I", DefaultMethod.std("44")); |
rfield@1422 | 105 | Interface J = new Interface("J", I); |
rfield@1422 | 106 | Interface K = new Interface("K", J); |
rfield@1422 | 107 | Class C = new Class("C", K); |
rfield@1422 | 108 | |
rfield@1422 | 109 | assertInvokeVirtualEquals(44, C); |
rfield@1422 | 110 | assertInvokeInterfaceEquals(44, C, K); |
rfield@1422 | 111 | } |
rfield@1422 | 112 | |
rfield@1422 | 113 | /** |
rfield@1422 | 114 | * interface I { int m(); } |
rfield@1422 | 115 | * interface J extends I { default int m() { return 44; } } |
rfield@1422 | 116 | * interface K extends J {} |
rfield@1422 | 117 | * class C implements K {} |
rfield@1422 | 118 | * |
rfield@1422 | 119 | * TEST: C c = new C(); c.m() == 44; |
rfield@1422 | 120 | * TEST: K k = new C(); k.m() == 44; |
rfield@1422 | 121 | */ |
rfield@1422 | 122 | public void testOverrideAbstract() { |
rfield@1422 | 123 | Interface I = new Interface("I", AbstractMethod.std()); |
rfield@1422 | 124 | Interface J = new Interface("J", I, DefaultMethod.std("44")); |
rfield@1422 | 125 | Interface K = new Interface("K", J); |
rfield@1422 | 126 | Class C = new Class("C", K); |
rfield@1422 | 127 | |
rfield@1422 | 128 | assertInvokeVirtualEquals(44, C); |
rfield@1422 | 129 | assertInvokeInterfaceEquals(44, C, K); |
rfield@1422 | 130 | } |
rfield@1422 | 131 | |
rfield@1422 | 132 | /** |
rfield@1422 | 133 | * interface I { int m() default { return 44; } } |
rfield@1422 | 134 | * class C implements I { public int m() { return 55; } } |
rfield@1422 | 135 | * |
rfield@1422 | 136 | * TEST: C c = new C(); c.m() == 55; |
rfield@1422 | 137 | * TEST: I i = new C(); i.m() == 55; |
rfield@1422 | 138 | */ |
rfield@1422 | 139 | public void testExisting() { |
rfield@1422 | 140 | Interface I = new Interface("I", DefaultMethod.std("44")); |
rfield@1422 | 141 | Class C = new Class("C", I, ConcreteMethod.std("55")); |
rfield@1422 | 142 | |
rfield@1422 | 143 | assertInvokeVirtualEquals(55, C); |
rfield@1422 | 144 | assertInvokeInterfaceEquals(55, C, I); |
rfield@1422 | 145 | } |
rfield@1422 | 146 | |
rfield@1422 | 147 | /** |
rfield@1422 | 148 | * interface I { default int m() { return 99; } } |
rfield@1422 | 149 | * class B implements I {} |
rfield@1422 | 150 | * class C extends B {} |
rfield@1422 | 151 | * |
rfield@1422 | 152 | * TEST: C c = new C(); c.m() == 99; |
rfield@1422 | 153 | * TEST: I i = new C(); i.m() == 99; |
rfield@1422 | 154 | */ |
rfield@1422 | 155 | public void testInherited() { |
rfield@1422 | 156 | Interface I = new Interface("I", DefaultMethod.std("99")); |
rfield@1422 | 157 | Class B = new Class("B", I); |
rfield@1422 | 158 | Class C = new Class("C", B); |
rfield@1422 | 159 | |
rfield@1422 | 160 | assertInvokeVirtualEquals(99, C); |
rfield@1422 | 161 | assertInvokeInterfaceEquals(99, C, I); |
rfield@1422 | 162 | } |
rfield@1422 | 163 | |
rfield@1422 | 164 | /** |
rfield@1422 | 165 | * interface I { default int m() { return 99; } } |
rfield@1422 | 166 | * class C { public int m() { return 11; } } |
rfield@1422 | 167 | * class D extends C implements I {} |
rfield@1422 | 168 | * |
rfield@1422 | 169 | * TEST: D d = new D(); d.m() == 11; |
rfield@1422 | 170 | * TEST: I i = new D(); i.m() == 11; |
rfield@1422 | 171 | */ |
rfield@1422 | 172 | public void testExistingInherited() { |
rfield@1422 | 173 | Interface I = new Interface("I", DefaultMethod.std("99")); |
rfield@1422 | 174 | Class C = new Class("C", ConcreteMethod.std("11")); |
rfield@1422 | 175 | Class D = new Class("D", C, I); |
rfield@1422 | 176 | |
rfield@1422 | 177 | assertInvokeVirtualEquals(11, D); |
rfield@1422 | 178 | assertInvokeInterfaceEquals(11, D, I); |
rfield@1422 | 179 | } |
rfield@1422 | 180 | |
rfield@1422 | 181 | /** |
rfield@1422 | 182 | * interface I { default int m() { return 44; } } |
rfield@1422 | 183 | * class C implements I { public int m() { return 11; } } |
rfield@1422 | 184 | * class D extends C { public int m() { return 22; } } |
rfield@1422 | 185 | * |
rfield@1422 | 186 | * TEST: D d = new D(); d.m() == 22; |
rfield@1422 | 187 | * TEST: I i = new D(); i.m() == 22; |
rfield@1422 | 188 | */ |
rfield@1422 | 189 | void testExistingInheritedOverride() { |
rfield@1422 | 190 | Interface I = new Interface("I", DefaultMethod.std("99")); |
rfield@1422 | 191 | Class C = new Class("C", I, ConcreteMethod.std("11")); |
rfield@1422 | 192 | Class D = new Class("D", C, ConcreteMethod.std("22")); |
rfield@1422 | 193 | |
rfield@1422 | 194 | assertInvokeVirtualEquals(22, D); |
rfield@1422 | 195 | assertInvokeInterfaceEquals(22, D, I); |
rfield@1422 | 196 | } |
rfield@1422 | 197 | |
rfield@1422 | 198 | /** |
rfield@1422 | 199 | * interface I { default int m() { return 99; } } |
rfield@1422 | 200 | * interface J { defaultint m() { return 88; } } |
rfield@1422 | 201 | * class C implements I { public int m() { return 11; } } |
rfield@1422 | 202 | * class D extends C { public int m() { return 22; } } |
rfield@1422 | 203 | * class E extends D implements J {} |
rfield@1422 | 204 | * |
rfield@1422 | 205 | * TEST: E e = new E(); e.m() == 22; |
rfield@1422 | 206 | * TEST: J j = new E(); j.m() == 22; |
rfield@1422 | 207 | */ |
rfield@1422 | 208 | public void testExistingInheritedPlusDefault() { |
rfield@1422 | 209 | Interface I = new Interface("I", DefaultMethod.std("99")); |
rfield@1422 | 210 | Interface J = new Interface("J", DefaultMethod.std("88")); |
rfield@1422 | 211 | Class C = new Class("C", I, ConcreteMethod.std("11")); |
rfield@1422 | 212 | Class D = new Class("D", C, ConcreteMethod.std("22")); |
rfield@1422 | 213 | Class E = new Class("E", D, J); |
rfield@1422 | 214 | |
rfield@1422 | 215 | assertInvokeVirtualEquals(22, E); |
rfield@1422 | 216 | assertInvokeInterfaceEquals(22, E, J); |
rfield@1422 | 217 | } |
rfield@1422 | 218 | |
rfield@1422 | 219 | /** |
rfield@1422 | 220 | * interface I { default int m() { return 99; } } |
rfield@1422 | 221 | * class B implements I {} |
rfield@1422 | 222 | * class C extends B { public int m() { return 77; } } |
rfield@1422 | 223 | * |
rfield@1422 | 224 | * TEST: C c = new C(); c.m() == 77; |
rfield@1422 | 225 | * TEST: I i = new C(); i.m() == 77; |
rfield@1422 | 226 | */ |
rfield@1422 | 227 | public void testInheritedWithConcrete() { |
rfield@1422 | 228 | Interface I = new Interface("I", DefaultMethod.std("99")); |
rfield@1422 | 229 | Class B = new Class("B", I); |
rfield@1422 | 230 | Class C = new Class("C", B, ConcreteMethod.std("77")); |
rfield@1422 | 231 | |
rfield@1422 | 232 | assertInvokeVirtualEquals(77, C); |
rfield@1422 | 233 | assertInvokeInterfaceEquals(77, C, I); |
rfield@1422 | 234 | } |
rfield@1422 | 235 | |
rfield@1422 | 236 | /** |
rfield@1422 | 237 | * interface I { default int m() { return 99; } } |
rfield@1422 | 238 | * class B implements I {} |
rfield@1422 | 239 | * class C extends B implements I { public int m() { return 66; } } |
rfield@1422 | 240 | * |
rfield@1422 | 241 | * TEST: C c = new C(); c.m() == 66; |
rfield@1422 | 242 | * TEST: I i = new C(); i.m() == 66; |
rfield@1422 | 243 | */ |
rfield@1422 | 244 | public void testInheritedWithConcreteAndImpl() { |
rfield@1422 | 245 | Interface I = new Interface("I", DefaultMethod.std("99")); |
rfield@1422 | 246 | Class B = new Class("B", I); |
rfield@1422 | 247 | Class C = new Class("C", B, I, ConcreteMethod.std("66")); |
rfield@1422 | 248 | |
rfield@1422 | 249 | assertInvokeVirtualEquals(66, C); |
rfield@1422 | 250 | assertInvokeInterfaceEquals(66, C, I); |
rfield@1422 | 251 | } |
rfield@1422 | 252 | |
rfield@1422 | 253 | /** |
rfield@1422 | 254 | * interface I { default int m() { return 99; } } |
rfield@1422 | 255 | * interface J { default int m() { return 88; } } |
rfield@1422 | 256 | * class C implements I, J {} |
rfield@1422 | 257 | * |
rfield@1422 | 258 | * TEST: C c = new C(); c.m() throws AME |
rfield@1422 | 259 | */ |
rfield@1422 | 260 | public void testConflict() { |
rfield@1422 | 261 | // debugTest(); |
rfield@1422 | 262 | Interface I = new Interface("I", DefaultMethod.std("99")); |
rfield@1422 | 263 | Interface J = new Interface("J", DefaultMethod.std("88")); |
rfield@1422 | 264 | Class C = new Class("C", I, J); |
rfield@1422 | 265 | |
rfield@1422 | 266 | assertThrows(AbstractMethodError.class, C); |
rfield@1422 | 267 | } |
rfield@1422 | 268 | |
rfield@1422 | 269 | /** |
rfield@1422 | 270 | * interface I { int m(); } |
rfield@1422 | 271 | * interface J { default int m() { return 88; } } |
rfield@1422 | 272 | * class C implements I, J {} |
rfield@1422 | 273 | * |
rfield@1422 | 274 | * TEST: C c = new C(); c.m() throws AME |
rfield@1422 | 275 | */ |
rfield@1422 | 276 | public void testAmbiguousReabstract() { |
rfield@1422 | 277 | Interface I = new Interface("I", AbstractMethod.std()); |
rfield@1422 | 278 | Interface J = new Interface("J", DefaultMethod.std("88")); |
rfield@1422 | 279 | Class C = new Class("C", I, J); |
rfield@1422 | 280 | |
rfield@1422 | 281 | assertThrows(AbstractMethodError.class, C); |
rfield@1422 | 282 | } |
rfield@1422 | 283 | |
rfield@1422 | 284 | /** |
rfield@1422 | 285 | * interface I { default int m() { return 99; } } |
rfield@1422 | 286 | * interface J extends I { } |
rfield@1422 | 287 | * interface K extends I { } |
rfield@1422 | 288 | * class C implements J, K {} |
rfield@1422 | 289 | * |
rfield@1422 | 290 | * TEST: C c = new C(); c.m() == 99 |
rfield@1422 | 291 | * TEST: J j = new C(); j.m() == 99 |
rfield@1422 | 292 | * TEST: K k = new C(); k.m() == 99 |
rfield@1422 | 293 | * TEST: I i = new C(); i.m() == 99 |
rfield@1422 | 294 | */ |
rfield@1422 | 295 | public void testDiamond() { |
rfield@1422 | 296 | Interface I = new Interface("I", DefaultMethod.std("99")); |
rfield@1422 | 297 | Interface J = new Interface("J", I); |
rfield@1422 | 298 | Interface K = new Interface("K", I); |
rfield@1422 | 299 | Class C = new Class("C", J, K); |
rfield@1422 | 300 | |
rfield@1422 | 301 | assertInvokeVirtualEquals(99, C); |
rfield@1422 | 302 | assertInvokeInterfaceEquals(99, C, J); |
rfield@1422 | 303 | assertInvokeInterfaceEquals(99, C, K); |
rfield@1422 | 304 | assertInvokeInterfaceEquals(99, C, I); |
rfield@1422 | 305 | } |
rfield@1422 | 306 | |
rfield@1422 | 307 | /** |
rfield@1422 | 308 | * interface I { default int m() { return 99; } } |
rfield@1422 | 309 | * interface J extends I { } |
rfield@1422 | 310 | * interface K extends I { } |
rfield@1422 | 311 | * interface L extends I { } |
rfield@1422 | 312 | * interface M extends I { } |
rfield@1422 | 313 | * class C implements I, J, K, L, M {} |
rfield@1422 | 314 | * |
rfield@1422 | 315 | * TEST: C c = new C(); c.m() == 99 |
rfield@1422 | 316 | * TEST: J j = new C(); j.m() == 99 |
rfield@1422 | 317 | * TEST: K k = new C(); k.m() == 99 |
rfield@1422 | 318 | * TEST: I i = new C(); i.m() == 99 |
rfield@1422 | 319 | * TEST: L l = new C(); l.m() == 99 |
rfield@1422 | 320 | * TEST: M m = new C(); m.m() == 99 |
rfield@1422 | 321 | */ |
rfield@1422 | 322 | public void testExpandedDiamond() { |
rfield@1422 | 323 | Interface I = new Interface("I", DefaultMethod.std("99")); |
rfield@1422 | 324 | Interface J = new Interface("J", I); |
rfield@1422 | 325 | Interface K = new Interface("K", I); |
rfield@1422 | 326 | Interface L = new Interface("L", I); |
rfield@1422 | 327 | Interface M = new Interface("M", L); |
rfield@1422 | 328 | Class C = new Class("C", I, J, K, L, M); |
rfield@1422 | 329 | |
rfield@1422 | 330 | assertInvokeVirtualEquals(99, C); |
rfield@1422 | 331 | assertInvokeInterfaceEquals(99, C, J); |
rfield@1422 | 332 | assertInvokeInterfaceEquals(99, C, K); |
rfield@1422 | 333 | assertInvokeInterfaceEquals(99, C, I); |
rfield@1422 | 334 | assertInvokeInterfaceEquals(99, C, L); |
rfield@1422 | 335 | assertInvokeInterfaceEquals(99, C, M); |
rfield@1422 | 336 | } |
rfield@1422 | 337 | |
rfield@1422 | 338 | /** |
rfield@1422 | 339 | * interface I { int m() default { return 99; } } |
rfield@1422 | 340 | * interface J extends I { int m(); } |
rfield@1422 | 341 | * class C implements J {} |
rfield@1422 | 342 | * |
rfield@1422 | 343 | * TEST: C c = new C(); c.m() throws AME |
rfield@1422 | 344 | */ |
rfield@1422 | 345 | public void testReabstract() { |
rfield@1422 | 346 | Interface I = new Interface("I", DefaultMethod.std("99")); |
rfield@1422 | 347 | Interface J = new Interface("J", I, AbstractMethod.std()); |
rfield@1422 | 348 | Class C = new Class("C", J); |
rfield@1422 | 349 | |
rfield@1422 | 350 | assertThrows(AbstractMethodError.class, C); |
rfield@1422 | 351 | } |
rfield@1422 | 352 | |
rfield@1422 | 353 | /** |
rfield@1422 | 354 | * interface I { default int m() { return 88; } } |
rfield@1422 | 355 | * interface J extends I { default int m() { return 99; } } |
rfield@1422 | 356 | * class C implements J {} |
rfield@1422 | 357 | * |
rfield@1422 | 358 | * TEST: C c = new C(); c.m() == 99; |
rfield@1422 | 359 | * TEST: J j = new C(); j.m() == 99; |
rfield@1422 | 360 | * TEST: I i = new C(); i.m() == 99; |
rfield@1422 | 361 | */ |
rfield@1422 | 362 | public void testShadow() { |
rfield@1422 | 363 | Interface I = new Interface("I", DefaultMethod.std("88")); |
rfield@1422 | 364 | Interface J = new Interface("J", I, DefaultMethod.std("99")); |
rfield@1422 | 365 | Class C = new Class("C", J); |
rfield@1422 | 366 | |
rfield@1422 | 367 | assertInvokeVirtualEquals(99, C); |
rfield@1422 | 368 | assertInvokeInterfaceEquals(99, C, J); |
rfield@1422 | 369 | assertInvokeInterfaceEquals(99, C, I); |
rfield@1422 | 370 | } |
rfield@1422 | 371 | |
rfield@1422 | 372 | /** |
rfield@1422 | 373 | * interface I { default int m() { return 88; } } |
rfield@1422 | 374 | * interface J extends I { default int m() { return 99; } } |
rfield@1422 | 375 | * class C implements I, J {} |
rfield@1422 | 376 | * |
rfield@1422 | 377 | * TEST: C c = new C(); c.m() == 99; |
rfield@1422 | 378 | * TEST: J j = new C(); j.m() == 99; |
rfield@1422 | 379 | * TEST: I i = new C(); i.m() == 99; |
rfield@1422 | 380 | */ |
rfield@1422 | 381 | public void testDisqualified() { |
rfield@1422 | 382 | Interface I = new Interface("I", DefaultMethod.std("88")); |
rfield@1422 | 383 | Interface J = new Interface("J", I, DefaultMethod.std("99")); |
rfield@1422 | 384 | Class C = new Class("C", I, J); |
rfield@1422 | 385 | |
rfield@1422 | 386 | assertInvokeVirtualEquals(99, C); |
rfield@1422 | 387 | assertInvokeInterfaceEquals(99, C, J); |
rfield@1422 | 388 | assertInvokeInterfaceEquals(99, C, I); |
rfield@1422 | 389 | } |
rfield@1422 | 390 | |
rfield@1422 | 391 | /** |
rfield@1422 | 392 | * interface I<T> { default int m(T t) { return 99; } } |
rfield@1422 | 393 | * Class C implements I<String> { public int m() { return 88; } } |
rfield@1422 | 394 | * |
rfield@1422 | 395 | * TEST: C c = new C(); c.m() == 88; |
rfield@1422 | 396 | * TEST: I i = new C(); i.m() == 88; |
rfield@1422 | 397 | */ |
mcimadamore@1882 | 398 | @Test(enabled=false) |
rfield@1422 | 399 | public void testSelfFill() { |
rfield@1422 | 400 | // This test ensures that a concrete method overrides a default method |
rfield@1422 | 401 | // that matches at the language-level, but has a different method |
rfield@1422 | 402 | // signature due to erasure. |
rfield@1422 | 403 | |
rfield@1422 | 404 | // debugTest(); |
rfield@1422 | 405 | |
rfield@1422 | 406 | DefaultMethod dm = new DefaultMethod( |
rfield@1422 | 407 | "int", "m", "return 99;", new MethodParameter("T", "t")); |
rfield@1422 | 408 | ConcreteMethod cm = new ConcreteMethod( |
rfield@1422 | 409 | "int", "m", "return 88;", AccessFlag.PUBLIC, |
rfield@1422 | 410 | new MethodParameter("String", "s")); |
rfield@1422 | 411 | |
rfield@1422 | 412 | Interface I = new Interface("I", new TypeParameter("T"), dm); |
rfield@1422 | 413 | Class C = new Class("C", I.with("String"), cm); |
rfield@1422 | 414 | |
rfield@1422 | 415 | AbstractMethod pm = new AbstractMethod( |
rfield@1422 | 416 | "int", "m", new MethodParameter("T", "t")); |
rfield@1422 | 417 | |
rfield@1422 | 418 | assertInvokeVirtualEquals(new Integer(88), C, cm, "-1", "\"string\""); |
rfield@1422 | 419 | assertInvokeInterfaceEquals( |
rfield@1422 | 420 | new Integer(88), C, I.with("String"), pm, "\"string\""); |
rfield@1422 | 421 | } |
rfield@1422 | 422 | |
rfield@1422 | 423 | /** |
rfield@1422 | 424 | * interface I { default int m() { return 99; } } |
rfield@1422 | 425 | * class C implements I {} |
rfield@1422 | 426 | * |
rfield@1422 | 427 | * TEST: C.class.getMethod("m").invoke(new C()) == 99 |
rfield@1422 | 428 | */ |
rfield@1422 | 429 | public void testReflectCall() { |
rfield@1422 | 430 | Interface I = new Interface("I", DefaultMethod.std("99")); |
mcimadamore@1675 | 431 | //workaround accessibility issue when loading C with DirectedClassLoader |
mcimadamore@1675 | 432 | I.addAccessFlag(AccessFlag.PUBLIC); |
rfield@1422 | 433 | Class C = new Class("C", I); |
rfield@1422 | 434 | |
rfield@1422 | 435 | Compiler.Flags[] flags = this.verbose ? |
rfield@1422 | 436 | new Compiler.Flags[] { Compiler.Flags.VERBOSE } : |
rfield@1422 | 437 | new Compiler.Flags[] {}; |
rfield@1422 | 438 | Compiler compiler = new Compiler(flags); |
rfield@1422 | 439 | java.lang.Class<?> cls = null; |
rfield@1422 | 440 | try { |
rfield@1422 | 441 | cls = compiler.compileAndLoad(C); |
rfield@1422 | 442 | } catch (ClassNotFoundException e) { |
rfield@1422 | 443 | fail("Could not load class"); |
rfield@1422 | 444 | } |
rfield@1422 | 445 | |
rfield@1422 | 446 | java.lang.reflect.Method method = null; |
rfield@1422 | 447 | try { |
rfield@1422 | 448 | method = cls.getMethod(stdMethodName); |
rfield@1422 | 449 | } catch (NoSuchMethodException e) { |
rfield@1422 | 450 | fail("Could not find method in class"); |
rfield@1422 | 451 | } |
rfield@1422 | 452 | assertNotNull(method); |
rfield@1422 | 453 | |
rfield@1422 | 454 | Object c = null; |
rfield@1422 | 455 | try { |
rfield@1422 | 456 | c = cls.newInstance(); |
rfield@1422 | 457 | } catch (InstantiationException | IllegalAccessException e) { |
rfield@1422 | 458 | fail("Could not create instance of class"); |
rfield@1422 | 459 | } |
rfield@1422 | 460 | assertNotNull(c); |
rfield@1422 | 461 | |
rfield@1422 | 462 | Integer res = null; |
rfield@1422 | 463 | try { |
rfield@1422 | 464 | res = (Integer)method.invoke(c); |
rfield@1422 | 465 | } catch (IllegalAccessException | |
rfield@1422 | 466 | java.lang.reflect.InvocationTargetException e) { |
rfield@1422 | 467 | fail("Could not invoke default instance method"); |
rfield@1422 | 468 | } |
rfield@1422 | 469 | assertNotNull(res); |
rfield@1422 | 470 | |
rfield@1422 | 471 | assertEquals(res.intValue(), 99); |
rfield@1422 | 472 | |
rfield@1422 | 473 | compiler.cleanup(); |
rfield@1422 | 474 | } |
rfield@1422 | 475 | |
rfield@1422 | 476 | /** |
rfield@1422 | 477 | * interface I<T,V,W> { default int m(T t, V v, W w) { return 99; } } |
rfield@1422 | 478 | * interface J<T,V> extends I<String,T,V> { int m(T t, V v, String w); } } |
rfield@1422 | 479 | * interface K<T> extends J<String,T> { int m(T t, String v, String w); } } |
rfield@1422 | 480 | * class C implements K<String> { |
rfield@1422 | 481 | * public int m(String t, String v, String w) { return 88; } |
rfield@1422 | 482 | * } |
rfield@1422 | 483 | * |
rfield@1422 | 484 | * TEST: I<String,String,String> i = new C(); i.m("A","B","C") == 88; |
rfield@1422 | 485 | * TEST: J<String,String> j = new C(); j.m("A","B","C") == 88; |
rfield@1422 | 486 | * TEST: K<String> k = new C(); k.m("A","B","C") == 88; |
rfield@1422 | 487 | */ |
mcimadamore@1882 | 488 | @Test(enabled=false) |
rfield@1422 | 489 | public void testBridges() { |
rfield@1422 | 490 | DefaultMethod dm = new DefaultMethod("int", stdMethodName, "return 99;", |
rfield@1422 | 491 | new MethodParameter("T", "t"), new MethodParameter("V", "v"), |
rfield@1422 | 492 | new MethodParameter("W", "w")); |
rfield@1422 | 493 | |
rfield@1422 | 494 | AbstractMethod pm0 = new AbstractMethod("int", stdMethodName, |
rfield@1422 | 495 | new MethodParameter("T", "t"), new MethodParameter("V", "v"), |
rfield@1422 | 496 | new MethodParameter("W", "w")); |
rfield@1422 | 497 | |
rfield@1422 | 498 | AbstractMethod pm1 = new AbstractMethod("int", stdMethodName, |
rfield@1422 | 499 | new MethodParameter("T", "t"), new MethodParameter("V", "v"), |
rfield@1422 | 500 | new MethodParameter("String", "w")); |
rfield@1422 | 501 | |
rfield@1422 | 502 | AbstractMethod pm2 = new AbstractMethod("int", stdMethodName, |
rfield@1422 | 503 | new MethodParameter("T", "t"), new MethodParameter("String", "v"), |
rfield@1422 | 504 | new MethodParameter("String", "w")); |
rfield@1422 | 505 | |
rfield@1422 | 506 | ConcreteMethod cm = new ConcreteMethod("int",stdMethodName,"return 88;", |
rfield@1422 | 507 | AccessFlag.PUBLIC, |
rfield@1422 | 508 | new MethodParameter("String", "t"), |
rfield@1422 | 509 | new MethodParameter("String", "v"), |
rfield@1422 | 510 | new MethodParameter("String", "w")); |
rfield@1422 | 511 | |
rfield@1422 | 512 | Interface I = new Interface("I", new TypeParameter("T"), |
rfield@1422 | 513 | new TypeParameter("V"), new TypeParameter("W"), dm); |
rfield@1422 | 514 | Interface J = new Interface("J", |
rfield@1422 | 515 | new TypeParameter("T"), new TypeParameter("V"), |
rfield@1422 | 516 | I.with("String", "T", "V"), pm1); |
rfield@1422 | 517 | Interface K = new Interface("K", new TypeParameter("T"), |
rfield@1422 | 518 | J.with("String", "T"), pm2); |
rfield@1422 | 519 | Class C = new Class("C", K.with("String"), cm); |
rfield@1422 | 520 | |
rfield@1422 | 521 | String[] args = new String[] { "\"A\"", "\"B\"", "\"C\"" }; |
rfield@1422 | 522 | assertInvokeInterfaceEquals(new Integer(88), C, |
rfield@1422 | 523 | I.with("String", "String", "String"), pm0, args); |
rfield@1422 | 524 | assertInvokeInterfaceEquals(new Integer(88), C, |
rfield@1422 | 525 | J.with("String", "String"), pm1, args); |
rfield@1422 | 526 | assertInvokeInterfaceEquals(new Integer(88), C, |
rfield@1422 | 527 | K.with("String"), pm2, args); |
rfield@1422 | 528 | } |
rfield@1422 | 529 | |
rfield@1422 | 530 | /** |
rfield@1422 | 531 | * interface J { default int m() { return 88; } } |
rfield@1422 | 532 | * interface I extends J { default int m() { return J.super.m(); } } |
rfield@1422 | 533 | * class C implements I {} |
rfield@1422 | 534 | * |
rfield@1422 | 535 | * TEST: C c = new C(); c.m() == 88; |
rfield@1422 | 536 | * TEST: I i = new C(); i.m() == 88; |
rfield@1422 | 537 | */ |
rfield@1422 | 538 | public void testSuperBasic() { |
rfield@1422 | 539 | // debugTest(); |
rfield@1422 | 540 | |
rfield@1422 | 541 | Interface J = new Interface("J", DefaultMethod.std("88")); |
rfield@1422 | 542 | Interface I = new Interface("I", J, new DefaultMethod( |
rfield@1422 | 543 | "int", stdMethodName, "return J.super.m();")); |
rfield@1422 | 544 | I.addCompilationDependency(J.findMethod(stdMethodName)); |
rfield@1422 | 545 | Class C = new Class("C", I); |
rfield@1422 | 546 | |
rfield@1422 | 547 | assertInvokeVirtualEquals(88, C); |
rfield@1422 | 548 | assertInvokeInterfaceEquals(88, C, I); |
rfield@1422 | 549 | } |
rfield@1422 | 550 | |
rfield@1422 | 551 | /** |
rfield@1422 | 552 | * interface K { int m() default { return 99; } } |
rfield@1422 | 553 | * interface L { int m() default { return 101; } } |
rfield@1422 | 554 | * interface J extends K, L {} |
rfield@1422 | 555 | * interface I extends J, K { int m() default { J.super.m(); } } |
rfield@1422 | 556 | * class C implements I {} |
rfield@1422 | 557 | * |
rfield@1422 | 558 | * TEST: C c = new C(); c.m() throws AME |
rfield@1422 | 559 | * TODO: add case for K k = new C(); k.m() throws AME |
rfield@1422 | 560 | */ |
rfield@1422 | 561 | public void testSuperConflict() { |
rfield@1422 | 562 | // debugTest(); |
rfield@1422 | 563 | |
rfield@1422 | 564 | Interface K = new Interface("K", DefaultMethod.std("99")); |
rfield@1422 | 565 | Interface L = new Interface("L", DefaultMethod.std("101")); |
rfield@1422 | 566 | Interface J = new Interface("J", K, L); |
rfield@1422 | 567 | Interface I = new Interface("I", J, K, new DefaultMethod( |
rfield@1422 | 568 | "int", stdMethodName, "return J.super.m();")); |
rfield@1422 | 569 | Interface Jstub = new Interface("J", DefaultMethod.std("-1")); |
rfield@1422 | 570 | I.addCompilationDependency(Jstub); |
rfield@1422 | 571 | I.addCompilationDependency(Jstub.findMethod(stdMethodName)); |
rfield@1422 | 572 | Class C = new Class("C", I); |
rfield@1422 | 573 | |
rfield@1422 | 574 | assertThrows(AbstractMethodError.class, C); |
rfield@1422 | 575 | } |
rfield@1422 | 576 | |
rfield@1422 | 577 | /** |
rfield@1422 | 578 | * interface I { default int m() { return 99; } } |
rfield@1422 | 579 | * interface J extends I { default int m() { return 55; } } |
rfield@1422 | 580 | * class C implements I, J { public int m() { return I.super.m(); } } |
rfield@1422 | 581 | * |
rfield@1422 | 582 | * TEST: C c = new C(); c.m() throws AME |
rfield@1422 | 583 | * TODO: add case for J j = new C(); j.m() throws AME |
rfield@1422 | 584 | */ |
rfield@1422 | 585 | public void testSuperDisqual() { |
rfield@1422 | 586 | Interface I = new Interface("I", DefaultMethod.std("99")); |
rfield@1422 | 587 | Interface J = new Interface("J", I, DefaultMethod.std("55")); |
rfield@1422 | 588 | Class C = new Class("C", I, J, |
rfield@1422 | 589 | new ConcreteMethod("int", stdMethodName, "return I.super.m();", |
rfield@1422 | 590 | AccessFlag.PUBLIC)); |
rfield@1422 | 591 | C.addCompilationDependency(I.findMethod(stdMethodName)); |
rfield@1422 | 592 | |
rfield@1422 | 593 | assertThrows(AbstractMethodError.class, C); |
rfield@1422 | 594 | } |
rfield@1422 | 595 | |
rfield@1422 | 596 | /** |
rfield@1422 | 597 | * interface J { int m(); } |
rfield@1422 | 598 | * interface I extends J { default int m() { return J.super.m(); } } |
rfield@1422 | 599 | * class C implements I {} |
rfield@1422 | 600 | * |
rfield@1422 | 601 | * TEST: C c = new C(); c.m() throws AME |
rfield@1422 | 602 | * TODO: add case for I i = new C(); i.m() throws AME |
rfield@1422 | 603 | */ |
rfield@1422 | 604 | public void testSuperNull() { |
rfield@1422 | 605 | Interface J = new Interface("J", AbstractMethod.std()); |
rfield@1422 | 606 | Interface I = new Interface("I", J, new DefaultMethod( |
rfield@1422 | 607 | "int", stdMethodName, "return J.super.m();")); |
rfield@1422 | 608 | Interface Jstub = new Interface("J", DefaultMethod.std("99")); |
rfield@1422 | 609 | I.addCompilationDependency(Jstub); |
rfield@1422 | 610 | I.addCompilationDependency(Jstub.findMethod(stdMethodName)); |
rfield@1422 | 611 | Class C = new Class("C", I); |
rfield@1422 | 612 | |
rfield@1422 | 613 | assertThrows(AbstractMethodError.class, C); |
rfield@1422 | 614 | } |
rfield@1422 | 615 | |
rfield@1422 | 616 | /** |
rfield@1422 | 617 | * interface J<T> { default int m(T t) { return 88; } } |
rfield@1422 | 618 | * interface I extends J<String> { |
rfield@1422 | 619 | * int m(String s) default { return J.super.m(); } |
rfield@1422 | 620 | * } |
rfield@1422 | 621 | * class C implements I {} |
rfield@1422 | 622 | * |
rfield@1422 | 623 | * TEST: I i = new C(); i.m("") == 88; |
rfield@1422 | 624 | */ |
rfield@1422 | 625 | public void testSuperGeneric() { |
rfield@1422 | 626 | Interface J = new Interface("J", new TypeParameter("T"), |
rfield@1422 | 627 | new DefaultMethod("int", stdMethodName, "return 88;", |
rfield@1422 | 628 | new MethodParameter("T", "t"))); |
rfield@1422 | 629 | Interface I = new Interface("I", J.with("String"), |
rfield@1422 | 630 | new DefaultMethod("int", stdMethodName, "return J.super.m(s);", |
rfield@1422 | 631 | new MethodParameter("String", "s"))); |
rfield@1422 | 632 | I.addCompilationDependency(J.findMethod(stdMethodName)); |
rfield@1422 | 633 | Class C = new Class("C", I); |
rfield@1422 | 634 | |
rfield@1422 | 635 | AbstractMethod pm = new AbstractMethod("int", stdMethodName, |
rfield@1422 | 636 | new MethodParameter("String", "s")); |
rfield@1422 | 637 | |
rfield@1422 | 638 | assertInvokeInterfaceEquals( |
rfield@1422 | 639 | new Integer(88), C, new Extends(I), pm, "\"\""); |
rfield@1422 | 640 | } |
rfield@1422 | 641 | |
rfield@1422 | 642 | /** |
rfield@1422 | 643 | * interface I<T> { int m(T t) default { return 44; } } |
rfield@1422 | 644 | * interface J extends I<String> { int m(String s) default { return 55; } } |
rfield@1422 | 645 | * class C implements I<String>, J { |
rfield@1422 | 646 | * public int m(String s) { return I.super.m(s); } |
rfield@1422 | 647 | * } |
rfield@1422 | 648 | * |
rfield@1422 | 649 | * TEST: C c = new C(); c.m("string") throws AME |
rfield@1422 | 650 | */ |
rfield@1422 | 651 | public void testSuperGenericDisqual() { |
rfield@1422 | 652 | MethodParameter t = new MethodParameter("T", "t"); |
rfield@1422 | 653 | MethodParameter s = new MethodParameter("String", "s"); |
rfield@1422 | 654 | |
rfield@1422 | 655 | Interface I = new Interface("I", new TypeParameter("T"), |
rfield@1422 | 656 | new DefaultMethod("int", stdMethodName, "return 44;", t)); |
rfield@1422 | 657 | Interface J = new Interface("J", I.with("String"), |
rfield@1422 | 658 | new DefaultMethod("int", stdMethodName, "return 55;", s)); |
rfield@1422 | 659 | Class C = new Class("C", I.with("String"), J, |
rfield@1422 | 660 | new ConcreteMethod("int", stdMethodName, |
rfield@1422 | 661 | "return I.super.m(s);", AccessFlag.PUBLIC, s)); |
rfield@1422 | 662 | C.addCompilationDependency(I.findMethod(stdMethodName)); |
rfield@1422 | 663 | |
rfield@1422 | 664 | assertThrows(AbstractMethodError.class, C, |
rfield@1422 | 665 | new ConcreteMethod( |
rfield@1422 | 666 | "int", stdMethodName, "return -1;", AccessFlag.PUBLIC, s), |
rfield@1422 | 667 | "-1", "\"string\""); |
rfield@1422 | 668 | } |
rfield@1422 | 669 | |
rfield@1422 | 670 | /** |
rfield@1422 | 671 | * interface I { default Integer m() { return new Integer(88); } } |
rfield@1422 | 672 | * class C { Number m() { return new Integer(99); } } |
rfield@1422 | 673 | * class D extends C implements I {} |
rfield@1422 | 674 | * class S { Object foo() { return (new D()).m(); } // link sig: ()LInteger; |
rfield@1422 | 675 | * TEST: S s = new S(); s.foo() == new Integer(99) |
rfield@1422 | 676 | */ |
mcimadamore@1882 | 677 | @Test(enabled=false) |
rfield@1422 | 678 | public void testCovarBridge() { |
rfield@1422 | 679 | Interface I = new Interface("I", new DefaultMethod( |
rfield@1422 | 680 | "Integer", "m", "return new Integer(88);")); |
rfield@1422 | 681 | Class C = new Class("C", new ConcreteMethod( |
rfield@1422 | 682 | "Number", "m", "return new Integer(99);", AccessFlag.PUBLIC)); |
rfield@1422 | 683 | Class D = new Class("D", I, C); |
rfield@1422 | 684 | |
rfield@1422 | 685 | ConcreteMethod DstubMethod = new ConcreteMethod( |
rfield@1422 | 686 | "Integer", "m", "return null;", AccessFlag.PUBLIC); |
rfield@1422 | 687 | Class Dstub = new Class("D", DstubMethod); |
rfield@1422 | 688 | |
rfield@1422 | 689 | ConcreteMethod toCall = new ConcreteMethod( |
rfield@1422 | 690 | "Object", "foo", "return (new D()).m();", AccessFlag.PUBLIC); |
rfield@1422 | 691 | Class S = new Class("S", D, toCall); |
rfield@1422 | 692 | S.addCompilationDependency(Dstub); |
rfield@1422 | 693 | S.addCompilationDependency(DstubMethod); |
rfield@1422 | 694 | |
rfield@1422 | 695 | assertInvokeVirtualEquals(new Integer(99), S, toCall, "null"); |
rfield@1422 | 696 | } |
rfield@1422 | 697 | |
rfield@1422 | 698 | /** |
rfield@1422 | 699 | * interface I { default Integer m() { return new Integer(88); } } |
rfield@1422 | 700 | * class C { int m() { return 99; } } |
rfield@1422 | 701 | * class D extends C implements I {} |
rfield@1422 | 702 | * class S { Object foo() { return (new D()).m(); } // link sig: ()LInteger; |
rfield@1422 | 703 | * TEST: S s = new S(); s.foo() == new Integer(88) |
rfield@1422 | 704 | */ |
rfield@1422 | 705 | public void testNoCovarNoBridge() { |
rfield@1422 | 706 | Interface I = new Interface("I", new DefaultMethod( |
rfield@1422 | 707 | "Integer", "m", "return new Integer(88);")); |
rfield@1422 | 708 | Class C = new Class("C", new ConcreteMethod( |
rfield@1422 | 709 | "int", "m", "return 99;", AccessFlag.PUBLIC)); |
rfield@1422 | 710 | Class D = new Class("D", I, C); |
rfield@1422 | 711 | |
rfield@1422 | 712 | ConcreteMethod DstubMethod = new ConcreteMethod( |
rfield@1422 | 713 | "Integer", "m", "return null;", AccessFlag.PUBLIC); |
rfield@1422 | 714 | Class Dstub = new Class("D", DstubMethod); |
rfield@1422 | 715 | |
rfield@1422 | 716 | ConcreteMethod toCall = new ConcreteMethod( |
rfield@1422 | 717 | "Object", "foo", "return (new D()).m();", AccessFlag.PUBLIC); |
rfield@1422 | 718 | Class S = new Class("S", D, toCall); |
rfield@1422 | 719 | S.addCompilationDependency(Dstub); |
rfield@1422 | 720 | S.addCompilationDependency(DstubMethod); |
rfield@1422 | 721 | |
rfield@1422 | 722 | assertInvokeVirtualEquals(new Integer(88), S, toCall, "null"); |
rfield@1422 | 723 | } |
rfield@1422 | 724 | |
rfield@1422 | 725 | /** |
rfield@1422 | 726 | * interface J { int m(); } |
rfield@1422 | 727 | * interface I extends J { default int m() { return 99; } } |
rfield@1422 | 728 | * class B implements J {} |
rfield@1422 | 729 | * class C extends B implements I {} |
rfield@1422 | 730 | * TEST: C c = new C(); c.m() == 99 |
rfield@1422 | 731 | * |
rfield@1422 | 732 | * The point of this test is that B does not get default method analysis, |
rfield@1422 | 733 | * and C does not generate any new miranda methods in the vtable. |
rfield@1422 | 734 | * It verifies that default method analysis occurs when mirandas have been |
rfield@1422 | 735 | * inherited and the supertypes don't have any overpass methods. |
rfield@1422 | 736 | */ |
rfield@1422 | 737 | public void testNoNewMiranda() { |
rfield@1422 | 738 | Interface J = new Interface("J", AbstractMethod.std()); |
rfield@1422 | 739 | Interface I = new Interface("I", J, DefaultMethod.std("99")); |
rfield@1422 | 740 | Class B = new Class("B", J); |
rfield@1422 | 741 | Class C = new Class("C", B, I); |
rfield@1422 | 742 | assertInvokeVirtualEquals(99, C); |
rfield@1422 | 743 | } |
rfield@1422 | 744 | |
rfield@1422 | 745 | /** |
rfield@1422 | 746 | * interface I<T,V,W> { int m(T t, V v, W w); } |
rfield@1422 | 747 | * interface J<T,V> implements I<T,V,String> { int m(T t, V v, String w); } |
rfield@1422 | 748 | * interface K<T> implements J<T,String> { |
rfield@1422 | 749 | * int m(T t, String v, String w); { return 99; } } |
rfield@1422 | 750 | * class C implements K<String> { |
rfield@1422 | 751 | * public int m(Object t, Object v, String w) { return 77; } |
rfield@1422 | 752 | * } |
rfield@1422 | 753 | * TEST C = new C(); ((I)c).m(Object,Object,Object) == 99 |
rfield@1422 | 754 | * TEST C = new C(); ((J)c).m(Object,Object,String) == 77 |
rfield@1422 | 755 | * TEST C = new C(); ((K)c).m(Object,String,String) == 99 |
rfield@1422 | 756 | * |
rfield@1422 | 757 | * Test that a erased-signature-matching method does not implement |
rfield@1422 | 758 | * non-language-level matching methods |
rfield@1422 | 759 | */ |
mcimadamore@1882 | 760 | @Test(enabled=false) |
rfield@1422 | 761 | public void testNonConcreteFill() { |
rfield@1422 | 762 | AbstractMethod ipm = new AbstractMethod("int", "m", |
rfield@1422 | 763 | new MethodParameter("T", "t"), |
rfield@1422 | 764 | new MethodParameter("V", "s"), |
rfield@1422 | 765 | new MethodParameter("W", "w")); |
rfield@1422 | 766 | Interface I = new Interface("I", |
rfield@1422 | 767 | new TypeParameter("T"), |
rfield@1422 | 768 | new TypeParameter("V"), |
rfield@1422 | 769 | new TypeParameter("W"), ipm); |
rfield@1422 | 770 | |
rfield@1422 | 771 | AbstractMethod jpm = new AbstractMethod("int", "m", |
rfield@1422 | 772 | new MethodParameter("T", "t"), |
rfield@1422 | 773 | new MethodParameter("V", "s"), |
rfield@1422 | 774 | new MethodParameter("String", "w")); |
rfield@1422 | 775 | Interface J = new Interface("J", |
rfield@1422 | 776 | new TypeParameter("T"), |
rfield@1422 | 777 | new TypeParameter("V"), |
rfield@1422 | 778 | I.with("T", "V", "String"), jpm); |
rfield@1422 | 779 | |
rfield@1422 | 780 | AbstractMethod kpm = new AbstractMethod("int", "m", |
rfield@1422 | 781 | new MethodParameter("T", "t"), |
rfield@1422 | 782 | new MethodParameter("String", "s"), |
rfield@1422 | 783 | new MethodParameter("String", "w")); |
rfield@1422 | 784 | Interface K = new Interface("K", |
rfield@1422 | 785 | new TypeParameter("T"), |
rfield@1422 | 786 | J.with("T", "String"), |
rfield@1422 | 787 | new DefaultMethod("int", "m", "return 99;", |
rfield@1422 | 788 | new MethodParameter("T", "t"), |
rfield@1422 | 789 | new MethodParameter("String", "v"), |
rfield@1422 | 790 | new MethodParameter("String", "w"))); |
rfield@1422 | 791 | |
rfield@1422 | 792 | Class C = new Class("C", |
rfield@1422 | 793 | K.with("String"), |
rfield@1422 | 794 | new ConcreteMethod("int", "m", "return 77;", |
rfield@1422 | 795 | AccessFlag.PUBLIC, |
rfield@1422 | 796 | new MethodParameter("Object", "t"), |
rfield@1422 | 797 | new MethodParameter("Object", "v"), |
rfield@1422 | 798 | new MethodParameter("String", "w"))); |
rfield@1422 | 799 | |
rfield@1422 | 800 | String a = "\"\""; |
rfield@1422 | 801 | assertInvokeInterfaceEquals(99, C, |
rfield@1422 | 802 | K.with("String"), kpm, a, a, a); |
rfield@1422 | 803 | assertInvokeInterfaceEquals(77, C, |
rfield@1422 | 804 | J.with("String", "String"), jpm, a, a, a); |
rfield@1422 | 805 | assertInvokeInterfaceEquals(99, C, |
rfield@1422 | 806 | I.with("String", "String", "String"), ipm, a, a, a); |
rfield@1422 | 807 | } |
rfield@1422 | 808 | |
rfield@1422 | 809 | public void testStrictfpDefault() { |
rfield@1422 | 810 | try { |
rfield@1422 | 811 | java.lang.Class.forName("org.openjdk.tests.vm.StrictfpDefault"); |
rfield@1422 | 812 | } catch (Exception e) { |
rfield@1422 | 813 | fail("Could not load class", e); |
rfield@1422 | 814 | } |
rfield@1422 | 815 | } |
rfield@1422 | 816 | } |
rfield@1422 | 817 | |
rfield@1422 | 818 | interface StrictfpDefault { |
rfield@1422 | 819 | default strictfp void m() {} |
rfield@1422 | 820 | } |