Skip to content

Instantly share code, notes, and snippets.

@raphw
Created July 22, 2019 20:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save raphw/a155d5ef66d11e5fb131b7e6b8fb10e5 to your computer and use it in GitHub Desktop.
Save raphw/a155d5ef66d11e5fb131b7e6b8fb10e5 to your computer and use it in GitHub Desktop.
Fix for JDK-8202471.
Index: src/java.base/share/classes/java/lang/reflect/Executable.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/java.base/share/classes/java/lang/reflect/Executable.java (revision 55752:8ae33203d600a7c9f9b2be9b31a0eb8197270ab1)
+++ src/java.base/share/classes/java/lang/reflect/Executable.java (revision 55752+:8ae33203d600+)
@@ -38,6 +38,7 @@
import sun.reflect.annotation.AnnotationSupport;
import sun.reflect.annotation.TypeAnnotationParser;
import sun.reflect.annotation.TypeAnnotation;
+import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
import sun.reflect.generics.repository.ConstructorRepository;
/**
@@ -687,14 +688,29 @@
public AnnotatedType getAnnotatedReceiverType() {
if (Modifier.isStatic(this.getModifiers()))
return null;
+ Class<?> c = getDeclaringClass();
+ TypeVariable<?>[] v = c.getTypeParameters();
+ Type o = resolveOwner(c);
+ Type t;
+ if (o != null || v.length > 0) {
+ t = ParameterizedTypeImpl.make(c, v, o);
+ } else {
+ t = c;
+ }
return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(),
- SharedSecrets.getJavaLangAccess().
- getConstantPool(getDeclaringClass()),
+ SharedSecrets.getJavaLangAccess().getConstantPool(c),
this,
- getDeclaringClass(),
- getDeclaringClass(),
+ c,
+ t,
TypeAnnotation.TypeAnnotationTarget.METHOD_RECEIVER);
}
+
+ static Type resolveOwner(Class<?> t) {
+ if (Modifier.isStatic(t.getModifiers()) || !(t.isLocalClass() || t.isMemberClass()))
+ return null;
+ Class<?> d = t.getDeclaringClass();
+ return ParameterizedTypeImpl.make(d, d.getTypeParameters(), resolveOwner(d));
+ }
/**
* Returns an array of {@code AnnotatedType} objects that represent the use
package sample;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedParameterizedType;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Method;
public class ReceiverTypeGeneric<T> {
void m(ReceiverTypeGeneric<@TypeAnnotation T> this) { }
public static void main(String[] args) throws NoSuchMethodException {
Method method = ReceiverTypeGeneric.class.getDeclaredMethod("m");
AnnotatedType receiverType = method.getAnnotatedReceiverType();
assert receiverType instanceof AnnotatedParameterizedType;
AnnotatedParameterizedType parameterizedType = (AnnotatedParameterizedType) receiverType;
AnnotatedType[] arguments = parameterizedType.getAnnotatedActualTypeArguments();
assert arguments.length == 1;
Annotation[] annotations = arguments[0].getAnnotations();
assert annotations.length == 1;
assert annotations[0] instanceof TypeAnnotation;
}
}
package sample;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedParameterizedType;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class ReceiverTypeGenericConstructor<T> {
class Inner {
Inner(ReceiverTypeGenericConstructor<@TypeAnnotation T> ReceiverTypeGenericConstructor.this) { }
}
public static void main(String[] args) throws NoSuchMethodException {
Constructor<?> constructor = ReceiverTypeGenericConstructor.Inner.class.getDeclaredConstructor(ReceiverTypeGenericConstructor.class);
AnnotatedType receiverType = constructor.getAnnotatedReceiverType();
assert receiverType instanceof AnnotatedParameterizedType;
AnnotatedParameterizedType parameterizedType = (AnnotatedParameterizedType) receiverType;
AnnotatedType[] arguments = parameterizedType.getAnnotatedActualTypeArguments();
assert arguments.length == 1;
Annotation[] annotations = arguments[0].getAnnotations();
assert annotations.length == 1;
assert annotations[0] instanceof TypeAnnotation;
}
}
package sample;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedParameterizedType;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Method;
public class ReceiverTypeGenericNested<T> {
class Inner {
void m(@TypeAnnotation ReceiverTypeGenericNested<T>.Inner this) { }
}
public static void main(String[] args) throws NoSuchMethodException {
Method method = ReceiverTypeGenericNested.Inner.class.getDeclaredMethod("m");
AnnotatedType receiverType = method.getAnnotatedReceiverType();
assert receiverType instanceof AnnotatedParameterizedType;
AnnotatedParameterizedType parameterizedType = (AnnotatedParameterizedType) receiverType;
AnnotatedType owner = parameterizedType.getAnnotatedOwnerType();
assert owner != null;
Annotation[] annotations = owner.getAnnotations();
assert annotations.length == 1;
assert annotations[0] instanceof TypeAnnotation;
}
}
package sample;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_USE)
public @interface TypeAnnotation { }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment