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