changeset 2138:6dcf94e32a3a

8019461: Clean up javac diagnostics 7196553: Review error messages for repeating annotations Summary: Changes to the diagnostic messages to improve clarity and JLS coherence Reviewed-by: jjg
author emc
date Thu, 10 Oct 2013 13:55:41 -0400
parents 933ba3f81a87
children b1b4a6dcc282
files src/share/classes/com/sun/tools/javac/comp/Attr.java src/share/classes/com/sun/tools/javac/comp/Check.java src/share/classes/com/sun/tools/javac/comp/MemberEnter.java src/share/classes/com/sun/tools/javac/resources/compiler.properties test/tools/javac/diags/examples/DuplicateAnnotation.java test/tools/javac/diags/examples/InterfaceOrArrayExpected.java test/tools/javac/diags/examples/RepeatableAnnotationsNotSupported.java
diffstat 7 files changed, 136 insertions(+), 91 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Oct 10 10:51:15 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Oct 10 13:55:41 2013 -0400
@@ -792,17 +792,19 @@
         Type t = tree.type != null ?
             tree.type :
             attribType(tree, env);
-        return checkBase(t, tree, env, classExpected, interfaceExpected, checkExtensible);
+        return checkBase(t, tree, env, classExpected, interfaceExpected, false, checkExtensible);
     }
     Type checkBase(Type t,
                    JCTree tree,
                    Env<AttrContext> env,
                    boolean classExpected,
-                   boolean interfaceOrArrayExpected,
+                   boolean interfacesOnlyExpected,
+                   boolean interfacesOrArraysExpected,
                    boolean checkExtensible) {
         if (t.isErroneous())
             return t;
-        if (t.hasTag(TYPEVAR) && !classExpected && !interfaceOrArrayExpected) {
+        if (t.hasTag(TYPEVAR) && !classExpected &&
+            !interfacesOrArraysExpected && !interfacesOnlyExpected) {
             // check that type variable is already visible
             if (t.getUpperBound() == null) {
                 log.error(tree.pos(), "illegal.forward.ref");
@@ -814,9 +816,14 @@
             t = chk.checkClassOrArrayType(tree.pos(), t,
                                           checkExtensible|!allowGenerics);
         }
-        if (interfaceOrArrayExpected &&
+        if (interfacesOnlyExpected && !t.tsym.isInterface()) {
+            log.error(tree.pos(), "intf.expected.here");
+            // return errType is necessary since otherwise there might
+            // be undetected cycles which cause attribution to loop
+            return types.createErrorType(t);
+        } else if (interfacesOrArraysExpected &&
             !(t.tsym.isInterface() || t.getTag() == ARRAY)) {
-            log.error(tree.pos(), "intf.expected.here");
+            log.error(tree.pos(), "intf.or.array.expected.here");
             // return errType is necessary since otherwise there might
             // be undetected cycles which cause attribution to loop
             return types.createErrorType(t);
@@ -3988,7 +3995,7 @@
         Set<Type> boundSet = new HashSet<Type>();
         if (bounds.nonEmpty()) {
             // accept class or interface or typevar as first bound.
-            bounds.head.type = checkBase(bounds.head.type, bounds.head, env, false, false, false);
+            bounds.head.type = checkBase(bounds.head.type, bounds.head, env, false, false, false, false);
             boundSet.add(types.erasure(bounds.head.type));
             if (bounds.head.type.isErroneous()) {
                 return bounds.head.type;
@@ -4004,7 +4011,7 @@
                 // if first bound was a class or interface, accept only interfaces
                 // as further bounds.
                 for (JCExpression bound : bounds.tail) {
-                    bound.type = checkBase(bound.type, bound, env, false, true, false);
+                    bound.type = checkBase(bound.type, bound, env, false, false, true, false);
                     if (bound.type.isErroneous()) {
                         bounds = List.of(bound);
                     }
--- a/src/share/classes/com/sun/tools/javac/comp/Check.java	Thu Oct 10 10:51:15 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Thu Oct 10 13:55:41 2013 -0400
@@ -3420,15 +3420,14 @@
                 sym.name != names.error &&
                 (!staticImport || !e.isStaticallyImported())) {
                 if (!e.sym.type.isErroneous()) {
-                    String what = e.sym.toString();
                     if (!isClassDecl) {
                         if (staticImport)
-                            log.error(pos, "already.defined.static.single.import", what);
+                            log.error(pos, "already.defined.static.single.import", e.sym);
                         else
-                        log.error(pos, "already.defined.single.import", what);
+                        log.error(pos, "already.defined.single.import", e.sym);
                     }
                     else if (sym != e.sym)
-                        log.error(pos, "already.defined.this.unit", what);
+                        log.error(pos, "already.defined.this.unit", e.sym);
                 }
                 return false;
             }
--- a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Thu Oct 10 10:51:15 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Thu Oct 10 13:55:41 2013 -0400
@@ -114,12 +114,15 @@
         deferredLintHandler = DeferredLintHandler.instance(context);
         lint = Lint.instance(context);
         allowTypeAnnos = source.allowTypeAnnotations();
+        allowRepeatedAnnos = source.allowRepeatedAnnotations();
     }
 
     /** Switch: support type annotations.
      */
     boolean allowTypeAnnos;
 
+    boolean allowRepeatedAnnos;
+
     /** A queue for classes whose members still need to be entered into the
      *  symbol table.
      */
@@ -906,14 +909,14 @@
             }
 
             if (annotated.containsKey(a.type.tsym)) {
-                if (source.allowRepeatedAnnotations()) {
-                    ListBuffer<Attribute.Compound> l = annotated.get(a.type.tsym);
-                    l = l.append(c);
-                    annotated.put(a.type.tsym, l);
-                    pos.put(c, a.pos());
-                } else {
-                    log.error(a.pos(), "duplicate.annotation");
+                if (!allowRepeatedAnnos) {
+                    log.error(a.pos(), "repeatable.annotations.not.supported.in.source");
+                    allowRepeatedAnnos = true;
                 }
+                ListBuffer<Attribute.Compound> l = annotated.get(a.type.tsym);
+                l = l.append(c);
+                annotated.put(a.type.tsym, l);
+                pos.put(c, a.pos());
             } else {
                 annotated.put(a.type.tsym, ListBuffer.of(c));
                 pos.put(c, a.pos());
@@ -1197,7 +1200,7 @@
                     annotated.put(a.type.tsym, l);
                     pos.put(tc, a.pos());
                 } else {
-                    log.error(a.pos(), "duplicate.annotation");
+                    log.error(a.pos(), "repeatable.annotations.not.supported.in.source");
                 }
             } else {
                 annotated.put(a.type.tsym, ListBuffer.of(tc));
--- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Thu Oct 10 10:51:15 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Thu Oct 10 13:55:41 2013 -0400
@@ -78,26 +78,26 @@
 
 # 0: string
 compiler.err.already.defined.single.import=\
-    {0} is already defined in a single-type import
+    a type with the same simple name is already defined by the single-type-import of {0}
 
 # 0: string
 compiler.err.already.defined.static.single.import=\
-    {0} is already defined in a static single-type import
+    a type with the same simple name is already defined by the static single-type-import of {0}
 
 compiler.err.already.defined.this.unit=\
     {0} is already defined in this compilation unit
 
 # 0: type, 1: list of name
 compiler.err.annotation.missing.default.value=\
-    annotation {0} is missing value for the attribute {1}
+    annotation @{0} is missing a default value for the element ''{1}''
 
 # 0: type, 1: list of name
 compiler.err.annotation.missing.default.value.1=\
-    annotation {0} is missing values for attributes {1}
+    annotation @{0} is missing default values for elements {1}
 
 # 0: type
 compiler.err.annotation.not.valid.for.type=\
-    annotation not valid for a value of type {0}
+    annotation not valid for an element of type {0}
 
 compiler.err.annotation.type.not.applicable=\
     annotation type not applicable to this kind of declaration
@@ -135,7 +135,7 @@
     array required, but {0} found
 
 compiler.err.attribute.value.must.be.constant=\
-    attribute value must be constant
+    element value must be a constant expression
 
 # 0: statement type
 compiler.err.bad.initializer=\
@@ -298,8 +298,9 @@
 compiler.err.cyclic.inheritance=\
     cyclic inheritance involving {0}
 
+# 0: symbol
 compiler.err.cyclic.annotation.element=\
-    cyclic annotation element type
+    type of element {0} is cyclic
 
 # 0: unused
 compiler.err.call.to.super.not.allowed.in.enum.ctor=\
@@ -307,73 +308,70 @@
 
 # 0: type
 compiler.err.no.superclass=\
-    {0} has no superclass
+    {0} has no superclass.
 
 # 0: symbol, 1: type, 2: symbol, 3: type, 4: unused
 compiler.err.concrete.inheritance.conflict=\
     methods {0} from {1} and {2} from {3} are inherited with the same signature
 
 compiler.err.default.allowed.in.intf.annotation.member=\
-    default value only allowed in an @interface member
+    default value only allowed in an annotation type declaration
 
 # 0: symbol
 compiler.err.doesnt.exist=\
     package {0} does not exist
 
-compiler.err.duplicate.annotation=\
-    duplicate annotation
-
 # 0: type
 compiler.err.duplicate.annotation.invalid.repeated=\
-    annotation {0} cannot be repeated\nIt does not define a valid containing annotation.
+    annotation {0} is not a valid repeatable annotation
 
 # 0: name, 1: type
 compiler.err.duplicate.annotation.member.value=\
-    duplicate annotation member value {0} in {1}
-
-# 0: type, 1: type
+    duplicate element ''{0}'' in annotation @{1}.
+
+# 0: name, 1: unused
 compiler.err.duplicate.annotation.missing.container=\
-    duplicate annotation: the declaration of {0} does not have a valid {1} annotation
-
-# 0: type
+    {0} is not a repeatable annotation type
+
+# 0: type, 1: unused
 compiler.err.invalid.repeatable.annotation=\
-    duplicate annotation: {0} is annotated with an invalid Repeatable annotation
+    duplicate annotation: {0} is annotated with an invalid @Repeatable annotation
 
 # 0: symbol or type
 compiler.err.invalid.repeatable.annotation.no.value=\
-    duplicate annotation: {0} is not a valid Repeatable, no value element method declared
+    {0} is not a valid @Repeatable, no value element method declared
 
 # 0: type, 1: number
 compiler.err.invalid.repeatable.annotation.multiple.values=\
-    duplicate annotation: {0} is not a valid Repeatable, {1} value element methods declared
+    {0} is not a valid @Repeatable, {1} element methods named ''value'' declared
 
 # 0: type
 compiler.err.invalid.repeatable.annotation.invalid.value=\
-    duplicate annotation: {0} is not a valid Repeatable: invalid value element
-
-# 0: symbol type, 1: type, 2: type
+    {0} is not a valid @Repeatable: invalid value element
+
+# 0: symbol type, 1: unused, 2: type
 compiler.err.invalid.repeatable.annotation.value.return=\
-    duplicate annotation: value element of containing annotation {0} should have type {2}, found {1}
+    containing annotation type ({0}) must declare an element named ''value'' of type {2}
 
 # 0: symbol or type, 1: symbol
 compiler.err.invalid.repeatable.annotation.elem.nondefault=\
-    containing annotation {0} does not have a default value for element {1}
-
-# 0: symbol, 1: type, 2: symbol, 3: type
+    containing annotation type ({0}) does not have a default value for element {1}
+
+# 0: symbol, 1: unused, 2: symbol, 3: unused
 compiler.err.invalid.repeatable.annotation.retention=\
-    containing annotation {0} has shorter retention ({1}) than the contained annotation {2} with retention {3}
+    retention of containing annotation type ({0}) is shorter than the retention of repeatable annotation type ({2})
 
 # 0: symbol, 1: symbol
 compiler.err.invalid.repeatable.annotation.not.documented=\
-    containing annotation type, {0}, is not @Documented while repeated annotation type, {1}, is
+    repeatable annotation type ({1}) is @Documented while containing annotation type ({0}) is not
 
 # 0: symbol, 1: symbol
 compiler.err.invalid.repeatable.annotation.not.inherited=\
-    containing annotation type, {0}, is not @Inherited while repeated annotation type, {1}, is
+    repeatable annotation type ({1}) is @Inherited while containing annotation type ({0}) is not
 
 # 0: symbol, 1: symbol
 compiler.err.invalid.repeatable.annotation.incompatible.target=\
-    target of container annotation {0} is not a subset of target of repeated annotation {1}
+    containing annotation type ({0}) is applicable to more targets than repeatable annotation type ({1})
 
 # 0: symbol
 compiler.err.invalid.repeatable.annotation.repeated.and.container.present=\
@@ -561,26 +559,31 @@
     integer number too large: {0}
 
 compiler.err.intf.annotation.members.cant.have.params=\
-    @interface members may not have parameters
-
+    elements in annotation type declarations cannot declare formal parameters
+
+# 0: symbol
 compiler.err.intf.annotation.cant.have.type.params=\
-    @interface may not have type parameters
+    annotation type {0} cannot be generic
 
 compiler.err.intf.annotation.members.cant.have.type.params=\
-    @interface members may not have type parameters
+    elements in annotation type declarations cannot be generic methods
 
 # 0: symbol, 1: type
 compiler.err.intf.annotation.member.clash=\
-    @interface member clashes with method ''{0}'' in {1}
+    annotation type {1} declares an element with the same name as method {0}
 
 compiler.err.intf.expected.here=\
     interface expected here
 
+compiler.err.intf.or.array.expected.here=\
+    interface or array type expected here
+
 compiler.err.intf.meth.cant.have.body=\
     interface abstract methods cannot have body
 
+# 0: symbol
 compiler.err.invalid.annotation.member.type=\
-    invalid type for annotation member
+    invalid type for element {0} of annotation type
 
 compiler.err.invalid.binary.number=\
     binary numbers must contain at least one binary digit
@@ -2310,8 +2313,13 @@
 (use -source 8 or higher to enable type annotations)
 
 # 0: string
+compiler.err.repeatable.annotations.not.supported.in.source=\
+    repeated annotations are not supported in -source {0}\n\
+(use -source 8 or higher to enable repeated annotations)
+
+# 0: string
 compiler.err.foreach.not.supported.in.source=\
-    for-each loops are not supported in -source {0}\n\
+    enhanced for loops are not supported in -source {0}\n\
     (use -source 5 or higher to enable for-each loops)
 
 # 0: string
--- a/test/tools/javac/diags/examples/DuplicateAnnotation.java	Thu Oct 10 10:51:15 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.duplicate.annotation
-// key: compiler.warn.source.no.bootclasspath
-// options: -source 7
-
-@interface Anno { }
-
-@Anno
-@Anno
-class DuplicateAnnotation { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/diags/examples/InterfaceOrArrayExpected.java	Thu Oct 10 13:55:41 2013 -0400
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.intf.or.array.expected.here
+
+import java.util.List;
+
+class InterfaceExpected<T extends List & String> { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/diags/examples/RepeatableAnnotationsNotSupported.java	Thu Oct 10 13:55:41 2013 -0400
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.repeatable.annotations.not.supported.in.source
+// key: compiler.warn.source.no.bootclasspath
+// options: -source 7
+
+@interface Anno { }
+
+@Anno
+@Anno
+class RepeatableAnnotationsNotSupported { }