langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
changeset 15385 ee1eebe7e210
parent 15377 515846bb6637
child 15705 c4124695db0c
child 15725 e0516b913894
equal deleted inserted replaced
15384:5a8d00abf076 15385:ee1eebe7e210
    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