[nullsafe][refactor tests] split and improve FieldNotNullable tests

Summary:
See motivation below.
This diff is dealing with FieldNotNullable:
- move not relevant subclasses into dedicated classes and files
- modify the tests so they comply with the standards below

--Motivation--

Gradual mode we are going to introduce is an invasive change in how Infer
treats nullability semantics.

In order to make the change in a controllable way, we need the tests to comply with the
following standards and conventions.

1. For each code peace where we expect a bug to happen, the there should be
corresponding (minimally different from above) peace of code where we expect a bug to NOT happen. (This is to ensure bug is happening for exact reason we think it is happening).
2. Conversely: for each peace of code where we expect a bug to be NOT
present, there shuold be a peace of code where the bug IS happening.
(Otherwise there can be too many reasons for a bug NOT to happen).
3. Convention: end corresponding methods IsOK and IsBUG correspondingly.
4. Keep code examples as small as possible.

Reviewed By: ngorogiannis

Differential Revision: D17183222

fbshipit-source-id: 83d03e67f
master
Mitya Lyubarskiy 5 years ago committed by Facebook Github Bot
parent 3250ff35d2
commit 8add080e4a

@ -0,0 +1,84 @@
/*
* 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 javax.annotation.Nullable;
@interface InjectView {}
/** Support assignments of null to @InjectView fields, generated by butterknife. */
public class ButterKnife {
@InjectView String injected;
String normal = ""; // assign to suppress not initialized warning
@Nullable String nullable = ""; // assign to suppress not initialized warning
void f(String nonNullable) {}
// When dereferencing, injected should behave as not nullable
void dereferencingInjectedIsOK() {
int n = injected.length();
}
void dereferencingNormalIsOK() {
int n = normal.length();
}
void dereferencingNullableIsBAD() {
int n = nullable.length();
}
// When returning a value, injected should be treated as non nullable
String convertingToNotNullableForInjectedIsOK() {
return injected;
}
String convertingToNotNullableForNormalIsOK() {
return normal;
}
String convertingToNotNullableForNullableIsBAD() {
return nullable;
}
// When passing to a non nullable param, injected should be treated as non nullable
void passingToNullableForInjectedIsOK() {
f(injected);
}
void passingToNullableForNormalIsOK() {
f(normal);
}
void passingToNullableForNullableIsBAD() {
f(nullable);
}
// Assigning null to Injected should be allowed (as if it was nullable)
// (Those assignments are generated by Butterknife framework.)
void assignNullToInjectedIsOK() {
injected = null;
}
void assignNullToNullableIsOK() {
nullable = null;
}
void assignNullToNormalIsBAD() {
normal = null;
}
class TestNotInitialized {
@InjectView String notInitializedInjectedIsOK;
@Nullable String notInitializedNullableIsOK;
String notInitializedNormalIsBAD;
}
}

@ -0,0 +1,29 @@
/*
* 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 javax.annotation.Nullable;
/** Nullability checks for captured params */
public class CapturedParam {
void dereferencingNullableIsBAD(@Nullable Object parameter) {
parameter.toString();
}
void dereferencingCapturedNullableShouldBeBAD_FIXME(@Nullable Object parameter) {
Object object =
new Object() {
void foo() {
// Should be disallowed, but it is not the case
// TODO(T53473076) fix the FN.
parameter.toString();
}
};
}
}

