74 private final ClassReader reader; |
74 private final ClassReader reader; |
75 private final Todo todo; |
75 private final Todo todo; |
76 private final Annotate annotate; |
76 private final Annotate annotate; |
77 private final Types types; |
77 private final Types types; |
78 private final JCDiagnostic.Factory diags; |
78 private final JCDiagnostic.Factory diags; |
|
79 private final Source source; |
79 private final Target target; |
80 private final Target target; |
80 private final DeferredLintHandler deferredLintHandler; |
81 private final DeferredLintHandler deferredLintHandler; |
81 |
|
82 private final boolean skipAnnotations; |
|
83 |
82 |
84 public static MemberEnter instance(Context context) { |
83 public static MemberEnter instance(Context context) { |
85 MemberEnter instance = context.get(memberEnterKey); |
84 MemberEnter instance = context.get(memberEnterKey); |
86 if (instance == null) |
85 if (instance == null) |
87 instance = new MemberEnter(context); |
86 instance = new MemberEnter(context); |
100 reader = ClassReader.instance(context); |
99 reader = ClassReader.instance(context); |
101 todo = Todo.instance(context); |
100 todo = Todo.instance(context); |
102 annotate = Annotate.instance(context); |
101 annotate = Annotate.instance(context); |
103 types = Types.instance(context); |
102 types = Types.instance(context); |
104 diags = JCDiagnostic.Factory.instance(context); |
103 diags = JCDiagnostic.Factory.instance(context); |
|
104 source = Source.instance(context); |
105 target = Target.instance(context); |
105 target = Target.instance(context); |
106 deferredLintHandler = DeferredLintHandler.instance(context); |
106 deferredLintHandler = DeferredLintHandler.instance(context); |
107 Options options = Options.instance(context); |
|
108 skipAnnotations = options.isSet("skipAnnotations"); |
|
109 } |
107 } |
110 |
108 |
111 /** A queue for classes whose members still need to be entered into the |
109 /** A queue for classes whose members still need to be entered into the |
112 * symbol table. |
110 * symbol table. |
113 */ |
111 */ |
688 memberEnter(tree.errs, env); |
686 memberEnter(tree.errs, env); |
689 } |
687 } |
690 |
688 |
691 public Env<AttrContext> getMethodEnv(JCMethodDecl tree, Env<AttrContext> env) { |
689 public Env<AttrContext> getMethodEnv(JCMethodDecl tree, Env<AttrContext> env) { |
692 Env<AttrContext> mEnv = methodEnv(tree, env); |
690 Env<AttrContext> mEnv = methodEnv(tree, env); |
693 mEnv.info.lint = mEnv.info.lint.augment(tree.sym.attributes_field, tree.sym.flags()); |
691 mEnv.info.lint = mEnv.info.lint.augment(tree.sym.annotations, tree.sym.flags()); |
694 for (List<JCTypeParameter> l = tree.typarams; l.nonEmpty(); l = l.tail) |
692 for (List<JCTypeParameter> l = tree.typarams; l.nonEmpty(); l = l.tail) |
695 mEnv.info.scope.enterIfAbsent(l.head.type.tsym); |
693 mEnv.info.scope.enterIfAbsent(l.head.type.tsym); |
696 for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) |
694 for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) |
697 mEnv.info.scope.enterIfAbsent(l.head.sym); |
695 mEnv.info.scope.enterIfAbsent(l.head.sym); |
698 return mEnv; |
696 return mEnv; |
725 |
723 |
726 /** Queue annotations for later processing. */ |
724 /** Queue annotations for later processing. */ |
727 void annotateLater(final List<JCAnnotation> annotations, |
725 void annotateLater(final List<JCAnnotation> annotations, |
728 final Env<AttrContext> localEnv, |
726 final Env<AttrContext> localEnv, |
729 final Symbol s) { |
727 final Symbol s) { |
730 if (annotations.isEmpty()) return; |
728 if (annotations.isEmpty()) { |
731 if (s.kind != PCK) s.attributes_field = null; // mark it incomplete for now |
729 return; |
732 annotate.later(new Annotate.Annotator() { |
730 } |
|
731 if (s.kind != PCK) { |
|
732 s.annotations.reset(); // mark Annotations as incomplete for now |
|
733 } |
|
734 annotate.normal(new Annotate.Annotator() { |
|
735 @Override |
733 public String toString() { |
736 public String toString() { |
734 return "annotate " + annotations + " onto " + s + " in " + s.owner; |
737 return "annotate " + annotations + " onto " + s + " in " + s.owner; |
735 } |
738 } |
|
739 |
|
740 @Override |
736 public void enterAnnotation() { |
741 public void enterAnnotation() { |
737 Assert.check(s.kind == PCK || s.attributes_field == null); |
742 Assert.check(s.kind == PCK || s.annotations.pendingCompletion()); |
738 JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile); |
743 JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile); |
739 try { |
744 try { |
740 if (s.attributes_field != null && |
745 if (!s.annotations.isEmpty() && |
741 s.attributes_field.nonEmpty() && |
|
742 annotations.nonEmpty()) |
746 annotations.nonEmpty()) |
743 log.error(annotations.head.pos, |
747 log.error(annotations.head.pos, |
744 "already.annotated", |
748 "already.annotated", |
745 kindName(s), s); |
749 kindName(s), s); |
746 enterAnnotations(annotations, localEnv, s); |
750 enterAnnotations(annotations, localEnv, s); |
754 /** |
758 /** |
755 * Check if a list of annotations contains a reference to |
759 * Check if a list of annotations contains a reference to |
756 * java.lang.Deprecated. |
760 * java.lang.Deprecated. |
757 **/ |
761 **/ |
758 private boolean hasDeprecatedAnnotation(List<JCAnnotation> annotations) { |
762 private boolean hasDeprecatedAnnotation(List<JCAnnotation> annotations) { |
759 for (List<JCAnnotation> al = annotations; al.nonEmpty(); al = al.tail) { |
763 for (List<JCAnnotation> al = annotations; !al.isEmpty(); al = al.tail) { |
760 JCAnnotation a = al.head; |
764 JCAnnotation a = al.head; |
761 if (a.annotationType.type == syms.deprecatedType && a.args.isEmpty()) |
765 if (a.annotationType.type == syms.deprecatedType && a.args.isEmpty()) |
762 return true; |
766 return true; |
763 } |
767 } |
764 return false; |
768 return false; |
765 } |
769 } |
766 |
|
767 |
770 |
768 /** Enter a set of annotations. */ |
771 /** Enter a set of annotations. */ |
769 private void enterAnnotations(List<JCAnnotation> annotations, |
772 private void enterAnnotations(List<JCAnnotation> annotations, |
770 Env<AttrContext> env, |
773 Env<AttrContext> env, |
771 Symbol s) { |
774 Symbol s) { |
772 ListBuffer<Attribute.Compound> buf = |
775 Map<TypeSymbol, ListBuffer<Attribute.Compound>> annotated = |
773 new ListBuffer<Attribute.Compound>(); |
776 new LinkedHashMap<TypeSymbol, ListBuffer<Attribute.Compound>>(); |
774 Set<TypeSymbol> annotated = new HashSet<TypeSymbol>(); |
777 Map<Attribute.Compound, DiagnosticPosition> pos = |
775 if (!skipAnnotations) |
778 new HashMap<Attribute.Compound, DiagnosticPosition>(); |
776 for (List<JCAnnotation> al = annotations; al.nonEmpty(); al = al.tail) { |
779 |
|
780 for (List<JCAnnotation> al = annotations; !al.isEmpty(); al = al.tail) { |
777 JCAnnotation a = al.head; |
781 JCAnnotation a = al.head; |
778 Attribute.Compound c = annotate.enterAnnotation(a, |
782 Attribute.Compound c = annotate.enterAnnotation(a, |
779 syms.annotationType, |
783 syms.annotationType, |
780 env); |
784 env); |
781 if (c == null) continue; |
785 if (c == null) { |
782 buf.append(c); |
786 continue; |
|
787 } |
|
788 |
|
789 if (annotated.containsKey(a.type.tsym)) { |
|
790 if (source.allowRepeatedAnnotations()) { |
|
791 ListBuffer<Attribute.Compound> l = annotated.get(a.type.tsym); |
|
792 l = l.append(c); |
|
793 annotated.put(a.type.tsym, l); |
|
794 pos.put(c, a.pos()); |
|
795 } else { |
|
796 log.error(a.pos(), "duplicate.annotation"); |
|
797 } |
|
798 } else { |
|
799 annotated.put(a.type.tsym, ListBuffer.of(c)); |
|
800 pos.put(c, a.pos()); |
|
801 } |
|
802 |
783 // Note: @Deprecated has no effect on local variables and parameters |
803 // Note: @Deprecated has no effect on local variables and parameters |
784 if (!c.type.isErroneous() |
804 if (!c.type.isErroneous() |
785 && s.owner.kind != MTH |
805 && s.owner.kind != MTH |
786 && types.isSameType(c.type, syms.deprecatedType)) |
806 && types.isSameType(c.type, syms.deprecatedType)) { |
787 s.flags_field |= Flags.DEPRECATED; |
807 s.flags_field |= Flags.DEPRECATED; |
788 if (!annotated.add(a.type.tsym)) |
808 } |
789 log.error(a.pos, "duplicate.annotation"); |
809 } |
790 } |
810 |
791 s.attributes_field = buf.toList(); |
811 s.annotations.setAttributesWithCompletion( |
|
812 annotate.new AnnotateRepeatedContext(env, annotated, pos, log)); |
792 } |
813 } |
793 |
814 |
794 /** Queue processing of an attribute default value. */ |
815 /** Queue processing of an attribute default value. */ |
795 void annotateDefaultValueLater(final JCExpression defaultValue, |
816 void annotateDefaultValueLater(final JCExpression defaultValue, |
796 final Env<AttrContext> localEnv, |
817 final Env<AttrContext> localEnv, |
797 final MethodSymbol m) { |
818 final MethodSymbol m) { |
798 annotate.later(new Annotate.Annotator() { |
819 annotate.normal(new Annotate.Annotator() { |
|
820 @Override |
799 public String toString() { |
821 public String toString() { |
800 return "annotate " + m.owner + "." + |
822 return "annotate " + m.owner + "." + |
801 m + " default " + defaultValue; |
823 m + " default " + defaultValue; |
802 } |
824 } |
|
825 |
|
826 @Override |
803 public void enterAnnotation() { |
827 public void enterAnnotation() { |
804 JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile); |
828 JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile); |
805 try { |
829 try { |
806 enterDefaultValue(defaultValue, localEnv, m); |
830 enterDefaultValue(defaultValue, localEnv, m); |
807 } finally { |
831 } finally { |