8026855: AnnoConstruct.getAnnotationsByType includes inherited indirectly present annotations even when containee type is not inheritable
authorjfranck
Tue, 22 Oct 2013 03:36:44 +0200
changeset 21485 2759750a8cdf
parent 21484 c64ceb9090aa
child 21486 847de793f27a
8026855: AnnoConstruct.getAnnotationsByType includes inherited indirectly present annotations even when containee type is not inheritable Summary: In AnnoConstruct.getAnnotationByType() check that the annotation sought after is inherited before looking on supertypes. Reviewed-by: jjg
langtools/src/share/classes/com/sun/tools/javac/code/AnnoConstruct.java
langtools/test/tools/javac/processing/model/element/TestNonInherited.java
--- a/langtools/src/share/classes/com/sun/tools/javac/code/AnnoConstruct.java	Mon Oct 21 15:37:11 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/AnnoConstruct.java	Tue Oct 22 03:36:44 2013 +0200
@@ -25,6 +25,7 @@
 package com.sun.tools.javac.code;
 
 import java.lang.annotation.Annotation;
+import java.lang.annotation.Inherited;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 
@@ -112,7 +113,8 @@
         }
 
         // Deal with inherited annotations
-        if (direct == null && container == null)
+        if (direct == null && container == null &&
+                annoType.isAnnotationPresent(Inherited.class))
             return getInheritedAnnotations(annoType);
 
         // Pack them in an array
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/model/element/TestNonInherited.java	Tue Oct 22 03:36:44 2013 +0200
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8026855
+ * @summary Javac should only look on supertypes for repeatable annotations if
+ *          both container and containee are inherited.
+ * @library /tools/javac/lib
+ * @build   JavacTestingAbstractProcessor TestNonInherited
+ * @compile -processor TestNonInherited -proc:only TestNonInherited.java
+ */
+
+import com.sun.tools.javac.util.Assert;
+
+import java.lang.annotation.*;
+import java.util.Arrays;
+import java.util.Set;
+import javax.annotation.processing.*;
+import javax.lang.model.element.*;
+import javax.lang.model.util.*;
+
+import static javax.lang.model.util.ElementFilter.*;
+
+@TestNonInherited.Foo(1)
+public class TestNonInherited extends JavacTestingAbstractProcessor {
+    public boolean process(Set<? extends TypeElement> annotations,
+                           RoundEnvironment roundEnv) {
+        if (!roundEnv.processingOver()) {
+            boolean hasRun = false;
+            for (Element element : roundEnv.getRootElements())
+                for (TypeElement te : typesIn(element.getEnclosedElements()))
+                    if (te.getQualifiedName().contentEquals("TestNonInherited.T2")) {
+                        hasRun = true;
+                        Foo[] foos = te.getAnnotationsByType(Foo.class);
+                        System.out.println("  " + te);
+                        System.out.println("  " + Arrays.asList(foos));
+                        Assert.check(foos.length == 0, "Should not find any instance of @Foo");
+                    }
+            if (!hasRun)
+                throw new RuntimeException("The annotation processor could not find the declaration of T2, test broken!");
+        }
+        return true;
+    }
+
+    public static class T2 extends TestNonInherited {
+    }
+
+    @Repeatable(FooContainer.class)
+    public static @interface Foo {
+        int value();
+    }
+
+    @Inherited
+    public static @interface FooContainer {
+        Foo[] value();
+    }
+}