@ -24,9 +24,6 @@ abstract class A {
}
}
// for butterknife
@interface InjectView {}
class FragmentExample extends Fragment {
View view;
@ -156,212 +153,3 @@ class TestInitializer {
TestInitializer x = b.build();
}
}
class NestedFieldAccess {
class C {
@Nullable String s;
}
class CC {
@Nullable C c;
}
class CCC {
@Nullable CC cc;
}
public class Test {
@Nullable String s;
C myc;
Test() {
myc = new C();
}
void test() {
if (s != null) {
int n = s.length();
}
}
void test1() {
if (myc.s != null) {
int n = myc.s.length();
}
}
void test2(C c) {
if (c.s != null) {
int n = c.s.length();
}
}
void test2_local() {
C c = new C();
if (c.s != null) {
int n = c.s.length();
}
}
void test3(CC cc) {
if (cc.c != null && cc.c.s != null) {
int n = cc.c.s.length();
}
}
void test4(CCC ccc) {
if (ccc.cc != null && ccc.cc.c != null && ccc.cc.c.s != null) {
int n = ccc.cc.c.s.length();
}
}
void test5(@Nullable CCC ccc) {
if (ccc == null || ccc.cc == null || ccc.cc.c == null || ccc.cc.c.s == null) {
} else {
int n = ccc.cc.c.s.length();
}
}
}
class TestFunctionsIdempotent {
@Nullable String s;
String dontAssignNull;
TestFunctionsIdempotent() {
dontAssignNull = "";
}
@Nullable
String getS(int n) {
return s;
}
TestFunctionsIdempotent getSelf() {
return this;
}
void FlatOK1(TestFunctionsIdempotent x) {
if (getS(3) != null) {
dontAssignNull = getS(3);
}
}
void FlatOK2(TestFunctionsIdempotent x) {
if (x.getS(3) != null) {
dontAssignNull = x.getS(3);
}
}
void FlatBAD1(TestFunctionsIdempotent x) {
if (x.getS(3) != null) {
dontAssignNull = getS(3);
}
}
void FlatBAD2(TestFunctionsIdempotent x) {
if (x.getS(3) != null) {
dontAssignNull = x.getS(4);
}
}
void NestedOK1() {
if (getSelf().getS(3) != null) {
dontAssignNull = getSelf().getS(3);
}
}
void NestedOK2() {
if (getSelf().getSelf().getS(3) != null) {
dontAssignNull = getSelf().getSelf().getS(3);
}
}
void NestedBAD1() {
if (getSelf().getS(3) != null) {
dontAssignNull = getSelf().getS(4);
}
}
void NestedBAD2() {
if (getS(3) != null) {
dontAssignNull = getSelf().getS(3);
}
}
void NestedBAD3() {
if (getSelf().getSelf().getS(3) != null) {
dontAssignNull = getSelf().getS(3);
}
}
}
class TestContainsKey {
void testMapContainsKey(java.util.Map<Integer, String> m) {
if (m.containsKey(3)) {
m.get(3).isEmpty();
}
}
void testMapContainsKeyInsideWhileLoop(java.util.Map<Integer, String> m) {
while (true) {
if (m.containsKey(3)) {
m.get(3).isEmpty();
}
}
}
void testImmutableMapContainsKey(com.google.common.collect.ImmutableMap<Integer, String> m) {
if (m.containsKey(3)) {
m.get(3).isEmpty();
}
}
}
// Test Map.put()
class TestPut {
String dontAssignNull = "";
public void putConstString(java.util.Map<String, String> map, String key) {
map.put(key, "abc");
dontAssignNull = map.get(key);
}
public void putNull(java.util.Map<String, String> map, String key) {
map.put(key, "abc");
map.put(key, null);
dontAssignNull = map.get(key);
}
public void putWithContainsKey(java.util.Map<String, String> map, String key) {
if (!map.containsKey(key)) {
map.put(key, "abc");
}
dontAssignNull = map.get(key);
}
}
// support assignments of null to @InjectView fields, generated by butterknife
class SupportButterKnife {
@InjectView String s;
SupportButterKnife() {}
void dereferencingIsOK() {
int n = s.length();
}
void assignNullIsOK() {
s = null;
}
}
void methodWithNullableCapturedParameterBad_FN(@Nullable Object parameter) {
Object object =
new Object() {
void foo() {
parameter.toString();
}
};
}
}

@ -0,0 +1,140 @@
/*
* 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 javax.annotation.Nullable;
/** Check how we model the behavior of Map nullability */
public class MapNullability {
class TestThatGetIsAllowedOnlyAfterContainsKeyWasChecked {
void usingGetAfterKeyWasCheckedIsOK(java.util.Map<Integer, String> m) {
if (m.containsKey(3)) {
m.get(3).isEmpty();
}
}
void usingGetWithoutCheckingKeyIsBAD(java.util.Map<Integer, String> m) {
m.get(3).isEmpty();
}
void usingGetAfterWrongKeyWasCheckedIsBAD(java.util.Map<Integer, String> m) {
if (m.containsKey(3)) {
m.get(4).isEmpty();
}
}
void usingGetAfterKeyWasCheckedInWhileLoopIsOK(java.util.Map<Integer, String> m) {
while (true) {
if (m.containsKey(3)) {
m.get(3).isEmpty();
}
}
}
void usingGetAfterWrongKeyWasCheckedInWhileLoopIsBAD(java.util.Map<Integer, String> m) {
while (true) {
if (m.containsKey(3)) {
m.get(4).isEmpty();
}
}
}
void immutableMap_usingGetAfterKeyWasCheckedIsOK(
com.google.common.collect.ImmutableMap<Integer, String> m) {
if (m.containsKey(3)) {
m.get(3).isEmpty();
}
}
void immutableMap_usingGetAfterWrongKeyWasCheckedIsBAD(
com.google.common.collect.ImmutableMap<Integer, String> m) {
if (m.containsKey(3)) {
m.get(4).isEmpty();
}
}
}
public class TestThatGetAfterPutIsAllowed {
String dontAssignNull = "";
public void getAfterPutIsOK(java.util.Map<String, String> map, String key) {
map.put(key, "abc");
dontAssignNull = map.get(key);
}
public void getWithoutPutIsBAD(java.util.Map<String, String> map, String key) {
dontAssignNull = map.get(key);
}
public void getAfterPutWrongKeyIsBAD(
java.util.Map<String, String> map, String key, String wrongKey) {
map.put(key, "abc");
dontAssignNull = map.get(wrongKey);
}
public void getAfterPutSeveralKeysIsOK(java.util.Map<String, String> map) {
map.put("key1", "value1");
map.put("key2", "value1");
dontAssignNull = map.get("key2");
dontAssignNull = map.get("key1");
dontAssignNull = map.get("key2");
map.put("key3", "value1");
dontAssignNull = map.get("key1");
dontAssignNull = map.get("key2");
dontAssignNull = map.get("key3");
}
public void getAfterPutSeveralKeysButGetWrongOneIsBAD(java.util.Map<String, String> map) {
map.put("key1", "value1");
map.put("key2", "value1");
dontAssignNull = map.get("key2"); // OK
dontAssignNull = map.get("wrong_key"); // BAD
}
public void getAfterPutNonnullIsOK(java.util.Map<String, String> map, String nonnullValue) {
map.put("key", nonnullValue);
dontAssignNull = map.get("key");
}
public void getAfterPutNullableIsBAD(
java.util.Map<String, String> map, @Nullable String nullableValue) {
map.put("key", nullableValue);
dontAssignNull = map.get("key");
}
public void overwriteKeyByNullIsBAD(java.util.Map<String, String> map, String key) {
map.put(key, "abc");
map.put(key, null); // Parameter not nullable
dontAssignNull = map.get(key); // BAD
}
public void overwriteKeyByNonnullIsOK(java.util.Map<String, String> map, String key) {
map.put(key, null); // Parameter not nullable
map.put(key, "abc");
dontAssignNull = map.get(key); // OK
}
public void getAfterConditionalPutIsOK(java.util.Map<String, String> map, String key) {
if (!map.containsKey(key)) {
map.put(key, "abc");
}
// OK: map either already contained a key, or we've just put it here!
dontAssignNull = map.get(key);
}
public void getAfterConditionalPutWrongKeyIsBAD(
java.util.Map<String, String> map, String key, String wrongKey) {
if (!map.containsKey(key)) {
map.put(wrongKey, "abc");
}
dontAssignNull = map.get(key);
}
}
}

