Skip to content

Commit 89ecd19

Browse files
author
duke
committed
Automatic merge of jdk:master into master
2 parents 5e4081f + 53a3188 commit 89ecd19

File tree

7 files changed

+242
-7
lines changed

7 files changed

+242
-7
lines changed

src/java.base/share/classes/java/lang/reflect/Constructor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,7 @@ public AnnotatedType getAnnotatedReceiverType() {
662662
getConstantPool(thisDeclClass),
663663
this,
664664
thisDeclClass,
665-
enclosingClass,
665+
resolveToOwnerType(enclosingClass),
666666
TypeAnnotation.TypeAnnotationTarget.METHOD_RECEIVER);
667667
}
668668
}

src/java.base/share/classes/java/lang/reflect/Executable.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import sun.reflect.annotation.AnnotationSupport;
3939
import sun.reflect.annotation.TypeAnnotationParser;
4040
import sun.reflect.annotation.TypeAnnotation;
41+
import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
4142
import sun.reflect.generics.repository.ConstructorRepository;
4243

4344
/**
@@ -698,7 +699,7 @@ public AnnotatedType getAnnotatedReceiverType() {
698699
getConstantPool(getDeclaringClass()),
699700
this,
700701
getDeclaringClass(),
701-
getDeclaringClass(),
702+
resolveToOwnerType(getDeclaringClass()),
702703
TypeAnnotation.TypeAnnotationTarget.METHOD_RECEIVER);
703704
}
704705

@@ -753,4 +754,23 @@ public AnnotatedType[] getAnnotatedExceptionTypes() {
753754
TypeAnnotation.TypeAnnotationTarget.THROWS);
754755
}
755756

757+
static Type resolveToOwnerType(Class<?> c) {
758+
TypeVariable<?>[] v = c.getTypeParameters();
759+
Type o = resolveOwner(c);
760+
Type t;
761+
if (o != null || v.length > 0) {
762+
t = ParameterizedTypeImpl.make(c, v, o);
763+
} else {
764+
t = c;
765+
}
766+
return t;
767+
}
768+
769+
private static Type resolveOwner(Class<?> t) {
770+
if (Modifier.isStatic(t.getModifiers()) || !(t.isLocalClass() || t.isMemberClass() || t.isAnonymousClass())) {
771+
return null;
772+
}
773+
Class<?> d = t.getDeclaringClass();
774+
return ParameterizedTypeImpl.make(d, d.getTypeParameters(), resolveOwner(d));
775+
}
756776
}

test/jdk/java/lang/annotation/typeAnnotations/ConstructorReceiverTest.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,16 @@ public void testAnnotatedReciver(Class<?> toTest, Class<?> ctorParamType,
8585
return;
8686
}
8787

88-
// check that getType() matches the receiver
89-
assertEquals(annotatedReceiverType.getType(),
90-
ctorParamType,
91-
"getType() doesn't match receiver type: " + ctorParamType);
88+
// check that getType() matches the receiver (which can be parameterized)
89+
if (annotatedReceiverType.getType() instanceof ParameterizedType) {
90+
assertEquals(((ParameterizedType) annotatedReceiverType.getType()).getRawType(),
91+
ctorParamType,
92+
"getType() doesn't match receiver type: " + ctorParamType);
93+
} else {
94+
assertEquals(annotatedReceiverType.getType(),
95+
ctorParamType,
96+
"getType() doesn't match receiver type: " + ctorParamType);
97+
}
9298

9399
Annotation[] receiverAnnotations = annotatedReceiverType.getAnnotations();
94100

test/jdk/java/lang/annotation/typeAnnotations/TestExecutableGetAnnotatedType.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public void testParameterTypes(Executable e) throws Exception {
7575

7676
@Test(dataProvider = "genericMethodData")
7777
public void testGenericReceiverType(Executable e) throws Exception {
78-
testReceiverType0(e);
78+
testParameterizedReceiverType0(e);
7979
}
8080

8181
@Test(dataProvider = "methodData")
@@ -136,6 +136,15 @@ private void testReceiverType0(Executable e) {
136136
assertSame(e.getAnnotatedReceiverType().getType(), e.getDeclaringClass());
137137
}
138138

139+
private void testParameterizedReceiverType0(Executable e) {
140+
if (Modifier.isStatic(e.getModifiers()))
141+
assertNull(e.getAnnotatedReceiverType());
142+
else {
143+
assertTrue(e.getAnnotatedReceiverType().getType() instanceof ParameterizedType);
144+
assertSame(((ParameterizedType) e.getAnnotatedReceiverType().getType()).getRawType(), e.getDeclaringClass());
145+
}
146+
}
147+
139148
private void testReturnType(Method m) {
140149
Type t = m.getGenericReturnType();
141150
AnnotatedType at = m.getAnnotatedReturnType();
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/*
25+
* @test
26+
* @bug 8202471
27+
* @summary A nested class's owner can be type annotated if used as a receiver type
28+
*/
29+
30+
import java.lang.annotation.Target;
31+
import java.lang.annotation.*;
32+
import java.lang.reflect.AnnotatedParameterizedType;
33+
import java.lang.reflect.AnnotatedType;
34+
import java.lang.reflect.Method;
35+
36+
public class TestReceiverTypeOwner<T> {
37+
38+
public static void main(String[] args) throws NoSuchMethodException {
39+
Method method = TestReceiverTypeOwner.Inner.class.getDeclaredMethod("m");
40+
AnnotatedType receiverType = method.getAnnotatedReceiverType();
41+
AnnotatedParameterizedType parameterizedType = (AnnotatedParameterizedType) receiverType;
42+
AnnotatedType owner = parameterizedType.getAnnotatedOwnerType();
43+
Annotation[] annotations = owner.getAnnotations();
44+
if (annotations.length != 1 || !(annotations[0] instanceof TypeAnnotation)) {
45+
throw new AssertionError();
46+
}
47+
}
48+
49+
class Inner {
50+
void m(@TypeAnnotation TestReceiverTypeOwner<T>.Inner this) { }
51+
}
52+
53+
@Retention(RetentionPolicy.RUNTIME)
54+
@Target(ElementType.TYPE_USE)
55+
@interface TypeAnnotation { }
56+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/*
25+
* @test
26+
* @bug 8202471
27+
* @summary A constructor's parameterized receiver type's type variables can be type annotated
28+
*/
29+
30+
import java.lang.annotation.Target;
31+
import java.lang.annotation.*;
32+
import java.lang.reflect.AnnotatedParameterizedType;
33+
import java.lang.reflect.AnnotatedType;
34+
import java.lang.reflect.Constructor;
35+
36+
public class TestReceiverTypeParameterizedConstructor<T> {
37+
38+
public static void main(String[] args) throws NoSuchMethodException {
39+
doAssert(TestReceiverTypeParameterizedConstructor.Inner.class);
40+
doAssert(TestReceiverTypeParameterizedConstructor.Inner.Inner2.class);
41+
}
42+
43+
private static void doAssert(Class<?> c) throws NoSuchMethodException {
44+
Constructor<?> constructor = c.getDeclaredConstructor(c.getDeclaringClass());
45+
AnnotatedType receiverType = constructor.getAnnotatedReceiverType();
46+
AnnotatedParameterizedType parameterizedType = (AnnotatedParameterizedType) receiverType;
47+
int count = 0;
48+
do {
49+
AnnotatedType[] arguments = parameterizedType.getAnnotatedActualTypeArguments();
50+
Annotation[] annotations = arguments[0].getAnnotations();
51+
if (annotations.length != 1
52+
|| !(annotations[0] instanceof TypeAnnotation)
53+
|| ((TypeAnnotation) annotations[0]).value() != count++) {
54+
throw new AssertionError();
55+
}
56+
parameterizedType = (AnnotatedParameterizedType) parameterizedType.getAnnotatedOwnerType();
57+
} while (parameterizedType != null);
58+
}
59+
60+
class Inner<S> {
61+
Inner(TestReceiverTypeParameterizedConstructor<@TypeAnnotation(0) T> TestReceiverTypeParameterizedConstructor.this) { }
62+
63+
class Inner2 {
64+
Inner2(TestReceiverTypeParameterizedConstructor<@TypeAnnotation(1) T>.Inner<@TypeAnnotation(0) S> TestReceiverTypeParameterizedConstructor.Inner.this) { }
65+
}
66+
}
67+
68+
@Retention(RetentionPolicy.RUNTIME)
69+
@Target(ElementType.TYPE_USE)
70+
@interface TypeAnnotation {
71+
int value();
72+
}
73+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/*
25+
* @test
26+
* @bug 8202471
27+
* @summary A method's parameterized receiver type's type variables can be type annotated
28+
*/
29+
30+
import java.lang.annotation.Target;
31+
import java.lang.annotation.*;
32+
import java.lang.reflect.AnnotatedParameterizedType;
33+
import java.lang.reflect.AnnotatedType;
34+
import java.lang.reflect.Method;
35+
36+
public class TestReceiverTypeParameterizedMethod<T> {
37+
38+
public static void main(String[] args) throws NoSuchMethodException {
39+
doAssert(TestReceiverTypeParameterizedMethod.class);
40+
doAssert(TestReceiverTypeParameterizedMethod.Inner.class);
41+
}
42+
43+
private static void doAssert(Class<?> c) throws NoSuchMethodException {
44+
Method method = c.getDeclaredMethod("m");
45+
AnnotatedType receiverType = method.getAnnotatedReceiverType();
46+
AnnotatedParameterizedType parameterizedType = (AnnotatedParameterizedType) receiverType;
47+
int count = 0;
48+
do {
49+
AnnotatedType[] arguments = parameterizedType.getAnnotatedActualTypeArguments();
50+
Annotation[] annotations = arguments[0].getAnnotations();
51+
if (annotations.length != 1
52+
|| !(annotations[0] instanceof TypeAnnotation)
53+
|| ((TypeAnnotation) annotations[0]).value() != count++) {
54+
throw new AssertionError();
55+
}
56+
parameterizedType = (AnnotatedParameterizedType) parameterizedType.getAnnotatedOwnerType();
57+
} while (parameterizedType != null);
58+
}
59+
60+
void m(TestReceiverTypeParameterizedMethod<@TypeAnnotation(0) T> this) { }
61+
62+
class Inner<S> {
63+
void m(TestReceiverTypeParameterizedMethod<@TypeAnnotation(1) T>.Inner<@TypeAnnotation(0) S> this) { }
64+
}
65+
66+
@Retention(RetentionPolicy.RUNTIME)
67+
@Target(ElementType.TYPE_USE)
68+
@interface TypeAnnotation {
69+
int value();
70+
}
71+
}

0 commit comments

Comments
 (0)