SIGN IN SIGN UP
facebook / react-native UNCLAIMED

A framework for building native applications using React

0 0 0 C++

Add @Nullsafe(Nullsafe.Mode.LOCAL) to clean interfaces and classes

Summary:
X-link: https://github.com/facebook/fresco/pull/2851

Add Nullsafe(Nullsafe.Mode.LOCAL) annotation to 10 un-annotated Java interfaces and classes across imagepipeline-base, drawee, and drawee-backends modules. These files require no NULLSAFE_FIXME suppressions — all null contracts are already correct. This is a compile-time annotation for Infer static analysis with zero runtime effect.

Files: QualityInfo, HasImageMetadata, ImageInfo (imagepipeline-base); DraweeHierarchy, SettableDraweeHierarchy, DraweeController, SimpleDraweeControllerBuilder, ControllerViewportVisibilityListener, GenericDraweeHierarchy (drawee); ImageOriginListener (drawee-backends). Also adds infer-annotations dep to drawee/interfaces BUCK.

**Context**

What is Nullsafe?

  Nullsafe is a Meta annotation that enables static null checking via https://fbinfer.com/, Meta's static analysis tool. When you annotate a class
  with Nullsafe, Infer analyzes the code at compile time (not runtime) and flags any place where a null value could sneak in and cause a crash.

  Without Nullsafe, Infer ignores null issues in that class. With it, every field, parameter, and return value is assumed non-null by default unless
   explicitly marked Nullable.

  What does Nullsafe.Mode.LOCAL mean?

  There are different strictness levels:
  ┌────────┬─────────────────────────────────────────────────────────────────────────────────────────────┐
  │  Mode  │                                       What it checks                                        │
  ├────────┼─────────────────────────────────────────────────────────────────────────────────────────────┤
  │ LOCAL  │ Only checks code within this class. Trusts that other classes return correct values.        │
  ├────────┼─────────────────────────────────────────────────────────────────────────────────────────────┤
  │ STRICT │ Checks this class AND requires all dependencies to also be Nullsafe. Much harder to adopt. │
  └────────┴─────────────────────────────────────────────────────────────────────────────────────────────┘
  LOCAL is the safe starting point — it catches bugs in the annotated class without requiring the entire dependency tree to be annotated first.

 **Java-Kotlin Interop and Platform Types**

  When Kotlin calls unannotated Java code, Kotlin treats return types as platform types (shown as Type!). This means Kotlin doesn't know if it's
  nullable or not, and lets you treat it either way:

  // Java: public String getName() { ... }  (no annotation)
  // Kotlin sees: String!  (platform type — could be null or non-null)

  val name: String = controller.name      // Kotlin allows this (treats as non-null)
  val name: String? = controller.name     // Kotlin also allows this (treats as nullable)

  Once we add Nullsafe to the Java class, unannotated types become strictly non-null, and Nullable-annotated types become strictly nullable:

 Safety

  These changes are compile-time only. Nullsafe and Nullable are annotation-only — they produce zero bytecode changes, zero runtime overhead, and
  don't change any actual behavior. They just make the compiler and static analysis catch null bugs earlier.

Changelog: [Internal]

Reviewed By: cortinico

Differential Revision: D93118745

fbshipit-source-id: b366466a4a7e702a09cdefe12681332f9ab0504e
N
Neha Gupta committed
945d1f5f51e70fce8a3b915e214e3a87f4c2f1bb
Parent: 88d40dc
Committed by meta-codesync[bot] <215208954+meta-codesync[bot]@users.noreply.github.com> on 2/16/2026, 5:44:26 PM