@ -0,0 +1,209 @@
/*
* 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 javax.annotation.Nullable;
public class NestedFieldAccess {
class C {
@Nullable String s;
}
class CC {
@Nullable C c;
}
class CCC {
@Nullable CC cc;
}
/**
* Tests nullability check patterns for f1.f2.f3, when all components in the chain are nullable.
* (it should require checking of all components in the chain)
*/
public class TestNullableChains {
@Nullable String s;
C myc;
TestNullableChains() {
myc = new C();
}
void field_AccessAfterNullCheckIsOK() {
if (s != null) {
int n = s.length();
}
}
void field_AccessWithoutNullCheckIsBad() {
int n = s.length();
}
void nestedField_AccessAfterNullCheckIsOK() {
if (myc.s != null) {
int n = myc.s.length();
}
}
void nestedField_AccessWithoutNullCheckIsBad() {
int n = myc.s.length();
}
void param_AccessAfterNullCheckIsOK(C c) {
if (c.s != null) {
int n = c.s.length();
}
}
void param_AccessWithoutNullCheckIsBad(C c) {
int n = c.s.length();
}
void local_AccessAfterNullCheckIsOK() {
C c = new C();
if (c.s != null) {
int n = c.s.length();
}
}
void local_AccessWithoutNullCheckIsBad() {
C c = new C();
int n = c.s.length();
}
void deep_AccessWithNullCheckIsOK(CC cc) {
if (cc.c != null && cc.c.s != null) {
int n = cc.c.s.length();
}
}
void deep_AccessWithoutNullCheckIsBad(CC cc) {
if (cc.c != null /* && cc.c.s != null */) {
int n = cc.c.s.length();
}
}
void veryDeep_AccessWithNullCheckIsOK(CCC ccc) {
if (ccc.cc != null && ccc.cc.c != null && ccc.cc.c.s != null) {
int n = ccc.cc.c.s.length();
}
}
void veryDeep_AccessWithoutNullCheckIsBad(CCC ccc) {
if (ccc.cc != null && ccc.cc.c != null /* && ccc.cc.c.s != null */) {
int n = ccc.cc.c.s.length();
}
}
void veryDeep_AccessViaOrEarlyReturnIsOK(@Nullable CCC ccc) {
if (ccc == null || ccc.cc == null || ccc.cc.c == null || ccc.cc.c.s == null) {
} else {
int n = ccc.cc.c.s.length();
}
}
void veryDeep_IncompleteAccessViaOrEarlyReturnIsBad(@Nullable CCC ccc) {
if (ccc == null || ccc.cc == null || ccc.cc.c == null /*|| ccc.cc.c.s == null*/) {
} else {
int n = ccc.cc.c.s.length();
}
}
}
/**
* Tests nullability patterns for chains a().a().a().a().nullable(). Basically nullsafe needs to
* realize that objects returned by a().a() and a().a().a() are different so it should not learn
* anything about the nullability of one based on evidence about the other one.
*/
class TestFunctionsIdempotent {
@Nullable String s;
String dontAssignNull = "";
@Nullable
String nullable(int n) {
return s;
}
TestFunctionsIdempotent getSelf() {
return this;
}
void chainOf0VsChainOf0IsOK() {
if (nullable(3) != null) {
dontAssignNull = nullable(3);
}
}
void chainOf0VsChainOf0ParamsMismatchIsBad() {
if (nullable(3) != null) {
dontAssignNull = nullable(4);
}
}
void otherObjVsItselfIsOK(TestFunctionsIdempotent otherObj) {
if (otherObj.nullable(3) != null) {
dontAssignNull = otherObj.nullable(3);
}
}
void otherObjVsItselfIsOKParamsMismatchIsBAD(TestFunctionsIdempotent otherObj) {
if (otherObj.nullable(3) != null) {
dontAssignNull = otherObj.nullable(4);
}
}
void selfVsOtherObjectIsBAD(TestFunctionsIdempotent otherObj) {
if (otherObj.nullable(3) != null) {
dontAssignNull = nullable(3);
}
}
void chainOf0VsChainOf1IsBad() {
if (nullable(3) != null) {
dontAssignNull = getSelf().nullable(3);
}
}
void chainOf1VsChainOf0IsBad() {
if (getSelf().nullable(3) != null) {
dontAssignNull = nullable(3);
}
}
void chainOf1VsChainOf1IsOK() {
if (getSelf().nullable(3) != null) {
dontAssignNull = getSelf().nullable(3);
}
}
void chainOf1VsChainOf1ParamMismatchIsBad() {
if (getSelf().nullable(3) != null) {
dontAssignNull = getSelf().nullable(4);
}
}
void chainOf2VsChainOf2IsOK() {
if (getSelf().getSelf().nullable(3) != null) {
dontAssignNull = getSelf().getSelf().nullable(3);
}
}
void chainOf1VsChainOf2IsBad() {
if (getSelf().nullable(3) != null) {
dontAssignNull = getSelf().getSelf().nullable(3);
}
}
void chainOf2VsChainOf1IsBad() {
if (getSelf().getSelf().nullable(3) != null) {
dontAssignNull = getSelf().nullable(3);
}
}
}
}

