src/share/classes/com/sun/tools/javac/comp/Check.java

changeset 1521
71f35e4b93a5
parent 1513
cf84b07a82db
child 1550
1df20330f6bd
child 1570
f91144b7da75
equal deleted inserted replaced
1520:5c956be64b9e 1521:71f35e4b93a5
24 */ 24 */
25 25
26 package com.sun.tools.javac.comp; 26 package com.sun.tools.javac.comp;
27 27
28 import java.util.*; 28 import java.util.*;
29 import java.util.Set; 29
30 import javax.tools.JavaFileManager; 30 import javax.tools.JavaFileManager;
31 31
32 import com.sun.tools.javac.code.*; 32 import com.sun.tools.javac.code.*;
33 import com.sun.tools.javac.jvm.*; 33 import com.sun.tools.javac.jvm.*;
34 import com.sun.tools.javac.tree.*; 34 import com.sun.tools.javac.tree.*;
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);
1322 log.error(tree.pos(), "cant.select.static.class.from.param.type"); 1318 log.error(tree.pos(), "cant.select.static.class.from.param.type");
1323 } else { 1319 } else {
1324 // otherwise validate the rest of the expression 1320 // otherwise validate the rest of the expression
1325 tree.selected.accept(this); 1321 tree.selected.accept(this);
1326 } 1322 }
1323 }
1324
1325 @Override
1326 public void visitAnnotatedType(JCAnnotatedType tree) {
1327 tree.underlyingType.accept(this);
1327 } 1328 }
1328 1329
1329 /** Default visitor method: do nothing. 1330 /** Default visitor method: do nothing.
1330 */ 1331 */
1331 @Override 1332 @Override
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
2609 } catch (Types.FunctionDescriptorLookupError ex) { 2617 } catch (Types.FunctionDescriptorLookupError ex) {
2610 log.error(a.pos(), "bad.functional.intf.anno.1", ex.getDiagnostic()); 2618 log.error(a.pos(), "bad.functional.intf.anno.1", ex.getDiagnostic());
2611 } 2619 }
2612 } 2620 }
2613 } 2621 }
2622 }
2623
2624 public void validateTypeAnnotation(JCAnnotation a, boolean isTypeParameter) {
2625 Assert.checkNonNull(a.type, "annotation tree hasn't been attributed yet: " + a);
2626 validateAnnotationTree(a);
2627
2628 if (!isTypeAnnotation(a, isTypeParameter))
2629 log.error(a.pos(), "annotation.type.not.applicable");
2614 } 2630 }
2615 2631
2616 /** 2632 /**
2617 * Validate the proposed container 'repeatable' on the 2633 * Validate the proposed container 'repeatable' on the
2618 * annotation type symbol 's'. Report errors at position 2634 * annotation type symbol 's'. Report errors at position
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

mercurial