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
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Thu Oct 10 10:51:15 2013 -0700
+++ b/langtools/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/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Thu Oct 10 10:51:15 2013 -0700
+++ b/langtools/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/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Thu Oct 10 10:51:15 2013 -0700
+++ b/langtools/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/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Thu Oct 10 10:51:15 2013 -0700
+++ b/langtools/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/langtools/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/langtools/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/langtools/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 { }