1.1 --- a/src/share/classes/com/sun/tools/javac/comp/Check.java Wed Dec 12 20:26:56 2012 +0100 1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java Mon Dec 03 11:16:32 2012 +0100 1.3 @@ -2892,39 +2892,54 @@ 1.4 } 1.5 1.6 /** Check an annotation value. 1.7 + * 1.8 + * @param a The annotation tree to check 1.9 + * @return true if this annotation tree is valid, otherwise false 1.10 */ 1.11 - public void validateAnnotation(JCAnnotation a) { 1.12 - // collect an inventory of the members (sorted alphabetically) 1.13 - Set<MethodSymbol> members = new TreeSet<MethodSymbol>(new Comparator<Symbol>() { 1.14 - public int compare(Symbol t, Symbol t1) { 1.15 - return t.name.compareTo(t1.name); 1.16 - } 1.17 - }); 1.18 + public boolean validateAnnotationDeferErrors(JCAnnotation a) { 1.19 + boolean res = false; 1.20 + final Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log); 1.21 + try { 1.22 + res = validateAnnotation(a); 1.23 + } finally { 1.24 + log.popDiagnosticHandler(diagHandler); 1.25 + } 1.26 + return res; 1.27 + } 1.28 + 1.29 + private boolean validateAnnotation(JCAnnotation a) { 1.30 + boolean isValid = true; 1.31 + // collect an inventory of the annotation elements 1.32 + Set<MethodSymbol> members = new LinkedHashSet<MethodSymbol>(); 1.33 for (Scope.Entry e = a.annotationType.type.tsym.members().elems; 1.34 e != null; 1.35 e = e.sibling) 1.36 if (e.sym.kind == MTH) 1.37 members.add((MethodSymbol) e.sym); 1.38 1.39 - // count them off as they're annotated 1.40 + // remove the ones that are assigned values 1.41 for (JCTree arg : a.args) { 1.42 if (!arg.hasTag(ASSIGN)) continue; // recovery 1.43 JCAssign assign = (JCAssign) arg; 1.44 Symbol m = TreeInfo.symbol(assign.lhs); 1.45 if (m == null || m.type.isErroneous()) continue; 1.46 - if (!members.remove(m)) 1.47 + if (!members.remove(m)) { 1.48 + isValid = false; 1.49 log.error(assign.lhs.pos(), "duplicate.annotation.member.value", 1.50 m.name, a.type); 1.51 + } 1.52 } 1.53 1.54 // all the remaining ones better have default values 1.55 - ListBuffer<Name> missingDefaults = ListBuffer.lb(); 1.56 + List<Name> missingDefaults = List.nil(); 1.57 for (MethodSymbol m : members) { 1.58 if (m.defaultValue == null && !m.type.isErroneous()) { 1.59 - missingDefaults.append(m.name); 1.60 + missingDefaults = missingDefaults.append(m.name); 1.61 } 1.62 } 1.63 + missingDefaults = missingDefaults.reverse(); 1.64 if (missingDefaults.nonEmpty()) { 1.65 + isValid = false; 1.66 String key = (missingDefaults.size() > 1) 1.67 ? "annotation.missing.default.value.1" 1.68 : "annotation.missing.default.value"; 1.69 @@ -2935,21 +2950,23 @@ 1.70 // repeated values in its value member 1.71 if (a.annotationType.type.tsym != syms.annotationTargetType.tsym || 1.72 a.args.tail == null) 1.73 - return; 1.74 + return isValid; 1.75 1.76 - if (!a.args.head.hasTag(ASSIGN)) return; // error recovery 1.77 + if (!a.args.head.hasTag(ASSIGN)) return false; // error recovery 1.78 JCAssign assign = (JCAssign) a.args.head; 1.79 Symbol m = TreeInfo.symbol(assign.lhs); 1.80 - if (m.name != names.value) return; 1.81 + if (m.name != names.value) return false; 1.82 JCTree rhs = assign.rhs; 1.83 - if (!rhs.hasTag(NEWARRAY)) return; 1.84 + if (!rhs.hasTag(NEWARRAY)) return false; 1.85 JCNewArray na = (JCNewArray) rhs; 1.86 Set<Symbol> targets = new HashSet<Symbol>(); 1.87 for (JCTree elem : na.elems) { 1.88 if (!targets.add(TreeInfo.symbol(elem))) { 1.89 + isValid = false; 1.90 log.error(elem.pos(), "repeated.annotation.target"); 1.91 } 1.92 } 1.93 + return isValid; 1.94 } 1.95 1.96 void checkDeprecatedAnnotation(DiagnosticPosition pos, Symbol s) {