@ -1,4 +1,10 @@
codetoanalyze/java/nullsafe-default/ActivityFieldNotInitialized.java, codetoanalyze.java.nullsafe_default.ActivityFieldNotInitialized$BadActivityWithOnCreate.<init>(codetoanalyze.java.nullsafe_default.ActivityFieldNotInitialized), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `ActivityFieldNotInitialized$BadActivityWithOnCreate.field` is not initialized in the constructor and is not declared `@Nullable`]
codetoanalyze/java/nullsafe-default/ButterKnife.java, codetoanalyze.java.nullsafe_default.ButterKnife$TestNotInitialized.<init>(codetoanalyze.java.nullsafe_default.ButterKnife), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `ButterKnife$TestNotInitialized.notInitializedNormalIsBAD` is not initialized in the constructor and is not declared `@Nullable`]
codetoanalyze/java/nullsafe-default/ButterKnife.java, codetoanalyze.java.nullsafe_default.ButterKnife.assignNullToNormalIsBAD():void, 1, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `ButterKnife.normal` can be null but is not declared `@Nullable`. (Origin: null constant at line 76)]
codetoanalyze/java/nullsafe-default/ButterKnife.java, codetoanalyze.java.nullsafe_default.ButterKnife.convertingToNotNullableForNullableIsBAD():java.lang.String, 0, ERADICATE_RETURN_NOT_NULLABLE, no_bucket, WARNING, [Method `convertingToNotNullableForNullableIsBAD()` may return null but it is not annotated with `@Nullable`. (Origin: field ButterKnife.nullable at line 47)]
codetoanalyze/java/nullsafe-default/ButterKnife.java, codetoanalyze.java.nullsafe_default.ButterKnife.dereferencingNullableIsBAD():void, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [The value of `ButterKnife.nullable` in the call to `length()` is nullable and is not locally checked for null. (Origin: field ButterKnife.nullable at line 33)]
codetoanalyze/java/nullsafe-default/ButterKnife.java, codetoanalyze.java.nullsafe_default.ButterKnife.passingToNullableForNullableIsBAD():void, 1, ERADICATE_PARAMETER_NOT_NULLABLE, no_bucket, WARNING, [`ButterKnife.f(...)` needs a non-null value in parameter 1 but argument `ButterKnife.nullable` can be null. (Origin: field ButterKnife.nullable at line 61)]
codetoanalyze/java/nullsafe-default/CapturedParam.java, codetoanalyze.java.nullsafe_default.CapturedParam.dereferencingNullableIsBAD(java.lang.Object):void, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [The value of `parameter` in the call to `toString()` is nullable and is not locally checked for null. (Origin: method parameter parameter)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestModeledTrueOnNull.testIsEmptyOrNullBad(java.lang.String):void, 2, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [The value of `string` in the call to `contains(...)` is nullable and is not locally checked for null. (Origin: method parameter string)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestPropagatesNullable.m12Bad1():void, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [The value of `m12(...)` in the call to `length()` is nullable and is not locally checked for null. (Origin: call to m12(...) at line 114)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestPropagatesNullable.m12Bad2():void, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [The value of `m12(...)` in the call to `length()` is nullable and is not locally checked for null. (Origin: call to m12(...) at line 118)]
@ -16,18 +22,11 @@ codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java
codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$Swap.<init>(codetoanalyze.java.nullsafe_default.FieldNotInitialized), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `FieldNotInitialized$Swap.o1` is not initialized in the constructor and is not declared `@Nullable`]
codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$WriteItself.<init>(codetoanalyze.java.nullsafe_default.FieldNotInitialized), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `FieldNotInitialized$WriteItself.o` 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.a` is not initialized in the constructor and is not declared `@Nullable`]
codetoanalyze/java/nullsafe-default/FieldNotNullable.java, codetoanalyze.java.nullsafe_default.FieldNotNullable.<init>(java.lang.Integer), -25, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `FieldNotNullable.static_s` can be null but is not declared `@Nullable`. (Origin: null constant at line 44)]
codetoanalyze/java/nullsafe-default/FieldNotNullable.java, codetoanalyze.java.nullsafe_default.FieldNotNullable.<init>(java.lang.String), -2, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `FieldNotNullable.static_s` can be null but is not declared `@Nullable`. (Origin: null constant at line 44)]
codetoanalyze/java/nullsafe-default/FieldNotNullable.java, codetoanalyze.java.nullsafe_default.FieldNotNullable.setYNull():void, 1, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `FieldNotNullable.y` can be null but is not declared `@Nullable`. (Origin: null constant at line 62)]
codetoanalyze/java/nullsafe-default/FieldNotNullable.java, codetoanalyze.java.nullsafe_default.FieldNotNullable.<init>(java.lang.Integer), -25, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `FieldNotNullable.static_s` can be null but is not declared `@Nullable`. (Origin: null constant at line 41)]
codetoanalyze/java/nullsafe-default/FieldNotNullable.java, codetoanalyze.java.nullsafe_default.FieldNotNullable.<init>(java.lang.String), -2, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `FieldNotNullable.static_s` can be null but is not declared `@Nullable`. (Origin: null constant at line 41)]
codetoanalyze/java/nullsafe-default/FieldNotNullable.java, codetoanalyze.java.nullsafe_default.FieldNotNullable.setYNull():void, 1, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `FieldNotNullable.y` can be null but is not declared `@Nullable`. (Origin: null constant at line 59)]
codetoanalyze/java/nullsafe-default/FieldNotNullable.java, codetoanalyze.java.nullsafe_default.FieldNotNullable.setYNullable(java.lang.String):void, 1, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `FieldNotNullable.y` can be null but is not declared `@Nullable`. (Origin: method parameter s)]
codetoanalyze/java/nullsafe-default/FieldNotNullable.java, codetoanalyze.java.nullsafe_default.FragmentExample.<init>(), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `FragmentExample.view` is not initialized in the constructor and is not declared `@Nullable`]
codetoanalyze/java/nullsafe-default/FieldNotNullable.java, codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestFunctionsIdempotent.FlatBAD1(codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestFunctionsIdempotent):void, 2, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `NestedFieldAccess$TestFunctionsIdempotent.dontAssignNull` can be null but is not declared `@Nullable`. (Origin: call to getS(...) at line 258)]
codetoanalyze/java/nullsafe-default/FieldNotNullable.java, codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestFunctionsIdempotent.FlatBAD2(codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestFunctionsIdempotent):void, 2, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `NestedFieldAccess$TestFunctionsIdempotent.dontAssignNull` can be null but is not declared `@Nullable`. (Origin: call to getS(...) at line 264)]
codetoanalyze/java/nullsafe-default/FieldNotNullable.java, codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestFunctionsIdempotent.NestedBAD1():void, 2, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `NestedFieldAccess$TestFunctionsIdempotent.dontAssignNull` can be null but is not declared `@Nullable`. (Origin: call to getS(...) at line 282)]
codetoanalyze/java/nullsafe-default/FieldNotNullable.java, codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestFunctionsIdempotent.NestedBAD2():void, 2, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `NestedFieldAccess$TestFunctionsIdempotent.dontAssignNull` can be null but is not declared `@Nullable`. (Origin: call to getS(...) at line 288)]
codetoanalyze/java/nullsafe-default/FieldNotNullable.java, codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestFunctionsIdempotent.NestedBAD3():void, 2, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `NestedFieldAccess$TestFunctionsIdempotent.dontAssignNull` can be null but is not declared `@Nullable`. (Origin: call to getS(...) at line 294)]
codetoanalyze/java/nullsafe-default/FieldNotNullable.java, codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestPut.putNull(java.util.Map,java.lang.String):void, 2, ERADICATE_PARAMETER_NOT_NULLABLE, no_bucket, WARNING, [`Map.put(...)` needs a non-null value in parameter 2 but argument `null` can be null. (Origin: null constant at line 332)]
codetoanalyze/java/nullsafe-default/FieldNotNullable.java, codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestPut.putNull(java.util.Map,java.lang.String):void, 3, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `NestedFieldAccess$TestPut.dontAssignNull` can be null but is not declared `@Nullable`. (Origin: null constant at line 332)]
codetoanalyze/java/nullsafe-default/FieldNotNullable.java, codetoanalyze.java.nullsafe_default.TestInitializerBuilder.build():codetoanalyze.java.nullsafe_default.TestInitializer, 2, ERADICATE_CONDITION_REDUNDANT, no_bucket, WARNING, [The condition TestInitializerBuilder.required1 is always true according to the existing annotations.]
codetoanalyze/java/nullsafe-default/FieldNotNullable.java, codetoanalyze.java.nullsafe_default.TestInitializerBuilder.build():codetoanalyze.java.nullsafe_default.TestInitializer, 2, ERADICATE_CONDITION_REDUNDANT, no_bucket, WARNING, [The condition TestInitializerBuilder.required2 is always true according to the existing annotations.]
codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, codetoanalyze.java.nullsafe_default.ExtendsExternalLibrary.externalMethod2(java.lang.Object):void, 0, ERADICATE_INCONSISTENT_SUBCLASS_PARAMETER_ANNOTATION, no_bucket, WARNING, [First parameter `object` of method `ExtendsExternalLibrary.externalMethod2(...)` is not `@Nullable` but is declared `@Nullable`in the parent class method `SomeExternalClass.externalMethod2(...)`.]
@ -42,6 +41,34 @@ codetoanalyze/java/nullsafe-default/LibraryCalls.java, codetoanalyze.java.nullsa
codetoanalyze/java/nullsafe-default/LibraryCalls.java, codetoanalyze.java.nullsafe_default.LibraryCalls.badReferenceDereference(java.lang.ref.Reference):java.lang.String, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [The value of `ref.get()` in the call to `toString()` is nullable and is not locally checked for null. (Origin: call to get() modelled in modelTables.ml at line 19)]
codetoanalyze/java/nullsafe-default/LibraryCalls.java, codetoanalyze.java.nullsafe_default.LibraryCalls.badSoftReferenceDereference(java.lang.ref.SoftReference):java.lang.String, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [The value of `ref.get()` in the call to `toString()` is nullable and is not locally checked for null. (Origin: call to get() modelled in modelTables.ml at line 31)]
codetoanalyze/java/nullsafe-default/LibraryCalls.java, codetoanalyze.java.nullsafe_default.LibraryCalls.badWeakReferenceDereference(java.lang.ref.WeakReference):java.lang.String, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [The value of `ref.get()` in the call to `toString()` is nullable and is not locally checked for null. (Origin: call to get() modelled in modelTables.ml at line 23)]
codetoanalyze/java/nullsafe-default/MapNullability.java, codetoanalyze.java.nullsafe_default.MapNullability$TestThatGetAfterPutIsAllowed.getAfterConditionalPutWrongKeyIsBAD(java.util.Map,java.lang.String,java.lang.String):void, 5, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `MapNullability$TestThatGetAfterPutIsAllowed.dontAssignNull` can be null but is not declared `@Nullable`. (Origin: call to get(...) modelled in modelTables.ml at line 137)]
codetoanalyze/java/nullsafe-default/MapNullability.java, codetoanalyze.java.nullsafe_default.MapNullability$TestThatGetAfterPutIsAllowed.getAfterPutNullableIsBAD(java.util.Map,java.lang.String):void, 2, ERADICATE_PARAMETER_NOT_NULLABLE, no_bucket, WARNING, [`Map.put(...)` needs a non-null value in parameter 2 but argument `nullableValue` can be null. (Origin: method parameter nullableValue)]
codetoanalyze/java/nullsafe-default/MapNullability.java, codetoanalyze.java.nullsafe_default.MapNullability$TestThatGetAfterPutIsAllowed.getAfterPutNullableIsBAD(java.util.Map,java.lang.String):void, 3, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `MapNullability$TestThatGetAfterPutIsAllowed.dontAssignNull` can be null but is not declared `@Nullable`. (Origin: method parameter nullableValue)]
codetoanalyze/java/nullsafe-default/MapNullability.java, codetoanalyze.java.nullsafe_default.MapNullability$TestThatGetAfterPutIsAllowed.getAfterPutSeveralKeysButGetWrongOneIsBAD(java.util.Map):void, 4, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `MapNullability$TestThatGetAfterPutIsAllowed.dontAssignNull` can be null but is not declared `@Nullable`. (Origin: call to get(...) modelled in modelTables.ml at line 98)]
codetoanalyze/java/nullsafe-default/MapNullability.java, codetoanalyze.java.nullsafe_default.MapNullability$TestThatGetAfterPutIsAllowed.getAfterPutWrongKeyIsBAD(java.util.Map,java.lang.String,java.lang.String):void, 3, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `MapNullability$TestThatGetAfterPutIsAllowed.dontAssignNull` can be null but is not declared `@Nullable`. (Origin: call to get(...) modelled in modelTables.ml at line 79)]
codetoanalyze/java/nullsafe-default/MapNullability.java, codetoanalyze.java.nullsafe_default.MapNullability$TestThatGetAfterPutIsAllowed.getWithoutPutIsBAD(java.util.Map,java.lang.String):void, 1, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `MapNullability$TestThatGetAfterPutIsAllowed.dontAssignNull` can be null but is not declared `@Nullable`. (Origin: call to get(...) modelled in modelTables.ml at line 73)]
codetoanalyze/java/nullsafe-default/MapNullability.java, codetoanalyze.java.nullsafe_default.MapNullability$TestThatGetAfterPutIsAllowed.overwriteKeyByNonnullIsOK(java.util.Map,java.lang.String):void, 1, ERADICATE_PARAMETER_NOT_NULLABLE, no_bucket, WARNING, [`Map.put(...)` needs a non-null value in parameter 2 but argument `null` can be null. (Origin: null constant at line 119)]
codetoanalyze/java/nullsafe-default/MapNullability.java, codetoanalyze.java.nullsafe_default.MapNullability$TestThatGetAfterPutIsAllowed.overwriteKeyByNullIsBAD(java.util.Map,java.lang.String):void, 2, ERADICATE_PARAMETER_NOT_NULLABLE, no_bucket, WARNING, [`Map.put(...)` needs a non-null value in parameter 2 but argument `null` can be null. (Origin: null constant at line 114)]
codetoanalyze/java/nullsafe-default/MapNullability.java, codetoanalyze.java.nullsafe_default.MapNullability$TestThatGetAfterPutIsAllowed.overwriteKeyByNullIsBAD(java.util.Map,java.lang.String):void, 3, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `MapNullability$TestThatGetAfterPutIsAllowed.dontAssignNull` can be null but is not declared `@Nullable`. (Origin: null constant at line 114)]
codetoanalyze/java/nullsafe-default/MapNullability.java, codetoanalyze.java.nullsafe_default.MapNullability$TestThatGetIsAllowedOnlyAfterContainsKeyWasChecked.immutableMap_usingGetAfterWrongKeyWasCheckedIsBAD(com.google.common.collect.ImmutableMap):void, 3, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [The value of `m.get(...)` in the call to `isEmpty()` is nullable and is not locally checked for null. (Origin: call to get(...) modelled in modelTables.ml at line 59)]
codetoanalyze/java/nullsafe-default/MapNullability.java, codetoanalyze.java.nullsafe_default.MapNullability$TestThatGetIsAllowedOnlyAfterContainsKeyWasChecked.usingGetAfterWrongKeyWasCheckedInWhileLoopIsBAD(java.util.Map):void, 3, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [The value of `m.get(...)` in the call to `isEmpty()` is nullable and is not locally checked for null. (Origin: call to get(...) modelled in modelTables.ml at line 44)]
codetoanalyze/java/nullsafe-default/MapNullability.java, codetoanalyze.java.nullsafe_default.MapNullability$TestThatGetIsAllowedOnlyAfterContainsKeyWasChecked.usingGetAfterWrongKeyWasCheckedIsBAD(java.util.Map):void, 2, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [The value of `m.get(...)` in the call to `isEmpty()` is nullable and is not locally checked for null. (Origin: call to get(...) modelled in modelTables.ml at line 29)]
codetoanalyze/java/nullsafe-default/MapNullability.java, codetoanalyze.java.nullsafe_default.MapNullability$TestThatGetIsAllowedOnlyAfterContainsKeyWasChecked.usingGetWithoutCheckingKeyIsBAD(java.util.Map):void, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [The value of `m.get(...)` in the call to `isEmpty()` is nullable and is not locally checked for null. (Origin: call to get(...) modelled in modelTables.ml at line 24)]
codetoanalyze/java/nullsafe-default/NestedFieldAccess.java, codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestFunctionsIdempotent.chainOf0VsChainOf0ParamsMismatchIsBad():void, 2, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `NestedFieldAccess$TestFunctionsIdempotent.dontAssignNull` can be null but is not declared `@Nullable`. (Origin: call to nullable(...) at line 145)]
codetoanalyze/java/nullsafe-default/NestedFieldAccess.java, codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestFunctionsIdempotent.chainOf0VsChainOf1IsBad():void, 2, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `NestedFieldAccess$TestFunctionsIdempotent.dontAssignNull` can be null but is not declared `@Nullable`. (Origin: call to nullable(...) at line 169)]
codetoanalyze/java/nullsafe-default/NestedFieldAccess.java, codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestFunctionsIdempotent.chainOf1VsChainOf0IsBad():void, 2, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `NestedFieldAccess$TestFunctionsIdempotent.dontAssignNull` can be null but is not declared `@Nullable`. (Origin: call to nullable(...) at line 175)]
codetoanalyze/java/nullsafe-default/NestedFieldAccess.java, codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestFunctionsIdempotent.chainOf1VsChainOf1ParamMismatchIsBad():void, 2, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `NestedFieldAccess$TestFunctionsIdempotent.dontAssignNull` can be null but is not declared `@Nullable`. (Origin: call to nullable(...) at line 187)]
codetoanalyze/java/nullsafe-default/NestedFieldAccess.java, codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestFunctionsIdempotent.chainOf1VsChainOf2IsBad():void, 2, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `NestedFieldAccess$TestFunctionsIdempotent.dontAssignNull` can be null but is not declared `@Nullable`. (Origin: call to nullable(...) at line 199)]
codetoanalyze/java/nullsafe-default/NestedFieldAccess.java, codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestFunctionsIdempotent.chainOf2VsChainOf1IsBad():void, 2, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `NestedFieldAccess$TestFunctionsIdempotent.dontAssignNull` can be null but is not declared `@Nullable`. (Origin: call to nullable(...) at line 205)]
codetoanalyze/java/nullsafe-default/NestedFieldAccess.java, codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestFunctionsIdempotent.otherObjVsItselfIsOKParamsMismatchIsBAD(codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestFunctionsIdempotent):void, 2, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `NestedFieldAccess$TestFunctionsIdempotent.dontAssignNull` can be null but is not declared `@Nullable`. (Origin: call to nullable(...) at line 157)]
codetoanalyze/java/nullsafe-default/NestedFieldAccess.java, codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestFunctionsIdempotent.selfVsOtherObjectIsBAD(codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestFunctionsIdempotent):void, 2, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field `NestedFieldAccess$TestFunctionsIdempotent.dontAssignNull` can be null but is not declared `@Nullable`. (Origin: call to nullable(...) at line 163)]
codetoanalyze/java/nullsafe-default/NestedFieldAccess.java, codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestNullableChains.deep_AccessWithoutNullCheckIsBad(codetoanalyze.java.nullsafe_default.NestedFieldAccess$CC):void, 2, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [The value of `cc.c.s` in the call to `length()` is nullable and is not locally checked for null. (Origin: field NestedFieldAccess$C.s at line 88)]
codetoanalyze/java/nullsafe-default/NestedFieldAccess.java, codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestNullableChains.field_AccessWithoutNullCheckIsBad():void, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [The value of `NestedFieldAccess$TestNullableChains.s` in the call to `length()` is nullable and is not locally checked for null. (Origin: field NestedFieldAccess$TestNullableChains.s at line 45)]
codetoanalyze/java/nullsafe-default/NestedFieldAccess.java, codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestNullableChains.local_AccessWithoutNullCheckIsBad():void, 2, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [The value of `c.s` in the call to `length()` is nullable and is not locally checked for null. (Origin: field NestedFieldAccess$C.s at line 77)]
codetoanalyze/java/nullsafe-default/NestedFieldAccess.java, codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestNullableChains.nestedField_AccessWithoutNullCheckIsBad():void, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [The value of `NestedFieldAccess$TestNullableChains.myc.s` in the call to `length()` is nullable and is not locally checked for null. (Origin: field NestedFieldAccess$C.s at line 55)]
codetoanalyze/java/nullsafe-default/NestedFieldAccess.java, codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestNullableChains.param_AccessWithoutNullCheckIsBad(codetoanalyze.java.nullsafe_default.NestedFieldAccess$C):void, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [The value of `c.s` in the call to `length()` is nullable and is not locally checked for null. (Origin: field NestedFieldAccess$C.s at line 65)]
codetoanalyze/java/nullsafe-default/NestedFieldAccess.java, codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestNullableChains.veryDeep_AccessWithoutNullCheckIsBad(codetoanalyze.java.nullsafe_default.NestedFieldAccess$CCC):void, 2, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [The value of `ccc.cc.c.s` in the call to `length()` is nullable and is not locally checked for null. (Origin: field NestedFieldAccess$C.s at line 100)]
codetoanalyze/java/nullsafe-default/NestedFieldAccess.java, codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestNullableChains.veryDeep_IncompleteAccessViaOrEarlyReturnIsBad(codetoanalyze.java.nullsafe_default.NestedFieldAccess$CCC):void, 3, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [The value of `ccc.cc.c.s` in the call to `length()` is nullable and is not locally checked for null. (Origin: field NestedFieldAccess$C.s at line 114)]
codetoanalyze/java/nullsafe-default/NullFieldAccess.java, codetoanalyze.java.nullsafe_default.NullFieldAccess.arrayAccess():java.lang.Object, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [Object `NullFieldAccess.objects` is nullable and is not locally checked for null when accessing element at index `0`. (Origin: field NullFieldAccess.objects at line 56)]
codetoanalyze/java/nullsafe-default/NullFieldAccess.java, codetoanalyze.java.nullsafe_default.NullFieldAccess.arrayLength():int, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [Object `NullFieldAccess.objects` is nullable and is not locally checked for null when accessing field `length`. (Origin: field NullFieldAccess.objects at line 52)]
codetoanalyze/java/nullsafe-default/NullFieldAccess.java, codetoanalyze.java.nullsafe_default.NullFieldAccess.useInterface(codetoanalyze.java.nullsafe_default.NullFieldAccess$I):int, 2, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [Object `c` is nullable and is not locally checked for null when accessing field `NullFieldAccess$C.n`. (Origin: field NullFieldAccess$I.c at line 45)]

Loading…
Cancel
Save