1.1 --- a/src/share/classes/com/sun/tools/javac/comp/Check.java Wed Jan 23 20:57:40 2013 +0000 1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java Wed Jan 23 13:27:24 2013 -0800 1.3 @@ -26,7 +26,7 @@ 1.4 package com.sun.tools.javac.comp; 1.5 1.6 import java.util.*; 1.7 -import java.util.Set; 1.8 + 1.9 import javax.tools.JavaFileManager; 1.10 1.11 import com.sun.tools.javac.code.*; 1.12 @@ -101,6 +101,9 @@ 1.13 context.put(checkKey, this); 1.14 1.15 names = Names.instance(context); 1.16 + dfltTargetMeta = new Name[] { names.PACKAGE, names.TYPE, 1.17 + names.FIELD, names.METHOD, names.CONSTRUCTOR, 1.18 + names.ANNOTATION_TYPE, names.LOCAL_VARIABLE, names.PARAMETER}; 1.19 log = Log.instance(context); 1.20 rs = Resolve.instance(context); 1.21 syms = Symtab.instance(context); 1.22 @@ -572,34 +575,27 @@ 1.23 if (!tree.type.isErroneous() && 1.24 (env.info.lint == null || env.info.lint.isEnabled(Lint.LintCategory.CAST)) 1.25 && types.isSameType(tree.expr.type, tree.clazz.type) 1.26 + && !(ignoreAnnotatedCasts && TreeInfo.containsTypeAnnotation(tree.clazz)) 1.27 && !is292targetTypeCast(tree)) { 1.28 log.warning(Lint.LintCategory.CAST, 1.29 tree.pos(), "redundant.cast", tree.expr.type); 1.30 } 1.31 } 1.32 //where 1.33 - private boolean is292targetTypeCast(JCTypeCast tree) { 1.34 - boolean is292targetTypeCast = false; 1.35 - JCExpression expr = TreeInfo.skipParens(tree.expr); 1.36 - if (expr.hasTag(APPLY)) { 1.37 - JCMethodInvocation apply = (JCMethodInvocation)expr; 1.38 - Symbol sym = TreeInfo.symbol(apply.meth); 1.39 - is292targetTypeCast = sym != null && 1.40 - sym.kind == MTH && 1.41 - (sym.flags() & HYPOTHETICAL) != 0; 1.42 - } 1.43 - return is292targetTypeCast; 1.44 + private boolean is292targetTypeCast(JCTypeCast tree) { 1.45 + boolean is292targetTypeCast = false; 1.46 + JCExpression expr = TreeInfo.skipParens(tree.expr); 1.47 + if (expr.hasTag(APPLY)) { 1.48 + JCMethodInvocation apply = (JCMethodInvocation)expr; 1.49 + Symbol sym = TreeInfo.symbol(apply.meth); 1.50 + is292targetTypeCast = sym != null && 1.51 + sym.kind == MTH && 1.52 + (sym.flags() & HYPOTHETICAL) != 0; 1.53 } 1.54 + return is292targetTypeCast; 1.55 + } 1.56 1.57 - 1.58 - 1.59 -//where 1.60 - /** Is type a type variable, or a (possibly multi-dimensional) array of 1.61 - * type variables? 1.62 - */ 1.63 - boolean isTypeVar(Type t) { 1.64 - return t.hasTag(TYPEVAR) || t.hasTag(ARRAY) && isTypeVar(types.elemtype(t)); 1.65 - } 1.66 + private static final boolean ignoreAnnotatedCasts = true; 1.67 1.68 /** Check that a type is within some bounds. 1.69 * 1.70 @@ -853,7 +849,7 @@ 1.71 // System.out.println("actuals: " + argtypes); 1.72 List<Type> formals = owntype.getParameterTypes(); 1.73 Type last = useVarargs ? formals.last() : null; 1.74 - if (sym.name==names.init && 1.75 + if (sym.name == names.init && 1.76 sym.owner == syms.enumSym) 1.77 formals = formals.tail.tail; 1.78 List<JCExpression> args = argtrees; 1.79 @@ -1326,6 +1322,11 @@ 1.80 } 1.81 } 1.82 1.83 + @Override 1.84 + public void visitAnnotatedType(JCAnnotatedType tree) { 1.85 + tree.underlyingType.accept(this); 1.86 + } 1.87 + 1.88 /** Default visitor method: do nothing. 1.89 */ 1.90 @Override 1.91 @@ -2246,7 +2247,7 @@ 1.92 void checkImplementations(JCClassDecl tree) { 1.93 checkImplementations(tree, tree.sym, tree.sym); 1.94 } 1.95 -//where 1.96 + //where 1.97 /** Check that all methods which implement some 1.98 * method in `ic' conform to the method they implement. 1.99 */ 1.100 @@ -2587,6 +2588,13 @@ 1.101 validateAnnotation(a, s); 1.102 } 1.103 1.104 + /** Check the type annotations. 1.105 + */ 1.106 + public void validateTypeAnnotations(List<JCAnnotation> annotations, boolean isTypeParameter) { 1.107 + for (JCAnnotation a : annotations) 1.108 + validateTypeAnnotation(a, isTypeParameter); 1.109 + } 1.110 + 1.111 /** Check an annotation of a symbol. 1.112 */ 1.113 private void validateAnnotation(JCAnnotation a, Symbol s) { 1.114 @@ -2613,6 +2621,14 @@ 1.115 } 1.116 } 1.117 1.118 + public void validateTypeAnnotation(JCAnnotation a, boolean isTypeParameter) { 1.119 + Assert.checkNonNull(a.type, "annotation tree hasn't been attributed yet: " + a); 1.120 + validateAnnotationTree(a); 1.121 + 1.122 + if (!isTypeAnnotation(a, isTypeParameter)) 1.123 + log.error(a.pos(), "annotation.type.not.applicable"); 1.124 + } 1.125 + 1.126 /** 1.127 * Validate the proposed container 'repeatable' on the 1.128 * annotation type symbol 's'. Report errors at position 1.129 @@ -2795,45 +2811,90 @@ 1.130 return false; 1.131 } 1.132 1.133 + /** Is the annotation applicable to type annotations? */ 1.134 + protected boolean isTypeAnnotation(JCAnnotation a, boolean isTypeParameter) { 1.135 + Attribute.Compound atTarget = 1.136 + a.annotationType.type.tsym.attribute(syms.annotationTargetType.tsym); 1.137 + if (atTarget == null) { 1.138 + // An annotation without @Target is not a type annotation. 1.139 + return false; 1.140 + } 1.141 + 1.142 + Attribute atValue = atTarget.member(names.value); 1.143 + if (!(atValue instanceof Attribute.Array)) { 1.144 + return false; // error recovery 1.145 + } 1.146 + 1.147 + Attribute.Array arr = (Attribute.Array) atValue; 1.148 + for (Attribute app : arr.values) { 1.149 + if (!(app instanceof Attribute.Enum)) { 1.150 + return false; // recovery 1.151 + } 1.152 + Attribute.Enum e = (Attribute.Enum) app; 1.153 + 1.154 + if (e.value.name == names.TYPE_USE) 1.155 + return true; 1.156 + else if (isTypeParameter && e.value.name == names.TYPE_PARAMETER) 1.157 + return true; 1.158 + } 1.159 + return false; 1.160 + } 1.161 + 1.162 /** Is the annotation applicable to the symbol? */ 1.163 boolean annotationApplicable(JCAnnotation a, Symbol s) { 1.164 Attribute.Array arr = getAttributeTargetAttribute(a.annotationType.type.tsym); 1.165 + Name[] targets; 1.166 + 1.167 if (arr == null) { 1.168 - return true; 1.169 + targets = defaultTargetMetaInfo(a, s); 1.170 + } else { 1.171 + // TODO: can we optimize this? 1.172 + targets = new Name[arr.values.length]; 1.173 + for (int i=0; i<arr.values.length; ++i) { 1.174 + Attribute app = arr.values[i]; 1.175 + if (!(app instanceof Attribute.Enum)) { 1.176 + return true; // recovery 1.177 + } 1.178 + Attribute.Enum e = (Attribute.Enum) app; 1.179 + targets[i] = e.value.name; 1.180 + } 1.181 } 1.182 - for (Attribute app : arr.values) { 1.183 - if (!(app instanceof Attribute.Enum)) return true; // recovery 1.184 - Attribute.Enum e = (Attribute.Enum) app; 1.185 - if (e.value.name == names.TYPE) 1.186 + for (Name target : targets) { 1.187 + if (target == names.TYPE) 1.188 { if (s.kind == TYP) return true; } 1.189 - else if (e.value.name == names.FIELD) 1.190 + else if (target == names.FIELD) 1.191 { if (s.kind == VAR && s.owner.kind != MTH) return true; } 1.192 - else if (e.value.name == names.METHOD) 1.193 + else if (target == names.METHOD) 1.194 { if (s.kind == MTH && !s.isConstructor()) return true; } 1.195 - else if (e.value.name == names.PARAMETER) 1.196 + else if (target == names.PARAMETER) 1.197 { if (s.kind == VAR && 1.198 s.owner.kind == MTH && 1.199 (s.flags() & PARAMETER) != 0) 1.200 return true; 1.201 } 1.202 - else if (e.value.name == names.CONSTRUCTOR) 1.203 + else if (target == names.CONSTRUCTOR) 1.204 { if (s.kind == MTH && s.isConstructor()) return true; } 1.205 - else if (e.value.name == names.LOCAL_VARIABLE) 1.206 + else if (target == names.LOCAL_VARIABLE) 1.207 { if (s.kind == VAR && s.owner.kind == MTH && 1.208 (s.flags() & PARAMETER) == 0) 1.209 return true; 1.210 } 1.211 - else if (e.value.name == names.ANNOTATION_TYPE) 1.212 + else if (target == names.ANNOTATION_TYPE) 1.213 { if (s.kind == TYP && (s.flags() & ANNOTATION) != 0) 1.214 return true; 1.215 } 1.216 - else if (e.value.name == names.PACKAGE) 1.217 + else if (target == names.PACKAGE) 1.218 { if (s.kind == PCK) return true; } 1.219 - else if (e.value.name == names.TYPE_USE) 1.220 + else if (target == names.TYPE_USE) 1.221 { if (s.kind == TYP || 1.222 s.kind == VAR || 1.223 (s.kind == MTH && !s.isConstructor() && 1.224 - !s.type.getReturnType().hasTag(VOID))) 1.225 + !s.type.getReturnType().hasTag(VOID)) || 1.226 + (s.kind == MTH && s.isConstructor())) 1.227 + return true; 1.228 + } 1.229 + else if (target == names.TYPE_PARAMETER) 1.230 + { if (s.kind == TYP && s.type.hasTag(TYPEVAR)) 1.231 return true; 1.232 } 1.233 else 1.234 @@ -2852,6 +2913,11 @@ 1.235 return (Attribute.Array) atValue; 1.236 } 1.237 1.238 + private final Name[] dfltTargetMeta; 1.239 + private Name[] defaultTargetMetaInfo(JCAnnotation a, Symbol s) { 1.240 + return dfltTargetMeta; 1.241 + } 1.242 + 1.243 /** Check an annotation value. 1.244 * 1.245 * @param a The annotation tree to check