1/* 2 * Copyright (c) 2013, 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 * @bug 8011590 27 * @summary Check modeling of default methods 28 * @author Joseph D. Darcy 29 */ 30 31import java.util.Objects; 32import java.lang.reflect.*; 33import java.lang.annotation.*; 34 35import static java.lang.reflect.Modifier.*; 36 37public class DefaultMethodModeling { 38 public static void main(String... args) { 39 int failures = 0; 40 41 Class<?>[] classes = {SuperC.class, SuperCchild.class, 42 SuperI.class, SuperIchild.class, 43 SuperIwithDefault.class, SuperIwithDefaultChild.class, 44 Base.class, Combo1.class, Combo2.class, 45 SonSuperIwithDefault.class, DaughterSuperIwithDefault.class, GrandchildSuperIwithDefault.class, D.class, 46 B.class, C.class, B1.class, D1.class 47 }; 48 49 for(Class<?> clazz : classes) { 50 System.err.println(clazz.toString()); 51 for(Method m : clazz.getMethods()) { 52 if (m.getDeclaringClass() != java.lang.Object.class) 53 failures += testMethod(m); 54 } 55 } 56 57 if (failures > 0) 58 throw new RuntimeException(); 59 } 60 61 private static int testMethod(Method m) { 62 ExpectedModel em = Objects.requireNonNull(m.getAnnotation(ExpectedModel.class)); 63 boolean failed = false; 64 65 if (m.getModifiers() != em.modifiers()) { 66 failed = true; 67 System.err.printf("Unexpected modifiers %d; expected %d%n", m.getModifiers(), em.modifiers()); 68 } 69 70 if (m.isDefault() != em.isDefault()) { 71 failed = true; 72 System.err.printf("Unexpected isDefualt %b; expected b%n", m.isDefault(), em.isDefault()); 73 } 74 75 if (!m.getDeclaringClass().equals(em.declaringClass())) { 76 failed = true; 77 System.err.printf("Unexpected isDefualt %s; expected %s%n", 78 m.getDeclaringClass().toString(), em.declaringClass().toString()); 79 } 80 81 return (!failed) ? 0 :1; 82 } 83} 84 85@Retention(RetentionPolicy.RUNTIME) 86@interface ExpectedModel { 87 boolean isDefault() default false; 88 int modifiers() default PUBLIC; 89 Class<?> declaringClass(); 90} 91 92abstract class SuperC { 93 @ExpectedModel(modifiers=PUBLIC|ABSTRACT, declaringClass=SuperC.class) 94 public abstract void foo(); 95 96 @ExpectedModel(declaringClass=SuperC.class) 97 public void bar() { 98 ; 99 } 100} 101 102class SuperCchild extends SuperC { 103 @ExpectedModel(declaringClass=SuperCchild.class) 104 @Override 105 public void foo() {;} 106} 107 108// -=-=-=- 109 110interface SuperI { 111 @ExpectedModel(modifiers=PUBLIC|ABSTRACT, declaringClass=SuperI.class) 112 void foo(); 113 114 @ExpectedModel(modifiers=PUBLIC|ABSTRACT, declaringClass=SuperI.class) 115 void bar(); 116} 117 118class SuperIchild implements SuperI { 119 @ExpectedModel(declaringClass=SuperIchild.class) 120 public void foo() {;} 121 122 @ExpectedModel(declaringClass=SuperIchild.class) 123 public void bar() {;} 124} 125 126// -=-=-=- 127 128interface SuperIwithDefault { 129 @ExpectedModel(modifiers=PUBLIC|ABSTRACT, declaringClass=SuperIwithDefault.class) 130 void foo(); 131 132 @ExpectedModel(isDefault=true, declaringClass=SuperIwithDefault.class) 133 default void bar() { 134 ; 135 } 136} 137 138class SuperIwithDefaultChild implements SuperIwithDefault { 139 @ExpectedModel(declaringClass=SuperIwithDefaultChild.class) 140 @Override 141 public void foo() {;} 142} 143 144// -=-=-=- 145 146abstract class Base { 147 @ExpectedModel(modifiers=PUBLIC|ABSTRACT, declaringClass=Base.class) 148 public abstract void baz(); 149 150 @ExpectedModel(declaringClass=Base.class) 151 public void quux() {;} 152} 153 154abstract class Combo1 extends Base implements SuperI { 155 @ExpectedModel(declaringClass=Combo1.class) 156 public void wombat() {} 157} 158 159abstract class Combo2 extends Base implements SuperIwithDefault { 160 @ExpectedModel(declaringClass=Combo2.class) 161 public void wombat() {} 162} 163 164// -=-=-=- 165 166interface SonSuperIwithDefault extends SuperIwithDefault { 167 @ExpectedModel(modifiers=PUBLIC|ABSTRACT, declaringClass=SonSuperIwithDefault.class) 168 void baz(); 169 170 @ExpectedModel(isDefault=true, declaringClass=SonSuperIwithDefault.class) 171 default void bazD() {;} 172} 173 174interface DaughterSuperIwithDefault extends SuperIwithDefault { 175 @ExpectedModel(modifiers=PUBLIC|ABSTRACT, declaringClass=DaughterSuperIwithDefault.class) 176 void quux(); 177 178 @ExpectedModel(isDefault=true, declaringClass=DaughterSuperIwithDefault.class) 179 default void quuxD() {;} 180} 181 182interface GrandchildSuperIwithDefault extends SonSuperIwithDefault, DaughterSuperIwithDefault { 183 @ExpectedModel(modifiers=PUBLIC|ABSTRACT, declaringClass=GrandchildSuperIwithDefault.class) 184 void wombat(); 185 186 @ExpectedModel(isDefault=true, declaringClass=GrandchildSuperIwithDefault.class) 187 default void wombatD() {;} 188 189} 190 191class D implements GrandchildSuperIwithDefault { 192 @ExpectedModel(declaringClass=D.class) 193 public void wombat(){} 194 195 @ExpectedModel(declaringClass=D.class) 196 public void baz(){} 197 198 @ExpectedModel(declaringClass=D.class) 199 public void foo(){} 200 201 @ExpectedModel(declaringClass=D.class) 202 public void quux(){} 203} 204 205class D1 implements SonSuperIwithDefault, DaughterSuperIwithDefault { 206 @ExpectedModel(declaringClass=D1.class) 207 public void foo(){} 208 209 @ExpectedModel(declaringClass=D1.class) 210 public void baz(){} 211 212 @ExpectedModel(declaringClass=D1.class) 213 public void quux(){} 214} 215 216// -=-=-=- 217 218// What does re-abstraction look like? 219 220class A implements SuperIwithDefault { 221 @ExpectedModel(declaringClass=A.class) 222 @Override 223 public void foo(){;} 224} 225 226abstract class B extends A { 227 @ExpectedModel(modifiers=PUBLIC|ABSTRACT, declaringClass=B.class) 228 @Override 229 public abstract void bar(); 230} 231 232class C extends B implements SuperIwithDefault { 233 @ExpectedModel(declaringClass=C.class) 234 public void bar(){} 235} 236 237abstract class A1 implements SonSuperIwithDefault { 238 @ExpectedModel(modifiers=PUBLIC|ABSTRACT, declaringClass=A1.class) 239 public abstract void baz(); 240 241 @ExpectedModel(modifiers=PUBLIC|ABSTRACT, declaringClass=A1.class) 242 public abstract void foo(); 243} 244 245class B1 extends A1 { 246 @ExpectedModel(declaringClass=B1.class) 247 @Override 248 public void foo(){;} 249 250 @ExpectedModel(declaringClass=B1.class) 251 @Override 252 public void baz(){} 253} 254