2590 log.error(a.pos(), "method.does.not.override.superclass"); |
2590 log.error(a.pos(), "method.does.not.override.superclass"); |
2591 } |
2591 } |
2592 } |
2592 } |
2593 |
2593 |
2594 /** |
2594 /** |
2595 * Validate the proposed container 'containedBy' on the |
2595 * Validate the proposed container 'repeatable' on the |
2596 * annotation type symbol 's'. Report errors at position |
2596 * annotation type symbol 's'. Report errors at position |
2597 * 'pos'. |
2597 * 'pos'. |
2598 * |
2598 * |
2599 * @param s The (annotation)type declaration annotated with a @ContainedBy |
2599 * @param s The (annotation)type declaration annotated with a @Repeatable |
2600 * @param containedBy the @ContainedBy on 's' |
2600 * @param repeatable the @Repeatable on 's' |
2601 * @param pos where to report errors |
2601 * @param pos where to report errors |
2602 */ |
2602 */ |
2603 public void validateContainedBy(TypeSymbol s, Attribute.Compound containedBy, DiagnosticPosition pos) { |
2603 public void validateRepeatable(TypeSymbol s, Attribute.Compound repeatable, DiagnosticPosition pos) { |
2604 Assert.check(types.isSameType(containedBy.type, syms.containedByType)); |
2604 Assert.check(types.isSameType(repeatable.type, syms.repeatableType)); |
2605 |
2605 |
2606 Type t = null; |
2606 Type t = null; |
2607 List<Pair<MethodSymbol,Attribute>> l = containedBy.values; |
2607 List<Pair<MethodSymbol,Attribute>> l = repeatable.values; |
2608 if (!l.isEmpty()) { |
2608 if (!l.isEmpty()) { |
2609 Assert.check(l.head.fst.name == names.value); |
2609 Assert.check(l.head.fst.name == names.value); |
2610 t = ((Attribute.Class)l.head.snd).getValue(); |
2610 t = ((Attribute.Class)l.head.snd).getValue(); |
2611 } |
2611 } |
2612 |
2612 |
2613 if (t == null) { |
2613 if (t == null) { |
2614 log.error(pos, "invalid.container.wrong.containedby", s, containedBy); |
2614 // errors should already have been reported during Annotate |
2615 return; |
2615 return; |
2616 } |
2616 } |
2617 |
2617 |
2618 validateHasContainerFor(t.tsym, s, pos); |
2618 validateValue(t.tsym, s, pos); |
2619 validateRetention(t.tsym, s, pos); |
2619 validateRetention(t.tsym, s, pos); |
2620 validateDocumented(t.tsym, s, pos); |
2620 validateDocumented(t.tsym, s, pos); |
2621 validateInherited(t.tsym, s, pos); |
2621 validateInherited(t.tsym, s, pos); |
2622 validateTarget(t.tsym, s, pos); |
2622 validateTarget(t.tsym, s, pos); |
2623 validateDefault(t.tsym, s, pos); |
2623 validateDefault(t.tsym, s, pos); |
2624 } |
2624 } |
2625 |
2625 |
2626 /** |
2626 private void validateValue(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) { |
2627 * Validate the proposed container 'containerFor' on the |
2627 Scope.Entry e = container.members().lookup(names.value); |
2628 * annotation type symbol 's'. Report errors at position |
2628 if (e.scope != null && e.sym.kind == MTH) { |
2629 * 'pos'. |
2629 MethodSymbol m = (MethodSymbol) e.sym; |
2630 * |
2630 Type ret = m.getReturnType(); |
2631 * @param s The (annotation)type declaration annotated with a @ContainerFor |
2631 if (!(ret.hasTag(ARRAY) && types.isSameType(((ArrayType)ret).elemtype, contained.type))) { |
2632 * @param containerFor the @ContainedFor on 's' |
2632 log.error(pos, "invalid.repeatable.annotation.value.return", |
2633 * @param pos where to report errors |
2633 container, ret, types.makeArrayType(contained.type)); |
2634 */ |
2634 } |
2635 public void validateContainerFor(TypeSymbol s, Attribute.Compound containerFor, DiagnosticPosition pos) { |
2635 } else { |
2636 Assert.check(types.isSameType(containerFor.type, syms.containerForType)); |
2636 log.error(pos, "invalid.repeatable.annotation.no.value", container); |
2637 |
2637 } |
2638 Type t = null; |
|
2639 List<Pair<MethodSymbol,Attribute>> l = containerFor.values; |
|
2640 if (!l.isEmpty()) { |
|
2641 Assert.check(l.head.fst.name == names.value); |
|
2642 t = ((Attribute.Class)l.head.snd).getValue(); |
|
2643 } |
|
2644 |
|
2645 if (t == null) { |
|
2646 log.error(pos, "invalid.container.wrong.containerfor", s, containerFor); |
|
2647 return; |
|
2648 } |
|
2649 |
|
2650 validateHasContainedBy(t.tsym, s, pos); |
|
2651 } |
|
2652 |
|
2653 private void validateHasContainedBy(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) { |
|
2654 Attribute.Compound containedBy = container.attribute(syms.containedByType.tsym); |
|
2655 |
|
2656 if (containedBy == null) { |
|
2657 log.error(pos, "invalid.container.no.containedby", container, syms.containedByType.tsym); |
|
2658 return; |
|
2659 } |
|
2660 |
|
2661 Type t = null; |
|
2662 List<Pair<MethodSymbol,Attribute>> l = containedBy.values; |
|
2663 if (!l.isEmpty()) { |
|
2664 Assert.check(l.head.fst.name == names.value); |
|
2665 t = ((Attribute.Class)l.head.snd).getValue(); |
|
2666 } |
|
2667 |
|
2668 if (t == null) { |
|
2669 log.error(pos, "invalid.container.wrong.containedby", container, contained); |
|
2670 return; |
|
2671 } |
|
2672 |
|
2673 if (!types.isSameType(t, contained.type)) |
|
2674 log.error(pos, "invalid.container.wrong.containedby", t.tsym, contained); |
|
2675 } |
|
2676 |
|
2677 private void validateHasContainerFor(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) { |
|
2678 Attribute.Compound containerFor = container.attribute(syms.containerForType.tsym); |
|
2679 |
|
2680 if (containerFor == null) { |
|
2681 log.error(pos, "invalid.container.no.containerfor", container, syms.containerForType.tsym); |
|
2682 return; |
|
2683 } |
|
2684 |
|
2685 Type t = null; |
|
2686 List<Pair<MethodSymbol,Attribute>> l = containerFor.values; |
|
2687 if (!l.isEmpty()) { |
|
2688 Assert.check(l.head.fst.name == names.value); |
|
2689 t = ((Attribute.Class)l.head.snd).getValue(); |
|
2690 } |
|
2691 |
|
2692 if (t == null) { |
|
2693 log.error(pos, "invalid.container.wrong.containerfor", container, contained); |
|
2694 return; |
|
2695 } |
|
2696 |
|
2697 if (!types.isSameType(t, contained.type)) |
|
2698 log.error(pos, "invalid.container.wrong.containerfor", t.tsym, contained); |
|
2699 } |
2638 } |
2700 |
2639 |
2701 private void validateRetention(Symbol container, Symbol contained, DiagnosticPosition pos) { |
2640 private void validateRetention(Symbol container, Symbol contained, DiagnosticPosition pos) { |
2702 Attribute.RetentionPolicy containerRetention = types.getRetention(container); |
2641 Attribute.RetentionPolicy containerRetention = types.getRetention(container); |
2703 Attribute.RetentionPolicy containedRetention = types.getRetention(contained); |
2642 Attribute.RetentionPolicy containedRetention = types.getRetention(contained); |
2713 if (containerRetention == Attribute.RetentionPolicy.SOURCE) { |
2652 if (containerRetention == Attribute.RetentionPolicy.SOURCE) { |
2714 error = true; |
2653 error = true; |
2715 } |
2654 } |
2716 } |
2655 } |
2717 if (error ) { |
2656 if (error ) { |
2718 log.error(pos, "invalid.containedby.annotation.retention", |
2657 log.error(pos, "invalid.repeatable.annotation.retention", |
2719 container, containerRetention, |
2658 container, containerRetention, |
2720 contained, containedRetention); |
2659 contained, containedRetention); |
2721 } |
2660 } |
2722 } |
2661 } |
2723 |
2662 |
2724 private void validateDocumented(Symbol container, Symbol contained, DiagnosticPosition pos) { |
2663 private void validateDocumented(Symbol container, Symbol contained, DiagnosticPosition pos) { |
2725 if (contained.attribute(syms.documentedType.tsym) != null) { |
2664 if (contained.attribute(syms.documentedType.tsym) != null) { |
2726 if (container.attribute(syms.documentedType.tsym) == null) { |
2665 if (container.attribute(syms.documentedType.tsym) == null) { |
2727 log.error(pos, "invalid.containedby.annotation.not.documented", container, contained); |
2666 log.error(pos, "invalid.repeatable.annotation.not.documented", container, contained); |
2728 } |
2667 } |
2729 } |
2668 } |
2730 } |
2669 } |
2731 |
2670 |
2732 private void validateInherited(Symbol container, Symbol contained, DiagnosticPosition pos) { |
2671 private void validateInherited(Symbol container, Symbol contained, DiagnosticPosition pos) { |
2733 if (contained.attribute(syms.inheritedType.tsym) != null) { |
2672 if (contained.attribute(syms.inheritedType.tsym) != null) { |
2734 if (container.attribute(syms.inheritedType.tsym) == null) { |
2673 if (container.attribute(syms.inheritedType.tsym) == null) { |
2735 log.error(pos, "invalid.containedby.annotation.not.inherited", container, contained); |
2674 log.error(pos, "invalid.repeatable.annotation.not.inherited", container, contained); |
2736 } |
2675 } |
2737 } |
2676 } |
2738 } |
2677 } |
2739 |
2678 |
2740 private void validateTarget(Symbol container, Symbol contained, DiagnosticPosition pos) { |
2679 private void validateTarget(Symbol container, Symbol contained, DiagnosticPosition pos) { |