1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2022 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker import pkg1.A; 18*795d594fSAndroid Build Coastguard Worker import pkg1.C; 19*795d594fSAndroid Build Coastguard Worker import pkg1.C2; 20*795d594fSAndroid Build Coastguard Worker import pkg1.C2I1; 21*795d594fSAndroid Build Coastguard Worker import pkg1.C2I2; 22*795d594fSAndroid Build Coastguard Worker import pkg1.CXI1; 23*795d594fSAndroid Build Coastguard Worker import pkg1.CXI2; 24*795d594fSAndroid Build Coastguard Worker import pkg1.I1; 25*795d594fSAndroid Build Coastguard Worker import pkg2.B; 26*795d594fSAndroid Build Coastguard Worker import pkg2.D; 27*795d594fSAndroid Build Coastguard Worker import pkg2.D2; 28*795d594fSAndroid Build Coastguard Worker import pkg2.D2I1; 29*795d594fSAndroid Build Coastguard Worker import pkg2.D2I2; 30*795d594fSAndroid Build Coastguard Worker import pkg2.DXI1; 31*795d594fSAndroid Build Coastguard Worker import pkg2.DXI2; 32*795d594fSAndroid Build Coastguard Worker import pkg2.I2; 33*795d594fSAndroid Build Coastguard Worker 34*795d594fSAndroid Build Coastguard Worker public class Main { main(String args[])35*795d594fSAndroid Build Coastguard Worker public static void main(String args[]) { 36*795d594fSAndroid Build Coastguard Worker // A single method signature can result in multiple vtable entries 37*795d594fSAndroid Build Coastguard Worker // when package-private methods from different packages are involved. 38*795d594fSAndroid Build Coastguard Worker // All classes here define the method `void foo()` but classes 39*795d594fSAndroid Build Coastguard Worker // class pkg1.A { ... } 40*795d594fSAndroid Build Coastguard Worker // class pkg2.B extends pkg1.A { ... } 41*795d594fSAndroid Build Coastguard Worker // class pkg1.C extends pkg2.B { ... } 42*795d594fSAndroid Build Coastguard Worker // class pkg2.D extends pkg1.C { ... } 43*795d594fSAndroid Build Coastguard Worker // define it as package-private and classes 44*795d594fSAndroid Build Coastguard Worker // class pkg1.C2 extends pkg2.B { ... } 45*795d594fSAndroid Build Coastguard Worker // class pkg2.D2 extends pkg1.C2 { ... } 46*795d594fSAndroid Build Coastguard Worker // define it as public, so that we can test different cases of overriding. 47*795d594fSAndroid Build Coastguard Worker 48*795d594fSAndroid Build Coastguard Worker A a = new A(); 49*795d594fSAndroid Build Coastguard Worker a.callAFoo(); // pkg1.A.foo 50*795d594fSAndroid Build Coastguard Worker 51*795d594fSAndroid Build Coastguard Worker B b = new B(); 52*795d594fSAndroid Build Coastguard Worker b.callAFoo(); // pkg1.A.foo (not overridden by pkg2.B.foo) 53*795d594fSAndroid Build Coastguard Worker b.callBFoo(); // pkg2.B.foo 54*795d594fSAndroid Build Coastguard Worker 55*795d594fSAndroid Build Coastguard Worker C c = new C(); 56*795d594fSAndroid Build Coastguard Worker c.callAFoo(); // pkg1.C.foo (overriddes pkg1.A.foo) 57*795d594fSAndroid Build Coastguard Worker c.callBFoo(); // pkg2.B.foo (not overridden by pkg1.C.foo) 58*795d594fSAndroid Build Coastguard Worker c.callCFoo(); // pkg1.C.foo 59*795d594fSAndroid Build Coastguard Worker 60*795d594fSAndroid Build Coastguard Worker D d = new D(); 61*795d594fSAndroid Build Coastguard Worker d.callAFoo(); // pkg1.C.foo (not overridden by pkg2.D.foo) 62*795d594fSAndroid Build Coastguard Worker d.callBFoo(); // pkg2.D.foo (overrides pkg2.B.foo) 63*795d594fSAndroid Build Coastguard Worker d.callCFoo(); // pkg1.C.foo (not overridden by pkg2.D.foo) 64*795d594fSAndroid Build Coastguard Worker d.callDFoo(); // pkg2.D.foo 65*795d594fSAndroid Build Coastguard Worker 66*795d594fSAndroid Build Coastguard Worker C2 c2 = new C2(); 67*795d594fSAndroid Build Coastguard Worker c2.callAFoo(); // pkg1.C2.foo (overriddes pkg1.A.foo) 68*795d594fSAndroid Build Coastguard Worker c2.callBFoo(); // pkg2.B.foo (not overridden by pkg1.C2.foo) 69*795d594fSAndroid Build Coastguard Worker c2.callC2Foo(); // pkg1.C2.foo 70*795d594fSAndroid Build Coastguard Worker 71*795d594fSAndroid Build Coastguard Worker D2 d2 = new D2(); 72*795d594fSAndroid Build Coastguard Worker d2.callAFoo(); // pkg2.D2.foo (overrides public pkg2.C2.foo which overrides pkg1.A.foo) 73*795d594fSAndroid Build Coastguard Worker d2.callBFoo(); // pkg2.D2.foo (overrides package-private pkg2.B.foo in the same package) 74*795d594fSAndroid Build Coastguard Worker d2.callC2Foo(); // pkg2.D2.foo (overrides public pkg2.C2.foo) 75*795d594fSAndroid Build Coastguard Worker d2.callD2Foo(); // pkg2.D2.foo 76*795d594fSAndroid Build Coastguard Worker 77*795d594fSAndroid Build Coastguard Worker // Interface methods always target the method in the most-derived class with implementation 78*795d594fSAndroid Build Coastguard Worker // even when package-private methods from different packages are involved. 79*795d594fSAndroid Build Coastguard Worker // 80*795d594fSAndroid Build Coastguard Worker // Test interface calls through the following interfaces: 81*795d594fSAndroid Build Coastguard Worker // interface pkg1.I1 { ... } 82*795d594fSAndroid Build Coastguard Worker // interface pkg2.I2 { ... } 83*795d594fSAndroid Build Coastguard Worker // that declare a public `void foo()` for concrete classes 84*795d594fSAndroid Build Coastguard Worker // class pkg1.C2I1 extends pkg1.C2 implements pkg1.I1 {} 85*795d594fSAndroid Build Coastguard Worker // class pkg1.C2I2 extends pkg1.C2 implements pkg2.I2 {} 86*795d594fSAndroid Build Coastguard Worker // class pkg2.D2I1 extends pkg2.D2 implements pkg1.I1 {} 87*795d594fSAndroid Build Coastguard Worker // class pkg2.D2I2 extends pkg2.D2 implements pkg2.I2 {} 88*795d594fSAndroid Build Coastguard Worker // class pkg1.CXI1 extends pkg1.CX implements pkg1.I1 {} 89*795d594fSAndroid Build Coastguard Worker // class pkg1.CXI2 extends pkg1.CX implements pkg2.I2 {} 90*795d594fSAndroid Build Coastguard Worker // class pkg2.DXI1 extends pkg2.DX implements pkg1.I1 {} 91*795d594fSAndroid Build Coastguard Worker // class pkg2.DXI2 extends pkg2.DX implements pkg2.I2 {} 92*795d594fSAndroid Build Coastguard Worker // with helper classes `pkg1.C2` and `pkg2.D2` from previous tests and helper class 93*795d594fSAndroid Build Coastguard Worker // class pkg2.BX extends pkg1.A { ... } 94*795d594fSAndroid Build Coastguard Worker // defining a public `void foo()` but helper classes 95*795d594fSAndroid Build Coastguard Worker // class pkg1.CX extends pkg2.BX { ... } 96*795d594fSAndroid Build Coastguard Worker // class pkg2.DX extends pkg1.CX { ... } 97*795d594fSAndroid Build Coastguard Worker // defining a package-private `void foo()`. This is a compilation error in Java, 98*795d594fSAndroid Build Coastguard Worker // so we're using different definitions for `pkg1.I1`, `pkg2.I2` and `pkg2.BX` in 99*795d594fSAndroid Build Coastguard Worker // src/ for compiling other classes and in src2/ for their run-time definition. 100*795d594fSAndroid Build Coastguard Worker 101*795d594fSAndroid Build Coastguard Worker C2I1 c2i1 = new C2I1(); 102*795d594fSAndroid Build Coastguard Worker I1.callI1Foo(c2i1); // pkg1.C2.foo 103*795d594fSAndroid Build Coastguard Worker 104*795d594fSAndroid Build Coastguard Worker C2I2 c2i2 = new C2I2(); 105*795d594fSAndroid Build Coastguard Worker I2.callI2Foo(c2i2); // pkg1.C2.foo 106*795d594fSAndroid Build Coastguard Worker 107*795d594fSAndroid Build Coastguard Worker D2I1 d2i1 = new D2I1(); 108*795d594fSAndroid Build Coastguard Worker I1.callI1Foo(d2i1); // pkg1.D2.foo 109*795d594fSAndroid Build Coastguard Worker 110*795d594fSAndroid Build Coastguard Worker D2I2 d2i2 = new D2I2(); 111*795d594fSAndroid Build Coastguard Worker I2.callI2Foo(d2i2); // pkg1.D2.foo 112*795d594fSAndroid Build Coastguard Worker 113*795d594fSAndroid Build Coastguard Worker CXI1 cxi1 = new CXI1(); 114*795d594fSAndroid Build Coastguard Worker try { 115*795d594fSAndroid Build Coastguard Worker I1.callI1Foo(cxi1); 116*795d594fSAndroid Build Coastguard Worker } catch (IllegalAccessError expected) { 117*795d594fSAndroid Build Coastguard Worker System.out.println("Caught IllegalAccessError"); 118*795d594fSAndroid Build Coastguard Worker } 119*795d594fSAndroid Build Coastguard Worker 120*795d594fSAndroid Build Coastguard Worker CXI2 cxi2 = new CXI2(); 121*795d594fSAndroid Build Coastguard Worker try { 122*795d594fSAndroid Build Coastguard Worker I2.callI2Foo(cxi2); 123*795d594fSAndroid Build Coastguard Worker } catch (IllegalAccessError expected) { 124*795d594fSAndroid Build Coastguard Worker System.out.println("Caught IllegalAccessError"); 125*795d594fSAndroid Build Coastguard Worker } 126*795d594fSAndroid Build Coastguard Worker 127*795d594fSAndroid Build Coastguard Worker DXI1 dxi1 = new DXI1(); 128*795d594fSAndroid Build Coastguard Worker try { 129*795d594fSAndroid Build Coastguard Worker I1.callI1Foo(dxi1); 130*795d594fSAndroid Build Coastguard Worker } catch (IllegalAccessError expected) { 131*795d594fSAndroid Build Coastguard Worker System.out.println("Caught IllegalAccessError"); 132*795d594fSAndroid Build Coastguard Worker } 133*795d594fSAndroid Build Coastguard Worker 134*795d594fSAndroid Build Coastguard Worker DXI2 dxi2 = new DXI2(); 135*795d594fSAndroid Build Coastguard Worker try { 136*795d594fSAndroid Build Coastguard Worker I2.callI2Foo(dxi2); 137*795d594fSAndroid Build Coastguard Worker } catch (IllegalAccessError expected) { 138*795d594fSAndroid Build Coastguard Worker System.out.println("Caught IllegalAccessError"); 139*795d594fSAndroid Build Coastguard Worker } 140*795d594fSAndroid Build Coastguard Worker 141*795d594fSAndroid Build Coastguard Worker InheritingProtectedAbstract ipa = new InheritingProtectedAbstract(); 142*795d594fSAndroid Build Coastguard Worker try { 143*795d594fSAndroid Build Coastguard Worker I1.callI1Foo(ipa); 144*795d594fSAndroid Build Coastguard Worker } catch (IllegalAccessError expected) { 145*795d594fSAndroid Build Coastguard Worker System.out.println("Caught IllegalAccessError"); 146*795d594fSAndroid Build Coastguard Worker } 147*795d594fSAndroid Build Coastguard Worker } 148*795d594fSAndroid Build Coastguard Worker } 149