Package: groovy.typecheckers

## [Groovy] Class NullChecker

- groovy.typecheckers.NullChecker

-     @Incubating
      class NullChecker
      extends TypeCheckingDSL

  A compile-time type checker that detects potential null dereferences and null-safety violations in code annotated with `@Nullable`, `@NonNull`, and `@MonotonicNonNull` annotations.

  By default, this checker performs annotation-based null checking only. For additional flow-sensitive analysis that tracks nullability through assignments and control flow (even in unannotated code), enable the `strict` option:

       @TypeChecked(extensions = 'groovy.typecheckers.NullChecker(strict: true)')

  Supported annotations are recognized by simple name from any package:

  - Nullable: `@Nullable`, `@CheckForNull`, `@MonotonicNonNull`
  - Non-null: `@NonNull`, `@NotNull`, `@Nonnull`

  Detected errors include:

  - Assigning `null` to a `@NonNull` variable
  - Passing `null` or a `@Nullable` value to a `@NonNull` parameter
  - Returning `null` or a `@Nullable` value from a `@NonNull` method
  - Dereferencing a `@Nullable` variable without a null check or safe navigation (`?.`)
  - Dereferencing the result of a `@Nullable`-returning method without a null check, whether called explicitly (`x.getA().b`) or via property syntax (`x.a.b`)
  - Dereferencing a result whose inferred type carries a `@Nullable` type argument reaching it through a class or method level type variable, e.g. `get(0)`, the idiomatic `xs[0]` subscript, or `head()` on a `List<@Nullable String>`, and `get(key)` or `m[key]` on a `Map<String, @Nullable Integer>`
  - Dereferencing a safe-navigation result without a further guard (`a?.b.c`; use `a?.b?.c` instead)
  - Passing other nullable expressions (safe-navigation results, `@Nullable`-returning calls, ternaries with a nullable branch) to `@NonNull` parameters, or returning them from `@NonNull` methods
  - Re-assigning `null` to a `@MonotonicNonNull` field after initialization
  - Dereferencing a variable known to be null through flow analysis (`strict` mode only)
  - An explicitly-annotated `@NonNull` instance field that is not definitely initialized — at its declaration, in an instance initializer block, or by every declared constructor (`strict` mode only)

  The checker recognizes a range of null-guard patterns:

  - Null comparisons: `if (x != null)`, `if (x == null)`
  - Early exit patterns: `if (x == null) return/throw`
  - Safe navigation: `?.`
  - Groovy-truth guards: `if (x)`, `if (!x) return`
  - Boolean conjunctions and disjunctions with short-circuit semantics: `if (x != null && x.length() > 0)`, `if (x == null || x.isEmpty()) return`
  - Type checks: `if (x instanceof Foo)`, `if (x !instanceof Foo) return`
  - Utility methods: `Objects.nonNull(x)`, `Objects.isNull(x)`
  - Assert statements: `assert x`, `assert x != null`
  - Guard conditions of while loops and ternary expressions
  - Validator methods which throw on null, so their argument is non-null afterwards: `Objects.requireNonNull(x)` and Guava-style `checkNotNull(x)`
  - Test assertions: `assertNotNull(x)` (JUnit 4/5, TestNG, or similar — message parameters are recognized in any position) and fluent `assertThat(x).isNotNull()` chains (AssertJ, Truth, or similar)
  Like annotations, validator and assertion methods are matched by simple name, so any library following the common naming conventions is recognized.

       @TypeChecked(extensions = 'groovy.typecheckers.NullChecker')
       void process(@Nullable String input) {
           // input.length()     // error: potential null dereference
           input?.length()       // ok: safe navigation
           if (input != null) {
               input.length()    // ok: null guard
           }
       }

  Over time, the idea would be to support more cases as per: https://checkerframework.org/manual/#nullness-checker
  Since:
    6.0.0

- - ### Constructor Summary

    Constructors
    Constructor and description
    `NullChecker()`

  - ### Methods Summary

    Methods
    Type Params | Return Type | Name and description
    --- | --- | ---
    `` | `Object` | `run()` Registers null-safety checks for each visited method body and, in strict mode, definite-initialization checks for `@NonNull` fields of each visited class.

- - ### Constructor Detail

    - #### NullChecker()

  - ### Method Detail

    - #### @Override
      Object run()

      Registers null-safety checks for each visited method body and, in strict mode, definite-initialization checks for `@NonNull` fields of each visited class.