langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
changeset 14443 91c05eb19277
parent 14369 3d660d08d1f7
child 14538 384681be798f
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Sat Nov 03 21:09:57 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Sun Nov 04 10:59:42 2012 +0000
@@ -135,6 +135,7 @@
         allowStringsInSwitch = source.allowStringsInSwitch();
         allowPoly = source.allowPoly() && options.isSet("allowPoly");
         allowLambda = source.allowLambda();
+        allowDefaultMethods = source.allowDefaultMethods();
         sourceName = source.name;
         relax = (options.isSet("-retrofit") ||
                  options.isSet("-relax"));
@@ -178,6 +179,10 @@
      */
     boolean allowCovariantReturns;
 
+    /** Switch: support default methods ?
+     */
+    boolean allowDefaultMethods;
+
     /** Switch: support lambda expressions ?
      */
     boolean allowLambda;
@@ -898,6 +903,10 @@
 
             localEnv.info.lint = lint;
 
+            if (isDefaultMethod && types.overridesObjectMethod(m)) {
+                log.error(tree, "default.overrides.object.member", m.name, Kinds.kindName(m.location()), m.location());
+            }
+
             // Enter all type parameters into the local method scope.
             for (List<JCTypeParameter> l = tree.typarams; l.nonEmpty(); l = l.tail)
                 localEnv.info.scope.enterIfAbsent(l.head.type.tsym);
@@ -961,10 +970,12 @@
                         log.error(tree.pos(),
                                   "default.allowed.in.intf.annotation.member");
                 }
-            } else if ((owner.flags() & INTERFACE) != 0 && !isDefaultMethod) {
-                log.error(tree.body.pos(), "intf.meth.cant.have.body");
-            } else if ((tree.mods.flags & ABSTRACT) != 0) {
-                log.error(tree.pos(), "abstract.meth.cant.have.body");
+            } else if ((tree.sym.flags() & ABSTRACT) != 0 && !isDefaultMethod) {
+                if ((owner.flags() & INTERFACE) != 0) {
+                    log.error(tree.body.pos(), "intf.meth.cant.have.body");
+                } else {
+                    log.error(tree.pos(), "abstract.meth.cant.have.body");
+                }
             } else if ((tree.mods.flags & NATIVE) != 0) {
                 log.error(tree.pos(), "native.meth.cant.have.body");
             } else {
@@ -3281,6 +3292,23 @@
             }
         }
 
+        if (env.info.defaultSuperCallSite != null &&
+                !types.interfaceCandidates(env.enclClass.type, (MethodSymbol)sym, true).contains(sym)) {
+            Symbol ovSym = null;
+            for (MethodSymbol msym : types.interfaceCandidates(env.enclClass.type, (MethodSymbol)sym, true)) {
+                if (msym.overrides(sym, msym.enclClass(), types, true)) {
+                    for (Type i : types.interfaces(env.enclClass.type)) {
+                        if (i.tsym.isSubClass(msym.owner, types)) {
+                            ovSym = i.tsym;
+                            break;
+                        }
+                    }
+                }
+            }
+            log.error(env.tree.pos(), "illegal.default.super.call", env.info.defaultSuperCallSite,
+                    diags.fragment("overridden.default", sym, ovSym));
+        }
+
         // Compute the identifier's instantiated type.
         // For methods, we need to compute the instance type by
         // Resolve.instantiate from the symbol's type as well as
@@ -3700,6 +3728,9 @@
             // are compatible (i.e. no two define methods with same arguments
             // yet different return types).  (JLS 8.4.6.3)
             chk.checkCompatibleSupertypes(tree.pos(), c.type);
+            if (allowDefaultMethods) {
+                chk.checkDefaultMethodClashes(tree.pos(), c.type);
+            }
         }
 
         // Check that class does not import the same parameterized interface