From a7bb7d320cf774a9ec6beb9e6b79b9bef30accf1 Mon Sep 17 00:00:00 2001 From: Manu Sridharan Date: Fri, 23 Feb 2024 10:56:47 -0800 Subject: [PATCH] Check dereference of qualifier expression in method reference (#920) Fixes #919 --- .../main/java/com/uber/nullaway/NullAway.java | 8 ++++++++ .../com/uber/nullaway/NullAwayJava8Tests.java | 16 ++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/nullaway/src/main/java/com/uber/nullaway/NullAway.java b/nullaway/src/main/java/com/uber/nullaway/NullAway.java index 811ea592ed..1f67a4a0c0 100644 --- a/nullaway/src/main/java/com/uber/nullaway/NullAway.java +++ b/nullaway/src/main/java/com/uber/nullaway/NullAway.java @@ -986,6 +986,14 @@ public Description matchMemberReference(MemberReferenceTree tree, VisitorState s if (!withinAnnotatedCode(state)) { return Description.NO_MATCH; } + // Technically the qualifier expression of a method reference gets passed to + // Objects.requireNonNull, but it's fine to treat it as a dereference for error-checking + // purposes. The error message will be slightly inaccurate + Description derefErrorDescription = + matchDereference(tree.getQualifierExpression(), tree, state); + if (derefErrorDescription != Description.NO_MATCH) { + state.reportMatch(derefErrorDescription); + } Symbol.MethodSymbol referencedMethod = ASTHelpers.getSymbol(tree); Symbol.MethodSymbol funcInterfaceSymbol = NullabilityUtil.getFunctionalInterfaceMethod(tree, state.getTypes()); diff --git a/nullaway/src/test/java/com/uber/nullaway/NullAwayJava8Tests.java b/nullaway/src/test/java/com/uber/nullaway/NullAwayJava8Tests.java index 4ed038f916..6c37861534 100644 --- a/nullaway/src/test/java/com/uber/nullaway/NullAwayJava8Tests.java +++ b/nullaway/src/test/java/com/uber/nullaway/NullAwayJava8Tests.java @@ -22,4 +22,20 @@ public void functionalMethodSuperInterface() { public void functionalMethodOverrideSuperInterface() { defaultCompilationHelper.addSourceFile("NullAwayOverrideFunctionalInterfaces.java").doTest(); } + + @Test + public void methodReferenceOnNullableVariable() { + defaultCompilationHelper + .addSourceLines( + "Test.java", + "package com.uber;", + "import org.jspecify.annotations.Nullable;", + "class Test {", + " public static boolean test(@Nullable String text, java.util.Set s) {", + " // BUG: Diagnostic contains: dereferenced expression text is @Nullable", + " return s.stream().anyMatch(text::contains);", + " }", + "}") + .doTest(); + } }