|
|
|
/*
|
|
|
|
* Copyright (c) 2013-present, Facebook, Inc.
|
|
|
|
*
|
|
|
|
* 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.eradicate;
|
|
|
|
|
|
|
|
import android.support.annotation.NonNull;
|
|
|
|
import android.widget.EditText;
|
|
|
|
import com.facebook.infer.annotation.SuppressViewNullability;
|
|
|
|
import javax.annotation.Nonnull;
|
|
|
|
import javax.annotation.Nullable;
|
|
|
|
import javax.inject.Inject;
|
|
|
|
|
|
|
|
// for butterknife
|
|
|
|
@interface Bind {}
|
|
|
|
|
|
|
|
public class FieldNotInitialized {
|
|
|
|
|
|
|
|
String a;
|
|
|
|
|
|
|
|
@Nullable String b;
|
|
|
|
|
|
|
|
@Nonnull String c; // Means: assume it will be initialized to a nonnull value somewhere else.
|
|
|
|
|
|
|
|
@Inject String d; // Means: assume it will be initialized via dependency injection
|
|
|
|
|
|
|
|
@NonNull String e;
|
|
|
|
|
|
|
|
@Bind EditText f; // Means: assume it will be initialized, and ignore null assignment
|
|
|
|
|
|
|
|
@SuppressViewNullability EditText g;
|
|
|
|
|
|
|
|
// Eradicate should only report one initialization error
|
|
|
|
FieldNotInitialized() {}
|
|
|
|
|
|
|
|
void testNullifyFields() {
|
|
|
|
f = null; // OK the framework could write null into the field
|
|
|
|
g = null; // OK the framework could write null into the field
|
|
|
|
}
|
|
|
|
|
|
|
|
class OnlyRead {
|
|
|
|
Object o;
|
|
|
|
|
|
|
|
OnlyRead() {
|
|
|
|
Object x = o; // not initialized
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class WriteItself {
|
|
|
|
Object o;
|
|
|
|
|
|
|
|
WriteItself() {
|
|
|
|
o = o; // not initialized
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class Swap {
|
|
|
|
Object o1;
|
|
|
|
Object o2;
|
|
|
|
|
|
|
|
Swap() {
|
|
|
|
o1 = o2; // not initialized
|
|
|
|
o2 = new Object();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class SwapOK {
|
|
|
|
Object o1;
|
|
|
|
Object o2;
|
|
|
|
|
|
|
|
SwapOK() {
|
|
|
|
o1 = new Object();
|
|
|
|
o2 = o1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class OnlyReadIndirect {
|
|
|
|
Object o1;
|
|
|
|
Object o2;
|
|
|
|
|
|
|
|
private void indirect() {
|
|
|
|
Object x = o1; // not initialized
|
|
|
|
o2 = new Object();
|
|
|
|
}
|
|
|
|
|
|
|
|
OnlyReadIndirect() {
|
|
|
|
indirect();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class ConditionalFieldInit {
|
|
|
|
Object o1;
|
|
|
|
@Nullable Object o2 = null;
|
|
|
|
|
|
|
|
public ConditionalFieldInit() {
|
|
|
|
if (o2 != null) {
|
|
|
|
o1 = new Object(); // Not always initialized
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class InitIfNull {
|
|
|
|
Object o;
|
|
|
|
|
|
|
|
public InitIfNull() {
|
|
|
|
if (o == null) o = new Object();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class InitIfNull2 {
|
|
|
|
Object o;
|
|
|
|
|
|
|
|
public InitIfNull2(Object x) {
|
|
|
|
if (o == null) o = x;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class InitIfNull3 {
|
|
|
|
Object o;
|
|
|
|
|
|
|
|
Object getNotNull() {
|
|
|
|
return new Object();
|
|
|
|
}
|
|
|
|
|
|
|
|
public InitIfNull3() {
|
|
|
|
if (o == null) o = getNotNull();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class InitCircular {
|
|
|
|
String s;
|
|
|
|
|
|
|
|
InitCircular() {
|
|
|
|
String tmp = s;
|
|
|
|
s = tmp; // s is not initialized: circular initialization
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class InitWithOtherClass {
|
|
|
|
class OtherClass {
|
|
|
|
String s = "";
|
|
|
|
}
|
|
|
|
|
|
|
|
String s;
|
|
|
|
|
|
|
|
InitWithOtherClass(OtherClass x) {
|
|
|
|
s = x.s;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class InitWithThisClass {
|
|
|
|
|
|
|
|
String s;
|
|
|
|
|
|
|
|
InitWithThisClass(InitWithThisClass x) {
|
|
|
|
s = x.s;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|