39
39
import com .google .common .reflect .TypeToken ;
40
40
import com .google .errorprone .annotations .CanIgnoreReturnValue ;
41
41
import com .google .errorprone .annotations .Var ;
42
+ import java .lang .reflect .AnnotatedElement ;
42
43
import java .lang .reflect .Constructor ;
43
44
import java .lang .reflect .Executable ;
44
45
import java .lang .reflect .InvocationTargetException ;
@@ -533,8 +534,9 @@ public static ClassLoaderBuilder<?> makeExtendedURLClassLoader() {
533
534
* <p>The factory interface needs to have exactly one method. The target class needs to have
534
535
* either a single public static method name {@code create}, or a single public constructor. The
535
536
* 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.
538
540
*
539
541
* @param factoryType The factory interface
540
542
* @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)
554
556
* <p>The factory interface needs to have exactly one method. The target class needs to have
555
557
* either a single public static method name {@code create}, or a single public constructor. The
556
558
* 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.
559
562
*
560
563
* @param factoryType A type token that represents the factory interface
561
564
* @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)
614
617
int [] parameterMapping = new int [targetParamTypes .size ()];
615
618
boolean [] parameterNullability = new boolean [targetParamTypes .size ()];
616
619
for (int i = 0 ; i < targetParamTypes .size (); i ++) {
617
- boolean targetNullability = targetParameters .get (i ). isAnnotationPresent ( Nullable . class );
620
+ boolean targetNullability = isNullable ( targetParameters .get (i ));
618
621
int sourceIndex = formalParamTypes .indexOf (targetParamTypes .get (i ));
619
622
boolean sourceNullability =
620
623
(sourceIndex == -1 ) // parameter not present in interface
621
- || formalParams [sourceIndex ]. isAnnotationPresent ( Nullable . class );
624
+ || isNullable ( formalParams [sourceIndex ]);
622
625
if (sourceNullability && !targetNullability ) {
623
626
throw new UnsuitedClassException (
624
627
"'%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)
669
672
return Arrays .stream (types ).<TypeToken <?>>map (type -> context .resolveType (type ));
670
673
}
671
674
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
+
672
685
/**
673
686
* Search for a method that we should use to instantiate the class. First, it looks for a public
674
687
* static method named "create", second, for a public constructor.
0 commit comments