diff --git a/jdk-annotations/jdk-integration-test/src/test/java/com/uber/nullaway/jdkannotations/JDKIntegrationTest.java b/jdk-annotations/jdk-integration-test/src/test/java/com/uber/nullaway/jdkannotations/JDKIntegrationTest.java index 9d7bb6584e..8588ec53c8 100644 --- a/jdk-annotations/jdk-integration-test/src/test/java/com/uber/nullaway/jdkannotations/JDKIntegrationTest.java +++ b/jdk-annotations/jdk-integration-test/src/test/java/com/uber/nullaway/jdkannotations/JDKIntegrationTest.java @@ -83,10 +83,13 @@ static void testPositive() { public void libraryModelWithoutJarInferEnabledTest() { compilationHelper .setArgs( - Arrays.asList( - "-d", - temporaryFolder.getRoot().getAbsolutePath(), - "-XepOpt:NullAway:AnnotatedPackages=com.uber")) + // Run this test in JSpecify mode to ensure that loading of JDK models does not also + // load external astubx files from JarInfer + JSpecifyJavacConfig.withJSpecifyModeArgs( + Arrays.asList( + "-d", + temporaryFolder.getRoot().getAbsolutePath(), + "-XepOpt:NullAway:AnnotatedPackages=com.uber"))) .addSourceLines( "Test.java", """ diff --git a/nullaway/src/main/java/com/uber/nullaway/generics/JSpecifyJavacConfig.java b/nullaway/src/main/java/com/uber/nullaway/generics/JSpecifyJavacConfig.java index a3a2d1094b..5116ed9332 100644 --- a/nullaway/src/main/java/com/uber/nullaway/generics/JSpecifyJavacConfig.java +++ b/nullaway/src/main/java/com/uber/nullaway/generics/JSpecifyJavacConfig.java @@ -20,9 +20,14 @@ public final class JSpecifyJavacConfig { public static final String ADD_TYPE_ANNOTATIONS_FLAG = "-XDaddTypeAnnotationsToSymbol=true"; public static final String HANDLE_WILDCARD_GENERICS_FLAG = "-XepOpt:NullAway:HandleWildcardGenerics=true"; + public static final String USE_JSPECIFY_JDK_MODELS = "-XepOpt:NullAway:JSpecifyJDKModels=true"; private static final List JSPECIFY_MODE_ARGS = - List.of(JSPECIFY_MODE_FLAG, ADD_TYPE_ANNOTATIONS_FLAG, HANDLE_WILDCARD_GENERICS_FLAG); + List.of( + JSPECIFY_MODE_FLAG, + ADD_TYPE_ANNOTATIONS_FLAG, + HANDLE_WILDCARD_GENERICS_FLAG, + USE_JSPECIFY_JDK_MODELS); private JSpecifyJavacConfig() {} diff --git a/nullaway/src/main/java/com/uber/nullaway/handlers/LibraryModelsHandler.java b/nullaway/src/main/java/com/uber/nullaway/handlers/LibraryModelsHandler.java index 9a30555c8b..d095e79344 100644 --- a/nullaway/src/main/java/com/uber/nullaway/handlers/LibraryModelsHandler.java +++ b/nullaway/src/main/java/com/uber/nullaway/handlers/LibraryModelsHandler.java @@ -1657,7 +1657,7 @@ private static class ExternalStubxLibraryModels implements LibraryModels { ExternalStubxLibraryModels(boolean isJarInferEnabled, boolean isJSpecifyJDKEnabled) { String libraryModelLogName = "LM"; - StubxCacheUtil cacheUtil = new StubxCacheUtil(libraryModelLogName); + StubxCacheUtil cacheUtil = new StubxCacheUtil(libraryModelLogName, isJarInferEnabled); if (isJarInferEnabled) { // hardcoded loading of stubx files from android-jarinfer-models-sdkXX artifacts try (InputStream androidStubxIS = diff --git a/nullaway/src/main/java/com/uber/nullaway/handlers/StubxCacheUtil.java b/nullaway/src/main/java/com/uber/nullaway/handlers/StubxCacheUtil.java index fd10c80c90..c6565d20ba 100644 --- a/nullaway/src/main/java/com/uber/nullaway/handlers/StubxCacheUtil.java +++ b/nullaway/src/main/java/com/uber/nullaway/handlers/StubxCacheUtil.java @@ -80,21 +80,23 @@ private void LOG(boolean cond, String tag, String msg) { private final Map> nestedAnnotationInfoCache; /** - * Initializes a new {@code StubxCacheUtil} instance. - * - *

This sets up the caches for argument annotations and upper bounds, sets the log caller, and - * loads the stubx files. + * Initializes a new {@code StubxCacheUtil} instance, optionally loading JarInfer stubx files + * discovered on the classpath. * * @param logCaller Identifier for logging purposes. + * @param loadJarInferModels whether to load stubx files provided by {@link JarInferStubxProvider} + * implementations */ - public StubxCacheUtil(String logCaller) { + StubxCacheUtil(String logCaller, boolean loadJarInferModels) { argAnnotCache = new LinkedHashMap<>(); upperBoundCache = new HashMap<>(); nullMarkedClassesCache = new HashSet<>(); methodTypeParamNullableUpperBoundCache = HashMultimap.create(); nestedAnnotationInfoCache = new HashMap<>(); this.logCaller = logCaller; - loadStubxFiles(); + if (loadJarInferModels) { + loadStubxFiles(); + } } public Map getUpperBoundCache() { diff --git a/nullaway/src/test/java/com/uber/nullaway/JSpecifyJDKModelsTest.java b/nullaway/src/test/java/com/uber/nullaway/JSpecifyJDKModelsTest.java index 5fe77cf758..901d912a55 100644 --- a/nullaway/src/test/java/com/uber/nullaway/JSpecifyJDKModelsTest.java +++ b/nullaway/src/test/java/com/uber/nullaway/JSpecifyJDKModelsTest.java @@ -36,9 +36,7 @@ void use(Attributes attrs) { public void listContainingNullsWithModel() { makeTestHelperWithArgs( JSpecifyJavacConfig.withJSpecifyModeArgs( - List.of( - "-XepOpt:NullAway:AnnotatedPackages=foo", - "-XepOpt:NullAway:JSpecifyJDKModels=true"))) + List.of("-XepOpt:NullAway:AnnotatedPackages=foo"))) .addSourceLines( "Test.java", """ @@ -66,8 +64,13 @@ void testNonNullContents(List list) { @Test public void listContainingNullsWithoutModel() { makeTestHelperWithArgs( - JSpecifyJavacConfig.withJSpecifyModeArgs( - List.of("-XepOpt:NullAway:AnnotatedPackages=foo"))) + // We specifically exclude the JSpecifyJDKModels flag here (so we can't use + // `withJSpecifyModeArgs`) + List.of( + "-XepOpt:NullAway:AnnotatedPackages=foo", + JSpecifyJavacConfig.JSPECIFY_MODE_FLAG, + JSpecifyJavacConfig.ADD_TYPE_ANNOTATIONS_FLAG, + JSpecifyJavacConfig.HANDLE_WILDCARD_GENERICS_FLAG)) .addSourceLines( "Test.java", """ diff --git a/nullaway/src/test/java/com/uber/nullaway/jspecify/GenericsTests.java b/nullaway/src/test/java/com/uber/nullaway/jspecify/GenericsTests.java index d693343c43..1046d328e7 100644 --- a/nullaway/src/test/java/com/uber/nullaway/jspecify/GenericsTests.java +++ b/nullaway/src/test/java/com/uber/nullaway/jspecify/GenericsTests.java @@ -2005,7 +2005,9 @@ public void testForNullTypeRhsTypeForArrayType() { class Test { static void testNegative() { List a = new ArrayList(); - Object[] o = a != null ? a.toArray() : null; + // TODO fix imprecise model of toArray() + // https://github.com/uber/NullAway/issues/1616 + @Nullable Object[] o = a != null ? a.toArray() : null; } } """) @@ -2582,6 +2584,8 @@ public class Test { static class K {} void foo(K<@Nullable Object> k) { K k2 = k; + // TODO should get no error here + // BUG: Diagnostic contains: returning @Nullable Supplier s = () -> null; } } diff --git a/nullaway/src/test/java/com/uber/nullaway/jspecify/StreamNullabilityPropagatorTests.java b/nullaway/src/test/java/com/uber/nullaway/jspecify/StreamNullabilityPropagatorTests.java index e02761b842..057d8ae58b 100644 --- a/nullaway/src/test/java/com/uber/nullaway/jspecify/StreamNullabilityPropagatorTests.java +++ b/nullaway/src/test/java/com/uber/nullaway/jspecify/StreamNullabilityPropagatorTests.java @@ -38,7 +38,7 @@ static Optional sumDoubles(@Nullable Double... doubles) { static Optional sumDoublesMissingfilter(@Nullable Double... doubles) { return Arrays.stream(doubles) - // BUG: Diagnostic contains: incompatible types + // BUG: Diagnostic contains: parameter a of referenced method is @NonNull .reduce(Double::sum); }