99 |
99 |
100 protected Check(Context context) { |
100 protected Check(Context context) { |
101 context.put(checkKey, this); |
101 context.put(checkKey, this); |
102 |
102 |
103 names = Names.instance(context); |
103 names = Names.instance(context); |
|
104 dfltTargetMeta = new Name[] { names.PACKAGE, names.TYPE, |
|
105 names.FIELD, names.METHOD, names.CONSTRUCTOR, |
|
106 names.ANNOTATION_TYPE, names.LOCAL_VARIABLE, names.PARAMETER}; |
104 log = Log.instance(context); |
107 log = Log.instance(context); |
105 rs = Resolve.instance(context); |
108 rs = Resolve.instance(context); |
106 syms = Symtab.instance(context); |
109 syms = Symtab.instance(context); |
107 enter = Enter.instance(context); |
110 enter = Enter.instance(context); |
108 deferredAttr = DeferredAttr.instance(context); |
111 deferredAttr = DeferredAttr.instance(context); |
570 */ |
573 */ |
571 public void checkRedundantCast(Env<AttrContext> env, JCTypeCast tree) { |
574 public void checkRedundantCast(Env<AttrContext> env, JCTypeCast tree) { |
572 if (!tree.type.isErroneous() && |
575 if (!tree.type.isErroneous() && |
573 (env.info.lint == null || env.info.lint.isEnabled(Lint.LintCategory.CAST)) |
576 (env.info.lint == null || env.info.lint.isEnabled(Lint.LintCategory.CAST)) |
574 && types.isSameType(tree.expr.type, tree.clazz.type) |
577 && types.isSameType(tree.expr.type, tree.clazz.type) |
|
578 && !(ignoreAnnotatedCasts && TreeInfo.containsTypeAnnotation(tree.clazz)) |
575 && !is292targetTypeCast(tree)) { |
579 && !is292targetTypeCast(tree)) { |
576 log.warning(Lint.LintCategory.CAST, |
580 log.warning(Lint.LintCategory.CAST, |
577 tree.pos(), "redundant.cast", tree.expr.type); |
581 tree.pos(), "redundant.cast", tree.expr.type); |
578 } |
582 } |
579 } |
583 } |
580 //where |
584 //where |
581 private boolean is292targetTypeCast(JCTypeCast tree) { |
585 private boolean is292targetTypeCast(JCTypeCast tree) { |
582 boolean is292targetTypeCast = false; |
586 boolean is292targetTypeCast = false; |
583 JCExpression expr = TreeInfo.skipParens(tree.expr); |
587 JCExpression expr = TreeInfo.skipParens(tree.expr); |
584 if (expr.hasTag(APPLY)) { |
588 if (expr.hasTag(APPLY)) { |
585 JCMethodInvocation apply = (JCMethodInvocation)expr; |
589 JCMethodInvocation apply = (JCMethodInvocation)expr; |
586 Symbol sym = TreeInfo.symbol(apply.meth); |
590 Symbol sym = TreeInfo.symbol(apply.meth); |
587 is292targetTypeCast = sym != null && |
591 is292targetTypeCast = sym != null && |
588 sym.kind == MTH && |
592 sym.kind == MTH && |
589 (sym.flags() & HYPOTHETICAL) != 0; |
593 (sym.flags() & HYPOTHETICAL) != 0; |
590 } |
594 } |
591 return is292targetTypeCast; |
595 return is292targetTypeCast; |
592 } |
596 } |
593 |
597 |
594 |
598 private static final boolean ignoreAnnotatedCasts = true; |
595 |
|
596 //where |
|
597 /** Is type a type variable, or a (possibly multi-dimensional) array of |
|
598 * type variables? |
|
599 */ |
|
600 boolean isTypeVar(Type t) { |
|
601 return t.hasTag(TYPEVAR) || t.hasTag(ARRAY) && isTypeVar(types.elemtype(t)); |
|
602 } |
|
603 |
599 |
604 /** Check that a type is within some bounds. |
600 /** Check that a type is within some bounds. |
605 * |
601 * |
606 * Used in TypeApply to verify that, e.g., X in {@code V<X>} is a valid |
602 * Used in TypeApply to verify that, e.g., X in {@code V<X>} is a valid |
607 * type argument. |
603 * type argument. |
851 // System.out.println("call : " + env.tree); |
847 // System.out.println("call : " + env.tree); |
852 // System.out.println("method : " + owntype); |
848 // System.out.println("method : " + owntype); |
853 // System.out.println("actuals: " + argtypes); |
849 // System.out.println("actuals: " + argtypes); |
854 List<Type> formals = owntype.getParameterTypes(); |
850 List<Type> formals = owntype.getParameterTypes(); |
855 Type last = useVarargs ? formals.last() : null; |
851 Type last = useVarargs ? formals.last() : null; |
856 if (sym.name==names.init && |
852 if (sym.name == names.init && |
857 sym.owner == syms.enumSym) |
853 sym.owner == syms.enumSym) |
858 formals = formals.tail.tail; |
854 formals = formals.tail.tail; |
859 List<JCExpression> args = argtrees; |
855 List<JCExpression> args = argtrees; |
860 DeferredAttr.DeferredTypeMap checkDeferredMap = |
856 DeferredAttr.DeferredTypeMap checkDeferredMap = |
861 deferredAttr.new DeferredTypeMap(DeferredAttr.AttrMode.CHECK, sym, env.info.pendingResolutionPhase); |
857 deferredAttr.new DeferredTypeMap(DeferredAttr.AttrMode.CHECK, sym, env.info.pendingResolutionPhase); |
2244 * @param tree The class definition whose members are checked. |
2245 * @param tree The class definition whose members are checked. |
2245 */ |
2246 */ |
2246 void checkImplementations(JCClassDecl tree) { |
2247 void checkImplementations(JCClassDecl tree) { |
2247 checkImplementations(tree, tree.sym, tree.sym); |
2248 checkImplementations(tree, tree.sym, tree.sym); |
2248 } |
2249 } |
2249 //where |
2250 //where |
2250 /** Check that all methods which implement some |
2251 /** Check that all methods which implement some |
2251 * method in `ic' conform to the method they implement. |
2252 * method in `ic' conform to the method they implement. |
2252 */ |
2253 */ |
2253 void checkImplementations(JCTree tree, ClassSymbol origin, ClassSymbol ic) { |
2254 void checkImplementations(JCTree tree, ClassSymbol origin, ClassSymbol ic) { |
2254 for (List<Type> l = types.closure(ic.type); l.nonEmpty(); l = l.tail) { |
2255 for (List<Type> l = types.closure(ic.type); l.nonEmpty(); l = l.tail) { |
2585 public void validateAnnotations(List<JCAnnotation> annotations, Symbol s) { |
2586 public void validateAnnotations(List<JCAnnotation> annotations, Symbol s) { |
2586 for (JCAnnotation a : annotations) |
2587 for (JCAnnotation a : annotations) |
2587 validateAnnotation(a, s); |
2588 validateAnnotation(a, s); |
2588 } |
2589 } |
2589 |
2590 |
|
2591 /** Check the type annotations. |
|
2592 */ |
|
2593 public void validateTypeAnnotations(List<JCAnnotation> annotations, boolean isTypeParameter) { |
|
2594 for (JCAnnotation a : annotations) |
|
2595 validateTypeAnnotation(a, isTypeParameter); |
|
2596 } |
|
2597 |
2590 /** Check an annotation of a symbol. |
2598 /** Check an annotation of a symbol. |
2591 */ |
2599 */ |
2592 private void validateAnnotation(JCAnnotation a, Symbol s) { |
2600 private void validateAnnotation(JCAnnotation a, Symbol s) { |
2593 validateAnnotationTree(a); |
2601 validateAnnotationTree(a); |
2594 |
2602 |
2793 } |
2809 } |
2794 } |
2810 } |
2795 return false; |
2811 return false; |
2796 } |
2812 } |
2797 |
2813 |
|
2814 /** Is the annotation applicable to type annotations? */ |
|
2815 protected boolean isTypeAnnotation(JCAnnotation a, boolean isTypeParameter) { |
|
2816 Attribute.Compound atTarget = |
|
2817 a.annotationType.type.tsym.attribute(syms.annotationTargetType.tsym); |
|
2818 if (atTarget == null) { |
|
2819 // An annotation without @Target is not a type annotation. |
|
2820 return false; |
|
2821 } |
|
2822 |
|
2823 Attribute atValue = atTarget.member(names.value); |
|
2824 if (!(atValue instanceof Attribute.Array)) { |
|
2825 return false; // error recovery |
|
2826 } |
|
2827 |
|
2828 Attribute.Array arr = (Attribute.Array) atValue; |
|
2829 for (Attribute app : arr.values) { |
|
2830 if (!(app instanceof Attribute.Enum)) { |
|
2831 return false; // recovery |
|
2832 } |
|
2833 Attribute.Enum e = (Attribute.Enum) app; |
|
2834 |
|
2835 if (e.value.name == names.TYPE_USE) |
|
2836 return true; |
|
2837 else if (isTypeParameter && e.value.name == names.TYPE_PARAMETER) |
|
2838 return true; |
|
2839 } |
|
2840 return false; |
|
2841 } |
|
2842 |
2798 /** Is the annotation applicable to the symbol? */ |
2843 /** Is the annotation applicable to the symbol? */ |
2799 boolean annotationApplicable(JCAnnotation a, Symbol s) { |
2844 boolean annotationApplicable(JCAnnotation a, Symbol s) { |
2800 Attribute.Array arr = getAttributeTargetAttribute(a.annotationType.type.tsym); |
2845 Attribute.Array arr = getAttributeTargetAttribute(a.annotationType.type.tsym); |
|
2846 Name[] targets; |
|
2847 |
2801 if (arr == null) { |
2848 if (arr == null) { |
2802 return true; |
2849 targets = defaultTargetMetaInfo(a, s); |
2803 } |
2850 } else { |
2804 for (Attribute app : arr.values) { |
2851 // TODO: can we optimize this? |
2805 if (!(app instanceof Attribute.Enum)) return true; // recovery |
2852 targets = new Name[arr.values.length]; |
2806 Attribute.Enum e = (Attribute.Enum) app; |
2853 for (int i=0; i<arr.values.length; ++i) { |
2807 if (e.value.name == names.TYPE) |
2854 Attribute app = arr.values[i]; |
|
2855 if (!(app instanceof Attribute.Enum)) { |
|
2856 return true; // recovery |
|
2857 } |
|
2858 Attribute.Enum e = (Attribute.Enum) app; |
|
2859 targets[i] = e.value.name; |
|
2860 } |
|
2861 } |
|
2862 for (Name target : targets) { |
|
2863 if (target == names.TYPE) |
2808 { if (s.kind == TYP) return true; } |
2864 { if (s.kind == TYP) return true; } |
2809 else if (e.value.name == names.FIELD) |
2865 else if (target == names.FIELD) |
2810 { if (s.kind == VAR && s.owner.kind != MTH) return true; } |
2866 { if (s.kind == VAR && s.owner.kind != MTH) return true; } |
2811 else if (e.value.name == names.METHOD) |
2867 else if (target == names.METHOD) |
2812 { if (s.kind == MTH && !s.isConstructor()) return true; } |
2868 { if (s.kind == MTH && !s.isConstructor()) return true; } |
2813 else if (e.value.name == names.PARAMETER) |
2869 else if (target == names.PARAMETER) |
2814 { if (s.kind == VAR && |
2870 { if (s.kind == VAR && |
2815 s.owner.kind == MTH && |
2871 s.owner.kind == MTH && |
2816 (s.flags() & PARAMETER) != 0) |
2872 (s.flags() & PARAMETER) != 0) |
2817 return true; |
2873 return true; |
2818 } |
2874 } |
2819 else if (e.value.name == names.CONSTRUCTOR) |
2875 else if (target == names.CONSTRUCTOR) |
2820 { if (s.kind == MTH && s.isConstructor()) return true; } |
2876 { if (s.kind == MTH && s.isConstructor()) return true; } |
2821 else if (e.value.name == names.LOCAL_VARIABLE) |
2877 else if (target == names.LOCAL_VARIABLE) |
2822 { if (s.kind == VAR && s.owner.kind == MTH && |
2878 { if (s.kind == VAR && s.owner.kind == MTH && |
2823 (s.flags() & PARAMETER) == 0) |
2879 (s.flags() & PARAMETER) == 0) |
2824 return true; |
2880 return true; |
2825 } |
2881 } |
2826 else if (e.value.name == names.ANNOTATION_TYPE) |
2882 else if (target == names.ANNOTATION_TYPE) |
2827 { if (s.kind == TYP && (s.flags() & ANNOTATION) != 0) |
2883 { if (s.kind == TYP && (s.flags() & ANNOTATION) != 0) |
2828 return true; |
2884 return true; |
2829 } |
2885 } |
2830 else if (e.value.name == names.PACKAGE) |
2886 else if (target == names.PACKAGE) |
2831 { if (s.kind == PCK) return true; } |
2887 { if (s.kind == PCK) return true; } |
2832 else if (e.value.name == names.TYPE_USE) |
2888 else if (target == names.TYPE_USE) |
2833 { if (s.kind == TYP || |
2889 { if (s.kind == TYP || |
2834 s.kind == VAR || |
2890 s.kind == VAR || |
2835 (s.kind == MTH && !s.isConstructor() && |
2891 (s.kind == MTH && !s.isConstructor() && |
2836 !s.type.getReturnType().hasTag(VOID))) |
2892 !s.type.getReturnType().hasTag(VOID)) || |
|
2893 (s.kind == MTH && s.isConstructor())) |
|
2894 return true; |
|
2895 } |
|
2896 else if (target == names.TYPE_PARAMETER) |
|
2897 { if (s.kind == TYP && s.type.hasTag(TYPEVAR)) |
2837 return true; |
2898 return true; |
2838 } |
2899 } |
2839 else |
2900 else |
2840 return true; // recovery |
2901 return true; // recovery |
2841 } |
2902 } |
2848 s.attribute(syms.annotationTargetType.tsym); |
2909 s.attribute(syms.annotationTargetType.tsym); |
2849 if (atTarget == null) return null; // ok, is applicable |
2910 if (atTarget == null) return null; // ok, is applicable |
2850 Attribute atValue = atTarget.member(names.value); |
2911 Attribute atValue = atTarget.member(names.value); |
2851 if (!(atValue instanceof Attribute.Array)) return null; // error recovery |
2912 if (!(atValue instanceof Attribute.Array)) return null; // error recovery |
2852 return (Attribute.Array) atValue; |
2913 return (Attribute.Array) atValue; |
|
2914 } |
|
2915 |
|
2916 private final Name[] dfltTargetMeta; |
|
2917 private Name[] defaultTargetMetaInfo(JCAnnotation a, Symbol s) { |
|
2918 return dfltTargetMeta; |
2853 } |
2919 } |
2854 |
2920 |
2855 /** Check an annotation value. |
2921 /** Check an annotation value. |
2856 * |
2922 * |
2857 * @param a The annotation tree to check |
2923 * @param a The annotation tree to check |