Skip to content

Suppress CastToNonNull warnings for @NullUnmarked method calls#1258

Merged
msridhar merged 3 commits intouber:masterfrom
raccoonback:do-not-warn-on-assume-nonnull
Aug 26, 2025
Merged

Suppress CastToNonNull warnings for @NullUnmarked method calls#1258
msridhar merged 3 commits intouber:masterfrom
raccoonback:do-not-warn-on-assume-nonnull

Conversation

@raccoonback
Copy link
Copy Markdown
Contributor

@raccoonback raccoonback commented Aug 25, 2025

Description

Currently, NullAway emits warnings when developers pass the return values of @NullUnmarked methods to assumeNonNull or castToNonNull.
However, in incremental null-safety migration scenarios, these warnings are unnecessary and may create noise for developers.

This change ensures that no warnings are reported in such cases, allowing developers to use assumeNonNull and castToNonNull freely with unmarked code.

Key Changes

  • The source expression is the return value of a method in a @NullUnmarked context.
  • That value is immediately wrapped with assumeNonNull or castToNonNull.

Related issue

Summary by CodeRabbit

  • Bug Fixes

    • Reduced false-positive Cast-to-NonNull warnings when values come from unmarked third‑party calls across package-, class-, and method-level unmarked contexts.
  • Tests

    • Added tests covering Cast-to-NonNull behavior with unmarked code at package, class, and method levels (including parenthesized and indirect scenarios).
    • Updated a test to remove an obsolete diagnostic expectation.
    • Note: the patch includes duplicated test blocks (tests added twice).

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Aug 25, 2025

Walkthrough

Adds a private helper to detect direct calls to unannotated methods and uses it to suppress CastToNonNull warnings for such calls. Removes one CastToNonNull diagnostic expectation in a Thrift test and adds multiple jspecify tests (duplicated blocks) covering @NullUnmarked package/class/method and related cases.

Changes

Cohort / File(s) Summary
Core analysis logic
nullaway/src/main/java/com/uber/nullaway/NullAway.java
Added private helper isCallToUnmarkedMethod(ExpressionTree) to detect direct method-invocation calls whose symbols are unannotated; extended checkCastToNonNullTakesNullable to skip reporting CastToNonNull when the argument is such a direct unannotated call. No public API changes.
Adjusted test
nullaway/src/test/java/com/uber/nullaway/ThriftTests.java
Removed an assertion that expected a CastToNonNull diagnostic for g.getId(); the call remains but the diagnostic is no longer asserted.
New jspecify tests (duplicated blocks)
nullaway/src/test/java/com/uber/nullaway/jspecify/NullMarkednessTests.java
Added five tests covering CastToNonNull interactions with @NullUnmarked code (package, class, method, parenthesized, indirect). The patch contains duplicate copies of these test blocks.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Compiler as Compilation
  participant NA as NullAway
  participant Check as checkCastToNonNullTakesNullable
  participant Helper as isCallToUnmarkedMethod
  participant CA as CodeAnnotationInfo

  Compiler->>NA: analyze cast-to-NonNull call
  NA->>Check: checkCastToNonNullTakesNullable(actual)
  Check->>Helper: isCallToUnmarkedMethod(actual)
  Helper->>CA: isSymbolUnannotated(methodSymbol)?
  CA-->>Helper: true/false
  Helper-->>Check: result
  alt direct unannotated call
    Check-->>NA: suppress CastToNonNull warning
  else
    Check-->>NA: proceed with existing checks (may report warning)
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • lazaroclapp
  • yuxincs

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.


📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between d1f96fe and 6624568.

