[nullafe] Consolidate different ways to suppress field not initialized

Summary: See title

Reviewed By: artempyanykh

Differential Revision: D17281701

fbshipit-source-id: 5a2775f3e
master
Mitya Lyubarskiy 5 years ago committed by Facebook Github Bot
parent b1810ef3ff
commit fbeb58c0f2

@ -7,11 +7,13 @@
package codetoanalyze.java.nullsafe_default; package codetoanalyze.java.nullsafe_default;
import android.annotation.SuppressLint;
import android.app.Activity; import android.app.Activity;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import com.facebook.infer.annotation.Assertions; import com.facebook.infer.annotation.Assertions;
import com.facebook.infer.annotation.Initializer; import com.facebook.infer.annotation.Initializer;
import com.facebook.infer.annotation.SuppressFieldNotInitialized;
import com.facebook.infer.annotation.SuppressViewNullability; import com.facebook.infer.annotation.SuppressViewNullability;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -22,29 +24,44 @@ import javax.inject.Inject;
public class FieldNotInitialized { public class FieldNotInitialized {
String notNullIsBAD; // BAD: need to initialize it // different ways to suppress the error
class Suppression {
String notNullIsBAD; // BAD: need to initialize it
@Nonnull String nonnullIsBAD; // BAD: explicit annotation does not make it better @Nonnull String nonnullIsBAD; // BAD: explicit annotation does not make it better
@NonNull String nonNullIsBAD; // BAD: explicit annotation does not make it better @NonNull String nonNullIsBAD; // BAD: explicit annotation does not make it better
@Nullable String nullableIsOK; // OK: will be init with null @Nullable String nullableIsOK; // OK: will be init with null
@Inject String injectIsOK; // Means: assume it will be initialized via dependency injection @SuppressFieldNotInitialized String suppressAnnotationIsOK; // OK: explicitly suppressed
@Bind String bindIsOK; // Means: assume it will be initialized, and ignore null assignment @SuppressLint("eradicate-field-not-initialized")
String suppressLintIsOK; // OK: explicitly suppressed on lint level
// Means: assume it will be initialized, and ignore null assignment @SuppressLint("some-irrelevant-linter")
@SuppressViewNullability String suppressViewNullabilityIsOK; String suppressWrongLintIsBAD; // BAD: this suppression is irrelevant
FieldNotInitialized() {} @Inject String injectIsOK; // Means: assume it will be initialized via dependency injection
void testNullifyFields() { @Bind String bindIsOK; // Means: assume it will be initialized, and ignore null assignment
bindIsOK = null; // OK: the framework could write null into the field
suppressViewNullabilityIsOK = null; // OK: the framework could write null into the field // Means: assume it will be initialized, and ignore null assignment
nonnullIsBAD = null; // BAD: explicit annotation does not allow nullifying @SuppressViewNullability String suppressViewNullabilityIsOK;
nonNullIsBAD = null; // BAD: explicit annotation does not allow nullifying
injectIsOK = null; // BAD: can not nullify this Suppression() {}
// Ensure that some suppressions suppress only field not initialized
// and nothing else, but some suppress setting to null as well.
void testNullifyFields() {
bindIsOK = null; // OK: the framework could write null into the field
suppressViewNullabilityIsOK = null; // OK: the framework could write null into the field
nonnullIsBAD = null; // BAD: explicit nonnull annotation does not allow nullifying
nonNullIsBAD = null; // BAD: explicit nonnull annotation does not allow nullifying
injectIsOK = null; // BAD: inject suppressed only initialization issues
suppressAnnotationIsOK = null; // BAD: only initialization issue was suppressed
suppressLintIsOK = null; // BAD: only initialization issue was suppressed
}
} }
class OnlyRead { class OnlyRead {

@ -1,28 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package codetoanalyze.java.nullsafe_default;
import android.annotation.SuppressLint;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.CLASS)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
@interface SuppressFieldNotInitialized {}
public class SuppressedFieldNotInitializedExample {
@SuppressLint("eradicate-field-not-initialized")
String iKnowBetter;
@SuppressFieldNotInitialized String annotationSuppressed;
SuppressedFieldNotInitializedExample() {}
}

@ -17,7 +17,7 @@ codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.n
codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$InitCircular.<init>(codetoanalyze.java.nullsafe_default.FieldNotInitialized), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `FieldNotInitialized$InitCircular.bad` is not initialized in the constructor and is not declared `@Nullable`] codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$InitCircular.<init>(codetoanalyze.java.nullsafe_default.FieldNotInitialized), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `FieldNotInitialized$InitCircular.bad` is not initialized in the constructor and is not declared `@Nullable`]
codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$InitCircular.<init>(codetoanalyze.java.nullsafe_default.FieldNotInitialized), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `FieldNotInitialized$InitCircular.stillBad` is not initialized in the constructor and is not declared `@Nullable`] codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$InitCircular.<init>(codetoanalyze.java.nullsafe_default.FieldNotInitialized), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `FieldNotInitialized$InitCircular.stillBad` is not initialized in the constructor and is not declared `@Nullable`]
codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$InitIfNull.<init>(codetoanalyze.java.nullsafe_default.FieldNotInitialized), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `FieldNotInitialized$InitIfNull.shouldBeGood_FIXME` is not initialized in the constructor and is not declared `@Nullable`] codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$InitIfNull.<init>(codetoanalyze.java.nullsafe_default.FieldNotInitialized), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `FieldNotInitialized$InitIfNull.shouldBeGood_FIXME` is not initialized in the constructor and is not declared `@Nullable`]
codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$InitWithOtherClass.<init>(codetoanalyze.java.nullsafe_default.FieldNotInitialized,codetoanalyze.java.nullsafe_default.FieldNotInitialized$InitWithOtherClass$OtherClass), 1, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `FieldNotInitialized$InitWithOtherClass.bad` can be null but is not declared `@Nullable`. (Origin: field FieldNotInitialized$InitWithOtherClass$OtherClass.nullable at line 165)] codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$InitWithOtherClass.<init>(codetoanalyze.java.nullsafe_default.FieldNotInitialized,codetoanalyze.java.nullsafe_default.FieldNotInitialized$InitWithOtherClass$OtherClass), 1, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `FieldNotInitialized$InitWithOtherClass.bad` can be null but is not declared `@Nullable`. (Origin: field FieldNotInitialized$InitWithOtherClass$OtherClass.nullable at line 182)]
codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$InitWithTheSameClass.<init>(codetoanalyze.java.nullsafe_default.FieldNotInitialized,codetoanalyze.java.nullsafe_default.FieldNotInitialized$InitWithTheSameClass), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `FieldNotInitialized$InitWithTheSameClass.bad` is not initialized in the constructor and is not declared `@Nullable`] codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$InitWithTheSameClass.<init>(codetoanalyze.java.nullsafe_default.FieldNotInitialized,codetoanalyze.java.nullsafe_default.FieldNotInitialized$InitWithTheSameClass), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `FieldNotInitialized$InitWithTheSameClass.bad` is not initialized in the constructor and is not declared `@Nullable`]
codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$InitializationOrder.<init>(codetoanalyze.java.nullsafe_default.FieldNotInitialized,int), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `FieldNotInitialized$InitializationOrder.o1` is not initialized in the constructor and is not declared `@Nullable`] codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$InitializationOrder.<init>(codetoanalyze.java.nullsafe_default.FieldNotInitialized,int), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `FieldNotInitialized$InitializationOrder.o1` is not initialized in the constructor and is not declared `@Nullable`]
codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$OnlyRead.<init>(codetoanalyze.java.nullsafe_default.FieldNotInitialized), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `FieldNotInitialized$OnlyRead.o` is not initialized in the constructor and is not declared `@Nullable`] codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$OnlyRead.<init>(codetoanalyze.java.nullsafe_default.FieldNotInitialized), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `FieldNotInitialized$OnlyRead.o` is not initialized in the constructor and is not declared `@Nullable`]
@ -25,13 +25,16 @@ codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java
codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$ShouldInitializeInAllBranches.<init>(codetoanalyze.java.nullsafe_default.FieldNotInitialized,int), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `FieldNotInitialized$ShouldInitializeInAllBranches.f3` is not initialized in the constructor and is not declared `@Nullable`] codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$ShouldInitializeInAllBranches.<init>(codetoanalyze.java.nullsafe_default.FieldNotInitialized,int), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `FieldNotInitialized$ShouldInitializeInAllBranches.f3` is not initialized in the constructor and is not declared `@Nullable`]
codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$ShouldInitializeInAllBranches.<init>(codetoanalyze.java.nullsafe_default.FieldNotInitialized,int), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `FieldNotInitialized$ShouldInitializeInAllBranches.f5` is not initialized in the constructor and is not declared `@Nullable`] codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$ShouldInitializeInAllBranches.<init>(codetoanalyze.java.nullsafe_default.FieldNotInitialized,int), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `FieldNotInitialized$ShouldInitializeInAllBranches.f5` is not initialized in the constructor and is not declared `@Nullable`]
codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$ShouldInitializeInAllBranches.<init>(codetoanalyze.java.nullsafe_default.FieldNotInitialized,int), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `FieldNotInitialized$ShouldInitializeInAllBranches.f2` is not initialized in the constructor and is not declared `@Nullable`] codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$ShouldInitializeInAllBranches.<init>(codetoanalyze.java.nullsafe_default.FieldNotInitialized,int), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `FieldNotInitialized$ShouldInitializeInAllBranches.f2` is not initialized in the constructor and is not declared `@Nullable`]
codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$Suppression.<init>(codetoanalyze.java.nullsafe_default.FieldNotInitialized), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `FieldNotInitialized$Suppression.nonnullIsBAD` is not initialized in the constructor and is not declared `@Nullable`]
codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$Suppression.<init>(codetoanalyze.java.nullsafe_default.FieldNotInitialized), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `FieldNotInitialized$Suppression.notNullIsBAD` is not initialized in the constructor and is not declared `@Nullable`]
codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$Suppression.<init>(codetoanalyze.java.nullsafe_default.FieldNotInitialized), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `FieldNotInitialized$Suppression.suppressWrongLintIsBAD` is not initialized in the constructor and is not declared `@Nullable`]
codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$Suppression.<init>(codetoanalyze.java.nullsafe_default.FieldNotInitialized), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `FieldNotInitialized$Suppression.nonNullIsBAD` is not initialized in the constructor and is not declared `@Nullable`]
codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$Suppression.testNullifyFields():void, 3, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `FieldNotInitialized$Suppression.nonnullIsBAD` can be null but is not declared `@Nullable`. (Origin: null constant at line 59)]
codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$Suppression.testNullifyFields():void, 4, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `FieldNotInitialized$Suppression.nonNullIsBAD` can be null but is not declared `@Nullable`. (Origin: null constant at line 60)]
codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$Suppression.testNullifyFields():void, 5, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `FieldNotInitialized$Suppression.injectIsOK` can be null but is not declared `@Nullable`. (Origin: null constant at line 61)]
codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$Suppression.testNullifyFields():void, 6, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `FieldNotInitialized$Suppression.suppressAnnotationIsOK` can be null but is not declared `@Nullable`. (Origin: null constant at line 62)]
codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$Suppression.testNullifyFields():void, 7, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `FieldNotInitialized$Suppression.suppressLintIsOK` can be null but is not declared `@Nullable`. (Origin: null constant at line 63)]
codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$WriteItselfIsBAD.<init>(codetoanalyze.java.nullsafe_default.FieldNotInitialized), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `FieldNotInitialized$WriteItselfIsBAD.bad` is not initialized in the constructor and is not declared `@Nullable`] codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$WriteItselfIsBAD.<init>(codetoanalyze.java.nullsafe_default.FieldNotInitialized), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `FieldNotInitialized$WriteItselfIsBAD.bad` is not initialized in the constructor and is not declared `@Nullable`]
codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized.<init>(), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `FieldNotInitialized.notNullIsBAD` is not initialized in the constructor and is not declared `@Nullable`]
codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized.<init>(), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `FieldNotInitialized.nonNullIsBAD` is not initialized in the constructor and is not declared `@Nullable`]
codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized.<init>(), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `FieldNotInitialized.nonnullIsBAD` is not initialized in the constructor and is not declared `@Nullable`]
codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized.testNullifyFields():void, 3, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `FieldNotInitialized.nonnullIsBAD` can be null but is not declared `@Nullable`. (Origin: null constant at line 45)]
codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized.testNullifyFields():void, 4, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `FieldNotInitialized.nonNullIsBAD` can be null but is not declared `@Nullable`. (Origin: null constant at line 46)]
codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized.testNullifyFields():void, 5, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `FieldNotInitialized.injectIsOK` can be null but is not declared `@Nullable`. (Origin: null constant at line 47)]
codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.TestInitializerAnnotation.<init>(), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `TestInitializerAnnotation.dontInitAtAllIsBAD` is not initialized in the constructor and is not declared `@Nullable`] codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.TestInitializerAnnotation.<init>(), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `TestInitializerAnnotation.dontInitAtAllIsBAD` is not initialized in the constructor and is not declared `@Nullable`]
codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.TestInitializerAnnotation.<init>(), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `TestInitializerAnnotation.initInAnyOtherMethodIsBAD` is not initialized in the constructor and is not declared `@Nullable`] codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.TestInitializerAnnotation.<init>(), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `TestInitializerAnnotation.initInAnyOtherMethodIsBAD` is not initialized in the constructor and is not declared `@Nullable`]
codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.TestInitializerAnnotation.build():java.lang.Object, 5, ERADICATE_CONDITION_REDUNDANT, no_bucket, WARNING, [The condition TestInitializerAnnotation.initInInitilizerMethod2IsOK is always true according to the existing annotations.] codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.TestInitializerAnnotation.build():java.lang.Object, 5, ERADICATE_CONDITION_REDUNDANT, no_bucket, WARNING, [The condition TestInitializerAnnotation.initInInitilizerMethod2IsOK is always true according to the existing annotations.]

Loading…
Cancel
Save