diff options
author | Sorin Basca <sorinbasca@google.com> | 2024-02-02 18:19:05 +0000 |
---|---|---|
committer | Sorin Basca <sorinbasca@google.com> | 2024-03-06 09:46:42 +0000 |
commit | d958d49fd4fa403bfd84aff8397ab4ce02eaf7c4 (patch) | |
tree | 884690b7c59c6253f2f715cae32b257397e6cef5 | |
parent | 01752c0520b50b1a042178e6c21e8eb4090cfe01 (diff) | |
download | nullaway-d958d49fd4fa403bfd84aff8397ab4ce02eaf7c4.tar.gz |
Allow build of nullaway with JDK21
PreservedAnnotationTreeVisitor.JDK17AndEarlierTypeMetadataBuilder
had to be built with JDK 17, or an earlier version. It was the
case that building with JDK 21 would cause build errors due to
changes in com.sun.tools.javac.code.TypeMetadata.Annotations and
com.sun.tools.javac.code.Type.cloneWithMetadata().
This change replicates the usage of MethodHandles used in
JDK21AndEarlierTypeMetadataBuilder to avoid compile time
references to the changed methods.
Bug: 313924276
Test: TH
Change-Id: I5bd38c66ebc058fc1fa206752a18de5412cf80fe
-rw-r--r-- | nullaway/src/main/java/com/uber/nullaway/generics/PreservedAnnotationTreeVisitor.java | 97 |
1 files changed, 56 insertions, 41 deletions
diff --git a/nullaway/src/main/java/com/uber/nullaway/generics/PreservedAnnotationTreeVisitor.java b/nullaway/src/main/java/com/uber/nullaway/generics/PreservedAnnotationTreeVisitor.java index 822fcf1..4549028 100644 --- a/nullaway/src/main/java/com/uber/nullaway/generics/PreservedAnnotationTreeVisitor.java +++ b/nullaway/src/main/java/com/uber/nullaway/generics/PreservedAnnotationTreeVisitor.java @@ -104,6 +104,41 @@ public class PreservedAnnotationTreeVisitor extends SimpleTreeVisitor<Type, Void TypeMetadata create(com.sun.tools.javac.util.List<Attribute.TypeCompound> attrs); Type cloneTypeWithMetadata(Type typeToBeCloned, TypeMetadata metaData); + + static MethodHandle createAnnotationsCtorHandle(Class<?> paramTypeClass) { + MethodHandles.Lookup lookup = MethodHandles.lookup(); + MethodType mt = MethodType.methodType(void.class, paramTypeClass); + try { + return lookup.findConstructor(TypeMetadata.Annotations.class, mt); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + /** + * Used to get a MethodHandle for a virtual method from the specified class + * + * @param retTypeClass Class to indicate the return type of the desired method + * @param paramTypeClass Class to indicate the parameter type of the desired method + * @param refClass Class within which the desired method is contained + * @param methodName Name of the desired method + * @return The appropriate MethodHandle for the virtual method + */ + static MethodHandle createVirtualMethodHandle( + Class<?> retTypeClass, Class<?> paramTypeClass, Class<?> refClass, String methodName) { + MethodHandles.Lookup lookup = MethodHandles.lookup(); + MethodType mt = MethodType.methodType(retTypeClass, paramTypeClass); + try { + return lookup.findVirtual(refClass, methodName, mt); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + } /** @@ -112,9 +147,18 @@ public class PreservedAnnotationTreeVisitor extends SimpleTreeVisitor<Type, Void */ private static class JDK17AndEarlierTypeMetadataBuilder implements TypeMetadataBuilder { + private static final MethodHandle typeMetadataHandle = + TypeMetadataBuilder.createAnnotationsCtorHandle(com.sun.tools.javac.util.List.class); + private static final MethodHandle cloneHandle = TypeMetadataBuilder.createVirtualMethodHandle( + Type.class, TypeMetadata.class, Type.class, "cloneWithMetadata"); + @Override public TypeMetadata create(com.sun.tools.javac.util.List<Attribute.TypeCompound> attrs) { - return new TypeMetadata(new TypeMetadata.Annotations(attrs)); + try { + return (TypeMetadata) typeMetadataHandle.invoke(attrs); + } catch (Throwable e) { + throw new RuntimeException(e); + } } /** @@ -127,7 +171,11 @@ public class PreservedAnnotationTreeVisitor extends SimpleTreeVisitor<Type, Void */ @Override public Type cloneTypeWithMetadata(Type typeToBeCloned, TypeMetadata metadata) { - return typeToBeCloned.cloneWithMetadata(metadata); + try { + return (Type) cloneHandle.invoke(typeToBeCloned, metadata); + } catch (Throwable e) { + throw new RuntimeException(e); + } } } @@ -138,45 +186,12 @@ public class PreservedAnnotationTreeVisitor extends SimpleTreeVisitor<Type, Void */ private static class JDK21TypeMetadataBuilder implements TypeMetadataBuilder { - private static final MethodHandle typeMetadataHandle = createHandle(); - private static final MethodHandle addMetadataHandle = - createVirtualMethodHandle(Type.class, TypeMetadata.class, Type.class, "addMetadata"); - private static final MethodHandle dropMetadataHandle = - createVirtualMethodHandle(Type.class, Class.class, Type.class, "dropMetadata"); - - private static MethodHandle createHandle() { - MethodHandles.Lookup lookup = MethodHandles.lookup(); - MethodType mt = MethodType.methodType(void.class, com.sun.tools.javac.util.ListBuffer.class); - try { - return lookup.findConstructor(TypeMetadata.Annotations.class, mt); - } catch (NoSuchMethodException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } - - /** - * Used to get a MethodHandle for a virtual method from the specified class - * - * @param retTypeClass Class to indicate the return type of the desired method - * @param paramTypeClass Class to indicate the parameter type of the desired method - * @param refClass Class within which the desired method is contained - * @param methodName Name of the desired method - * @return The appropriate MethodHandle for the virtual method - */ - private static MethodHandle createVirtualMethodHandle( - Class<?> retTypeClass, Class<?> paramTypeClass, Class<?> refClass, String methodName) { - MethodHandles.Lookup lookup = MethodHandles.lookup(); - MethodType mt = MethodType.methodType(retTypeClass, paramTypeClass); - try { - return lookup.findVirtual(refClass, methodName, mt); - } catch (NoSuchMethodException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } + private static final MethodHandle typeMetadataHandle = + TypeMetadataBuilder.createAnnotationsCtorHandle(com.sun.tools.javac.util.ListBuffer.class); + private static final MethodHandle addMetadataHandle = TypeMetadataBuilder.createVirtualMethodHandle( + Type.class, TypeMetadata.class, Type.class, "addMetadata"); + private static final MethodHandle dropMetadataHandle = TypeMetadataBuilder.createVirtualMethodHandle( + Type.class, Class.class, Type.class, "dropMetadata"); @Override public TypeMetadata create(com.sun.tools.javac.util.List<Attribute.TypeCompound> attrs) { |