📒 Files selected for processing (1)
  • nullaway/src/main/java/com/uber/nullaway/NullAway.java (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • nullaway/src/main/java/com/uber/nullaway/NullAway.java
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Aug 25, 2025

CLA assistant check
All committers have signed the CLA.

Don't warn when passing return values from @NullUnmarked methods to castToNonNull/assumeNonNull methods. This supports incremental null safety migrations by allowing developers to use assumeNonNull on unmarked code without spurious warnings.
@raccoonback raccoonback force-pushed the do-not-warn-on-assume-nonnull branch from 60a57e2 to 88e0c31 Compare August 25, 2025 13:33
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (5)
nullaway/src/main/java/com/uber/nullaway/NullAway.java (2)

324-346: Broaden detection: strip parens/casts and use base symbol for invocation lookup

The helper does the job for direct calls, but two small tweaks will make it robust and consistent with the rest of this class:

  • Strip surrounding parentheses and casts before the instanceof check.
  • Use getSymbolForMethodInvocation(...) (baseSymbol) instead of ASTHelpers.getSymbol(...) to correctly handle static imports and JDK 18’s implicit Object methods.

Also consider clarifying “direct” in the method name or Javadoc.

Apply:

-  private boolean isCallToUnmarkedMethod(ExpressionTree expr) {
-    if (!(expr instanceof MethodInvocationTree)) {
+  private boolean isCallToUnmarkedMethod(ExpressionTree expr) {
+    expr = stripParensAndCasts(expr);
+    if (!(expr instanceof MethodInvocationTree)) {
       return false;
     }
 
-    MethodInvocationTree methodInvoke = (MethodInvocationTree) expr;
-    Symbol.MethodSymbol methodSymbol = ASTHelpers.getSymbol(methodInvoke);
+    MethodInvocationTree methodInvoke = (MethodInvocationTree) expr;
+    Symbol.MethodSymbol methodSymbol = getSymbolForMethodInvocation(methodInvoke);
 
     if (methodSymbol == null) {
       return false;
     }
 
     return codeAnnotationInfo.isSymbolUnannotated(methodSymbol, config, handler);
   }

2082-2101: Minor perf: check isCallToUnmarkedMethod before mayBeNullExpr

When the argument is a call to @NullUnmarked code, we can skip the (potentially) more expensive dataflow in mayBeNullExpr. Flip the checks for a tiny win in hot code paths.

-      if (!isInitializer && !mayBeNullExpr(state, actual) && !isCallToUnmarkedMethod(actual)) {
+      if (!isInitializer && !isCallToUnmarkedMethod(actual) && !mayBeNullExpr(state, actual)) {
         String message =
             "passing known @NonNull parameter '"
                 + state.getSourceForNode(actual)
                 + "' to CastToNonNullMethod ("
                 + qualifiedName
                 + ") at position "
                 + castToNonNullPosition
                 + ". This method argument should only take values that NullAway considers @Nullable "
                 + "at the invocation site, but which are known not to be null at runtime.";
         return errorBuilder.createErrorDescription(
             new ErrorMessage(MessageTypes.CAST_TO_NONNULL_ARG_NONNULL, message),
             // The Tree passed as suggestTree is the expression being cast
             // to avoid recomputing the arg index:
             actual,
             buildDescription(tree),
             state,
             null);
       }
nullaway/src/test/java/com/uber/nullaway/jspecify/NullMarkednessTests.java (3)

1288-1326: Good coverage for package-level @NullUnmarked; add a “non-immediate wrapping” negative case

These assertions validate the intended suppression when castToNonNull immediately wraps a return from unmarked code. Add a companion test to ensure we still warn if the unmarked value is first stored in a local (i.e., not immediately wrapped).

Suggested addition:

+  @Test
+  public void castToNonNullWithNullUnmarkedPackage_localVariableStillWarns() {
+    makeTestHelperWithArgs(
+            Arrays.asList(
+                "-d",
+                temporaryFolder.getRoot().getAbsolutePath(),
+                "-XepOpt:NullAway:AnnotatedPackages=com.uber",
+                "-XepOpt:NullAway:CastToNonNullMethod=com.uber.nullaway.testdata.Util.castToNonNull"))
+        .addSourceLines(
+            "package-info.java",
+            "@NullUnmarked package com.example.thirdparty;",
+            "import org.jspecify.annotations.NullUnmarked;")
+        .addSourceLines(
+            "ThirdPartyUtils.java",
+            "package com.example.thirdparty;",
+            "public class ThirdPartyUtils {",
+            "  public static String getStringValue() {",
+            "    return \"some value\";",
+            "  }",
+            "}")
+        .addSourceLines(
+            "Test.java",
+            "package com.uber;",
+            "import static com.uber.nullaway.testdata.Util.castToNonNull;",
+            "import com.example.thirdparty.ThirdPartyUtils;",
+            "public class Test {",
+            "  public static void test() {",
+            "    String s = ThirdPartyUtils.getStringValue();",
+            "    // Now not an immediate wrapper around the unmarked call; should warn:",
+            "    // BUG: Diagnostic contains: passing known @NonNull parameter",
+            "    String val = castToNonNull(s);",
+            "  }",
+            "}")
+        .doTest();
+  }

1330-1359: Also test parentheses/casts around the unmarked call

The production code now strips parens/casts (or will, with the suggested refactor). Add a test to lock this in so we don’t regress.

+  @Test
+  public void castToNonNullWithNullUnmarkedClass_withParensAndCast() {
+    makeTestHelperWithArgs(
+            Arrays.asList(
+                "-d",
+                temporaryFolder.getRoot().getAbsolutePath(),
+                "-XepOpt:NullAway:AnnotatedPackages=com.uber",
+                "-XepOpt:NullAway:CastToNonNullMethod=com.uber.nullaway.testdata.Util.castToNonNull"))
+        .addSourceLines(
+            "ThirdPartyUtils.java",
+            "package com.uber;",
+            "import org.jspecify.annotations.NullUnmarked;",
+            "@NullUnmarked",
+            "public class ThirdPartyUtils {",
+            "  public static String getStringValue() {",
+            "    return \"x\";",
+            "  }",
+            "}")
+        .addSourceLines(
+            "Test.java",
+            "package com.uber;",
+            "import static com.uber.nullaway.testdata.Util.castToNonNull;",
+            "public class Test {",
+            "  public static void test() {",
+            "    String a = castToNonNull((ThirdPartyUtils.getStringValue()));",
+            "    String b = castToNonNull((String) (ThirdPartyUtils.getStringValue()));",
+            "    System.out.println(a + b);",
+            "  }",
+            "}")
+        .doTest();
+  }

1361-1392: Add a chained-call negative case to ensure we only suppress immediate wrappers

To prevent over-suppression, add a test where the unmarked return is first transformed by a marked method (e.g., String.trim()) before the cast. This should still warn.

+  @Test
+  public void castToNonNullWithNullUnmarkedMethod_chainedCallShouldWarn() {
+    makeTestHelperWithArgs(
+            Arrays.asList(
+                "-d",
+                temporaryFolder.getRoot().getAbsolutePath(),
+                "-XepOpt:NullAway:AnnotatedPackages=com.uber",
+                "-XepOpt:NullAway:CastToNonNullMethod=com.uber.nullaway.testdata.Util.castToNonNull"))
+        .addSourceLines(
+            "ThirdPartyUtils.java",
+            "package com.uber;",
+            "import org.jspecify.annotations.NullUnmarked;",
+            "public class ThirdPartyUtils {",
+            "  @NullUnmarked",
+            "  public static String getStringValue() {",
+            "    return \"x\";",
+            "  }",
+            "}")
+        .addSourceLines(
+            "Test.java",
+            "package com.uber;",
+            "import static com.uber.nullaway.testdata.Util.castToNonNull;",
+            "public class Test {",
+            "  public static void test() {",
+            "    // BUG: Diagnostic contains: passing known @NonNull parameter",
+            "    String s = castToNonNull(ThirdPartyUtils.getStringValue().trim());",
+            "  }",
+            "}")
+        .doTest();
+  }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between cbc3b51 and 88e0c31.

📒 Files selected for processing (3)
  • nullaway/src/main/java/com/uber/nullaway/NullAway.java (2 hunks)
  • nullaway/src/test/java/com/uber/nullaway/ThriftTests.java (0 hunks)
  • nullaway/src/test/java/com/uber/nullaway/jspecify/NullMarkednessTests.java (1 hunks)
💤 Files with no reviewable changes (1)
  • nullaway/src/test/java/com/uber/nullaway/ThriftTests.java
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: msridhar
PR: uber/NullAway#1245
File: guava-recent-unit-tests/src/test/java/com/uber/nullaway/guava/NullAwayGuavaParametricNullnessTests.java:101-102
Timestamp: 2025-08-14T18:50:06.159Z
Learning: In NullAway JSpecify tests, when JDK version requirements exist due to bytecode annotation reading capabilities, prefer failing tests over skipping them on unsupported versions to ensure CI catches regressions and enforces proper JDK version usage for developers.
📚 Learning: 2025-08-14T18:50:06.159Z
Learnt from: msridhar
PR: uber/NullAway#1245
File: guava-recent-unit-tests/src/test/java/com/uber/nullaway/guava/NullAwayGuavaParametricNullnessTests.java:101-102
Timestamp: 2025-08-14T18:50:06.159Z
Learning: In NullAway JSpecify tests, when JDK version requirements exist due to bytecode annotation reading capabilities, prefer failing tests over skipping them on unsupported versions to ensure CI catches regressions and enforces proper JDK version usage for developers.

Applied to files:

  • nullaway/src/test/java/com/uber/nullaway/jspecify/NullMarkednessTests.java

@codecov
Copy link
Copy Markdown

codecov bot commented Aug 25, 2025

Codecov Report

❌ Patch coverage is 77.77778% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.17%. Comparing base (cbc3b51) to head (6624568).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
...away/src/main/java/com/uber/nullaway/NullAway.java 77.77% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master    #1258      +/-   ##
============================================
- Coverage     88.19%   88.17%   -0.02%     
- Complexity     2424     2427       +3     
============================================
  Files            92       92              
  Lines          8002     8010       +8     
  Branches       1593     1595       +2     
============================================
+ Hits           7057     7063       +6     
- Misses          491      492       +1     
- Partials        454      455       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Collaborator

@msridhar msridhar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot @raccoonback!! Overall this looks great. I think the nitpick comments from @coderabbitai in this comment are worth addressing, except for the last comment asking for a test case involving trim() (I don't get that one). Could you look at those and then I will approve this?

@raccoonback
Copy link
Copy Markdown
Contributor Author

@msridhar I will check it!

@raccoonback raccoonback requested a review from msridhar August 26, 2025 14:54
@raccoonback
Copy link
Copy Markdown
Contributor Author

@msridhar
Hello
reviews have been reflected!
Please check it.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
nullaway/src/test/java/com/uber/nullaway/jspecify/NullMarkednessTests.java (3)

1397-1427: Great: covers ParenthesizedTree and TypeCastTree wrappers. Consider a negative case for conditionals.

You’re already guarding against trivial wrappers. One more high-signal negative would ensure we don’t suppress on non-trivial wrappers like conditionals (argument expression is not “a call” anymore):

Add a test like the following (new method), expecting a diagnostic on the conditional:

@Test
public void castToNonNullWithConditionalFromNullUnmarkedDoesWarn() {
  makeTestHelperWithArgs(
          Arrays.asList(
              "-d", temporaryFolder.getRoot().getAbsolutePath(),
              "-XepOpt:NullAway:AnnotatedPackages=com.uber",
              "-XepOpt:NullAway:CastToNonNullMethod=com.uber.nullaway.testdata.Util.castToNonNull"))
      .addSourceLines(
          "ThirdPartyUtils.java",
          "package com.uber;",
          "import org.jspecify.annotations.NullUnmarked;",
          "@NullUnmarked",
          "public class ThirdPartyUtils {",
          "  public static String a() { return \"a\"; }",
          "  public static String b() { return \"b\"; }",
          "}")
      .addSourceLines(
          "Test.java",
          "package com.uber;",
          "import static com.uber.nullaway.testdata.Util.castToNonNull;",
          "public class Test {",
          "  public static void test(boolean flag) {",
          "    // BUG: Diagnostic contains: CastToNonNullMethod",
          "    String s = castToNonNull(flag ? ThirdPartyUtils.a() : ThirdPartyUtils.b());",
          "  }",
          "}")
      .doTest();
}

1287-1460: Add parallel coverage for assumeNonNull and an explicit-@Nullable-in-unmarked negative.

The PR objective mentions both assumeNonNull and castToNonNull. These tests only target castToNonNull. To guard against regressions and clarify semantics, please add:

  1. Parallel tests for assumeNonNull (same five scenarios). Example for the package-level case:
@Test
public void assumeNonNullWithNullUnmarkedPackage() {
  makeTestHelperWithArgs(
          Arrays.asList(
              "-d", temporaryFolder.getRoot().getAbsolutePath(),
              "-XepOpt:NullAway:AnnotatedPackages=com.uber",
              "-XepOpt:NullAway:AssumeNonNullMethod=com.uber.nullaway.testdata.Util.assumeNonNull"))
      .addSourceLines(
          "package-info.java",
          "@NullUnmarked package com.example.thirdparty;",
          "import org.jspecify.annotations.NullUnmarked;")
      .addSourceLines(
          "ThirdPartyUtils.java",
          "package com.example.thirdparty;",
          "public class ThirdPartyUtils {",
          "  public static String getStringValue() { return \"v\"; }",
          "}")
      .addSourceLines(
          "Test.java",
          "package com.uber;",
          "import static com.uber.nullaway.testdata.Util.assumeNonNull;",
          "import com.example.thirdparty.ThirdPartyUtils;",
          "public class Test {",
          "  public static void test() {",
          "    String val = assumeNonNull(ThirdPartyUtils.getStringValue());",
          "    System.out.println(val);",
          "  }",
          "}")
      .doTest();
}
  1. A negative to ensure we still warn when the unmarked method explicitly returns @nullable (i.e., we do not suppress in that case). Example:
@Test
public void castToNonNullWithExplicitNullableFromUnmarkedWarns() {
  makeTestHelperWithArgs(
          Arrays.asList(
              "-d", temporaryFolder.getRoot().getAbsolutePath(),
              "-XepOpt:NullAway:AnnotatedPackages=com.uber",
              "-XepOpt:NullAway:CastToNonNullMethod=com.uber.nullaway.testdata.Util.castToNonNull"))
      .addSourceLines(
          "ThirdPartyUtils.java",
          "package com.uber;",
          "import org.jspecify.annotations.NullUnmarked;",
          "import org.jspecify.annotations.Nullable;",
          "@NullUnmarked",
          "public class ThirdPartyUtils {",
          "  public static @Nullable String maybeNull() { return null; }",
          "}")
      .addSourceLines(
          "Test.java",
          "package com.uber;",
          "import static com.uber.nullaway.testdata.Util.castToNonNull;",
          "public class Test {",
          "  public static void test() {",
          "    // BUG: Diagnostic contains: passing @Nullable parameter",
          "    String s = castToNonNull(ThirdPartyUtils.maybeNull());",
          "  }",
          "}")
      .doTest();
}

These additions tighten the spec coverage without inflating complexity.

If you’d like, I can push a follow-up commit adding these tests in the same style as the current ones.


1328-1362: Strengthen CastToNonNull warning assertion

The test in NullMarkednessTests.java (lines 1328–1362) currently checks only for the substring

// BUG: Diagnostic contains: passing known @NonNull parameter

but the real message built in NullAway.java (around line 2085) is:

"passing known @NonNull parameter '" 
    + state.getSourceForNode(actual) 
    + "' to CastToNonNullMethod (" 
    + qualifiedName 
    + ") at position "

To reduce brittleness without weakening the check, add a second contains assertion for the configured method name. For example:

@@ Test.java (in NullMarkednessTests.java)
-    // BUG: Diagnostic contains: passing known @NonNull parameter
+    // BUG: Diagnostic contains: passing known @NonNull parameter
+    // BUG: Diagnostic contains: Util.castToNonNull

If you’d rather match the fully-qualified name:

+    // BUG: Diagnostic contains: com.uber.nullaway.testdata.Util.castToNonNull

This ensures the test still fails if the message wording shifts, while confirming we’re warning on the right method.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 88e0c31 and d1f96fe.

📒 Files selected for processing (2)
  • nullaway/src/main/java/com/uber/nullaway/NullAway.java (2 hunks)
  • nullaway/src/test/java/com/uber/nullaway/jspecify/NullMarkednessTests.java (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • nullaway/src/main/java/com/uber/nullaway/NullAway.java
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: msridhar
PR: uber/NullAway#1245
File: guava-recent-unit-tests/src/test/java/com/uber/nullaway/guava/NullAwayGuavaParametricNullnessTests.java:101-102
Timestamp: 2025-08-14T18:50:06.159Z
Learning: In NullAway JSpecify tests, when JDK version requirements exist due to bytecode annotation reading capabilities, prefer failing tests over skipping them on unsupported versions to ensure CI catches regressions and enforces proper JDK version usage for developers.
📚 Learning: 2025-08-14T18:50:06.159Z
Learnt from: msridhar
PR: uber/NullAway#1245
File: guava-recent-unit-tests/src/test/java/com/uber/nullaway/guava/NullAwayGuavaParametricNullnessTests.java:101-102
Timestamp: 2025-08-14T18:50:06.159Z
Learning: In NullAway JSpecify tests, when JDK version requirements exist due to bytecode annotation reading capabilities, prefer failing tests over skipping them on unsupported versions to ensure CI catches regressions and enforces proper JDK version usage for developers.

Applied to files:

  • nullaway/src/test/java/com/uber/nullaway/jspecify/NullMarkednessTests.java
🔇 Additional comments (3)
nullaway/src/test/java/com/uber/nullaway/jspecify/NullMarkednessTests.java (3)

1287-1326: Good positive coverage for direct wrapping of @NullUnmarked package returns.

This validates the intended suppression path for immediate castToNonNull on values returned from @NullUnmarked code. Scenarios with both definitely-non-null and maybe-null flows are exercised. Looks good.


1364-1395: Class-level @NullUnmarked: direct wrapper suppression behaves as intended.

This complements the package-level case and ensures the helper recognizes class-level marking. No issues spotted.


1429-1460: Method-level @NullUnmarked: direct wrapper suppression covered.

This completes the trio (package/class/method) and aligns with the stated behavior. Good.

Copy link
Copy Markdown
Collaborator

@msridhar msridhar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Thanks again @raccoonback!

@msridhar msridhar enabled auto-merge (squash) August 26, 2025 15:12
@msridhar msridhar merged commit dedcd6c into uber:master Aug 26, 2025
11 of 14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants