/* * Copyright (c) 2017 - present Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ package codetoanalyze.java.checkers; import com.google.common.base.Preconditions; import javax.annotation.Nullable; public class NullableViolation { class T { int x; void doSomething() {} } static native @Nullable T returnsNullable(); void dereferenceNullableReturnValueBad() { T t = returnsNullable(); t.x = 42; // reports here } void dereferenceNullableReturnValueOkay() { T t = returnsNullable(); if (t != null) { t.x = 42; // does not report here } } void dereferenceNullableMethodBad() { returnsNullable().doSomething(); // reports here } void dereferenceNullableMethodCheckedForNullOkay() { if (returnsNullable() != null) { returnsNullable().doSomething(); // does not report here } } void nullableMethodCheckedForNullAndReturnOkay() { if (returnsNullable() == null) { return; } returnsNullable().doSomething(); // does not report here } void dereferenceNullableMethodIncorrectlyCheckedForNullBad() { if (returnsNullable() == null) { returnsNullable().doSomething(); // reports here } } void dereferenceNullableMethodInElseBranchBad() { if (returnsNullable() != null) { } else { returnsNullable().doSomething(); // reports here } } native boolean star(); void dereferenceNullableMethodAlwaysCheckedForNullOkay() { if (star() && returnsNullable() != null) { returnsNullable().doSomething(); // does not report here } } void dereferenceNullableMethodNotAlwaysCheckedForNullBad() { if (star() || returnsNullable() != null) { returnsNullable().doSomething(); // reports here } } void usePreconditionsCheckNotNullOnVariableOkay() { T t = returnsNullable(); Preconditions.checkNotNull(t); t.doSomething(); // does not report here } void usePreconditionsCheckNotNullOnMethodOkay() { Preconditions.checkNotNull(returnsNullable()).doSomething(); // does not report here } void usePreconditionsCheckNotNullRepeatedCallOkay() { Preconditions.checkNotNull(returnsNullable()); returnsNullable().doSomething(); // does not report here } native @Nullable Object getNullableObject(); void pointerAssignmentWithSubtype() { Object object = getNullableObject(); object = "Hello"; } void deferenceAliasOfNullableValueCheckedForNullOkay() { T t = returnsNullable(); T s = t; if (t != null) { s.x = 42; } } void dereferenceWithAssignmentExpressionsOkay() { T t; while ((t = returnsNullable()) != null) { t.doSomething(); } } }