langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
changeset 21018 95d225149128
parent 21009 b35973e2d42e
child 21025 9d4e765fe447
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java	Mon Oct 14 12:38:09 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java	Mon Oct 14 22:11:09 2013 +0200
@@ -30,6 +30,7 @@
 import javax.tools.JavaFileManager;
 
 import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.code.Attribute.Compound;
 import com.sun.tools.javac.jvm.*;
 import com.sun.tools.javac.tree.*;
 import com.sun.tools.javac.util.*;
@@ -1951,7 +1952,7 @@
      *                      for errors.
      *  @param m            The overriding method.
      */
-    void checkOverride(JCTree tree, MethodSymbol m) {
+    void checkOverride(JCMethodDecl tree, MethodSymbol m) {
         ClassSymbol origin = (ClassSymbol)m.owner;
         if ((origin.flags() & ENUM) != 0 && names.finalize.equals(m.name))
             if (m.overrides(syms.enumFinalFinalize, origin, types, false)) {
@@ -1967,6 +1968,17 @@
                 checkOverride(tree, t2, origin, m);
             }
         }
+
+        if (m.attribute(syms.overrideType.tsym) != null && !isOverrider(m)) {
+            DiagnosticPosition pos = tree.pos();
+            for (JCAnnotation a : tree.getModifiers().annotations) {
+                if (a.annotationType.type.tsym == syms.overrideType.tsym) {
+                    pos = a.pos();
+                    break;
+                }
+            }
+            log.error(pos, "method.does.not.override.superclass");
+        }
     }
 
     void checkOverride(JCTree tree, Type site, ClassSymbol origin, MethodSymbol m) {
@@ -2725,20 +2737,11 @@
         if (!annotationApplicable(a, s))
             log.error(a.pos(), "annotation.type.not.applicable");
 
-        if (a.annotationType.type.tsym == syms.overrideType.tsym) {
-            if (!isOverrider(s))
-                log.error(a.pos(), "method.does.not.override.superclass");
-        }
-
         if (a.annotationType.type.tsym == syms.functionalInterfaceType.tsym) {
             if (s.kind != TYP) {
                 log.error(a.pos(), "bad.functional.intf.anno");
-            } else {
-                try {
-                    types.findDescriptorSymbol((TypeSymbol)s);
-                } catch (Types.FunctionDescriptorLookupError ex) {
-                    log.error(a.pos(), "bad.functional.intf.anno.1", ex.getDiagnostic());
-                }
+            } else if (!s.isInterface() || (s.flags() & ANNOTATION) != 0) {
+                log.error(a.pos(), "bad.functional.intf.anno.1", diags.fragment("not.a.functional.intf", s));
             }
         }
     }
@@ -2953,7 +2956,7 @@
         return false;
     }
 
-    /** Is the annotation applicable to type annotations? */
+    /** Is the annotation applicable to types? */
     protected boolean isTypeAnnotation(JCAnnotation a, boolean isTypeParameter) {
         Attribute.Compound atTarget =
             a.annotationType.type.tsym.attribute(syms.annotationTargetType.tsym);
@@ -3507,4 +3510,23 @@
     public Warner convertWarner(DiagnosticPosition pos, Type found, Type expected) {
         return new ConversionWarner(pos, "unchecked.assign", found, expected);
     }
+
+    public void checkFunctionalInterface(JCClassDecl tree, ClassSymbol cs) {
+        Compound functionalType = cs.attribute(syms.functionalInterfaceType.tsym);
+
+        if (functionalType != null) {
+            try {
+                types.findDescriptorSymbol((TypeSymbol)cs);
+            } catch (Types.FunctionDescriptorLookupError ex) {
+                DiagnosticPosition pos = tree.pos();
+                for (JCAnnotation a : tree.getModifiers().annotations) {
+                    if (a.annotationType.type.tsym == syms.functionalInterfaceType.tsym) {
+                        pos = a.pos();
+                        break;
+                    }
+                }
+                log.error(pos, "bad.functional.intf.anno.1", ex.getDiagnostic());
+            }
+        }
+    }
 }