diff -r 5c956be64b9e -r 71f35e4b93a5 src/share/classes/com/sun/tools/javac/comp/Check.java --- a/src/share/classes/com/sun/tools/javac/comp/Check.java Wed Jan 23 20:57:40 2013 +0000 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java Wed Jan 23 13:27:24 2013 -0800 @@ -26,7 +26,7 @@ package com.sun.tools.javac.comp; import java.util.*; -import java.util.Set; + import javax.tools.JavaFileManager; import com.sun.tools.javac.code.*; @@ -101,6 +101,9 @@ context.put(checkKey, this); names = Names.instance(context); + dfltTargetMeta = new Name[] { names.PACKAGE, names.TYPE, + names.FIELD, names.METHOD, names.CONSTRUCTOR, + names.ANNOTATION_TYPE, names.LOCAL_VARIABLE, names.PARAMETER}; log = Log.instance(context); rs = Resolve.instance(context); syms = Symtab.instance(context); @@ -572,34 +575,27 @@ if (!tree.type.isErroneous() && (env.info.lint == null || env.info.lint.isEnabled(Lint.LintCategory.CAST)) && types.isSameType(tree.expr.type, tree.clazz.type) + && !(ignoreAnnotatedCasts && TreeInfo.containsTypeAnnotation(tree.clazz)) && !is292targetTypeCast(tree)) { log.warning(Lint.LintCategory.CAST, tree.pos(), "redundant.cast", tree.expr.type); } } //where - private boolean is292targetTypeCast(JCTypeCast tree) { - boolean is292targetTypeCast = false; - JCExpression expr = TreeInfo.skipParens(tree.expr); - if (expr.hasTag(APPLY)) { - JCMethodInvocation apply = (JCMethodInvocation)expr; - Symbol sym = TreeInfo.symbol(apply.meth); - is292targetTypeCast = sym != null && - sym.kind == MTH && - (sym.flags() & HYPOTHETICAL) != 0; - } - return is292targetTypeCast; + private boolean is292targetTypeCast(JCTypeCast tree) { + boolean is292targetTypeCast = false; + JCExpression expr = TreeInfo.skipParens(tree.expr); + if (expr.hasTag(APPLY)) { + JCMethodInvocation apply = (JCMethodInvocation)expr; + Symbol sym = TreeInfo.symbol(apply.meth); + is292targetTypeCast = sym != null && + sym.kind == MTH && + (sym.flags() & HYPOTHETICAL) != 0; } + return is292targetTypeCast; + } - - -//where - /** Is type a type variable, or a (possibly multi-dimensional) array of - * type variables? - */ - boolean isTypeVar(Type t) { - return t.hasTag(TYPEVAR) || t.hasTag(ARRAY) && isTypeVar(types.elemtype(t)); - } + private static final boolean ignoreAnnotatedCasts = true; /** Check that a type is within some bounds. * @@ -853,7 +849,7 @@ // System.out.println("actuals: " + argtypes); List formals = owntype.getParameterTypes(); Type last = useVarargs ? formals.last() : null; - if (sym.name==names.init && + if (sym.name == names.init && sym.owner == syms.enumSym) formals = formals.tail.tail; List args = argtrees; @@ -1326,6 +1322,11 @@ } } + @Override + public void visitAnnotatedType(JCAnnotatedType tree) { + tree.underlyingType.accept(this); + } + /** Default visitor method: do nothing. */ @Override @@ -2246,7 +2247,7 @@ void checkImplementations(JCClassDecl tree) { checkImplementations(tree, tree.sym, tree.sym); } -//where + //where /** Check that all methods which implement some * method in `ic' conform to the method they implement. */ @@ -2587,6 +2588,13 @@ validateAnnotation(a, s); } + /** Check the type annotations. + */ + public void validateTypeAnnotations(List annotations, boolean isTypeParameter) { + for (JCAnnotation a : annotations) + validateTypeAnnotation(a, isTypeParameter); + } + /** Check an annotation of a symbol. */ private void validateAnnotation(JCAnnotation a, Symbol s) { @@ -2613,6 +2621,14 @@ } } + public void validateTypeAnnotation(JCAnnotation a, boolean isTypeParameter) { + Assert.checkNonNull(a.type, "annotation tree hasn't been attributed yet: " + a); + validateAnnotationTree(a); + + if (!isTypeAnnotation(a, isTypeParameter)) + log.error(a.pos(), "annotation.type.not.applicable"); + } + /** * Validate the proposed container 'repeatable' on the * annotation type symbol 's'. Report errors at position @@ -2795,45 +2811,90 @@ return false; } + /** Is the annotation applicable to type annotations? */ + protected boolean isTypeAnnotation(JCAnnotation a, boolean isTypeParameter) { + Attribute.Compound atTarget = + a.annotationType.type.tsym.attribute(syms.annotationTargetType.tsym); + if (atTarget == null) { + // An annotation without @Target is not a type annotation. + return false; + } + + Attribute atValue = atTarget.member(names.value); + if (!(atValue instanceof Attribute.Array)) { + return false; // error recovery + } + + Attribute.Array arr = (Attribute.Array) atValue; + for (Attribute app : arr.values) { + if (!(app instanceof Attribute.Enum)) { + return false; // recovery + } + Attribute.Enum e = (Attribute.Enum) app; + + if (e.value.name == names.TYPE_USE) + return true; + else if (isTypeParameter && e.value.name == names.TYPE_PARAMETER) + return true; + } + return false; + } + /** Is the annotation applicable to the symbol? */ boolean annotationApplicable(JCAnnotation a, Symbol s) { Attribute.Array arr = getAttributeTargetAttribute(a.annotationType.type.tsym); + Name[] targets; + if (arr == null) { - return true; + targets = defaultTargetMetaInfo(a, s); + } else { + // TODO: can we optimize this? + targets = new Name[arr.values.length]; + for (int i=0; i