langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
changeset 13689 4d519199a6aa
parent 12917 0c381f0ac967
child 14051 9097cec96212
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Mon Aug 27 10:59:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Fri Aug 31 10:37:46 2012 +0100
@@ -76,11 +76,10 @@
     private final Annotate annotate;
     private final Types types;
     private final JCDiagnostic.Factory diags;
+    private final Source source;
     private final Target target;
     private final DeferredLintHandler deferredLintHandler;
 
-    private final boolean skipAnnotations;
-
     public static MemberEnter instance(Context context) {
         MemberEnter instance = context.get(memberEnterKey);
         if (instance == null)
@@ -102,10 +101,9 @@
         annotate = Annotate.instance(context);
         types = Types.instance(context);
         diags = JCDiagnostic.Factory.instance(context);
+        source = Source.instance(context);
         target = Target.instance(context);
         deferredLintHandler = DeferredLintHandler.instance(context);
-        Options options = Options.instance(context);
-        skipAnnotations = options.isSet("skipAnnotations");
     }
 
     /** A queue for classes whose members still need to be entered into the
@@ -690,7 +688,7 @@
 
     public Env<AttrContext> getMethodEnv(JCMethodDecl tree, Env<AttrContext> env) {
         Env<AttrContext> mEnv = methodEnv(tree, env);
-        mEnv.info.lint = mEnv.info.lint.augment(tree.sym.attributes_field, tree.sym.flags());
+        mEnv.info.lint = mEnv.info.lint.augment(tree.sym.annotations, tree.sym.flags());
         for (List<JCTypeParameter> l = tree.typarams; l.nonEmpty(); l = l.tail)
             mEnv.info.scope.enterIfAbsent(l.head.type.tsym);
         for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail)
@@ -727,18 +725,24 @@
     void annotateLater(final List<JCAnnotation> annotations,
                        final Env<AttrContext> localEnv,
                        final Symbol s) {
-        if (annotations.isEmpty()) return;
-        if (s.kind != PCK) s.attributes_field = null; // mark it incomplete for now
-        annotate.later(new Annotate.Annotator() {
+        if (annotations.isEmpty()) {
+            return;
+        }
+        if (s.kind != PCK) {
+            s.annotations.reset(); // mark Annotations as incomplete for now
+        }
+        annotate.normal(new Annotate.Annotator() {
+                @Override
                 public String toString() {
                     return "annotate " + annotations + " onto " + s + " in " + s.owner;
                 }
+
+                @Override
                 public void enterAnnotation() {
-                    Assert.check(s.kind == PCK || s.attributes_field == null);
+                    Assert.check(s.kind == PCK || s.annotations.pendingCompletion());
                     JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
                     try {
-                        if (s.attributes_field != null &&
-                            s.attributes_field.nonEmpty() &&
+                        if (!s.annotations.isEmpty() &&
                             annotations.nonEmpty())
                             log.error(annotations.head.pos,
                                       "already.annotated",
@@ -756,7 +760,7 @@
      * java.lang.Deprecated.
      **/
     private boolean hasDeprecatedAnnotation(List<JCAnnotation> annotations) {
-        for (List<JCAnnotation> al = annotations; al.nonEmpty(); al = al.tail) {
+        for (List<JCAnnotation> al = annotations; !al.isEmpty(); al = al.tail) {
             JCAnnotation a = al.head;
             if (a.annotationType.type == syms.deprecatedType && a.args.isEmpty())
                 return true;
@@ -764,42 +768,62 @@
         return false;
     }
 
-
     /** Enter a set of annotations. */
     private void enterAnnotations(List<JCAnnotation> annotations,
                           Env<AttrContext> env,
                           Symbol s) {
-        ListBuffer<Attribute.Compound> buf =
-            new ListBuffer<Attribute.Compound>();
-        Set<TypeSymbol> annotated = new HashSet<TypeSymbol>();
-        if (!skipAnnotations)
-        for (List<JCAnnotation> al = annotations; al.nonEmpty(); al = al.tail) {
+        Map<TypeSymbol, ListBuffer<Attribute.Compound>> annotated =
+                new LinkedHashMap<TypeSymbol, ListBuffer<Attribute.Compound>>();
+        Map<Attribute.Compound, DiagnosticPosition> pos =
+                new HashMap<Attribute.Compound, DiagnosticPosition>();
+
+        for (List<JCAnnotation> al = annotations; !al.isEmpty(); al = al.tail) {
             JCAnnotation a = al.head;
             Attribute.Compound c = annotate.enterAnnotation(a,
                                                             syms.annotationType,
                                                             env);
-            if (c == null) continue;
-            buf.append(c);
+            if (c == null) {
+                continue;
+            }
+
+            if (annotated.containsKey(a.type.tsym)) {
+                if (source.allowRepeatedAnnotations()) {
+                    ListBuffer<Attribute.Compound> l = annotated.get(a.type.tsym);
+                    l = l.append(c);
+                    annotated.put(a.type.tsym, l);
+                    pos.put(c, a.pos());
+                } else {
+                    log.error(a.pos(), "duplicate.annotation");
+                }
+            } else {
+                annotated.put(a.type.tsym, ListBuffer.of(c));
+                pos.put(c, a.pos());
+            }
+
             // Note: @Deprecated has no effect on local variables and parameters
             if (!c.type.isErroneous()
                 && s.owner.kind != MTH
-                && types.isSameType(c.type, syms.deprecatedType))
+                && types.isSameType(c.type, syms.deprecatedType)) {
                 s.flags_field |= Flags.DEPRECATED;
-            if (!annotated.add(a.type.tsym))
-                log.error(a.pos, "duplicate.annotation");
+        }
         }
-        s.attributes_field = buf.toList();
+
+        s.annotations.setAttributesWithCompletion(
+                annotate.new AnnotateRepeatedContext(env, annotated, pos, log));
     }
 
     /** Queue processing of an attribute default value. */
     void annotateDefaultValueLater(final JCExpression defaultValue,
                                    final Env<AttrContext> localEnv,
                                    final MethodSymbol m) {
-        annotate.later(new Annotate.Annotator() {
+        annotate.normal(new Annotate.Annotator() {
+                @Override
                 public String toString() {
                     return "annotate " + m.owner + "." +
                         m + " default " + defaultValue;
                 }
+
+                @Override
                 public void enterAnnotation() {
                     JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
                     try {