Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/vmTestbase/vm/runtime/defmeth/MethodResolutionTest.java
41159 views
1
/*
2
* Copyright (c) 2013, 2021, 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
/*
25
* @test
26
*
27
* @modules java.base/jdk.internal.org.objectweb.asm:+open java.base/jdk.internal.org.objectweb.asm.util:+open
28
* @library /vmTestbase /test/lib
29
*
30
* @comment build retransform.jar in current dir
31
* @run driver vm.runtime.defmeth.shared.BuildJar
32
*
33
* @run driver jdk.test.lib.FileInstaller . .
34
* @run main/othervm/native
35
* -agentlib:redefineClasses
36
* -javaagent:retransform.jar
37
* vm.runtime.defmeth.MethodResolutionTest
38
*/
39
package vm.runtime.defmeth;
40
41
import java.util.Set;
42
43
import vm.runtime.defmeth.shared.data.*;
44
import vm.runtime.defmeth.shared.data.method.param.*;
45
import vm.runtime.defmeth.shared.DefMethTest;
46
import vm.runtime.defmeth.shared.builder.TestBuilder;
47
48
import static jdk.internal.org.objectweb.asm.Opcodes.*;
49
import static vm.runtime.defmeth.shared.ExecutionMode.*;
50
51
/**
52
* Tests on method resolution in presence of default methods in the hierarchy.
53
*
54
* Because default methods reside in interfaces, and interfaces do not have
55
* the constraint of being single-inheritance, it is possible to inherit
56
* multiple conflicting default methods, or even inherit the same default method
57
* from many different inheritance paths.
58
*
59
* There is an algorithm to select which method to use in the case that a
60
* concrete class does not provide an implementation. Informally, the algorithm
61
* works as follows:
62
*
63
* (1) If there is a adequate implementation in the class itself or in a
64
* superclass (not an interface), then that implementation should be used
65
* (i.e., class methods always "win").
66
*
67
* (2) Failing that, create the set of methods consisting of all methods in the
68
* type hierarchy which satisfy the slot to be filled, where in this case
69
* 'satisfy' means that the methods have the same name, the same language-
70
* level representation of the parameters, and covariant return values. Both
71
* default methods and abstract methods will be part of this set.
72
*
73
* (3) Remove from this set, any method which has a "more specific" version
74
* anywhere in the hierarchy. That is, if C implements I,J and I extends J,
75
* then if both I and J have a suitable methods, J's method is eliminated
76
* from the set since I is a subtype of J -- there exist a more specific
77
* method than J's method, so that is eliminated.
78
*
79
* (4) If the remaining set contains only a single entry, then that method is
80
* selected. Note that the method may be abstract, in which case an
81
* IncompatibleClassChangeError is thrown when/if the method is called. If there are
82
* multiple entries in the set, or no entries, then this also results in an
83
* IncompatibleClassChangeError when called.
84
*/
85
public class MethodResolutionTest extends DefMethTest {
86
87
public static void main(String[] args) {
88
DefMethTest.runTest(MethodResolutionTest.class,
89
/* majorVer */ Set.of(MIN_MAJOR_VER, MAX_MAJOR_VER),
90
/* flags */ Set.of(0, ACC_SYNCHRONIZED),
91
/* redefine */ Set.of(false, true),
92
/* execMode */ Set.of(DIRECT, REFLECTION, INVOKE_EXACT, INVOKE_GENERIC, INVOKE_WITH_ARGS, INDY));
93
}
94
95
/*
96
* Basic
97
*
98
* interface I { int m(); }
99
* class C implements I { public int m() { return 1; } }
100
*
101
* TEST: C c = new C(); c.m() == 1;
102
* TEST: I i = new C(); i.m() == 1;
103
*/
104
public void testBasic(TestBuilder b) {
105
Interface I =
106
b.intf("I")
107
.abstractMethod("m", "()I").build()
108
.build();
109
110
ConcreteClass C =
111
b.clazz("C").implement(I)
112
.concreteMethod("m", "()I").returns(1).build()
113
.build();
114
115
b.test()
116
.callSite(I, C, "m", "()I")
117
.returns(1)
118
.done()
119
.test()
120
.callSite(C, C, "m", "()I")
121
.returns(1)
122
.done();
123
}
124
125
/*
126
* Basic Default
127
*
128
* interface I { int m() default { return 1; } }
129
* class C implements I {}
130
*
131
* TEST: C c = new C(); c.m() == 1;
132
* TEST: I i = new C(); i.m() == 1;
133
*/
134
public void testBasicDefault(TestBuilder b) {
135
Interface I =
136
b.intf("I")
137
.defaultMethod("m", "()I").returns(1)
138
.build()
139
.build();
140
141
ConcreteClass C =
142
b.clazz("C").implement(I)
143
.build();
144
145
b.test()
146
.callSite(I, C, "m", "()I")
147
.returns(1)
148
.done()
149
.test().callSite(C, C, "m", "()I")
150
.returns(1)
151
.done();
152
}
153
154
/*
155
* Far Default
156
*
157
* interface I { int m() default { return 1; } }
158
* interface J extends I {}
159
* interface K extends J {}
160
* class C implements K {}
161
*
162
* TEST: [I|J|K|C] i = new C(); i.m() == 1;
163
*/
164
public void testFarDefault(TestBuilder b) {
165
Interface I =
166
b.intf("I")
167
.defaultMethod("m", "()I").returns(1)
168
.build()
169
.build();
170
171
Interface J = b.intf("J").extend(I).build();
172
Interface K = b.intf("K").extend(J).build();
173
174
ConcreteClass C =
175
b.clazz("C").implement(K)
176
.build();
177
178
b.test()
179
.callSite(I, C, "m", "()I")
180
.returns(1)
181
.done()
182
.test().callSite(J, C, "m", "()I")
183
.returns(1)
184
.done()
185
.test().callSite(K, C, "m", "()I")
186
.returns(1)
187
.done()
188
.test().callSite(C, C, "m", "()I")
189
.returns(1)
190
.done();
191
}
192
193
/*
194
* Override Abstract
195
*
196
* interface I { int m(); }
197
* interface J extends I { int m() default { return 1; } }
198
* interface K extends J {}
199
* class C implements K {}
200
*
201
* TEST: C c = new C(); c.m() == 1;
202
* TEST: K k = new C(); k.m() == 1;
203
*/
204
public void testOverrideAbstract(TestBuilder b) {
205
Interface I = b.intf("I")
206
.abstractMethod("m", "()I").build()
207
.build();
208
209
Interface J = b.intf("J").extend(I)
210
.defaultMethod("m", "()I").returns(1).build()
211
.build();
212
213
Interface K = b.intf("K").extend(J).build();
214
215
ConcreteClass C = b.clazz("C").implement(K).build();
216
217
b.test()
218
.callSite(I, C, "m", "()I")
219
.returns(1)
220
.done()
221
.test()
222
.callSite(J, C, "m", "()I")
223
.returns(1)
224
.done()
225
.test()
226
.callSite(K, C, "m", "()I")
227
.returns(1)
228
.done()
229
.test()
230
.callSite(C, C, "m", "()I")
231
.returns(1)
232
.done();
233
}
234
235
/*
236
* Default vs Concrete
237
*
238
* interface I { int m() default { return 1; } }
239
* class C implements I { public int m() { return 2; } }
240
*
241
* TEST: [C|I] c = new C(); c.m() == 2;
242
*/
243
public void testDefaultVsConcrete(TestBuilder b) {
244
Interface I = b.intf("I")
245
.defaultMethod("m", "()I").returns(1).build()
246
.build();
247
248
ConcreteClass C = b.clazz("C").implement(I)
249
.concreteMethod("m", "()I").returns(2).build()
250
.build();
251
252
b.test()
253
.callSite(I, C, "m", "()I")
254
.returns(2)
255
.done()
256
.test()
257
.callSite(C, C, "m", "()I")
258
.returns(2)
259
.done();
260
}
261
262
/*
263
* InheritedDefault
264
*
265
* interface I { int m() default { return 1; } }
266
* class B implements I {}
267
* class C extends B {}
268
*
269
* TEST: [I|B|C] v = new C(); v.m() == 1;
270
*/
271
public void testInheritedDefault(TestBuilder b) {
272
Interface I = b.intf("I")
273
.defaultMethod("m", "()I").returns(1).build()
274
.build();
275
276
ConcreteClass B = b.clazz("B").implement(I).build();
277
ConcreteClass C = b.clazz("C").extend(B).build();
278
279
b.test()
280
.callSite(I, C, "m","()I")
281
.returns(1)
282
.done()
283
.test()
284
.callSite(B, C, "m","()I")
285
.returns(1)
286
.done()
287
.test()
288
.callSite(C, C, "m","()I")
289
.returns(1)
290
.done();
291
}
292
293
/*
294
* ExistingInherited
295
*
296
* interface I { int m() default { return 1; } }
297
* class B { public int m() { return 2; } }
298
* class C extends B implements I {}
299
*
300
* TEST: [I|B|C] v = new C(); v.m() == 2;
301
*/
302
public void testExistingInherited(TestBuilder b) {
303
Interface I = b.intf("I")
304
.defaultMethod("m", "()I").returns(1).build()
305
.build();
306
307
ConcreteClass B = b.clazz("B")
308
.concreteMethod("m", "()I").returns(2).build()
309
.build();
310
311
ConcreteClass C = b.clazz("C").extend(B).implement(I).build();
312
313
b.test()
314
.callSite(I, C, "m","()I")
315
.returns(2)
316
.done()
317
.test()
318
.callSite(B, C, "m","()I")
319
.returns(2)
320
.done()
321
.test()
322
.callSite(C, C, "m","()I")
323
.returns(2)
324
.done();
325
}
326
327
/*
328
* ExistingInheritedOverride
329
*
330
* interface I { int m() default { return 1; } }
331
* class B implements I { public int m() { return 2; } }
332
* class C extends B { public int m() { return 3; } }
333
*
334
* TEST: [I|B|D] v = new C(); v.m() == 3;
335
*/
336
public void testExistingInheritedOverride(TestBuilder b) {
337
Interface I = b.intf("I")
338
.defaultMethod("m", "()I").returns(1).build()
339
.build();
340
341
ConcreteClass B = b.clazz("B").implement(I)
342
.concreteMethod("m", "()I").returns(2).build()
343
.build();
344
345
ConcreteClass C = b.clazz("C").extend(B)
346
.concreteMethod("m", "()I").returns(3).build()
347
.build();
348
349
b.test()
350
.callSite(I, C, "m","()I")
351
.returns(3)
352
.done()
353
.test()
354
.callSite(B, C, "m","()I")
355
.returns(3)
356
.done()
357
.test()
358
.callSite(C, C, "m","()I")
359
.returns(3)
360
.done();
361
}
362
363
/*
364
* ExistingInheritedPlusDefault
365
*
366
* interface I { int m() default { return 11; } }
367
* interface J { int m() default { return 12; } }
368
* class C implements I { public int m() { return 21; } }
369
* class D extends C { public int m() { return 22; } }
370
* class E extends D implements J {}
371
*
372
* TEST: [I|J|C|D|J] v = new E(); v.m() == 22;
373
*/
374
public void testExistingInheritedPlusDefault(TestBuilder b) {
375
Interface I = b.intf("I")
376
.defaultMethod("m", "()I").returns(11).build()
377
.build();
378
379
Interface J = b.intf("J")
380
.defaultMethod("m", "()I").returns(12).build()
381
.build();
382
383
ConcreteClass C = b.clazz("C").implement(I)
384
.concreteMethod("m","()I").returns(21).build()
385
.build();
386
387
ConcreteClass D = b.clazz("D").extend(C)
388
.concreteMethod("m", "()I").returns(22).build()
389
.build();
390
391
ConcreteClass E = b.clazz("E").extend(D).implement(J)
392
.build();
393
394
b.test()
395
.callSite(I, E, "m","()I")
396
.returns(22)
397
.done()
398
.test()
399
.callSite(J, E, "m","()I")
400
.returns(22)
401
.done()
402
.test()
403
.callSite(C, E, "m","()I")
404
.returns(22)
405
.done()
406
.test()
407
.callSite(D, E, "m","()I")
408
.returns(22)
409
.done()
410
.test()
411
.callSite(E, E, "m","()I")
412
.returns(22)
413
.done();
414
}
415
416
/*
417
* InheritedWithConcrete
418
*
419
* interface I { int m() default { return 1; } }
420
* class B implements I {}
421
* class C extends B { public int m() { return 2; } }
422
*
423
* TEST: [I|B|C] v = new C(); v.m() == 2;
424
*/
425
public void testInheritedWithConcrete(TestBuilder b) {
426
Interface I = b.intf("I")
427
.defaultMethod("m", "()I").returns(1).build()
428
.build();
429
430
ConcreteClass B = b.clazz("B").implement(I).build();
431
432
ConcreteClass C = b.clazz("C").extend(B)
433
.concreteMethod("m", "()I").returns(2).build()
434
.build();
435
436
b.test()
437
.callSite(I, C, "m","()I")
438
.returns(2)
439
.done()
440
.test()
441
.callSite(B, C, "m","()I")
442
.returns(2)
443
.done()
444
.test()
445
.callSite(C, C, "m","()I")
446
.returns(2)
447
.done();
448
}
449
450
/*
451
* InheritedWithConcreteAndImpl
452
*
453
* interface I { int m() default { return 1; } }
454
* class B implements I {}
455
* class C extends B implements I { public int m() { return 2; } }
456
*
457
* TEST: [I|B|C] v = new C(); v.m() == 2;
458
*/
459
public void testInheritedWithConcreteAndImpl(TestBuilder b) {
460
Interface I = b.intf("I")
461
.defaultMethod("m", "()I").returns(1).build()
462
.build();
463
464
ConcreteClass B = b.clazz("B").implement(I).build();
465
466
ConcreteClass C = b.clazz("C").extend(B)
467
.concreteMethod("m", "()I").returns(2).build()
468
.build();
469
470
b.test()
471
.callSite(I, C, "m","()I")
472
.returns(2)
473
.done()
474
.test()
475
.callSite(B, C, "m","()I")
476
.returns(2)
477
.done()
478
.test()
479
.callSite(C, C, "m","()I")
480
.returns(2)
481
.done();
482
}
483
484
/*
485
* Diamond
486
*
487
* interface I { int m() default { return 1; } }
488
* interface J extends I {}
489
* interface K extends I {}
490
* class C implements J, K {}
491
*
492
* TEST: [I|J|K|C] c = new C(); c.m() == 99
493
*/
494
public void testDiamond(TestBuilder b) {
495
Interface I = b.intf("I")
496
.defaultMethod("m", "()I").returns(1).build()
497
.build();
498
499
Interface J = b.intf("J").extend(I).build();
500
Interface K = b.intf("K").extend(I).build();
501
502
ConcreteClass C = b.clazz("C").implement(J,K)
503
.build();
504
505
b.test()
506
.callSite(I, C, "m","()I")
507
.returns(1)
508
.done()
509
.test()
510
.callSite(J, C, "m","()I")
511
.returns(1)
512
.done()
513
.test()
514
.callSite(K, C, "m","()I")
515
.returns(1)
516
.done()
517
.test()
518
.callSite(C, C, "m","()I")
519
.returns(1)
520
.done();
521
}
522
523
/*
524
* ExpandedDiamond
525
*
526
* interface I { int m() default { return 1; } }
527
* interface J extends I {}
528
* interface K extends I {}
529
* interface L extends I {}
530
* interface M extends I {}
531
* class C implements J, K, L, M {}
532
*
533
* TEST: [I|J|K|L|M|C] c = new C(); c.m() == 1
534
*/
535
public void testExpandedDiamond(TestBuilder b) {
536
Interface I = b.intf("I")
537
.defaultMethod("m", "()I").returns(1).build()
538
.build();
539
540
Interface J = b.intf("J").extend(I).build();
541
Interface K = b.intf("K").extend(I).build();
542
Interface L = b.intf("L").extend(I).build();
543
Interface M = b.intf("M").extend(I).build();
544
545
ConcreteClass C = b.clazz("C").implement(J,K,L,M)
546
.build();
547
548
b.test()
549
.callSite(I, C, "m","()I")
550
.returns(1)
551
.done()
552
.test()
553
.callSite(J, C, "m","()I")
554
.returns(1)
555
.done()
556
.test()
557
.callSite(K, C, "m","()I")
558
.returns(1)
559
.done()
560
.test()
561
.callSite(L, C, "m","()I")
562
.returns(1)
563
.done()
564
.test()
565
.callSite(M, C, "m","()I")
566
.returns(1)
567
.done()
568
.test()
569
.callSite(C, C, "m","()I")
570
.returns(1)
571
.done();
572
}
573
574
/*
575
* SelfFill w/ explicit bridge
576
*
577
* interface I<T> { int m(T t) default { return 1; } }
578
* class C implements I<C> {
579
* public int m(C s) { return 2; }
580
* public int m(Object o) { ... }
581
* }
582
*
583
* TEST: I i = new C(); i.m((Object)null) == 2;
584
* TEST: C c = new C(); c.m((Object)null) == 2;
585
* TEST: C c = new C(); c.m((C)null) == 2;
586
*/
587
public void testSelfFillWithExplicitBridge(TestBuilder b) {
588
/* interface I<T> { ... */
589
Interface I = b.intf("I").sig("<T:Ljava/lang/Object;>Ljava/lang/Object;")
590
/* default int m(T t) { return 1; } */
591
.defaultMethod("m", "(Ljava/lang/Object;)I")
592
.sig("(TT;)I")
593
.returns(1)
594
.build()
595
.build();
596
597
/* class C implements I<C> { ... */
598
ConcreteClass C = b.clazz("C").implement(I)
599
.sig("Ljava/lang/Object;LI<LC;>;")
600
601
/* public int m(I i) { return 2; } */
602
.concreteMethod("m","(LC;)I").returns(2).build()
603
604
/* bridge method for m(LI;)I */
605
.concreteMethod("m","(Ljava/lang/Object;)I")
606
.flags(ACC_PUBLIC | ACC_BRIDGE | ACC_SYNTHETIC)
607
.returns(2)
608
.build()
609
.build();
610
611
// I i = new C(); ...
612
b.test()
613
.callSite(I, C, "m", "(Ljava/lang/Object;)I")
614
.params(new NullParam())
615
.returns(2)
616
.done()
617
// C c = new C(); ...
618
.test()
619
.callSite(C, C, "m", "(Ljava/lang/Object;)I")
620
.params(new NullParam())
621
.returns(2)
622
.done()
623
.test()
624
.callSite(C, C, "m", "(LC;)I")
625
.params(new NullParam())
626
.returns(2)
627
.done();
628
}
629
630
/*
631
* interface I { int m() default { return 1; } }
632
* class C implements I { int m(int i) { return 2; } }
633
*
634
* TEST: C c = new C(); c.m(0) == 2;
635
* TEST: I i = new C(); i.m() == 1;
636
*/
637
public void testMixedArity() {
638
TestBuilder b = factory.getBuilder();
639
640
Interface I =
641
b.intf("I")
642
.defaultMethod("m", "()I").returns(1)
643
.build()
644
.build();
645
646
ConcreteClass C =
647
b.clazz("C").implement(I)
648
.concreteMethod("m", "(I)I").returns(2)
649
.build()
650
.build();
651
652
b.test().callSite(I, C, "m", "()I")
653
.returns(1)
654
.build();
655
b.test().callSite(C, C, "m", "(I)I").params(ICONST_0)
656
.returns(2)
657
.build();
658
}
659
660
/*
661
* interface I { int m() default { return 1; } }
662
* interface J { int m(int i) default { return 2; } }
663
* class C implements I, J {}
664
*
665
* TEST: I i = new C(); i.m() == 1; i.m(0) ==> NSME
666
* TEST: J j = new C(); j.m() ==> NSME; j.m(0) == 2
667
* TEST: C c = new C(); c.m() == 1; c.m(0) == 2
668
*/
669
public void testConflictingDefaultMixedArity1(TestBuilder b) {
670
Interface I = b.intf("I")
671
.defaultMethod("m", "()I").returns(1)
672
.build()
673
.build();
674
675
Interface J = b.intf("J")
676
.defaultMethod("m", "(I)I").returns(2)
677
.build()
678
.build();
679
680
ConcreteClass C = b.clazz("C").implement(I,J).build();
681
682
683
// I i = new C(); ...
684
b.test().callSite(I, C, "m", "()I")
685
.returns(1)
686
.build();
687
b.test().callSite(I, C, "m", "(I)I").params(ICONST_0)
688
.throws_(NoSuchMethodError.class)
689
.build();
690
691
// J j = new C(); ...
692
b.test().callSite(J, C, "m", "()I")
693
.throws_(NoSuchMethodError.class)
694
.build();
695
b.test().callSite(J, C, "m", "(I)I").params(ICONST_0)
696
.returns(2)
697
.build();
698
699
// C c = new C(); ...
700
b.test().callSite(C, C, "m", "()I")
701
.returns(1)
702
.build();
703
b.test().callSite(C, C, "m", "(I)I").params(ICONST_0)
704
.returns(2)
705
.build();
706
}
707
708
/*
709
* interface I { int m() default { return 1; } }
710
* interface J { int m() default { return 2; } }
711
* class C implements I, J {
712
* int m(int i) { return 3; }
713
* }
714
*
715
* TEST: I i = new C(); i.m(0) ==> ICCE
716
* TEST: J j = new C(); j.m(0) ==> ICCE
717
* TEST: C c = new C(); c.m() ==> ICCE; c.m(0) == 3
718
*/
719
public void testConflictingDefaultMixedArity2(TestBuilder b) {
720
Interface I = b.intf("I")
721
.defaultMethod("m", "()I").returns(1)
722
.build()
723
.build();
724
725
Interface J = b.intf("J")
726
.defaultMethod("m", "()I").returns(2)
727
.build()
728
.build();
729
730
ConcreteClass C = b.clazz("C").implement(I, J)
731
.concreteMethod("m", "(I)I").returns(3)
732
.build()
733
.build();
734
735
// I i = new C(); ...
736
b.test().callSite(I, C, "m", "()I")
737
.throws_(IncompatibleClassChangeError.class)
738
.build();
739
b.test().callSite(I, C, "m", "(I)I").params(ICONST_0)
740
.throws_(NoSuchMethodError.class)
741
.build();
742
743
// J j = new C(); ...
744
b.test().callSite(J, C, "m", "()I")
745
.throws_(IncompatibleClassChangeError.class)
746
.build();
747
b.test().callSite(J, C, "m", "(I)I").params(ICONST_0)
748
.throws_(NoSuchMethodError.class)
749
.build();
750
751
// C c = new C(); ...
752
b.test().callSite(C, C, "m", "()I")
753
.throws_(IncompatibleClassChangeError.class)
754
.build();
755
b.test().callSite(C, C, "m", "(I)I").params(ICONST_0)
756
.returns(3)
757
.build();
758
}
759
760
/* In package1:
761
* package p1;
762
* interface I {
763
* default int m() { return 10; };
764
* }
765
* public interface J extends I {};
766
*
767
* In package2:
768
* class A implements p1.J {}
769
* A myA = new A;
770
* myA.m(); // should return 10 except for reflect mode,
771
* // throw IllegalAccessException with reflect mode
772
*/
773
774
public void testMethodResolvedInDifferentPackage(TestBuilder b) {
775
Interface I = b.intf("p1.I").flags(~ACC_PUBLIC & ACC_PUBLIC) // make it package private
776
.defaultMethod("m", "()I").returns(10)
777
.build()
778
.build();
779
780
Interface J = b.intf("p1.J").extend(I)
781
.build();
782
783
ConcreteClass myA = b.clazz("p2.A").implement(J)
784
.build();
785
if (!factory.getExecutionMode().equals("REFLECTION")) {
786
b.test()
787
.callSite(myA, myA, "m", "()I")
788
.returns(10)
789
.done();
790
} else {
791
// -mode reflect will fail with IAE as expected
792
b.test()
793
.callSite(myA, myA, "m", "()I")
794
.throws_(IllegalAccessException.class)
795
.done();
796
}
797
}
798
799
/* In package p1:
800
* package p1;
801
* interface I {
802
* public default int m() { return 12; };
803
* }
804
*
805
* public class A implements I {}
806
*
807
* In package p2:
808
* package p2;
809
* public interface J { int m(); }
810
*
811
* public class B extends p1.A implements J {
812
* public int m() { return 13; }
813
* }
814
*
815
* Then:
816
* A myA = new B;
817
* myA.m(); // should return 13, not throw IllegalAccessError
818
*/
819
820
public void testMethodResolvedInLocalFirst(TestBuilder b) {
821
Interface I = b.intf("p1.I")
822
.defaultMethod("m", "()I").returns(12)
823
.build()
824
.build();
825
826
ConcreteClass myA = b.clazz("p1.A").implement(I)
827
.build();
828
829
Interface J = b.intf("p2.J").abstractMethod("m", "()I")
830
.build()
831
.build();
832
833
ConcreteClass myB = b.clazz("p2.B").extend(myA).implement(J)
834
.concreteMethod("m", "()I").returns(13)
835
.build()
836
.build();
837
838
b.test()
839
.callSite(myB, myB, "m", "()I")
840
.returns(13)
841
.done();
842
}
843
}
844
845