[nullsafe] Redo InconsistentSubclassAnnotation tests

Reviewed By: jvillard

Differential Revision: D19161020

fbshipit-source-id: 06d5e5b77
master
Artem Pianykh 5 years ago committed by Facebook Github Bot
parent 598a4d5a55
commit 59c6967e64

@ -10,67 +10,134 @@ package codetoanalyze.java.nullsafe_default;
import external.library.SomeExternalClass;
import javax.annotation.Nullable;
class SubclassExample {
interface VariousMethods {
String valBoth(String arg);
class T {
public void f() {}
@Nullable
String nullableReturn(String arg);
String nullableArg(@Nullable String arg);
@Nullable
String nullableBoth(@Nullable String arg);
}
interface Overloads {
String overload(int arg);
String overload(@Nullable String arg);
String overload(String arg1, int arg2);
String overload(String arg1, String arg2);
}
// Check return annotations
abstract class ReturnValToNullBAD implements VariousMethods {
@Nullable
public String valBoth(String arg) {
return null;
}
}
class A {
abstract class ReturnNullToValOK implements VariousMethods {
public abstract String nullableReturn(String arg);
}
public T foo() {
return new T();
}
abstract class ReturnValFromValAndNullFromNullOK implements VariousMethods {
@Nullable
public String nullableReturn(String arg) {
return null;
}
public @Nullable T bar() {
return null;
}
public String valBoth(String arg) {
return arg;
}
}
public void deref(@Nullable T t) {
if (t != null) {
t.f();
}
}
abstract class AbstractReturnValToNullFN implements VariousMethods {
// An abstract override method with inconsistent signature is not reported
@Nullable
public abstract String valBoth(String arg);
}
// Check parameter annotations
public void noDeref(T t) {}
abstract class ArgValToNullOK implements VariousMethods {
public String valBoth(@Nullable String arg) {
return "OK";
}
}
class B extends A {
abstract class ArgNullToValBAD implements VariousMethods {
public String nullableArg(String arg) {
return arg;
}
}
public @Nullable T foo() {
return null;
}
abstract class ArgNullToValForInterfaceInAnotherFileBAD
implements InconsistentSubclassAnnotationInterface {
public String implementInAnotherFile(String s) {
return "BAD";
}
}
public T bar() {
return new T();
}
abstract class ArgValToValAndNullToNullOK implements VariousMethods {
public String valBoth(String arg) {
return arg;
}
interface I {
public T baz();
@Nullable
public String nullableBoth(@Nullable String arg) {
return arg;
}
}
class C implements I {
// Check overrides + overloads
public @Nullable T baz() {
return null;
}
// This is 'good' cases (should be OK except 1 FP due to broken is_override logic)
abstract class OverrideExistingCorrectlyOK implements Overloads {
// This is FP
public String overload(int arg) {
return "OK";
}
class D extends A {
public String overload(@Nullable String arg) {
return arg;
}
public void deref(T t) {
t.f();
}
public String overload(String arg1, int arg2) {
return arg1;
}
public void noDeref(@Nullable T t) {
if (t != null) {
t.f();
}
}
public String overload(String arg1, String arg2) {
return arg1;
}
}
// These are FP cases that get reported due to broken is_override logic
abstract class NoOverrideSinceDifferentTypesFP implements Overloads {
@Nullable
public String overload(Object arg) {
return arg.toString();
}
public String overload(Double arg) {
return arg.toString();
}
}
// This is just a smoke test to check that incorrect overrides of overloaded methods get reported
abstract class OverloadExistingIncorrectBAD implements Overloads {
@Nullable
public String overload(String arg1, String arg2) {
return null;
}
}
// Check constructors
class ConstructorsAreExcluded {
class Base {
Base(@Nullable String s) {}
@ -83,6 +150,8 @@ class ConstructorsAreExcluded {
}
}
// Check interop with external libraries
class ExtendsExternalLibrary extends SomeExternalClass {
@Override
@ -97,40 +166,3 @@ class ExtendsExternalLibrary extends SomeExternalClass {
// subtyping error on the parameter type are reported
}
}
public class InconsistentSubclassAnnotation implements InconsistentSubclassAnnotationInterface {
public static void callFromSuperclass(SubclassExample.A a) {
SubclassExample.T t = a.foo();
t.f();
}
public static void callWithNullableParam(SubclassExample.A a, @Nullable SubclassExample.T t) {
a.deref(t);
}
public String implementInAnotherFile(String s) {
return "";
}
public @Nullable Object overloadedMethod() {
return null;
}
public Object overloadedMethod(Object object) {
return object;
}
}
class Super {
String overloadingMethodLookupFP(int i) {
return Integer.toString(i);
}
}
class Sub extends Super {
@Nullable
String overloadingMethodLookupFP(Object object) {
return null;
}
}

@ -96,13 +96,17 @@ codetoanalyze/java/nullsafe-default/FieldOverAnnotated.java, codetoanalyze.java.
codetoanalyze/java/nullsafe-default/FieldOverAnnotated.java, codetoanalyze.java.nullsafe_default.FieldOverAnnotated.<init>(int,int), 0, ERADICATE_FIELD_OVER_ANNOTATED, no_bucket, WARNING, [Field `FieldOverAnnotated.FP_initializedInAllConstructorsButSetToNullInAPublicMethodShouldBeOK` is always initialized in the constructor but is declared `@Nullable`]
codetoanalyze/java/nullsafe-default/FieldOverAnnotated.java, codetoanalyze.java.nullsafe_default.FieldOverAnnotated.<init>(int,int), 0, ERADICATE_FIELD_OVER_ANNOTATED, no_bucket, WARNING, [Field `FieldOverAnnotated.initializedInAllConstructorsIsBAD` is always initialized in the constructor but is declared `@Nullable`]
codetoanalyze/java/nullsafe-default/FieldOverAnnotated.java, codetoanalyze.java.nullsafe_default.FieldOverAnnotated.<init>(int,int), 0, ERADICATE_FIELD_OVER_ANNOTATED, no_bucket, WARNING, [Field `FieldOverAnnotated.initilizedInAllConstructorsAndAllBranchesIsBAD` is always initialized in the constructor but is declared `@Nullable`]
codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, codetoanalyze.java.nullsafe_default.ArgNullToValBAD.nullableArg(java.lang.String):java.lang.String, 0, ERADICATE_INCONSISTENT_SUBCLASS_PARAMETER_ANNOTATION, no_bucket, WARNING, [First parameter `arg` of method `ArgNullToValBAD.nullableArg(...)` is not `@Nullable` but is declared `@Nullable`in the parent class method `VariousMethods.nullableArg(...)`.]
codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, codetoanalyze.java.nullsafe_default.ArgNullToValForInterfaceInAnotherFileBAD.implementInAnotherFile(java.lang.String):java.lang.String, 0, ERADICATE_INCONSISTENT_SUBCLASS_PARAMETER_ANNOTATION, no_bucket, WARNING, [First parameter `s` of method `ArgNullToValForInterfaceInAnotherFileBAD.implementInAnotherFile(...)` is not `@Nullable` but is declared `@Nullable`in the parent class method `InconsistentSubclassAnnotationInterface.implementInAnotherFile(...)`.]
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(...)`.]
codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, codetoanalyze.java.nullsafe_default.InconsistentSubclassAnnotation.implementInAnotherFile(java.lang.String):java.lang.String, 0, ERADICATE_INCONSISTENT_SUBCLASS_PARAMETER_ANNOTATION, no_bucket, WARNING, [First parameter `s` of method `InconsistentSubclassAnnotation.implementInAnotherFile(...)` is not `@Nullable` but is declared `@Nullable`in the parent class method `InconsistentSubclassAnnotationInterface.implementInAnotherFile(...)`.]
codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, codetoanalyze.java.nullsafe_default.InconsistentSubclassAnnotation.overloadedMethod():java.lang.Object, 0, ERADICATE_INCONSISTENT_SUBCLASS_RETURN_ANNOTATION, no_bucket, WARNING, [Method `InconsistentSubclassAnnotation.overloadedMethod()` is annotated with `@Nullable` but overrides unannotated method `InconsistentSubclassAnnotationInterface.overloadedMethod()`.]
codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, codetoanalyze.java.nullsafe_default.Sub.overloadingMethodLookupFP(java.lang.Object):java.lang.String, 0, ERADICATE_INCONSISTENT_SUBCLASS_RETURN_ANNOTATION, no_bucket, WARNING, [Method `Sub.overloadingMethodLookupFP(...)` is annotated with `@Nullable` but overrides unannotated method `Super.overloadingMethodLookupFP(...)`.]
codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, codetoanalyze.java.nullsafe_default.SubclassExample$B.foo():codetoanalyze.java.nullsafe_default.SubclassExample$T, 0, ERADICATE_INCONSISTENT_SUBCLASS_RETURN_ANNOTATION, no_bucket, WARNING, [Method `SubclassExample$B.foo()` is annotated with `@Nullable` but overrides unannotated method `SubclassExample$A.foo()`.]
codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, codetoanalyze.java.nullsafe_default.SubclassExample$C.baz():codetoanalyze.java.nullsafe_default.SubclassExample$T, 0, ERADICATE_INCONSISTENT_SUBCLASS_RETURN_ANNOTATION, no_bucket, WARNING, [Method `SubclassExample$C.baz()` is annotated with `@Nullable` but overrides unannotated method `SubclassExample$I.baz()`.]
codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, codetoanalyze.java.nullsafe_default.SubclassExample$D.deref(codetoanalyze.java.nullsafe_default.SubclassExample$T):void, 0, ERADICATE_INCONSISTENT_SUBCLASS_PARAMETER_ANNOTATION, no_bucket, WARNING, [First parameter `t` of method `SubclassExample$D.deref(...)` is not `@Nullable` but is declared `@Nullable`in the parent class method `SubclassExample$A.deref(...)`.]
codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, codetoanalyze.java.nullsafe_default.NoOverrideSinceDifferentTypesFP.overload(java.lang.Double):java.lang.String, 0, ERADICATE_INCONSISTENT_SUBCLASS_PARAMETER_ANNOTATION, no_bucket, WARNING, [First parameter `arg` of method `NoOverrideSinceDifferentTypesFP.overload(...)` is not `@Nullable` but is declared `@Nullable`in the parent class method `Overloads.overload(...)`.]
codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, codetoanalyze.java.nullsafe_default.NoOverrideSinceDifferentTypesFP.overload(java.lang.Object):java.lang.String, 0, ERADICATE_INCONSISTENT_SUBCLASS_PARAMETER_ANNOTATION, no_bucket, WARNING, [First parameter `arg` of method `NoOverrideSinceDifferentTypesFP.overload(...)` is not `@Nullable` but is declared `@Nullable`in the parent class method `Overloads.overload(...)`.]
codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, codetoanalyze.java.nullsafe_default.NoOverrideSinceDifferentTypesFP.overload(java.lang.Object):java.lang.String, 0, ERADICATE_INCONSISTENT_SUBCLASS_RETURN_ANNOTATION, no_bucket, WARNING, [Method `NoOverrideSinceDifferentTypesFP.overload(...)` is annotated with `@Nullable` but overrides unannotated method `Overloads.overload(...)`.]
codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, codetoanalyze.java.nullsafe_default.NoOverrideSinceDifferentTypesFP.overload(java.lang.Object):java.lang.String, 0, ERADICATE_RETURN_OVER_ANNOTATED, no_bucket, WARNING, [Method `overload(...)` is annotated with `@Nullable` but never returns null.]
codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, codetoanalyze.java.nullsafe_default.OverloadExistingIncorrectBAD.overload(java.lang.String,java.lang.String):java.lang.String, 0, ERADICATE_INCONSISTENT_SUBCLASS_RETURN_ANNOTATION, no_bucket, WARNING, [Method `OverloadExistingIncorrectBAD.overload(...)` is annotated with `@Nullable` but overrides unannotated method `Overloads.overload(...)`.]
codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, codetoanalyze.java.nullsafe_default.OverrideExistingCorrectlyOK.overload(int):java.lang.String, 0, ERADICATE_INCONSISTENT_SUBCLASS_PARAMETER_ANNOTATION, no_bucket, WARNING, [First parameter `arg` of method `OverrideExistingCorrectlyOK.overload(...)` is not `@Nullable` but is declared `@Nullable`in the parent class method `Overloads.overload(...)`.]
codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, codetoanalyze.java.nullsafe_default.OverrideExistingCorrectlyOK.overload(java.lang.String):java.lang.String, 0, ERADICATE_RETURN_NOT_NULLABLE, no_bucket, WARNING, [`overload(...)`: return type is declared non-nullable but the method returns a nullable value: method parameter arg.]
codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, codetoanalyze.java.nullsafe_default.ReturnValToNullBAD.valBoth(java.lang.String):java.lang.String, 0, ERADICATE_INCONSISTENT_SUBCLASS_RETURN_ANNOTATION, no_bucket, WARNING, [Method `ReturnValToNullBAD.valBoth(...)` is annotated with `@Nullable` but overrides unannotated method `VariousMethods.valBoth(...)`.]
codetoanalyze/java/nullsafe-default/LibraryCalls.java, codetoanalyze.java.nullsafe_default.LibraryCalls.badAtomicReferenceDereference(java.util.concurrent.atomic.AtomicReference):java.lang.String, 0, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`ref.get()` is nullable and is not locally checked for null when calling `toString()`: call to AtomicReference.get() at line 35 (nullable according to nullsafe internal models)]
codetoanalyze/java/nullsafe-default/LibraryCalls.java, codetoanalyze.java.nullsafe_default.LibraryCalls.badPhantomReferenceDereference(java.lang.ref.PhantomReference):java.lang.String, 0, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`ref.get()` is nullable and is not locally checked for null when calling `toString()`: call to PhantomReference.get() at line 27 (nullable according to nullsafe internal models)]
codetoanalyze/java/nullsafe-default/LibraryCalls.java, codetoanalyze.java.nullsafe_default.LibraryCalls.badReferenceDereference(java.lang.ref.Reference):java.lang.String, 0, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`ref.get()` is nullable and is not locally checked for null when calling `toString()`: call to Reference.get() at line 19 (nullable according to nullsafe internal models)]

Loading…
Cancel
Save