com um clique
nullaway
// Guide for resolving NullAway static analysis errors. Best practices for: - Passing ObservableSupplier/Supplier<@Nullable T> - Dereferencing potentially @Nullable values - Adding @NullMarked to Java code
// Guide for resolving NullAway static analysis errors. Best practices for: - Passing ObservableSupplier/Supplier<@Nullable T> - Dereferencing potentially @Nullable values - Adding @NullMarked to Java code
Add missing LINT.IfChange(...) / LINT.ThenChange(...) guards to enums in C++/Java and XML to keep them in sync. Trigger this skill ONLY when a contributor explicitly asks to add lint guards or synchronize enums using LINT guards.
Use when removing a `base::Feature` and its associated code
Identify and safely remove expired Chromium histograms (dead metrics/technical debt). Use this skill when a contributor asks to clean up metrics, fix code health issues related to histograms, remove obsolete code, or work on a histogram cleanup task.
Orchestrator for the "Code Health Hub" framework. Trigger only when the user refers to the Hub or asks to see "available cleanup tasks" within the Chromium technical debt reduction system.
How to identify and fix Java memory leaks in Android Chrome using LeakCanary traces.
Modularize a chrome/browser/ subfolder by splitting its sources out of the monolithic //chrome/browser:browser target into dedicated source_set targets in the subfolder's own BUILD.gn. Use when the user asks to modularize, extract, or create BUILD targets for a chrome/browser/ subfolder, or mentions "Project Bedrock", "//chrome/browser modularization", or wants to split a subfolder into header/impl/test targets. Also use when the user says "modularize chrome/browser/X" for any X.
| name | nullaway |
| description | Guide for resolving NullAway static analysis errors. Best practices for: - Passing ObservableSupplier/Supplier<@Nullable T> - Dereferencing potentially @Nullable values - Adding @NullMarked to Java code |
@NullMarked vs New CodeThe approach differs significantly depending on whether you are migrating
existing code to @NullMarked or writing new code in an already @NullMarked
context:
@NullMarked:
NullUtil.assumeNonNull() when dereferencing immediately
to satisfy the analyzer without runtime overhead. Use assert when storing
or returning values. Use if guards occasionally if it helps avoid
assertions, but avoid changing the logic.@NullMarked code):
asserts to enforce contracts. Rely on
correct annotations (or their absence for implicit @NonNull) and only use
null guards for @Nullable values. assumeNonNull() should generally not
be used for new code.assumeNonNull vs assert != nullThe choice between assumeNonNull and Java assert depends on how the value is
used:
NullUtil.assumeNonNull(x).
var value = mSupplier.get();
assumeNonNull(value);
value.doSomething();
assumeNonNull
is a no-op that satisfies the analyzer without adding redundant runtime
checks.assumeNonNull() should be on a separate line, almost
always, rather than used inline.assumeNonNull().assert x != null; before the
operation.
var value = mSupplier.get();
assert value != null;
return value;
@Nullable, prefer updating the method
signature over adding an assertion.assert value != null on Supplier.get()
during initialization. If the supplier value is set LATER (as is common with
UI wiring), the assert might fail immediately during construction. In such
cases, the getter should return @Nullable and callers should handle it,
rather than asserting non-null immediately.Supplier<@Nullable T> to a constructor that expects
Supplier<T> (non-nullable), or vice versa.Supplier<@Nullable T> rather
than wildcards like Supplier<? extends @Nullable T> in method signatures and
fields.SupplierUtils.upcast() is strictly for upcasting the type
parameter to a base class (e.g., Supplier<DerivedT> to Supplier<BaseT>).
Do NOT use it solely for handling nullability differences (e.g., Supplier<T>
to Supplier<@Nullable T>).Supplier<T> to Supplier<@Nullable T>) if you are passing around subclasses
of ObservableSupplier.Supplier<@Nullable T> and handle the nullity. Never use
hacks or assertions to force a Supplier<@Nullable T> to act as a
non-nullable Supplier<T>.Supplier<@Nullable T>.
assumeNonNull or assert).@Nullable.() -> { var x = getter(); assert x != null; return x; }). This defers the
assertion until the supplier is resolved.Supplier<@Nullable T> or MonotonicObservableSupplier<T> in method
signatures to avoid forcing non-nullability on callers.@NullMarked: Apply to the class level when you are ready to make the
whole class null-safe.@Nullable: Apply to fields, parameters, and return types that can be
null.@SuppressWarnings("NullAway"):
destroy or onDestroy methods if circular
references or cleanup order make it hard to satisfy the analyzer without
functional changes.@Nullable
field, the parameter itself should usually be marked @Nullable as well, even
if it is not immediately used as nullable in the constructor. This avoids
artificial non-null requirements at construction time.@Nullable, look at
how callers handle the return value:
@Nullable.Before (in Caller):
mReceiver = new Receiver(() -> assumeNonNull(nullableSupplier.get()));
After:
// Change constructor to take exact Supplier<@Nullable Item>
public Receiver(Supplier<@Nullable Item> supplier) {
mSupplier = supplier;
}
// In usage (Dereferenced right away)
void doSomething() {
var item = mSupplier.get();
assumeNonNull(item);
item.use();
}
// In usage (Stored or Passed)
void storeItem() {
var item = mSupplier.get();
assert item != null;
mStoredItem = item;
}
Supplier<DerivedItem> and the receiver
expects Supplier<@Nullable BaseItem>, use SupplierUtils.upcast() to pass
it:
mReceiver = new Receiver(SupplierUtils.upcast(derivedSupplier, BaseItem.class));
If the caller already has a Supplier<@Nullable Item>, pass it directly:
mReceiver = new Receiver(nullableSupplier);
Before applying the recipe above to force non-nullability or add assertions,
investigate the receiver. If the receiver (or classes it passes the supplier
to) already checks for null or can easily be updated to handle null, prefer
updating the signature to accept Supplier<@Nullable T> instead of forcing
non-nullability.
supplier.asNonNull().get() over var x = supplier.get(); assert x != null;.assumeNonNull(object) from
org.chromium.build.NullUtil instead of assert object != null when you want
to chain calls on the non-null object (e.g.,
assumeNonNull(mLayoutManager).getSomething()). It returns the non-null
object.if (x != null) to assert x != null).get_forTesting methods should just return @Nullable
(and be annotated as such) rather than asserting non-null, if the underlying
field is nullable. Let the test handle the nullity.PublicTransitLeakTest as a smoke test locally before
running all tests on CQ to validate functional changes introduced by
assertions.@Nullable or @MonotonicNonNull if
it's initialized later (e.g., in init or initWithProfile).@Nullable to
the method signature.assumeNonNull(null) to satisfy
a callback that expects a non-null value if the value can actually be null.
Update the callback definition to accept @Nullable T.