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

changeset 1570
f91144b7da75
parent 1569
475eb15dfdad
parent 1521
71f35e4b93a5
child 1571
af8417e590f4
     1.1 --- a/src/share/classes/com/sun/tools/javac/comp/Check.java	Mon Jan 21 01:27:42 2013 -0500
     1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Mon Feb 04 18:08:53 2013 -0500
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -26,7 +26,7 @@
    1.11  package com.sun.tools.javac.comp;
    1.12  
    1.13  import java.util.*;
    1.14 -import java.util.Set;
    1.15 +
    1.16  import javax.tools.JavaFileManager;
    1.17  
    1.18  import com.sun.tools.javac.code.*;
    1.19 @@ -36,7 +36,6 @@
    1.20  import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
    1.21  import com.sun.tools.javac.util.List;
    1.22  
    1.23 -import com.sun.tools.javac.tree.JCTree.*;
    1.24  import com.sun.tools.javac.code.Lint;
    1.25  import com.sun.tools.javac.code.Lint.LintCategory;
    1.26  import com.sun.tools.javac.code.Type.*;
    1.27 @@ -44,6 +43,8 @@
    1.28  import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
    1.29  import com.sun.tools.javac.comp.Infer.InferenceContext;
    1.30  import com.sun.tools.javac.comp.Infer.InferenceContext.FreeTypeListener;
    1.31 +import com.sun.tools.javac.tree.JCTree.*;
    1.32 +import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
    1.33  
    1.34  import static com.sun.tools.javac.code.Flags.*;
    1.35  import static com.sun.tools.javac.code.Flags.ANNOTATION;
    1.36 @@ -101,6 +102,9 @@
    1.37          context.put(checkKey, this);
    1.38  
    1.39          names = Names.instance(context);
    1.40 +        dfltTargetMeta = new Name[] { names.PACKAGE, names.TYPE,
    1.41 +            names.FIELD, names.METHOD, names.CONSTRUCTOR,
    1.42 +            names.ANNOTATION_TYPE, names.LOCAL_VARIABLE, names.PARAMETER};
    1.43          log = Log.instance(context);
    1.44          rs = Resolve.instance(context);
    1.45          syms = Symtab.instance(context);
    1.46 @@ -574,34 +578,27 @@
    1.47          if (!tree.type.isErroneous() &&
    1.48                  (env.info.lint == null || env.info.lint.isEnabled(Lint.LintCategory.CAST))
    1.49                  && types.isSameType(tree.expr.type, tree.clazz.type)
    1.50 +                && !(ignoreAnnotatedCasts && TreeInfo.containsTypeAnnotation(tree.clazz))
    1.51                  && !is292targetTypeCast(tree)) {
    1.52              log.warning(Lint.LintCategory.CAST,
    1.53                      tree.pos(), "redundant.cast", tree.expr.type);
    1.54          }
    1.55      }
    1.56      //where
    1.57 -            private boolean is292targetTypeCast(JCTypeCast tree) {
    1.58 -                boolean is292targetTypeCast = false;
    1.59 -                JCExpression expr = TreeInfo.skipParens(tree.expr);
    1.60 -                if (expr.hasTag(APPLY)) {
    1.61 -                    JCMethodInvocation apply = (JCMethodInvocation)expr;
    1.62 -                    Symbol sym = TreeInfo.symbol(apply.meth);
    1.63 -                    is292targetTypeCast = sym != null &&
    1.64 -                        sym.kind == MTH &&
    1.65 -                        (sym.flags() & HYPOTHETICAL) != 0;
    1.66 -                }
    1.67 -                return is292targetTypeCast;
    1.68 +        private boolean is292targetTypeCast(JCTypeCast tree) {
    1.69 +            boolean is292targetTypeCast = false;
    1.70 +            JCExpression expr = TreeInfo.skipParens(tree.expr);
    1.71 +            if (expr.hasTag(APPLY)) {
    1.72 +                JCMethodInvocation apply = (JCMethodInvocation)expr;
    1.73 +                Symbol sym = TreeInfo.symbol(apply.meth);
    1.74 +                is292targetTypeCast = sym != null &&
    1.75 +                    sym.kind == MTH &&
    1.76 +                    (sym.flags() & HYPOTHETICAL) != 0;
    1.77              }
    1.78 +            return is292targetTypeCast;
    1.79 +        }
    1.80  
    1.81 -
    1.82 -
    1.83 -//where
    1.84 -        /** Is type a type variable, or a (possibly multi-dimensional) array of
    1.85 -         *  type variables?
    1.86 -         */
    1.87 -        boolean isTypeVar(Type t) {
    1.88 -            return t.hasTag(TYPEVAR) || t.hasTag(ARRAY) && isTypeVar(types.elemtype(t));
    1.89 -        }
    1.90 +        private static final boolean ignoreAnnotatedCasts = true;
    1.91  
    1.92      /** Check that a type is within some bounds.
    1.93       *
    1.94 @@ -637,25 +634,40 @@
    1.95          }
    1.96      }
    1.97  
    1.98 +    Type checkClassOrArrayType(DiagnosticPosition pos, Type t) {
    1.99 +        if (!t.hasTag(CLASS) && !t.hasTag(ARRAY) && !t.hasTag(ERROR)) {
   1.100 +            return typeTagError(pos,
   1.101 +                                diags.fragment("type.req.class.array"),
   1.102 +                                asTypeParam(t));
   1.103 +        } else {
   1.104 +            return t;
   1.105 +        }
   1.106 +    }
   1.107 +
   1.108      /** Check that type is a class or interface type.
   1.109       *  @param pos           Position to be used for error reporting.
   1.110       *  @param t             The type to be checked.
   1.111       */
   1.112      Type checkClassType(DiagnosticPosition pos, Type t) {
   1.113 -        if (!t.hasTag(CLASS) && !t.hasTag(ERROR))
   1.114 +        if (!t.hasTag(CLASS) && !t.hasTag(ERROR)) {
   1.115              return typeTagError(pos,
   1.116                                  diags.fragment("type.req.class"),
   1.117 -                                (t.hasTag(TYPEVAR))
   1.118 -                                ? diags.fragment("type.parameter", t)
   1.119 -                                : t);
   1.120 -        else
   1.121 +                                asTypeParam(t));
   1.122 +        } else {
   1.123              return t;
   1.124 +        }
   1.125      }
   1.126 +    //where
   1.127 +        private Object asTypeParam(Type t) {
   1.128 +            return (t.hasTag(TYPEVAR))
   1.129 +                                    ? diags.fragment("type.parameter", t)
   1.130 +                                    : t;
   1.131 +        }
   1.132  
   1.133      /** Check that type is a valid qualifier for a constructor reference expression
   1.134       */
   1.135      Type checkConstructorRefType(DiagnosticPosition pos, Type t) {
   1.136 -        t = checkClassType(pos, t);
   1.137 +        t = checkClassOrArrayType(pos, t);
   1.138          if (t.hasTag(CLASS)) {
   1.139              if ((t.tsym.flags() & (ABSTRACT | INTERFACE)) != 0) {
   1.140                  log.error(pos, "abstract.cant.be.instantiated");
   1.141 @@ -693,11 +705,8 @@
   1.142       *  @param t             The type to be checked.
   1.143       */
   1.144      Type checkReifiableReferenceType(DiagnosticPosition pos, Type t) {
   1.145 -        if (!t.hasTag(CLASS) && !t.hasTag(ARRAY) && !t.hasTag(ERROR)) {
   1.146 -            return typeTagError(pos,
   1.147 -                                diags.fragment("type.req.class.array"),
   1.148 -                                t);
   1.149 -        } else if (!types.isReifiable(t)) {
   1.150 +        t = checkClassOrArrayType(pos, t);
   1.151 +        if (!t.isErroneous() && !types.isReifiable(t)) {
   1.152              log.error(pos, "illegal.generic.type.for.instof");
   1.153              return types.createErrorType(t);
   1.154          } else {
   1.155 @@ -843,7 +852,7 @@
   1.156          // System.out.println("actuals: " + argtypes);
   1.157          List<Type> formals = owntype.getParameterTypes();
   1.158          Type last = useVarargs ? formals.last() : null;
   1.159 -        if (sym.name==names.init &&
   1.160 +        if (sym.name == names.init &&
   1.161                  sym.owner == syms.enumSym)
   1.162                  formals = formals.tail.tail;
   1.163          List<JCExpression> args = argtrees;
   1.164 @@ -891,7 +900,6 @@
   1.165                     syms.methodClass);
   1.166          }
   1.167          if (useVarargs) {
   1.168 -            JCTree tree = env.tree;
   1.169              Type argtype = owntype.getParameterTypes().last();
   1.170              if (!types.isReifiable(argtype) &&
   1.171                      (!allowSimplifiedVarargs ||
   1.172 @@ -902,22 +910,13 @@
   1.173                                    argtype);
   1.174              }
   1.175              if (!((MethodSymbol)sym.baseSymbol()).isSignaturePolymorphic(types)) {
   1.176 -                Type elemtype = types.elemtype(argtype);
   1.177 -                switch (tree.getTag()) {
   1.178 -                    case APPLY:
   1.179 -                        ((JCMethodInvocation) tree).varargsElement = elemtype;
   1.180 -                        break;
   1.181 -                    case NEWCLASS:
   1.182 -                        ((JCNewClass) tree).varargsElement = elemtype;
   1.183 -                        break;
   1.184 -                    case REFERENCE:
   1.185 -                        ((JCMemberReference) tree).varargsElement = elemtype;
   1.186 -                        break;
   1.187 -                    default:
   1.188 -                        throw new AssertionError(""+tree);
   1.189 -                }
   1.190 +                TreeInfo.setVarargsElement(env.tree, types.elemtype(argtype));
   1.191              }
   1.192           }
   1.193 +         PolyKind pkind = (sym.type.hasTag(FORALL) &&
   1.194 +                 sym.type.getReturnType().containsAny(((ForAll)sym.type).tvars)) ?
   1.195 +                 PolyKind.POLY : PolyKind.STANDALONE;
   1.196 +         TreeInfo.setPolyKind(env.tree, pkind);
   1.197           return owntype;
   1.198      }
   1.199      //where
   1.200 @@ -1058,9 +1057,12 @@
   1.201                  } else
   1.202                      mask = ConstructorFlags;
   1.203              }  else if ((sym.owner.flags_field & INTERFACE) != 0) {
   1.204 -                if ((flags & DEFAULT) != 0) {
   1.205 -                    mask = InterfaceDefaultMethodMask;
   1.206 -                    implicit = PUBLIC | ABSTRACT;
   1.207 +                if ((flags & (DEFAULT | STATIC)) != 0) {
   1.208 +                    mask = InterfaceMethodMask;
   1.209 +                    implicit = PUBLIC;
   1.210 +                    if ((flags & DEFAULT) != 0) {
   1.211 +                        implicit |= ABSTRACT;
   1.212 +                    }
   1.213                  } else {
   1.214                      mask = implicit = InterfaceMethodFlags;
   1.215                  }
   1.216 @@ -1130,6 +1132,10 @@
   1.217                                  PRIVATE | STATIC | DEFAULT))
   1.218                   &&
   1.219                   checkDisjoint(pos, flags,
   1.220 +                                STATIC,
   1.221 +                                DEFAULT)
   1.222 +                 &&
   1.223 +                 checkDisjoint(pos, flags,
   1.224                                 ABSTRACT | INTERFACE,
   1.225                                 FINAL | NATIVE | SYNCHRONIZED)
   1.226                   &&
   1.227 @@ -1319,6 +1325,11 @@
   1.228              }
   1.229          }
   1.230  
   1.231 +        @Override
   1.232 +        public void visitAnnotatedType(JCAnnotatedType tree) {
   1.233 +            tree.underlyingType.accept(this);
   1.234 +        }
   1.235 +
   1.236          /** Default visitor method: do nothing.
   1.237           */
   1.238          @Override
   1.239 @@ -2239,7 +2250,7 @@
   1.240      void checkImplementations(JCClassDecl tree) {
   1.241          checkImplementations(tree, tree.sym, tree.sym);
   1.242      }
   1.243 -//where
   1.244 +    //where
   1.245          /** Check that all methods which implement some
   1.246           *  method in `ic' conform to the method they implement.
   1.247           */
   1.248 @@ -2580,6 +2591,13 @@
   1.249              validateAnnotation(a, s);
   1.250      }
   1.251  
   1.252 +    /** Check the type annotations.
   1.253 +     */
   1.254 +    public void validateTypeAnnotations(List<JCAnnotation> annotations, boolean isTypeParameter) {
   1.255 +        for (JCAnnotation a : annotations)
   1.256 +            validateTypeAnnotation(a, isTypeParameter);
   1.257 +    }
   1.258 +
   1.259      /** Check an annotation of a symbol.
   1.260       */
   1.261      private void validateAnnotation(JCAnnotation a, Symbol s) {
   1.262 @@ -2592,33 +2610,53 @@
   1.263              if (!isOverrider(s))
   1.264                  log.error(a.pos(), "method.does.not.override.superclass");
   1.265          }
   1.266 +
   1.267 +        if (a.annotationType.type.tsym == syms.functionalInterfaceType.tsym) {
   1.268 +            if (s.kind != TYP) {
   1.269 +                log.error(a.pos(), "bad.functional.intf.anno");
   1.270 +            } else {
   1.271 +                try {
   1.272 +                    types.findDescriptorSymbol((TypeSymbol)s);
   1.273 +                } catch (Types.FunctionDescriptorLookupError ex) {
   1.274 +                    log.error(a.pos(), "bad.functional.intf.anno.1", ex.getDiagnostic());
   1.275 +                }
   1.276 +            }
   1.277 +        }
   1.278 +    }
   1.279 +
   1.280 +    public void validateTypeAnnotation(JCAnnotation a, boolean isTypeParameter) {
   1.281 +        Assert.checkNonNull(a.type, "annotation tree hasn't been attributed yet: " + a);
   1.282 +        validateAnnotationTree(a);
   1.283 +
   1.284 +        if (!isTypeAnnotation(a, isTypeParameter))
   1.285 +            log.error(a.pos(), "annotation.type.not.applicable");
   1.286      }
   1.287  
   1.288      /**
   1.289 -     * Validate the proposed container 'containedBy' on the
   1.290 +     * Validate the proposed container 'repeatable' on the
   1.291       * annotation type symbol 's'. Report errors at position
   1.292       * 'pos'.
   1.293       *
   1.294 -     * @param s The (annotation)type declaration annotated with a @ContainedBy
   1.295 -     * @param containedBy the @ContainedBy on 's'
   1.296 +     * @param s The (annotation)type declaration annotated with a @Repeatable
   1.297 +     * @param repeatable the @Repeatable on 's'
   1.298       * @param pos where to report errors
   1.299       */
   1.300 -    public void validateContainedBy(TypeSymbol s, Attribute.Compound containedBy, DiagnosticPosition pos) {
   1.301 -        Assert.check(types.isSameType(containedBy.type, syms.containedByType));
   1.302 +    public void validateRepeatable(TypeSymbol s, Attribute.Compound repeatable, DiagnosticPosition pos) {
   1.303 +        Assert.check(types.isSameType(repeatable.type, syms.repeatableType));
   1.304  
   1.305          Type t = null;
   1.306 -        List<Pair<MethodSymbol,Attribute>> l = containedBy.values;
   1.307 +        List<Pair<MethodSymbol,Attribute>> l = repeatable.values;
   1.308          if (!l.isEmpty()) {
   1.309              Assert.check(l.head.fst.name == names.value);
   1.310              t = ((Attribute.Class)l.head.snd).getValue();
   1.311          }
   1.312  
   1.313          if (t == null) {
   1.314 -            log.error(pos, "invalid.container.wrong.containedby", s, containedBy);
   1.315 +            // errors should already have been reported during Annotate
   1.316              return;
   1.317          }
   1.318  
   1.319 -        validateHasContainerFor(t.tsym, s, pos);
   1.320 +        validateValue(t.tsym, s, pos);
   1.321          validateRetention(t.tsym, s, pos);
   1.322          validateDocumented(t.tsym, s, pos);
   1.323          validateInherited(t.tsym, s, pos);
   1.324 @@ -2626,79 +2664,18 @@
   1.325          validateDefault(t.tsym, s, pos);
   1.326      }
   1.327  
   1.328 -    /**
   1.329 -     * Validate the proposed container 'containerFor' on the
   1.330 -     * annotation type symbol 's'. Report errors at position
   1.331 -     * 'pos'.
   1.332 -     *
   1.333 -     * @param s The (annotation)type declaration annotated with a @ContainerFor
   1.334 -     * @param containerFor the @ContainedFor on 's'
   1.335 -     * @param pos where to report errors
   1.336 -     */
   1.337 -    public void validateContainerFor(TypeSymbol s, Attribute.Compound containerFor, DiagnosticPosition pos) {
   1.338 -        Assert.check(types.isSameType(containerFor.type, syms.containerForType));
   1.339 -
   1.340 -        Type t = null;
   1.341 -        List<Pair<MethodSymbol,Attribute>> l = containerFor.values;
   1.342 -        if (!l.isEmpty()) {
   1.343 -            Assert.check(l.head.fst.name == names.value);
   1.344 -            t = ((Attribute.Class)l.head.snd).getValue();
   1.345 +    private void validateValue(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
   1.346 +        Scope.Entry e = container.members().lookup(names.value);
   1.347 +        if (e.scope != null && e.sym.kind == MTH) {
   1.348 +            MethodSymbol m = (MethodSymbol) e.sym;
   1.349 +            Type ret = m.getReturnType();
   1.350 +            if (!(ret.hasTag(ARRAY) && types.isSameType(((ArrayType)ret).elemtype, contained.type))) {
   1.351 +                log.error(pos, "invalid.repeatable.annotation.value.return",
   1.352 +                        container, ret, types.makeArrayType(contained.type));
   1.353 +            }
   1.354 +        } else {
   1.355 +            log.error(pos, "invalid.repeatable.annotation.no.value", container);
   1.356          }
   1.357 -
   1.358 -        if (t == null) {
   1.359 -            log.error(pos, "invalid.container.wrong.containerfor", s, containerFor);
   1.360 -            return;
   1.361 -        }
   1.362 -
   1.363 -        validateHasContainedBy(t.tsym, s, pos);
   1.364 -    }
   1.365 -
   1.366 -    private void validateHasContainedBy(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
   1.367 -        Attribute.Compound containedBy = container.attribute(syms.containedByType.tsym);
   1.368 -
   1.369 -        if (containedBy == null) {
   1.370 -            log.error(pos, "invalid.container.no.containedby", container, syms.containedByType.tsym);
   1.371 -            return;
   1.372 -        }
   1.373 -
   1.374 -        Type t = null;
   1.375 -        List<Pair<MethodSymbol,Attribute>> l = containedBy.values;
   1.376 -        if (!l.isEmpty()) {
   1.377 -            Assert.check(l.head.fst.name == names.value);
   1.378 -            t = ((Attribute.Class)l.head.snd).getValue();
   1.379 -        }
   1.380 -
   1.381 -        if (t == null) {
   1.382 -            log.error(pos, "invalid.container.wrong.containedby", container, contained);
   1.383 -            return;
   1.384 -        }
   1.385 -
   1.386 -        if (!types.isSameType(t, contained.type))
   1.387 -            log.error(pos, "invalid.container.wrong.containedby", t.tsym, contained);
   1.388 -    }
   1.389 -
   1.390 -    private void validateHasContainerFor(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
   1.391 -        Attribute.Compound containerFor = container.attribute(syms.containerForType.tsym);
   1.392 -
   1.393 -        if (containerFor == null) {
   1.394 -            log.error(pos, "invalid.container.no.containerfor", container, syms.containerForType.tsym);
   1.395 -            return;
   1.396 -        }
   1.397 -
   1.398 -        Type t = null;
   1.399 -        List<Pair<MethodSymbol,Attribute>> l = containerFor.values;
   1.400 -        if (!l.isEmpty()) {
   1.401 -            Assert.check(l.head.fst.name == names.value);
   1.402 -            t = ((Attribute.Class)l.head.snd).getValue();
   1.403 -        }
   1.404 -
   1.405 -        if (t == null) {
   1.406 -            log.error(pos, "invalid.container.wrong.containerfor", container, contained);
   1.407 -            return;
   1.408 -        }
   1.409 -
   1.410 -        if (!types.isSameType(t, contained.type))
   1.411 -            log.error(pos, "invalid.container.wrong.containerfor", t.tsym, contained);
   1.412      }
   1.413  
   1.414      private void validateRetention(Symbol container, Symbol contained, DiagnosticPosition pos) {
   1.415 @@ -2718,7 +2695,7 @@
   1.416              }
   1.417          }
   1.418          if (error ) {
   1.419 -            log.error(pos, "invalid.containedby.annotation.retention",
   1.420 +            log.error(pos, "invalid.repeatable.annotation.retention",
   1.421                        container, containerRetention,
   1.422                        contained, containedRetention);
   1.423          }
   1.424 @@ -2727,7 +2704,7 @@
   1.425      private void validateDocumented(Symbol container, Symbol contained, DiagnosticPosition pos) {
   1.426          if (contained.attribute(syms.documentedType.tsym) != null) {
   1.427              if (container.attribute(syms.documentedType.tsym) == null) {
   1.428 -                log.error(pos, "invalid.containedby.annotation.not.documented", container, contained);
   1.429 +                log.error(pos, "invalid.repeatable.annotation.not.documented", container, contained);
   1.430              }
   1.431          }
   1.432      }
   1.433 @@ -2735,7 +2712,7 @@
   1.434      private void validateInherited(Symbol container, Symbol contained, DiagnosticPosition pos) {
   1.435          if (contained.attribute(syms.inheritedType.tsym) != null) {
   1.436              if (container.attribute(syms.inheritedType.tsym) == null) {
   1.437 -                log.error(pos, "invalid.containedby.annotation.not.inherited", container, contained);
   1.438 +                log.error(pos, "invalid.repeatable.annotation.not.inherited", container, contained);
   1.439              }
   1.440          }
   1.441      }
   1.442 @@ -2755,7 +2732,7 @@
   1.443          // contained has target, but container has not, error
   1.444          Attribute.Array containerTarget = getAttributeTargetAttribute(container);
   1.445          if (containerTarget == null) {
   1.446 -            log.error(pos, "invalid.containedby.annotation.incompatible.target", container, contained);
   1.447 +            log.error(pos, "invalid.repeatable.annotation.incompatible.target", container, contained);
   1.448              return;
   1.449          }
   1.450  
   1.451 @@ -2778,7 +2755,7 @@
   1.452          }
   1.453  
   1.454          if (!isTargetSubset(containedTargets, containerTargets)) {
   1.455 -            log.error(pos, "invalid.containedby.annotation.incompatible.target", container, contained);
   1.456 +            log.error(pos, "invalid.repeatable.annotation.incompatible.target", container, contained);
   1.457          }
   1.458      }
   1.459  
   1.460 @@ -2812,7 +2789,7 @@
   1.461                  elm.kind == Kinds.MTH &&
   1.462                  ((MethodSymbol)elm).defaultValue == null) {
   1.463                  log.error(pos,
   1.464 -                          "invalid.containedby.annotation.elem.nondefault",
   1.465 +                          "invalid.repeatable.annotation.elem.nondefault",
   1.466                            container,
   1.467                            elm);
   1.468              }
   1.469 @@ -2837,45 +2814,90 @@
   1.470          return false;
   1.471      }
   1.472  
   1.473 +    /** Is the annotation applicable to type annotations? */
   1.474 +    protected boolean isTypeAnnotation(JCAnnotation a, boolean isTypeParameter) {
   1.475 +        Attribute.Compound atTarget =
   1.476 +            a.annotationType.type.tsym.attribute(syms.annotationTargetType.tsym);
   1.477 +        if (atTarget == null) {
   1.478 +            // An annotation without @Target is not a type annotation.
   1.479 +            return false;
   1.480 +        }
   1.481 +
   1.482 +        Attribute atValue = atTarget.member(names.value);
   1.483 +        if (!(atValue instanceof Attribute.Array)) {
   1.484 +            return false; // error recovery
   1.485 +        }
   1.486 +
   1.487 +        Attribute.Array arr = (Attribute.Array) atValue;
   1.488 +        for (Attribute app : arr.values) {
   1.489 +            if (!(app instanceof Attribute.Enum)) {
   1.490 +                return false; // recovery
   1.491 +            }
   1.492 +            Attribute.Enum e = (Attribute.Enum) app;
   1.493 +
   1.494 +            if (e.value.name == names.TYPE_USE)
   1.495 +                return true;
   1.496 +            else if (isTypeParameter && e.value.name == names.TYPE_PARAMETER)
   1.497 +                return true;
   1.498 +        }
   1.499 +        return false;
   1.500 +    }
   1.501 +
   1.502      /** Is the annotation applicable to the symbol? */
   1.503      boolean annotationApplicable(JCAnnotation a, Symbol s) {
   1.504          Attribute.Array arr = getAttributeTargetAttribute(a.annotationType.type.tsym);
   1.505 +        Name[] targets;
   1.506 +
   1.507          if (arr == null) {
   1.508 -            return true;
   1.509 +            targets = defaultTargetMetaInfo(a, s);
   1.510 +        } else {
   1.511 +            // TODO: can we optimize this?
   1.512 +            targets = new Name[arr.values.length];
   1.513 +            for (int i=0; i<arr.values.length; ++i) {
   1.514 +                Attribute app = arr.values[i];
   1.515 +                if (!(app instanceof Attribute.Enum)) {
   1.516 +                    return true; // recovery
   1.517 +                }
   1.518 +                Attribute.Enum e = (Attribute.Enum) app;
   1.519 +                targets[i] = e.value.name;
   1.520 +            }
   1.521          }
   1.522 -        for (Attribute app : arr.values) {
   1.523 -            if (!(app instanceof Attribute.Enum)) return true; // recovery
   1.524 -            Attribute.Enum e = (Attribute.Enum) app;
   1.525 -            if (e.value.name == names.TYPE)
   1.526 +        for (Name target : targets) {
   1.527 +            if (target == names.TYPE)
   1.528                  { if (s.kind == TYP) return true; }
   1.529 -            else if (e.value.name == names.FIELD)
   1.530 +            else if (target == names.FIELD)
   1.531                  { if (s.kind == VAR && s.owner.kind != MTH) return true; }
   1.532 -            else if (e.value.name == names.METHOD)
   1.533 +            else if (target == names.METHOD)
   1.534                  { if (s.kind == MTH && !s.isConstructor()) return true; }
   1.535 -            else if (e.value.name == names.PARAMETER)
   1.536 +            else if (target == names.PARAMETER)
   1.537                  { if (s.kind == VAR &&
   1.538                        s.owner.kind == MTH &&
   1.539                        (s.flags() & PARAMETER) != 0)
   1.540                      return true;
   1.541                  }
   1.542 -            else if (e.value.name == names.CONSTRUCTOR)
   1.543 +            else if (target == names.CONSTRUCTOR)
   1.544                  { if (s.kind == MTH && s.isConstructor()) return true; }
   1.545 -            else if (e.value.name == names.LOCAL_VARIABLE)
   1.546 +            else if (target == names.LOCAL_VARIABLE)
   1.547                  { if (s.kind == VAR && s.owner.kind == MTH &&
   1.548                        (s.flags() & PARAMETER) == 0)
   1.549                      return true;
   1.550                  }
   1.551 -            else if (e.value.name == names.ANNOTATION_TYPE)
   1.552 +            else if (target == names.ANNOTATION_TYPE)
   1.553                  { if (s.kind == TYP && (s.flags() & ANNOTATION) != 0)
   1.554                      return true;
   1.555                  }
   1.556 -            else if (e.value.name == names.PACKAGE)
   1.557 +            else if (target == names.PACKAGE)
   1.558                  { if (s.kind == PCK) return true; }
   1.559 -            else if (e.value.name == names.TYPE_USE)
   1.560 +            else if (target == names.TYPE_USE)
   1.561                  { if (s.kind == TYP ||
   1.562                        s.kind == VAR ||
   1.563                        (s.kind == MTH && !s.isConstructor() &&
   1.564 -                       !s.type.getReturnType().hasTag(VOID)))
   1.565 +                      !s.type.getReturnType().hasTag(VOID)) ||
   1.566 +                      (s.kind == MTH && s.isConstructor()))
   1.567 +                    return true;
   1.568 +                }
   1.569 +            else if (target == names.TYPE_PARAMETER)
   1.570 +                { if (s.kind == TYP && s.type.hasTag(TYPEVAR))
   1.571                      return true;
   1.572                  }
   1.573              else
   1.574 @@ -2894,6 +2916,11 @@
   1.575          return (Attribute.Array) atValue;
   1.576      }
   1.577  
   1.578 +    private final Name[] dfltTargetMeta;
   1.579 +    private Name[] defaultTargetMetaInfo(JCAnnotation a, Symbol s) {
   1.580 +        return dfltTargetMeta;
   1.581 +    }
   1.582 +
   1.583      /** Check an annotation value.
   1.584       *
   1.585       * @param a The annotation tree to check

mercurial