8007961: javax.lang.model tests for repeating annotations fail in getAnnotationsByType

Thu, 25 Jul 2013 11:02:27 +0200

author
jfranck
date
Thu, 25 Jul 2013 11:02:27 +0200
changeset 1918
a218f7befd55
parent 1917
2fbe77c38802
child 1919
3155e77d2676

8007961: javax.lang.model tests for repeating annotations fail in getAnnotationsByType
Reviewed-by: jjg

src/share/classes/com/sun/tools/javac/code/Symbol.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/model/JavacAnnoConstructs.java file | annotate | diff | comparison | revisions
test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedA1Test.java file | annotate | diff | comparison | revisions
test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedB1Test.java file | annotate | diff | comparison | revisions
test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedB2Test.java file | annotate | diff | comparison | revisions
test/tools/javac/processing/model/element/repeatingAnnotations/RepeatableOverrideATest.java file | annotate | diff | comparison | revisions
test/tools/javac/processing/model/element/repeatingAnnotations/RepeatableOverrideBTest.java file | annotate | diff | comparison | revisions
test/tools/javac/processing/model/inheritedByType/EnsureOrder.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/classes/com/sun/tools/javac/code/Symbol.java	Wed Jul 24 17:35:42 2013 -0700
     1.2 +++ b/src/share/classes/com/sun/tools/javac/code/Symbol.java	Thu Jul 25 11:02:27 2013 +0200
     1.3 @@ -596,7 +596,7 @@
     1.4  
     1.5      // This method is part of the javax.lang.model API, do not use this in javac code.
     1.6      public <A extends java.lang.annotation.Annotation> A[] getAnnotationsByType(Class<A> annoType) {
     1.7 -        return JavacAnnoConstructs.getAnnotations(this, annoType);
     1.8 +        return JavacAnnoConstructs.getAnnotationsByType(this, annoType);
     1.9      }
    1.10  
    1.11      // TODO: getEnclosedElements should return a javac List, fix in FilteredMemberList
     2.1 --- a/src/share/classes/com/sun/tools/javac/model/JavacAnnoConstructs.java	Wed Jul 24 17:35:42 2013 -0700
     2.2 +++ b/src/share/classes/com/sun/tools/javac/model/JavacAnnoConstructs.java	Thu Jul 25 11:02:27 2013 +0200
     2.3 @@ -108,20 +108,38 @@
     2.4      }
     2.5  
     2.6      // Helper to getAnnotation[s]
     2.7 -    private static <A extends Annotation> Attribute.Compound getAttributeOnClass(ClassSymbol annotated,
     2.8 -                                                                Class<A> annoType) {
     2.9 +    private static <A extends Annotation> Attribute.Compound getAttributeOnClass(
    2.10 +            ClassSymbol annotated,
    2.11 +            final Class<A> annoType)
    2.12 +    {
    2.13          boolean inherited = annoType.isAnnotationPresent(Inherited.class);
    2.14          Attribute.Compound result = null;
    2.15 -        while (annotated.name != annotated.name.table.names.java_lang_Object) {
    2.16 +
    2.17 +        result = getAttribute(annotated, annoType);
    2.18 +        if (result != null || !inherited)
    2.19 +            return result;
    2.20 +
    2.21 +        while ((annotated = nextSupertypeToSearch(annotated)) != null) {
    2.22              result = getAttribute(annotated, annoType);
    2.23 -            if (result != null || !inherited)
    2.24 -                break;
    2.25 -            Type sup = annotated.getSuperclass();
    2.26 -            if (!sup.hasTag(CLASS) || sup.isErroneous())
    2.27 -                break;
    2.28 -            annotated = (ClassSymbol) sup.tsym;
    2.29 +            if (result != null)
    2.30 +                return result;
    2.31          }
    2.32 -        return result;
    2.33 +        return null; // no more supertypes to search
    2.34 +    }
    2.35 +
    2.36 +    /**
    2.37 +     * Returns the next type to search for inherited annotations or {@code null}
    2.38 +     * if the next type can't be found.
    2.39 +     */
    2.40 +    private static ClassSymbol nextSupertypeToSearch(ClassSymbol annotated) {
    2.41 +        if (annotated.name == annotated.name.table.names.java_lang_Object)
    2.42 +            return null;
    2.43 +
    2.44 +        Type sup = annotated.getSuperclass();
    2.45 +        if (!sup.hasTag(CLASS) || sup.isErroneous())
    2.46 +            return null;
    2.47 +
    2.48 +        return (ClassSymbol) sup.tsym;
    2.49      }
    2.50  
    2.51      /**
    2.52 @@ -129,8 +147,9 @@
    2.53       * annotations. This is the implementation of
    2.54       * Element.getAnnotations(Class).
    2.55       */
    2.56 -    public static <A extends Annotation> A[] getAnnotations(Symbol annotated,
    2.57 -                                                            Class<A> annoType) {
    2.58 +    public static <A extends Annotation> A[] getAnnotationsByType(Symbol annotated,
    2.59 +            Class<A> annoType)
    2.60 +    {
    2.61          if (!annoType.isAnnotation())
    2.62              throw new IllegalArgumentException("Not an annotation type: "
    2.63                                                 + annoType);
    2.64 @@ -153,62 +172,48 @@
    2.65          }
    2.66  
    2.67          // So we have a containing type
    2.68 -        String name = annoType.getName();
    2.69          String annoTypeName = annoType.getSimpleName();
    2.70          String containerTypeName = containerType.getSimpleName();
    2.71          int directIndex = -1, containerIndex = -1;
    2.72          Attribute.Compound direct = null, container = null;
    2.73 -        Attribute.Compound[] rawAttributes = annotated.getRawAttributes().toArray(new Attribute.Compound[0]);
    2.74 -
    2.75 -        // Find directly present annotations
    2.76 -        for (int i = 0; i < rawAttributes.length; i++) {
    2.77 -            if (annoTypeName.equals(rawAttributes[i].type.tsym.flatName().toString())) {
    2.78 -                directIndex = i;
    2.79 -                direct = rawAttributes[i];
    2.80 +        // Find directly (explicit or implicit) present annotations
    2.81 +        int index = -1;
    2.82 +        for (List<Attribute.Compound> list = annotated.getAnnotationMirrors();
    2.83 +                !list.isEmpty();
    2.84 +                list = list.tail) {
    2.85 +            Attribute.Compound attribute = list.head;
    2.86 +            index++;
    2.87 +            if (attribute.type.tsym.flatName().contentEquals(annoTypeName)) {
    2.88 +                directIndex = index;
    2.89 +                direct = attribute;
    2.90              } else if(containerTypeName != null &&
    2.91 -                      containerTypeName.equals(rawAttributes[i].type.tsym.flatName().toString())) {
    2.92 -                containerIndex = i;
    2.93 -                container = rawAttributes[i];
    2.94 +                      attribute.type.tsym.flatName().contentEquals(containerTypeName)) {
    2.95 +                containerIndex = index;
    2.96 +                container = attribute;
    2.97              }
    2.98          }
    2.99  
   2.100          // Deal with inherited annotations
   2.101 -        if (annotated.kind == Kinds.TYP &&
   2.102 -                (annotated instanceof ClassSymbol)) {
   2.103 -            ClassSymbol s = (ClassSymbol)annotated;
   2.104 -            if (direct == null && container == null) {
   2.105 -                direct = getAttributeOnClass(s, annoType);
   2.106 -                container = getAttributeOnClass(s, containerType);
   2.107 -
   2.108 -                // both are inherited and found, put container last
   2.109 -                if (direct != null && container != null) {
   2.110 -                    directIndex = 0;
   2.111 -                    containerIndex = 1;
   2.112 -                } else if (direct != null) {
   2.113 -                    directIndex = 0;
   2.114 -                } else {
   2.115 -                    containerIndex = 0;
   2.116 -                }
   2.117 -            } else if (direct == null) {
   2.118 -                direct = getAttributeOnClass(s, annoType);
   2.119 -                if (direct != null)
   2.120 -                    directIndex = containerIndex + 1;
   2.121 -            } else if (container == null) {
   2.122 -                container = getAttributeOnClass(s, containerType);
   2.123 -                if (container != null)
   2.124 -                    containerIndex = directIndex + 1;
   2.125 +        if (direct == null && container == null) {
   2.126 +            if (annotated.kind == Kinds.TYP &&
   2.127 +                    (annotated instanceof ClassSymbol)) {
   2.128 +                ClassSymbol s = nextSupertypeToSearch((ClassSymbol)annotated);
   2.129 +                if (s != null)
   2.130 +                    return getAnnotationsByType(s, annoType);
   2.131              }
   2.132          }
   2.133  
   2.134          // Pack them in an array
   2.135 -        Attribute[] contained0 = new Attribute[0];
   2.136 +        Attribute[] contained0 = null;
   2.137          if (container != null)
   2.138              contained0 = unpackAttributes(container);
   2.139          ListBuffer<Attribute.Compound> compounds = ListBuffer.lb();
   2.140 -        for (Attribute a : contained0)
   2.141 -            if (a instanceof Attribute.Compound)
   2.142 -                compounds = compounds.append((Attribute.Compound)a);
   2.143 -        Attribute.Compound[] contained = compounds.toArray(new Attribute.Compound[0]);
   2.144 +        if (contained0 != null) {
   2.145 +            for (Attribute a : contained0)
   2.146 +                if (a instanceof Attribute.Compound)
   2.147 +                    compounds = compounds.append((Attribute.Compound)a);
   2.148 +        }
   2.149 +        Attribute.Compound[] contained = compounds.toArray(new Attribute.Compound[compounds.size()]);
   2.150  
   2.151          int size = (direct == null ? 0 : 1) + contained.length;
   2.152          @SuppressWarnings("unchecked") // annoType is the Class for A
   2.153 @@ -298,35 +303,38 @@
   2.154          }
   2.155  
   2.156          // So we have a containing type
   2.157 -        String name = annoType.getName();
   2.158          String annoTypeName = annoType.getSimpleName();
   2.159          String containerTypeName = containerType.getSimpleName();
   2.160          int directIndex = -1, containerIndex = -1;
   2.161          Attribute.Compound direct = null, container = null;
   2.162 -        Attribute.Compound[] rawAttributes = annotated.getAnnotationMirrors().toArray(new Attribute.Compound[0]);
   2.163 -
   2.164 -        // Find directly present annotations
   2.165 -        for (int i = 0; i < rawAttributes.length; i++) {
   2.166 -            if (annoTypeName.equals(rawAttributes[i].type.tsym.flatName().toString())) {
   2.167 -                directIndex = i;
   2.168 -                direct = rawAttributes[i];
   2.169 +        // Find directly (explicit or implicit) present annotations
   2.170 +        int index = -1;
   2.171 +        for (List<? extends Attribute.Compound> list = annotated.getAnnotationMirrors();
   2.172 +                !list.isEmpty();
   2.173 +                list = list.tail) {
   2.174 +            Attribute.Compound attribute = list.head;
   2.175 +            index++;
   2.176 +            if (attribute.type.tsym.flatName().contentEquals(annoTypeName)) {
   2.177 +                directIndex = index;
   2.178 +                direct = attribute;
   2.179              } else if(containerTypeName != null &&
   2.180 -                      containerTypeName.equals(rawAttributes[i].type.tsym.flatName().toString())) {
   2.181 -                containerIndex = i;
   2.182 -                container = rawAttributes[i];
   2.183 +                      attribute.type.tsym.flatName().contentEquals(containerTypeName)) {
   2.184 +                containerIndex = index;
   2.185 +                container = attribute;
   2.186              }
   2.187          }
   2.188  
   2.189          // Pack them in an array
   2.190 -        Attribute[] contained0 = new Attribute[0];
   2.191 +        Attribute[] contained0 = null;
   2.192          if (container != null)
   2.193              contained0 = unpackAttributes(container);
   2.194          ListBuffer<Attribute.Compound> compounds = ListBuffer.lb();
   2.195 -        for (Attribute a : contained0) {
   2.196 -            if (a instanceof Attribute.Compound)
   2.197 -                compounds = compounds.append((Attribute.Compound)a);
   2.198 +        if (contained0 != null) {
   2.199 +            for (Attribute a : contained0)
   2.200 +                if (a instanceof Attribute.Compound)
   2.201 +                    compounds = compounds.append((Attribute.Compound)a);
   2.202          }
   2.203 -        Attribute.Compound[] contained = compounds.toArray(new Attribute.Compound[0]);
   2.204 +        Attribute.Compound[] contained = compounds.toArray(new Attribute.Compound[compounds.size()]);
   2.205  
   2.206          int size = (direct == null ? 0 : 1) + contained.length;
   2.207          @SuppressWarnings("unchecked") // annoType is the Class for A
     3.1 --- a/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedA1Test.java	Wed Jul 24 17:35:42 2013 -0700
     3.2 +++ b/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedA1Test.java	Thu Jul 25 11:02:27 2013 +0200
     3.3 @@ -23,12 +23,11 @@
     3.4  
     3.5  /*
     3.6   * @test
     3.7 - * @bug     8004822
     3.8 + * @bug     8004822 8007961
     3.9   * @author  mnunez
    3.10   * @summary Language model api test basics for repeating annotations
    3.11   * @library /tools/javac/lib
    3.12   * @library supportingAnnotations
    3.13 - * @ignore  8013407: test failures for repeating annotations
    3.14   * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
    3.15   * @compile -processor ElementRepAnnoTester -proc:only
    3.16   * MixRepeatableAndOfficialContainerInheritedA1Test.java
     4.1 --- a/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedB1Test.java	Wed Jul 24 17:35:42 2013 -0700
     4.2 +++ b/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedB1Test.java	Thu Jul 25 11:02:27 2013 +0200
     4.3 @@ -23,12 +23,11 @@
     4.4  
     4.5  /*
     4.6   * @test
     4.7 - * @bug     8004822
     4.8 + * @bug     8004822 8007961
     4.9   * @author  mnunez
    4.10   * @summary Language model api test basics for repeating annotations
    4.11   * @library /tools/javac/lib
    4.12   * @library supportingAnnotations
    4.13 - * @ignore  8013407: test failures for repeating annotations
    4.14   * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
    4.15   * @compile -processor ElementRepAnnoTester -proc:only
    4.16   * MixRepeatableAndOfficialContainerInheritedB1Test.java
     5.1 --- a/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedB2Test.java	Wed Jul 24 17:35:42 2013 -0700
     5.2 +++ b/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedB2Test.java	Thu Jul 25 11:02:27 2013 +0200
     5.3 @@ -23,12 +23,11 @@
     5.4  
     5.5  /*
     5.6   * @test
     5.7 - * @bug     8004822
     5.8 + * @bug     8004822 8007961
     5.9   * @author  mnunez
    5.10   * @summary Language model api test basics for repeating annotations
    5.11   * @library /tools/javac/lib
    5.12   * @library supportingAnnotations
    5.13 - * @ignore  8013407: test failures for repeating annotations
    5.14   * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
    5.15   * @compile -processor ElementRepAnnoTester -proc:only
    5.16   * MixRepeatableAndOfficialContainerInheritedB2Test.java
     6.1 --- a/test/tools/javac/processing/model/element/repeatingAnnotations/RepeatableOverrideATest.java	Wed Jul 24 17:35:42 2013 -0700
     6.2 +++ b/test/tools/javac/processing/model/element/repeatingAnnotations/RepeatableOverrideATest.java	Thu Jul 25 11:02:27 2013 +0200
     6.3 @@ -23,12 +23,11 @@
     6.4  
     6.5  /*
     6.6   * @test
     6.7 - * @bug     8004822
     6.8 + * @bug     8004822 8007961
     6.9   * @author  mnunez
    6.10   * @summary Language model api test basics for repeating annotations
    6.11   * @library /tools/javac/lib
    6.12   * @library supportingAnnotations
    6.13 - * @ignore  8013407: test failures for repeating annotations
    6.14   * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
    6.15   * @compile -processor ElementRepAnnoTester -proc:only RepeatableOverrideATest.java
    6.16   */
     7.1 --- a/test/tools/javac/processing/model/element/repeatingAnnotations/RepeatableOverrideBTest.java	Wed Jul 24 17:35:42 2013 -0700
     7.2 +++ b/test/tools/javac/processing/model/element/repeatingAnnotations/RepeatableOverrideBTest.java	Thu Jul 25 11:02:27 2013 +0200
     7.3 @@ -23,12 +23,11 @@
     7.4  
     7.5  /*
     7.6   * @test
     7.7 - * @bug     8004822
     7.8 + * @bug     8004822 8007961
     7.9   * @author  mnunez
    7.10   * @summary Language model api test basics for repeating annotations
    7.11   * @library /tools/javac/lib
    7.12   * @library supportingAnnotations
    7.13 - * @ignore  8013407: test failures for repeating annotations
    7.14   * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
    7.15   * @compile -processor ElementRepAnnoTester -proc:only RepeatableOverrideBTest.java
    7.16   */
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/test/tools/javac/processing/model/inheritedByType/EnsureOrder.java	Thu Jul 25 11:02:27 2013 +0200
     8.3 @@ -0,0 +1,106 @@
     8.4 +/*
     8.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
     8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     8.7 + *
     8.8 + * This code is free software; you can redistribute it and/or modify it
     8.9 + * under the terms of the GNU General Public License version 2 only, as
    8.10 + * published by the Free Software Foundation.
    8.11 + *
    8.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    8.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    8.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    8.15 + * version 2 for more details (a copy is included in the LICENSE file that
    8.16 + * accompanied this code).
    8.17 + *
    8.18 + * You should have received a copy of the GNU General Public License version
    8.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    8.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    8.21 + *
    8.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    8.23 + * or visit www.oracle.com if you need additional information or have any
    8.24 + * questions.
    8.25 + */
    8.26 +
    8.27 +/**
    8.28 + * @test
    8.29 + * @summary test that order is respected when inheriting both legacy container and single anno
    8.30 + * @bug 8007961
    8.31 + * @library /tools/javac/lib
    8.32 + * @build   JavacTestingAbstractProcessor EnsureOrder
    8.33 + * @compile -processor EnsureOrder -proc:only EnsureOrder.java
    8.34 + */
    8.35 +
    8.36 +import java.util.Set;
    8.37 +import java.lang.annotation.*;
    8.38 +import javax.annotation.processing.*;
    8.39 +import javax.lang.model.SourceVersion;
    8.40 +import static javax.lang.model.SourceVersion.*;
    8.41 +import javax.lang.model.element.*;
    8.42 +import javax.lang.model.util.*;
    8.43 +import static javax.lang.model.util.ElementFilter.*;
    8.44 +import static javax.tools.Diagnostic.Kind.*;
    8.45 +import static javax.tools.StandardLocation.*;
    8.46 +import com.sun.tools.javac.util.Assert;
    8.47 +
    8.48 +@Target({ElementType.TYPE_PARAMETER, ElementType.TYPE})
    8.49 +@Inherited
    8.50 +@Retention(RetentionPolicy.RUNTIME)
    8.51 +@Repeatable(Foos.class)
    8.52 +@interface Foo {
    8.53 +    int value();
    8.54 +}
    8.55 +
    8.56 +@Target({ElementType.TYPE_PARAMETER, ElementType.TYPE})
    8.57 +@Inherited
    8.58 +@Retention(RetentionPolicy.RUNTIME)
    8.59 +@interface Foos {
    8.60 +    Foo[] value();
    8.61 +}
    8.62 +
    8.63 +@Foos({@Foo(0), @Foo(1)}) @Foo(2)
    8.64 +class Base {}
    8.65 +
    8.66 +class Sub extends Base {}
    8.67 +
    8.68 +public class EnsureOrder<@Foos({@Foo(0), @Foo(1)}) @Foo(2)T> extends JavacTestingAbstractProcessor {
    8.69 +    public boolean process(Set<? extends TypeElement> annotations,
    8.70 +                           RoundEnvironment roundEnv) {
    8.71 +        if (!roundEnv.processingOver()) {
    8.72 +            int hasRun = 0;
    8.73 +            for (Element element : roundEnv.getRootElements()) {
    8.74 +                Name elemName = element.getSimpleName();
    8.75 +                if (elemName.contentEquals("Base")) {
    8.76 +                    hasRun++;
    8.77 +                    Foo[] foos = element.getAnnotationsByType(Foo.class);
    8.78 +                    Assert.check(foos.length == 3);
    8.79 +                    Assert.check(foos[0].value() == 0);
    8.80 +                    Assert.check(foos[1].value() == 1);
    8.81 +                    Assert.check(foos[2].value() == 2);
    8.82 +                }
    8.83 +                if (elemName.contentEquals("Sub")) {
    8.84 +                    hasRun++;
    8.85 +                    Foo[] foos = element.getAnnotationsByType(Foo.class);
    8.86 +                    Assert.check(foos.length == 3);
    8.87 +                    Assert.check(foos[0].value() == 0);
    8.88 +                    Assert.check(foos[1].value() == 1);
    8.89 +                    Assert.check(foos[2].value() == 2);
    8.90 +                }
    8.91 +                if (elemName.contentEquals("EnsureOrder")) {
    8.92 +                    for (TypeParameterElement t : ((TypeElement)element).getTypeParameters()) {
    8.93 +                        if (t.getSimpleName().contentEquals("T")) {
    8.94 +                            hasRun++;
    8.95 +                            Foo[] foos = t.getAnnotationsByType(Foo.class);
    8.96 +                            Assert.check(foos.length == 3);
    8.97 +                            Assert.check(foos[0].value() == 0);
    8.98 +                            Assert.check(foos[1].value() == 1);
    8.99 +                            Assert.check(foos[2].value() == 2);
   8.100 +                        }
   8.101 +                    }
   8.102 +                }
   8.103 +            }
   8.104 +            if (hasRun != 3)
   8.105 +                throw new RuntimeException("Couldn't find elements");
   8.106 +        }
   8.107 +        return true;
   8.108 +    }
   8.109 +}

mercurial