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

changeset 1570
f91144b7da75
parent 1569
475eb15dfdad
parent 1521
71f35e4b93a5
child 1571
af8417e590f4
equal deleted inserted replaced
1569:475eb15dfdad 1570:f91144b7da75
1 /* 1 /*
2 * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this 7 * published by the Free Software Foundation. Oracle designates this
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.*;
35 import com.sun.tools.javac.util.*; 35 import com.sun.tools.javac.util.*;
36 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; 36 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
37 import com.sun.tools.javac.util.List; 37 import com.sun.tools.javac.util.List;
38 38
39 import com.sun.tools.javac.tree.JCTree.*;
40 import com.sun.tools.javac.code.Lint; 39 import com.sun.tools.javac.code.Lint;
41 import com.sun.tools.javac.code.Lint.LintCategory; 40 import com.sun.tools.javac.code.Lint.LintCategory;
42 import com.sun.tools.javac.code.Type.*; 41 import com.sun.tools.javac.code.Type.*;
43 import com.sun.tools.javac.code.Symbol.*; 42 import com.sun.tools.javac.code.Symbol.*;
44 import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext; 43 import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
45 import com.sun.tools.javac.comp.Infer.InferenceContext; 44 import com.sun.tools.javac.comp.Infer.InferenceContext;
46 import com.sun.tools.javac.comp.Infer.InferenceContext.FreeTypeListener; 45 import com.sun.tools.javac.comp.Infer.InferenceContext.FreeTypeListener;
46 import com.sun.tools.javac.tree.JCTree.*;
47 import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
47 48
48 import static com.sun.tools.javac.code.Flags.*; 49 import static com.sun.tools.javac.code.Flags.*;
49 import static com.sun.tools.javac.code.Flags.ANNOTATION; 50 import static com.sun.tools.javac.code.Flags.ANNOTATION;
50 import static com.sun.tools.javac.code.Flags.SYNCHRONIZED; 51 import static com.sun.tools.javac.code.Flags.SYNCHRONIZED;
51 import static com.sun.tools.javac.code.Kinds.*; 52 import static com.sun.tools.javac.code.Kinds.*;
99 100
100 protected Check(Context context) { 101 protected Check(Context context) {
101 context.put(checkKey, this); 102 context.put(checkKey, this);
102 103
103 names = Names.instance(context); 104 names = Names.instance(context);
105 dfltTargetMeta = new Name[] { names.PACKAGE, names.TYPE,
106 names.FIELD, names.METHOD, names.CONSTRUCTOR,
107 names.ANNOTATION_TYPE, names.LOCAL_VARIABLE, names.PARAMETER};
104 log = Log.instance(context); 108 log = Log.instance(context);
105 rs = Resolve.instance(context); 109 rs = Resolve.instance(context);
106 syms = Symtab.instance(context); 110 syms = Symtab.instance(context);
107 enter = Enter.instance(context); 111 enter = Enter.instance(context);
108 deferredAttr = DeferredAttr.instance(context); 112 deferredAttr = DeferredAttr.instance(context);
572 */ 576 */
573 public void checkRedundantCast(Env<AttrContext> env, JCTypeCast tree) { 577 public void checkRedundantCast(Env<AttrContext> env, JCTypeCast tree) {
574 if (!tree.type.isErroneous() && 578 if (!tree.type.isErroneous() &&
575 (env.info.lint == null || env.info.lint.isEnabled(Lint.LintCategory.CAST)) 579 (env.info.lint == null || env.info.lint.isEnabled(Lint.LintCategory.CAST))
576 && types.isSameType(tree.expr.type, tree.clazz.type) 580 && types.isSameType(tree.expr.type, tree.clazz.type)
581 && !(ignoreAnnotatedCasts && TreeInfo.containsTypeAnnotation(tree.clazz))
577 && !is292targetTypeCast(tree)) { 582 && !is292targetTypeCast(tree)) {
578 log.warning(Lint.LintCategory.CAST, 583 log.warning(Lint.LintCategory.CAST,
579 tree.pos(), "redundant.cast", tree.expr.type); 584 tree.pos(), "redundant.cast", tree.expr.type);
580 } 585 }
581 } 586 }
582 //where 587 //where
583 private boolean is292targetTypeCast(JCTypeCast tree) { 588 private boolean is292targetTypeCast(JCTypeCast tree) {
584 boolean is292targetTypeCast = false; 589 boolean is292targetTypeCast = false;
585 JCExpression expr = TreeInfo.skipParens(tree.expr); 590 JCExpression expr = TreeInfo.skipParens(tree.expr);
586 if (expr.hasTag(APPLY)) { 591 if (expr.hasTag(APPLY)) {
587 JCMethodInvocation apply = (JCMethodInvocation)expr; 592 JCMethodInvocation apply = (JCMethodInvocation)expr;
588 Symbol sym = TreeInfo.symbol(apply.meth); 593 Symbol sym = TreeInfo.symbol(apply.meth);
589 is292targetTypeCast = sym != null && 594 is292targetTypeCast = sym != null &&
590 sym.kind == MTH && 595 sym.kind == MTH &&
591 (sym.flags() & HYPOTHETICAL) != 0; 596 (sym.flags() & HYPOTHETICAL) != 0;
592 } 597 }
593 return is292targetTypeCast; 598 return is292targetTypeCast;
594 } 599 }
595 600
596 601 private static final boolean ignoreAnnotatedCasts = true;
597
598 //where
599 /** Is type a type variable, or a (possibly multi-dimensional) array of
600 * type variables?
601 */
602 boolean isTypeVar(Type t) {
603 return t.hasTag(TYPEVAR) || t.hasTag(ARRAY) && isTypeVar(types.elemtype(t));
604 }
605 602
606 /** Check that a type is within some bounds. 603 /** Check that a type is within some bounds.
607 * 604 *
608 * Used in TypeApply to verify that, e.g., X in {@code V<X>} is a valid 605 * Used in TypeApply to verify that, e.g., X in {@code V<X>} is a valid
609 * type argument. 606 * type argument.
635 } else { 632 } else {
636 return t; 633 return t;
637 } 634 }
638 } 635 }
639 636
637 Type checkClassOrArrayType(DiagnosticPosition pos, Type t) {
638 if (!t.hasTag(CLASS) && !t.hasTag(ARRAY) && !t.hasTag(ERROR)) {
639 return typeTagError(pos,
640 diags.fragment("type.req.class.array"),
641 asTypeParam(t));
642 } else {
643 return t;
644 }
645 }
646
640 /** Check that type is a class or interface type. 647 /** Check that type is a class or interface type.
641 * @param pos Position to be used for error reporting. 648 * @param pos Position to be used for error reporting.
642 * @param t The type to be checked. 649 * @param t The type to be checked.
643 */ 650 */
644 Type checkClassType(DiagnosticPosition pos, Type t) { 651 Type checkClassType(DiagnosticPosition pos, Type t) {
645 if (!t.hasTag(CLASS) && !t.hasTag(ERROR)) 652 if (!t.hasTag(CLASS) && !t.hasTag(ERROR)) {
646 return typeTagError(pos, 653 return typeTagError(pos,
647 diags.fragment("type.req.class"), 654 diags.fragment("type.req.class"),
648 (t.hasTag(TYPEVAR)) 655 asTypeParam(t));
649 ? diags.fragment("type.parameter", t) 656 } else {
650 : t);
651 else
652 return t; 657 return t;
653 } 658 }
659 }
660 //where
661 private Object asTypeParam(Type t) {
662 return (t.hasTag(TYPEVAR))
663 ? diags.fragment("type.parameter", t)
664 : t;
665 }
654 666
655 /** Check that type is a valid qualifier for a constructor reference expression 667 /** Check that type is a valid qualifier for a constructor reference expression
656 */ 668 */
657 Type checkConstructorRefType(DiagnosticPosition pos, Type t) { 669 Type checkConstructorRefType(DiagnosticPosition pos, Type t) {
658 t = checkClassType(pos, t); 670 t = checkClassOrArrayType(pos, t);
659 if (t.hasTag(CLASS)) { 671 if (t.hasTag(CLASS)) {
660 if ((t.tsym.flags() & (ABSTRACT | INTERFACE)) != 0) { 672 if ((t.tsym.flags() & (ABSTRACT | INTERFACE)) != 0) {
661 log.error(pos, "abstract.cant.be.instantiated"); 673 log.error(pos, "abstract.cant.be.instantiated");
662 t = types.createErrorType(t); 674 t = types.createErrorType(t);
663 } else if ((t.tsym.flags() & ENUM) != 0) { 675 } else if ((t.tsym.flags() & ENUM) != 0) {
691 /** Check that type is a reifiable class, interface or array type. 703 /** Check that type is a reifiable class, interface or array type.
692 * @param pos Position to be used for error reporting. 704 * @param pos Position to be used for error reporting.
693 * @param t The type to be checked. 705 * @param t The type to be checked.
694 */ 706 */
695 Type checkReifiableReferenceType(DiagnosticPosition pos, Type t) { 707 Type checkReifiableReferenceType(DiagnosticPosition pos, Type t) {
696 if (!t.hasTag(CLASS) && !t.hasTag(ARRAY) && !t.hasTag(ERROR)) { 708 t = checkClassOrArrayType(pos, t);
697 return typeTagError(pos, 709 if (!t.isErroneous() && !types.isReifiable(t)) {
698 diags.fragment("type.req.class.array"),
699 t);
700 } else if (!types.isReifiable(t)) {
701 log.error(pos, "illegal.generic.type.for.instof"); 710 log.error(pos, "illegal.generic.type.for.instof");
702 return types.createErrorType(t); 711 return types.createErrorType(t);
703 } else { 712 } else {
704 return t; 713 return t;
705 } 714 }
841 // System.out.println("call : " + env.tree); 850 // System.out.println("call : " + env.tree);
842 // System.out.println("method : " + owntype); 851 // System.out.println("method : " + owntype);
843 // System.out.println("actuals: " + argtypes); 852 // System.out.println("actuals: " + argtypes);
844 List<Type> formals = owntype.getParameterTypes(); 853 List<Type> formals = owntype.getParameterTypes();
845 Type last = useVarargs ? formals.last() : null; 854 Type last = useVarargs ? formals.last() : null;
846 if (sym.name==names.init && 855 if (sym.name == names.init &&
847 sym.owner == syms.enumSym) 856 sym.owner == syms.enumSym)
848 formals = formals.tail.tail; 857 formals = formals.tail.tail;
849 List<JCExpression> args = argtrees; 858 List<JCExpression> args = argtrees;
850 DeferredAttr.DeferredTypeMap checkDeferredMap = 859 DeferredAttr.DeferredTypeMap checkDeferredMap =
851 deferredAttr.new DeferredTypeMap(DeferredAttr.AttrMode.CHECK, sym, env.info.pendingResolutionPhase); 860 deferredAttr.new DeferredTypeMap(DeferredAttr.AttrMode.CHECK, sym, env.info.pendingResolutionPhase);
889 types.erasure(owntype.getReturnType()), 898 types.erasure(owntype.getReturnType()),
890 types.erasure(owntype.getThrownTypes()), 899 types.erasure(owntype.getThrownTypes()),
891 syms.methodClass); 900 syms.methodClass);
892 } 901 }
893 if (useVarargs) { 902 if (useVarargs) {
894 JCTree tree = env.tree;
895 Type argtype = owntype.getParameterTypes().last(); 903 Type argtype = owntype.getParameterTypes().last();
896 if (!types.isReifiable(argtype) && 904 if (!types.isReifiable(argtype) &&
897 (!allowSimplifiedVarargs || 905 (!allowSimplifiedVarargs ||
898 sym.attribute(syms.trustMeType.tsym) == null || 906 sym.attribute(syms.trustMeType.tsym) == null ||
899 !isTrustMeAllowedOnMethod(sym))) { 907 !isTrustMeAllowedOnMethod(sym))) {
900 warnUnchecked(env.tree.pos(), 908 warnUnchecked(env.tree.pos(),
901 "unchecked.generic.array.creation", 909 "unchecked.generic.array.creation",
902 argtype); 910 argtype);
903 } 911 }
904 if (!((MethodSymbol)sym.baseSymbol()).isSignaturePolymorphic(types)) { 912 if (!((MethodSymbol)sym.baseSymbol()).isSignaturePolymorphic(types)) {
905 Type elemtype = types.elemtype(argtype); 913 TreeInfo.setVarargsElement(env.tree, types.elemtype(argtype));
906 switch (tree.getTag()) {
907 case APPLY:
908 ((JCMethodInvocation) tree).varargsElement = elemtype;
909 break;
910 case NEWCLASS:
911 ((JCNewClass) tree).varargsElement = elemtype;
912 break;
913 case REFERENCE:
914 ((JCMemberReference) tree).varargsElement = elemtype;
915 break;
916 default:
917 throw new AssertionError(""+tree);
918 }
919 } 914 }
920 } 915 }
916 PolyKind pkind = (sym.type.hasTag(FORALL) &&
917 sym.type.getReturnType().containsAny(((ForAll)sym.type).tvars)) ?
918 PolyKind.POLY : PolyKind.STANDALONE;
919 TreeInfo.setPolyKind(env.tree, pkind);
921 return owntype; 920 return owntype;
922 } 921 }
923 //where 922 //where
924 private void assertConvertible(JCTree tree, Type actual, Type formal, Warner warn) { 923 private void assertConvertible(JCTree tree, Type actual, Type formal, Warner warn) {
925 if (types.isConvertible(actual, formal, warn)) 924 if (types.isConvertible(actual, formal, warn))
1056 implicit = PRIVATE; 1055 implicit = PRIVATE;
1057 mask = PRIVATE; 1056 mask = PRIVATE;
1058 } else 1057 } else
1059 mask = ConstructorFlags; 1058 mask = ConstructorFlags;
1060 } else if ((sym.owner.flags_field & INTERFACE) != 0) { 1059 } else if ((sym.owner.flags_field & INTERFACE) != 0) {
1061 if ((flags & DEFAULT) != 0) { 1060 if ((flags & (DEFAULT | STATIC)) != 0) {
1062 mask = InterfaceDefaultMethodMask; 1061 mask = InterfaceMethodMask;
1063 implicit = PUBLIC | ABSTRACT; 1062 implicit = PUBLIC;
1063 if ((flags & DEFAULT) != 0) {
1064 implicit |= ABSTRACT;
1065 }
1064 } else { 1066 } else {
1065 mask = implicit = InterfaceMethodFlags; 1067 mask = implicit = InterfaceMethodFlags;
1066 } 1068 }
1067 } 1069 }
1068 else { 1070 else {
1126 // ISSUE: Disallowing abstract&private is no longer appropriate 1128 // ISSUE: Disallowing abstract&private is no longer appropriate
1127 // in the presence of inner classes. Should it be deleted here? 1129 // in the presence of inner classes. Should it be deleted here?
1128 checkDisjoint(pos, flags, 1130 checkDisjoint(pos, flags,
1129 ABSTRACT, 1131 ABSTRACT,
1130 PRIVATE | STATIC | DEFAULT)) 1132 PRIVATE | STATIC | DEFAULT))
1133 &&
1134 checkDisjoint(pos, flags,
1135 STATIC,
1136 DEFAULT)
1131 && 1137 &&
1132 checkDisjoint(pos, flags, 1138 checkDisjoint(pos, flags,
1133 ABSTRACT | INTERFACE, 1139 ABSTRACT | INTERFACE,
1134 FINAL | NATIVE | SYNCHRONIZED) 1140 FINAL | NATIVE | SYNCHRONIZED)
1135 && 1141 &&
1315 log.error(tree.pos(), "cant.select.static.class.from.param.type"); 1321 log.error(tree.pos(), "cant.select.static.class.from.param.type");
1316 } else { 1322 } else {
1317 // otherwise validate the rest of the expression 1323 // otherwise validate the rest of the expression
1318 tree.selected.accept(this); 1324 tree.selected.accept(this);
1319 } 1325 }
1326 }
1327
1328 @Override
1329 public void visitAnnotatedType(JCAnnotatedType tree) {
1330 tree.underlyingType.accept(this);
1320 } 1331 }
1321 1332
1322 /** Default visitor method: do nothing. 1333 /** Default visitor method: do nothing.
1323 */ 1334 */
1324 @Override 1335 @Override
2237 * @param tree The class definition whose members are checked. 2248 * @param tree The class definition whose members are checked.
2238 */ 2249 */
2239 void checkImplementations(JCClassDecl tree) { 2250 void checkImplementations(JCClassDecl tree) {
2240 checkImplementations(tree, tree.sym, tree.sym); 2251 checkImplementations(tree, tree.sym, tree.sym);
2241 } 2252 }
2242 //where 2253 //where
2243 /** Check that all methods which implement some 2254 /** Check that all methods which implement some
2244 * method in `ic' conform to the method they implement. 2255 * method in `ic' conform to the method they implement.
2245 */ 2256 */
2246 void checkImplementations(JCTree tree, ClassSymbol origin, ClassSymbol ic) { 2257 void checkImplementations(JCTree tree, ClassSymbol origin, ClassSymbol ic) {
2247 for (List<Type> l = types.closure(ic.type); l.nonEmpty(); l = l.tail) { 2258 for (List<Type> l = types.closure(ic.type); l.nonEmpty(); l = l.tail) {
2578 public void validateAnnotations(List<JCAnnotation> annotations, Symbol s) { 2589 public void validateAnnotations(List<JCAnnotation> annotations, Symbol s) {
2579 for (JCAnnotation a : annotations) 2590 for (JCAnnotation a : annotations)
2580 validateAnnotation(a, s); 2591 validateAnnotation(a, s);
2581 } 2592 }
2582 2593
2594 /** Check the type annotations.
2595 */
2596 public void validateTypeAnnotations(List<JCAnnotation> annotations, boolean isTypeParameter) {
2597 for (JCAnnotation a : annotations)
2598 validateTypeAnnotation(a, isTypeParameter);
2599 }
2600
2583 /** Check an annotation of a symbol. 2601 /** Check an annotation of a symbol.
2584 */ 2602 */
2585 private void validateAnnotation(JCAnnotation a, Symbol s) { 2603 private void validateAnnotation(JCAnnotation a, Symbol s) {
2586 validateAnnotationTree(a); 2604 validateAnnotationTree(a);
2587 2605
2590 2608
2591 if (a.annotationType.type.tsym == syms.overrideType.tsym) { 2609 if (a.annotationType.type.tsym == syms.overrideType.tsym) {
2592 if (!isOverrider(s)) 2610 if (!isOverrider(s))
2593 log.error(a.pos(), "method.does.not.override.superclass"); 2611 log.error(a.pos(), "method.does.not.override.superclass");
2594 } 2612 }
2613
2614 if (a.annotationType.type.tsym == syms.functionalInterfaceType.tsym) {
2615 if (s.kind != TYP) {
2616 log.error(a.pos(), "bad.functional.intf.anno");
2617 } else {
2618 try {
2619 types.findDescriptorSymbol((TypeSymbol)s);
2620 } catch (Types.FunctionDescriptorLookupError ex) {
2621 log.error(a.pos(), "bad.functional.intf.anno.1", ex.getDiagnostic());
2622 }
2623 }
2624 }
2625 }
2626
2627 public void validateTypeAnnotation(JCAnnotation a, boolean isTypeParameter) {
2628 Assert.checkNonNull(a.type, "annotation tree hasn't been attributed yet: " + a);
2629 validateAnnotationTree(a);
2630
2631 if (!isTypeAnnotation(a, isTypeParameter))
2632 log.error(a.pos(), "annotation.type.not.applicable");
2595 } 2633 }
2596 2634
2597 /** 2635 /**
2598 * Validate the proposed container 'containedBy' on the 2636 * Validate the proposed container 'repeatable' on the
2599 * annotation type symbol 's'. Report errors at position 2637 * annotation type symbol 's'. Report errors at position
2600 * 'pos'. 2638 * 'pos'.
2601 * 2639 *
2602 * @param s The (annotation)type declaration annotated with a @ContainedBy 2640 * @param s The (annotation)type declaration annotated with a @Repeatable
2603 * @param containedBy the @ContainedBy on 's' 2641 * @param repeatable the @Repeatable on 's'
2604 * @param pos where to report errors 2642 * @param pos where to report errors
2605 */ 2643 */
2606 public void validateContainedBy(TypeSymbol s, Attribute.Compound containedBy, DiagnosticPosition pos) { 2644 public void validateRepeatable(TypeSymbol s, Attribute.Compound repeatable, DiagnosticPosition pos) {
2607 Assert.check(types.isSameType(containedBy.type, syms.containedByType)); 2645 Assert.check(types.isSameType(repeatable.type, syms.repeatableType));
2608 2646
2609 Type t = null; 2647 Type t = null;
2610 List<Pair<MethodSymbol,Attribute>> l = containedBy.values; 2648 List<Pair<MethodSymbol,Attribute>> l = repeatable.values;
2611 if (!l.isEmpty()) { 2649 if (!l.isEmpty()) {
2612 Assert.check(l.head.fst.name == names.value); 2650 Assert.check(l.head.fst.name == names.value);
2613 t = ((Attribute.Class)l.head.snd).getValue(); 2651 t = ((Attribute.Class)l.head.snd).getValue();
2614 } 2652 }
2615 2653
2616 if (t == null) { 2654 if (t == null) {
2617 log.error(pos, "invalid.container.wrong.containedby", s, containedBy); 2655 // errors should already have been reported during Annotate
2618 return; 2656 return;
2619 } 2657 }
2620 2658
2621 validateHasContainerFor(t.tsym, s, pos); 2659 validateValue(t.tsym, s, pos);
2622 validateRetention(t.tsym, s, pos); 2660 validateRetention(t.tsym, s, pos);
2623 validateDocumented(t.tsym, s, pos); 2661 validateDocumented(t.tsym, s, pos);
2624 validateInherited(t.tsym, s, pos); 2662 validateInherited(t.tsym, s, pos);
2625 validateTarget(t.tsym, s, pos); 2663 validateTarget(t.tsym, s, pos);
2626 validateDefault(t.tsym, s, pos); 2664 validateDefault(t.tsym, s, pos);
2627 } 2665 }
2628 2666
2629 /** 2667 private void validateValue(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
2630 * Validate the proposed container 'containerFor' on the 2668 Scope.Entry e = container.members().lookup(names.value);
2631 * annotation type symbol 's'. Report errors at position 2669 if (e.scope != null && e.sym.kind == MTH) {
2632 * 'pos'. 2670 MethodSymbol m = (MethodSymbol) e.sym;
2633 * 2671 Type ret = m.getReturnType();
2634 * @param s The (annotation)type declaration annotated with a @ContainerFor 2672 if (!(ret.hasTag(ARRAY) && types.isSameType(((ArrayType)ret).elemtype, contained.type))) {
2635 * @param containerFor the @ContainedFor on 's' 2673 log.error(pos, "invalid.repeatable.annotation.value.return",
2636 * @param pos where to report errors 2674 container, ret, types.makeArrayType(contained.type));
2637 */ 2675 }
2638 public void validateContainerFor(TypeSymbol s, Attribute.Compound containerFor, DiagnosticPosition pos) { 2676 } else {
2639 Assert.check(types.isSameType(containerFor.type, syms.containerForType)); 2677 log.error(pos, "invalid.repeatable.annotation.no.value", container);
2640 2678 }
2641 Type t = null;
2642 List<Pair<MethodSymbol,Attribute>> l = containerFor.values;
2643 if (!l.isEmpty()) {
2644 Assert.check(l.head.fst.name == names.value);
2645 t = ((Attribute.Class)l.head.snd).getValue();
2646 }
2647
2648 if (t == null) {
2649 log.error(pos, "invalid.container.wrong.containerfor", s, containerFor);
2650 return;
2651 }
2652
2653 validateHasContainedBy(t.tsym, s, pos);
2654 }
2655
2656 private void validateHasContainedBy(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
2657 Attribute.Compound containedBy = container.attribute(syms.containedByType.tsym);
2658
2659 if (containedBy == null) {
2660 log.error(pos, "invalid.container.no.containedby", container, syms.containedByType.tsym);
2661 return;
2662 }
2663
2664 Type t = null;
2665 List<Pair<MethodSymbol,Attribute>> l = containedBy.values;
2666 if (!l.isEmpty()) {
2667 Assert.check(l.head.fst.name == names.value);
2668 t = ((Attribute.Class)l.head.snd).getValue();
2669 }
2670
2671 if (t == null) {
2672 log.error(pos, "invalid.container.wrong.containedby", container, contained);
2673 return;
2674 }
2675
2676 if (!types.isSameType(t, contained.type))
2677 log.error(pos, "invalid.container.wrong.containedby", t.tsym, contained);
2678 }
2679
2680 private void validateHasContainerFor(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
2681 Attribute.Compound containerFor = container.attribute(syms.containerForType.tsym);
2682
2683 if (containerFor == null) {
2684 log.error(pos, "invalid.container.no.containerfor", container, syms.containerForType.tsym);
2685 return;
2686 }
2687
2688 Type t = null;
2689 List<Pair<MethodSymbol,Attribute>> l = containerFor.values;
2690 if (!l.isEmpty()) {
2691 Assert.check(l.head.fst.name == names.value);
2692 t = ((Attribute.Class)l.head.snd).getValue();
2693 }
2694
2695 if (t == null) {
2696 log.error(pos, "invalid.container.wrong.containerfor", container, contained);
2697 return;
2698 }
2699
2700 if (!types.isSameType(t, contained.type))
2701 log.error(pos, "invalid.container.wrong.containerfor", t.tsym, contained);
2702 } 2679 }
2703 2680
2704 private void validateRetention(Symbol container, Symbol contained, DiagnosticPosition pos) { 2681 private void validateRetention(Symbol container, Symbol contained, DiagnosticPosition pos) {
2705 Attribute.RetentionPolicy containerRetention = types.getRetention(container); 2682 Attribute.RetentionPolicy containerRetention = types.getRetention(container);
2706 Attribute.RetentionPolicy containedRetention = types.getRetention(contained); 2683 Attribute.RetentionPolicy containedRetention = types.getRetention(contained);
2716 if (containerRetention == Attribute.RetentionPolicy.SOURCE) { 2693 if (containerRetention == Attribute.RetentionPolicy.SOURCE) {
2717 error = true; 2694 error = true;
2718 } 2695 }
2719 } 2696 }
2720 if (error ) { 2697 if (error ) {
2721 log.error(pos, "invalid.containedby.annotation.retention", 2698 log.error(pos, "invalid.repeatable.annotation.retention",
2722 container, containerRetention, 2699 container, containerRetention,
2723 contained, containedRetention); 2700 contained, containedRetention);
2724 } 2701 }
2725 } 2702 }
2726 2703
2727 private void validateDocumented(Symbol container, Symbol contained, DiagnosticPosition pos) { 2704 private void validateDocumented(Symbol container, Symbol contained, DiagnosticPosition pos) {
2728 if (contained.attribute(syms.documentedType.tsym) != null) { 2705 if (contained.attribute(syms.documentedType.tsym) != null) {
2729 if (container.attribute(syms.documentedType.tsym) == null) { 2706 if (container.attribute(syms.documentedType.tsym) == null) {
2730 log.error(pos, "invalid.containedby.annotation.not.documented", container, contained); 2707 log.error(pos, "invalid.repeatable.annotation.not.documented", container, contained);
2731 } 2708 }
2732 } 2709 }
2733 } 2710 }
2734 2711
2735 private void validateInherited(Symbol container, Symbol contained, DiagnosticPosition pos) { 2712 private void validateInherited(Symbol container, Symbol contained, DiagnosticPosition pos) {
2736 if (contained.attribute(syms.inheritedType.tsym) != null) { 2713 if (contained.attribute(syms.inheritedType.tsym) != null) {
2737 if (container.attribute(syms.inheritedType.tsym) == null) { 2714 if (container.attribute(syms.inheritedType.tsym) == null) {
2738 log.error(pos, "invalid.containedby.annotation.not.inherited", container, contained); 2715 log.error(pos, "invalid.repeatable.annotation.not.inherited", container, contained);
2739 } 2716 }
2740 } 2717 }
2741 } 2718 }
2742 2719
2743 private void validateTarget(Symbol container, Symbol contained, DiagnosticPosition pos) { 2720 private void validateTarget(Symbol container, Symbol contained, DiagnosticPosition pos) {
2753 // trivially true if contained has no target as per above). 2730 // trivially true if contained has no target as per above).
2754 2731
2755 // contained has target, but container has not, error 2732 // contained has target, but container has not, error
2756 Attribute.Array containerTarget = getAttributeTargetAttribute(container); 2733 Attribute.Array containerTarget = getAttributeTargetAttribute(container);
2757 if (containerTarget == null) { 2734 if (containerTarget == null) {
2758 log.error(pos, "invalid.containedby.annotation.incompatible.target", container, contained); 2735 log.error(pos, "invalid.repeatable.annotation.incompatible.target", container, contained);
2759 return; 2736 return;
2760 } 2737 }
2761 2738
2762 Set<Name> containerTargets = new HashSet<Name>(); 2739 Set<Name> containerTargets = new HashSet<Name>();
2763 for (Attribute app : containerTarget.values) { 2740 for (Attribute app : containerTarget.values) {
2776 Attribute.Enum e = (Attribute.Enum)app; 2753 Attribute.Enum e = (Attribute.Enum)app;
2777 containedTargets.add(e.value.name); 2754 containedTargets.add(e.value.name);
2778 } 2755 }
2779 2756
2780 if (!isTargetSubset(containedTargets, containerTargets)) { 2757 if (!isTargetSubset(containedTargets, containerTargets)) {
2781 log.error(pos, "invalid.containedby.annotation.incompatible.target", container, contained); 2758 log.error(pos, "invalid.repeatable.annotation.incompatible.target", container, contained);
2782 } 2759 }
2783 } 2760 }
2784 2761
2785 /** Checks that t is a subset of s, with respect to ElementType 2762 /** Checks that t is a subset of s, with respect to ElementType
2786 * semantics, specifically {ANNOTATION_TYPE} is a subset of {TYPE} 2763 * semantics, specifically {ANNOTATION_TYPE} is a subset of {TYPE}
2810 for(Symbol elm : scope.getElements()) { 2787 for(Symbol elm : scope.getElements()) {
2811 if (elm.name != names.value && 2788 if (elm.name != names.value &&
2812 elm.kind == Kinds.MTH && 2789 elm.kind == Kinds.MTH &&
2813 ((MethodSymbol)elm).defaultValue == null) { 2790 ((MethodSymbol)elm).defaultValue == null) {
2814 log.error(pos, 2791 log.error(pos,
2815 "invalid.containedby.annotation.elem.nondefault", 2792 "invalid.repeatable.annotation.elem.nondefault",
2816 container, 2793 container,
2817 elm); 2794 elm);
2818 } 2795 }
2819 } 2796 }
2820 } 2797 }
2835 } 2812 }
2836 } 2813 }
2837 return false; 2814 return false;
2838 } 2815 }
2839 2816
2817 /** Is the annotation applicable to type annotations? */
2818 protected boolean isTypeAnnotation(JCAnnotation a, boolean isTypeParameter) {
2819 Attribute.Compound atTarget =
2820 a.annotationType.type.tsym.attribute(syms.annotationTargetType.tsym);
2821 if (atTarget == null) {
2822 // An annotation without @Target is not a type annotation.
2823 return false;
2824 }
2825
2826 Attribute atValue = atTarget.member(names.value);
2827 if (!(atValue instanceof Attribute.Array)) {
2828 return false; // error recovery
2829 }
2830
2831 Attribute.Array arr = (Attribute.Array) atValue;
2832 for (Attribute app : arr.values) {
2833 if (!(app instanceof Attribute.Enum)) {
2834 return false; // recovery
2835 }
2836 Attribute.Enum e = (Attribute.Enum) app;
2837
2838 if (e.value.name == names.TYPE_USE)
2839 return true;
2840 else if (isTypeParameter && e.value.name == names.TYPE_PARAMETER)
2841 return true;
2842 }
2843 return false;
2844 }
2845
2840 /** Is the annotation applicable to the symbol? */ 2846 /** Is the annotation applicable to the symbol? */
2841 boolean annotationApplicable(JCAnnotation a, Symbol s) { 2847 boolean annotationApplicable(JCAnnotation a, Symbol s) {
2842 Attribute.Array arr = getAttributeTargetAttribute(a.annotationType.type.tsym); 2848 Attribute.Array arr = getAttributeTargetAttribute(a.annotationType.type.tsym);
2849 Name[] targets;
2850
2843 if (arr == null) { 2851 if (arr == null) {
2844 return true; 2852 targets = defaultTargetMetaInfo(a, s);
2845 } 2853 } else {
2846 for (Attribute app : arr.values) { 2854 // TODO: can we optimize this?
2847 if (!(app instanceof Attribute.Enum)) return true; // recovery 2855 targets = new Name[arr.values.length];
2848 Attribute.Enum e = (Attribute.Enum) app; 2856 for (int i=0; i<arr.values.length; ++i) {
2849 if (e.value.name == names.TYPE) 2857 Attribute app = arr.values[i];
2858 if (!(app instanceof Attribute.Enum)) {
2859 return true; // recovery
2860 }
2861 Attribute.Enum e = (Attribute.Enum) app;
2862 targets[i] = e.value.name;
2863 }
2864 }
2865 for (Name target : targets) {
2866 if (target == names.TYPE)
2850 { if (s.kind == TYP) return true; } 2867 { if (s.kind == TYP) return true; }
2851 else if (e.value.name == names.FIELD) 2868 else if (target == names.FIELD)
2852 { if (s.kind == VAR && s.owner.kind != MTH) return true; } 2869 { if (s.kind == VAR && s.owner.kind != MTH) return true; }
2853 else if (e.value.name == names.METHOD) 2870 else if (target == names.METHOD)
2854 { if (s.kind == MTH && !s.isConstructor()) return true; } 2871 { if (s.kind == MTH && !s.isConstructor()) return true; }
2855 else if (e.value.name == names.PARAMETER) 2872 else if (target == names.PARAMETER)
2856 { if (s.kind == VAR && 2873 { if (s.kind == VAR &&
2857 s.owner.kind == MTH && 2874 s.owner.kind == MTH &&
2858 (s.flags() & PARAMETER) != 0) 2875 (s.flags() & PARAMETER) != 0)
2859 return true; 2876 return true;
2860 } 2877 }
2861 else if (e.value.name == names.CONSTRUCTOR) 2878 else if (target == names.CONSTRUCTOR)
2862 { if (s.kind == MTH && s.isConstructor()) return true; } 2879 { if (s.kind == MTH && s.isConstructor()) return true; }
2863 else if (e.value.name == names.LOCAL_VARIABLE) 2880 else if (target == names.LOCAL_VARIABLE)
2864 { if (s.kind == VAR && s.owner.kind == MTH && 2881 { if (s.kind == VAR && s.owner.kind == MTH &&
2865 (s.flags() & PARAMETER) == 0) 2882 (s.flags() & PARAMETER) == 0)
2866 return true; 2883 return true;
2867 } 2884 }
2868 else if (e.value.name == names.ANNOTATION_TYPE) 2885 else if (target == names.ANNOTATION_TYPE)
2869 { if (s.kind == TYP && (s.flags() & ANNOTATION) != 0) 2886 { if (s.kind == TYP && (s.flags() & ANNOTATION) != 0)
2870 return true; 2887 return true;
2871 } 2888 }
2872 else if (e.value.name == names.PACKAGE) 2889 else if (target == names.PACKAGE)
2873 { if (s.kind == PCK) return true; } 2890 { if (s.kind == PCK) return true; }
2874 else if (e.value.name == names.TYPE_USE) 2891 else if (target == names.TYPE_USE)
2875 { if (s.kind == TYP || 2892 { if (s.kind == TYP ||
2876 s.kind == VAR || 2893 s.kind == VAR ||
2877 (s.kind == MTH && !s.isConstructor() && 2894 (s.kind == MTH && !s.isConstructor() &&
2878 !s.type.getReturnType().hasTag(VOID))) 2895 !s.type.getReturnType().hasTag(VOID)) ||
2896 (s.kind == MTH && s.isConstructor()))
2897 return true;
2898 }
2899 else if (target == names.TYPE_PARAMETER)
2900 { if (s.kind == TYP && s.type.hasTag(TYPEVAR))
2879 return true; 2901 return true;
2880 } 2902 }
2881 else 2903 else
2882 return true; // recovery 2904 return true; // recovery
2883 } 2905 }
2890 s.attribute(syms.annotationTargetType.tsym); 2912 s.attribute(syms.annotationTargetType.tsym);
2891 if (atTarget == null) return null; // ok, is applicable 2913 if (atTarget == null) return null; // ok, is applicable
2892 Attribute atValue = atTarget.member(names.value); 2914 Attribute atValue = atTarget.member(names.value);
2893 if (!(atValue instanceof Attribute.Array)) return null; // error recovery 2915 if (!(atValue instanceof Attribute.Array)) return null; // error recovery
2894 return (Attribute.Array) atValue; 2916 return (Attribute.Array) atValue;
2917 }
2918
2919 private final Name[] dfltTargetMeta;
2920 private Name[] defaultTargetMetaInfo(JCAnnotation a, Symbol s) {
2921 return dfltTargetMeta;
2895 } 2922 }
2896 2923
2897 /** Check an annotation value. 2924 /** Check an annotation value.
2898 * 2925 *
2899 * @param a The annotation tree to check 2926 * @param a The annotation tree to check

mercurial