# HG changeset patch # User emc # Date 1381427741 14400 # Node ID b35973e2d42eb229eb57e040698345574adc3ddc # Parent af0b915df7ccced708976bce8ca63d37685f0777 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 diff -r af0b915df7cc -r b35973e2d42e langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java --- 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 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 boundSet = new HashSet(); 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); } diff -r af0b915df7cc -r b35973e2d42e langtools/src/share/classes/com/sun/tools/javac/comp/Check.java --- 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; } diff -r af0b915df7cc -r b35973e2d42e langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java --- 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 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 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)); diff -r af0b915df7cc -r b35973e2d42e langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties --- 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 diff -r af0b915df7cc -r b35973e2d42e langtools/test/tools/javac/diags/examples/DuplicateAnnotation.java --- 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 { } diff -r af0b915df7cc -r b35973e2d42e langtools/test/tools/javac/diags/examples/InterfaceOrArrayExpected.java --- /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 { } diff -r af0b915df7cc -r b35973e2d42e langtools/test/tools/javac/diags/examples/RepeatableAnnotationsNotSupported.java --- /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 { }