From 8a2713830f03cad63f0cfe8c0e5d69da22d160a8 Mon Sep 17 00:00:00 2001 From: jfranck Date: Thu, 18 Sep 2014 12:26:39 +0200 Subject: [PATCH] 8058632: Revert JDK-8054984 from 8u40 Reviewed-by: sla --- .../java/lang/reflect/Constructor.java | 28 +---- .../classes/java/lang/reflect/Executable.java | 23 ++-- .../ConstructorReceiverTest.java | 38 ++----- .../GetAnnotatedReceiverType.java | 101 +++--------------- .../TestExecutableGetAnnotatedType.java | 2 + 5 files changed, 37 insertions(+), 155 deletions(-) diff --git a/src/share/classes/java/lang/reflect/Constructor.java b/src/share/classes/java/lang/reflect/Constructor.java index 16671eba2..fb2aa2cc5 100644 --- a/src/share/classes/java/lang/reflect/Constructor.java +++ b/src/share/classes/java/lang/reflect/Constructor.java @@ -557,33 +557,15 @@ public final class Constructor extends Executable { */ @Override public AnnotatedType getAnnotatedReceiverType() { - Class thisDeclClass = getDeclaringClass(); - Class enclosingClass = thisDeclClass.getEnclosingClass(); + if (getDeclaringClass().getEnclosingClass() == null) + return super.getAnnotatedReceiverType(); - if (enclosingClass == null) { - // A Constructor for a top-level class - return null; - } - - Class outerDeclaringClass = thisDeclClass.getDeclaringClass(); - if (outerDeclaringClass == null) { - // A constructor for a local or anonymous class - return null; - } - - // Either static nested or inner class - if (Modifier.isStatic(thisDeclClass.getModifiers())) { - // static nested - return null; - } - - // A Constructor for an inner class return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(), sun.misc.SharedSecrets.getJavaLangAccess(). - getConstantPool(thisDeclClass), + getConstantPool(getDeclaringClass()), this, - thisDeclClass, - enclosingClass, + getDeclaringClass(), + getDeclaringClass().getEnclosingClass(), TypeAnnotation.TypeAnnotationTarget.METHOD_RECEIVER); } } diff --git a/src/share/classes/java/lang/reflect/Executable.java b/src/share/classes/java/lang/reflect/Executable.java index 70d87d8f1..75642265a 100644 --- a/src/share/classes/java/lang/reflect/Executable.java +++ b/src/share/classes/java/lang/reflect/Executable.java @@ -602,24 +602,21 @@ public abstract class Executable extends AccessibleObject /** * Returns an {@code AnnotatedType} object that represents the use of a * type to specify the receiver type of the method/constructor represented - * by this {@code Executable} object. + * by this Executable object. The receiver type of a method/constructor is + * available only if the method/constructor has a receiver + * parameter (JLS 8.4.1). * - * The receiver type of a method/constructor is available only if the - * method/constructor has a receiver parameter (JLS 8.4.1). If this {@code - * Executable} object represents an instance method or represents a - * constructor of an inner member class, and the - * method/constructor either has no receiver parameter or has a - * receiver parameter with no annotations on its type, then the return - * value is an {@code AnnotatedType} object representing an element with no + * If this {@code Executable} object represents a constructor or instance + * method that does not have a receiver parameter, or has a receiver + * parameter with no annotations on its type, then the return value is an + * {@code AnnotatedType} object representing an element with no * annotations. * - * If this {@code Executable} object represents a static method or - * represents a constructor of a top level, static member, local, or - * anoymous class, then the return value is null. + * If this {@code Executable} object represents a static method, then the + * return value is null. * * @return an object representing the receiver type of the method or - * constructor represented by this {@code Executable} or {@code null} if - * this {@code Executable} can not have a receiver parameter + * constructor represented by this {@code Executable} * * @since 1.8 */ diff --git a/test/java/lang/annotation/typeAnnotations/ConstructorReceiverTest.java b/test/java/lang/annotation/typeAnnotations/ConstructorReceiverTest.java index fb3145027..d4a75daaa 100644 --- a/test/java/lang/annotation/typeAnnotations/ConstructorReceiverTest.java +++ b/test/java/lang/annotation/typeAnnotations/ConstructorReceiverTest.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8023651 8044629 + * @bug 8023651 * @summary Test that the receiver annotations and the return annotations of * constructors behave correctly. * @run testng ConstructorReceiverTest @@ -38,16 +38,11 @@ import org.testng.annotations.Test; import static org.testng.Assert.*; public class ConstructorReceiverTest { - public static final Integer EMPTY_ANNOTATED_TYPE = Integer.valueOf(-1); - // Format is { // { Class to get ctor for, // ctor param class, // value of anno of return type, - // value of anno for receiver, - // or null if there should be no receiver, - // or EMPTY_ANNOTATED_TYPE of there should be a receiver but - // no annotation + // value of anno for receiver or null if there should be no receiver anno // }, // ... // } @@ -56,15 +51,13 @@ public class ConstructorReceiverTest { { ConstructorReceiverTest.Middle.class, ConstructorReceiverTest.class, Integer.valueOf(10), Integer.valueOf(15) }, { ConstructorReceiverTest.Middle.Inner.class, ConstructorReceiverTest.Middle.class, Integer.valueOf(100), Integer.valueOf(150) }, { ConstructorReceiverTest.Middle.Inner.Innermost.class, ConstructorReceiverTest.Middle.Inner.class, Integer.valueOf(1000), Integer.valueOf(1500) }, - { ConstructorReceiverTest.Middle.InnerNoReceiver.class, ConstructorReceiverTest.Middle.class, Integer.valueOf(300), EMPTY_ANNOTATED_TYPE }, + { ConstructorReceiverTest.Middle.InnerNoReceiver.class, ConstructorReceiverTest.Middle.class, Integer.valueOf(300), null }, { ConstructorReceiverTest.Nested.class, null, Integer.valueOf(20), null }, { ConstructorReceiverTest.Nested.NestedMiddle.class, ConstructorReceiverTest.Nested.class, Integer.valueOf(200), Integer.valueOf(250)}, { ConstructorReceiverTest.Nested.NestedMiddle.NestedInner.class, ConstructorReceiverTest.Nested.NestedMiddle.class, Integer.valueOf(2000), Integer.valueOf(2500)}, - { ConstructorReceiverTest.Nested.NestedMiddle.NestedInnerNoReceiver.class, ConstructorReceiverTest.Nested.NestedMiddle.class, Integer.valueOf(4000), EMPTY_ANNOTATED_TYPE}, - { ConstructorReceiverTest.Nested.NestedMiddle.SecondNestedInnerNoReceiver.class, ConstructorReceiverTest.Nested.NestedMiddle.class, Integer.valueOf(5000), EMPTY_ANNOTATED_TYPE}, + { ConstructorReceiverTest.Nested.NestedMiddle.NestedInnerNoReceiver.class, ConstructorReceiverTest.Nested.NestedMiddle.class, Integer.valueOf(4000), null}, }; - @DataProvider public Object[][] data() { return TESTS; } @@ -78,27 +71,14 @@ public class ConstructorReceiverTest { c = toTest.getDeclaredConstructor(ctorParamType); AnnotatedType annotatedReceiverType = c.getAnnotatedReceiverType(); - - // Some Constructors doesn't conceptually have a receiver, they should return null - if (receiverVal == null) { - assertNull(annotatedReceiverType, "getAnnotatedReciverType should return null for Constructor: " + c); - return; - } - - // check that getType() matches the receiver - assertEquals(annotatedReceiverType.getType(), - ctorParamType, - "getType() doesn't match receiver type: " + ctorParamType); - Annotation[] receiverAnnotations = annotatedReceiverType.getAnnotations(); - // Some Constructors have no annotations on but in theory can have a receiver - if (receiverVal.equals(EMPTY_ANNOTATED_TYPE)) { - assertEquals(receiverAnnotations.length, 0, "expecting an empty annotated type for: " + c); + if (receiverVal == null) { + assertEquals(receiverAnnotations.length, 0, Arrays.asList(receiverAnnotations).toString() + + " should be empty. Looking at 'length': "); return; } - // The rest should have annotations assertEquals(receiverAnnotations.length, 1, "expecting a 1 element array. Looking at 'length': "); assertEquals(((Annot)receiverAnnotations[0]).value(), receiverVal.intValue(), " wrong annotation found. Found " + receiverAnnotations[0] + @@ -156,10 +136,6 @@ public class ConstructorReceiverTest { class NestedInnerNoReceiver { @Annot(4000) public NestedInnerNoReceiver() {} } - - class SecondNestedInnerNoReceiver { - @Annot(5000) public SecondNestedInnerNoReceiver(NestedMiddle NestedMiddle.this) {} - } } } diff --git a/test/java/lang/annotation/typeAnnotations/GetAnnotatedReceiverType.java b/test/java/lang/annotation/typeAnnotations/GetAnnotatedReceiverType.java index e96080897..e3dd64612 100644 --- a/test/java/lang/annotation/typeAnnotations/GetAnnotatedReceiverType.java +++ b/test/java/lang/annotation/typeAnnotations/GetAnnotatedReceiverType.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. + * 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 @@ -23,11 +23,10 @@ /* * @test - * @bug 8024915 8044629 + * @bug 8024915 */ import java.lang.reflect.AnnotatedType; -import java.lang.reflect.Executable; import java.util.Arrays; public class GetAnnotatedReceiverType { @@ -43,115 +42,41 @@ public class GetAnnotatedReceiverType { public Inner1(GetAnnotatedReceiverType GetAnnotatedReceiverType.this) {} } - public static class Nested { - public Nested() {} - - public class NestedInner { - public NestedInner() { } - - public Class getLocalClass () { - class NestedInnerLocal { public NestedInnerLocal() {} } - return NestedInnerLocal.class; - } - - public Class getAnonymousClass() { - return new Object() {}.getClass(); - } - } - } - - public class Inner2 { - public Inner2() { } - - public class Inner3 { - public Inner3() { } - - public Class getLocalClass () { - class InnerLocal { public InnerLocal() {} } - return InnerLocal.class; - } - - public Class getAnonymousClass() { - return new Object() {}.getClass(); - } - } - - public Class getLocalClass () { - class InnerLocal { public InnerLocal() {} } - return InnerLocal.class; - } - - public Class getAnonymousClass() { - return new Object() {}.getClass(); - } - } - private static int failures = 0; private static int tests = 0; public static void main(String[] args) throws NoSuchMethodException { - checkEmptyAT(GetAnnotatedReceiverType.class.getMethod("method"), + checkEmptyAT(GetAnnotatedReceiverType.class.getMethod("method").getAnnotatedReceiverType(), "getAnnotatedReceiverType for \"method\" should return an empty AnnotatedType"); - checkEmptyAT(Inner0.class.getConstructor(GetAnnotatedReceiverType.class), + checkEmptyAT(Inner0.class.getConstructor(GetAnnotatedReceiverType.class).getAnnotatedReceiverType(), "getAnnotatedReceiverType for a ctor without a \"this\" should return an empty AnnotatedType"); - checkEmptyAT(GetAnnotatedReceiverType.class.getMethod("method0"), + checkEmptyAT(GetAnnotatedReceiverType.class.getMethod("method0").getAnnotatedReceiverType(), "getAnnotatedReceiverType for \"method0\" should return an empty AnnotatedType"); - checkEmptyAT(Inner1.class.getConstructor(GetAnnotatedReceiverType.class), + checkEmptyAT(Inner1.class.getConstructor(GetAnnotatedReceiverType.class).getAnnotatedReceiverType(), "getAnnotatedReceiverType for a ctor with a \"this\" should return an empty AnnotatedType"); - checkNull(GetAnnotatedReceiverType.class.getMethod("method4"), + checkNull(GetAnnotatedReceiverType.class.getMethod("method4").getAnnotatedReceiverType(), "getAnnotatedReceiverType() on a static method should return null"); - // More nested, inner, local and anonymous classes - Nested nested = new Nested(); - Nested.NestedInner instance = nested.new NestedInner(); - checkNull(nested.getClass().getConstructors()[0], - "getAnnotatedReceiverType() on a constructor for a static class should return null"); - checkEmptyAT(instance.getClass().getConstructors()[0], - "getAnnotatedReceiverType for a ctor without a \"this\" should return an empty AnnotatedType"); - checkNull(instance.getLocalClass().getConstructors()[0], - "getAnnotatedReceiverType() on a constructor for a local class should return null"); - checkNull(instance.getAnonymousClass().getDeclaredConstructors()[0], - "getAnnotatedReceiverType() on a constructor for an anonymous class should return null"); - - GetAnnotatedReceiverType outer = new GetAnnotatedReceiverType(); - Inner2 instance2 = outer.new Inner2(); - checkEmptyAT(instance2.getClass().getConstructors()[0], - "getAnnotatedReceiverType for a ctor without a \"this\" should return an empty AnnotatedType"); - checkNull(instance2.getLocalClass().getConstructors()[0], - "getAnnotatedReceiverType() on a constructor for a local class should return null"); - checkNull(instance2.getAnonymousClass().getDeclaredConstructors()[0], - "getAnnotatedReceiverType() on a constructor for an anonymous class should return null"); - - Inner2.Inner3 instance3 = instance2.new Inner3(); - checkEmptyAT(instance3.getClass().getConstructors()[0], - "getAnnotatedReceiverType for a ctor without a \"this\" should return an empty AnnotatedType"); - checkNull(instance3.getLocalClass().getConstructors()[0], - "getAnnotatedReceiverType() on a constructor for a local class should return null"); - checkNull(instance3.getAnonymousClass().getDeclaredConstructors()[0], - "getAnnotatedReceiverType() on a constructor for an anonymous class should return null"); - if (failures != 0) throw new RuntimeException("Test failed, see log for details"); - else if (tests != 15) + else if (tests != 5) throw new RuntimeException("Not all cases ran, failing"); } - private static void checkNull(Executable e, String msg) { - AnnotatedType a = e.getAnnotatedReceiverType(); - if (a != null) { + private static void checkNull(Object o, String msg) { + if (o != null) { failures++; - System.err.println(msg + ": " + e); + System.err.println(msg); } tests++; } - private static void checkEmptyAT(Executable e, String msg) { - AnnotatedType a = e.getAnnotatedReceiverType(); + private static void checkEmptyAT(AnnotatedType a, String msg) { if (a.getAnnotations().length != 0) { failures++; - System.err.print(msg + ": " + e); + System.err.print(msg); } tests++; } diff --git a/test/java/lang/annotation/typeAnnotations/TestExecutableGetAnnotatedType.java b/test/java/lang/annotation/typeAnnotations/TestExecutableGetAnnotatedType.java index 6735f46ce..ad8a87a13 100644 --- a/test/java/lang/annotation/typeAnnotations/TestExecutableGetAnnotatedType.java +++ b/test/java/lang/annotation/typeAnnotations/TestExecutableGetAnnotatedType.java @@ -73,11 +73,13 @@ public class TestExecutableGetAnnotatedType { testParameters(e.getParameters()); } + // should test constructors as well, see JDK-8044629 @Test(dataProvider = "genericMethodData") public void testGenericReceiverType(Executable e) throws Exception { testReceiverType0(e); } + // should test constructors as well, see JDK-8044629 @Test(dataProvider = "methodData") public void testReceiverType(Executable e) throws Exception { testReceiverType0(e); -- GitLab