Skip to content

Commit 055f2fd

Browse files
Support @NullableDecl in Classes.createFactory
We want to migrate away from @nullable (#17), and this is a first step. Furthermore, support all annotations with name Nullable or NullableDecl, regardless of their package. This makes it easier for people who cannot use the standard annotations, because they can just define their own annotations.
1 parent 031ab45 commit 055f2fd

File tree

2 files changed

+20
-7
lines changed

2 files changed

+20
-7
lines changed

.classpath

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<classpathentry kind="lib" path="lib/java/test/byte-buddy.jar"/>
1717
<classpathentry kind="lib" path="lib/java/runtime/spotbugs-annotations.jar" sourcepath="lib/java-contrib/spotbugs-annotations-sources.jar"/>
1818
<classpathentry kind="lib" path="lib/java/runtime/jsr305.jar" sourcepath="lib/java-contrib/jsr305-sources.jar"/>
19-
<classpathentry kind="lib" path="lib/java/runtime/checker-compat-qual.jar"/>
19+
<classpathentry kind="lib" path="lib/java/runtime/checker-qual.jar"/>
2020
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
2121
<classpathentry kind="src" path=".apt-generated">
2222
<attributes>

src/org/sosy_lab/common/Classes.java

+19-6
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import com.google.common.reflect.TypeToken;
4040
import com.google.errorprone.annotations.CanIgnoreReturnValue;
4141
import com.google.errorprone.annotations.Var;
42+
import java.lang.reflect.AnnotatedElement;
4243
import java.lang.reflect.Constructor;
4344
import java.lang.reflect.Executable;
4445
import java.lang.reflect.InvocationTargetException;
@@ -533,8 +534,9 @@ public static ClassLoaderBuilder<?> makeExtendedURLClassLoader() {
533534
* <p>The factory interface needs to have exactly one method. The target class needs to have
534535
* either a single public static method name {@code create}, or a single public constructor. The
535536
* declared exceptions of the static method/constructor need to be a subset of those of the method
536-
* of the factory interface, and the same holds for the parameters. Parameters that are declared
537-
* {@link Nullable} may be missing in the factory interface.
537+
* of the factory interface, and the same holds for the parameters. Parameters that are annotated
538+
* with an annotation named {@code Nullable} or {@code NullableDecl} may be missing in the factory
539+
* interface.
538540
*
539541
* @param factoryType The factory interface
540542
* @param cls The class which should be instantiated by the returned factory
@@ -554,8 +556,9 @@ public static <I> I createFactory(Class<I> factoryType, Class<?> cls)
554556
* <p>The factory interface needs to have exactly one method. The target class needs to have
555557
* either a single public static method name {@code create}, or a single public constructor. The
556558
* declared exceptions of the static method/constructor need to be a subset of those of the method
557-
* of the factory interface, and the same holds for the parameters. Parameters that are declared
558-
* {@link Nullable} may be missing in the factory interface.
559+
* of the factory interface, and the same holds for the parameters. Parameters that are annotated
560+
* with an annotation named {@code Nullable} or {@code NullableDecl} may be missing in the factory
561+
* interface.
559562
*
560563
* @param factoryType A type token that represents the factory interface
561564
* @param cls The class which should be instantiated by the returned factory
@@ -614,11 +617,11 @@ public static <I> I createFactory(TypeToken<I> factoryType, Class<?> cls)
614617
int[] parameterMapping = new int[targetParamTypes.size()];
615618
boolean[] parameterNullability = new boolean[targetParamTypes.size()];
616619
for (int i = 0; i < targetParamTypes.size(); i++) {
617-
boolean targetNullability = targetParameters.get(i).isAnnotationPresent(Nullable.class);
620+
boolean targetNullability = isNullable(targetParameters.get(i));
618621
int sourceIndex = formalParamTypes.indexOf(targetParamTypes.get(i));
619622
boolean sourceNullability =
620623
(sourceIndex == -1) // parameter not present in interface
621-
|| formalParams[sourceIndex].isAnnotationPresent(Nullable.class);
624+
|| isNullable(formalParams[sourceIndex]);
622625
if (sourceNullability && !targetNullability) {
623626
throw new UnsuitedClassException(
624627
"'%s' requires parameter of type %s which is not present in factory interface",
@@ -669,6 +672,16 @@ private static Stream<TypeToken<?>> resolve(TypeToken<?> context, Type[] types)
669672
return Arrays.stream(types).<TypeToken<?>>map(type -> context.resolveType(type));
670673
}
671674

675+
private static boolean isNullable(AnnotatedElement elem) {
676+
for (java.lang.annotation.Annotation annotation : elem.getAnnotations()) {
677+
String name = annotation.annotationType().getSimpleName();
678+
if (name.equals("Nullable") || name.equals("NullableDecl")) {
679+
return true;
680+
}
681+
}
682+
return false;
683+
}
684+
672685
/**
673686
* Search for a method that we should use to instantiate the class. First, it looks for a public
674687
* static method named "create", second, for a public constructor.

0 commit comments

Comments
 (0)