[eradicate] match the number of parameters when iterating over the list of overridden methods

Summary: This fixes some cases of false positives where the analysis will compare with the wrong overridden methods. This could later be improved with the possibility to do sub-typing comparison on the parameters.

Reviewed By: ngorogiannis

Differential Revision: D9985249

fbshipit-source-id: 7998d8619
master
Jeremy Dubreil 6 years ago committed by Facebook Github Bot
parent a3f428e90f
commit ae1861ca42

@ -312,23 +312,24 @@ let proc_calls resolve_attributes pdesc filter : (Typ.Procname.t * ProcAttribute
let override_find ?(check_current_type = true) f tenv proc_name =
let method_name = Typ.Procname.get_method proc_name in
let parameter_length = List.length (Typ.Procname.get_parameters proc_name) in
let is_override pname =
(* Note: very coarse! TODO: match parameter names/types to get an exact match *)
String.equal (Typ.Procname.get_method pname) method_name
&& not (Typ.Procname.is_constructor pname)
(not (Typ.Procname.is_constructor pname))
&& String.equal (Typ.Procname.get_method pname) method_name
(* TODO (T32979782): match parameter types, taking subtyping and type erasure into account *)
&& Int.equal (List.length (Typ.Procname.get_parameters pname)) parameter_length
in
let rec find_super_type_ super_class_name =
let rec find_super_type super_class_name =
Tenv.lookup tenv super_class_name
|> Option.bind ~f:(fun {Typ.Struct.methods; supers} ->
match List.find ~f:(fun pname -> is_override pname && f pname) methods with
| None ->
List.find_map ~f:find_super_type_ supers
List.find_map ~f:find_super_type supers
| pname_opt ->
pname_opt )
in
let find_super_type type_name =
List.find_map ~f:find_super_type_
(type_get_direct_supertypes tenv (Typ.mk (Tstruct type_name)))
List.find_map ~f:find_super_type (type_get_direct_supertypes tenv (Typ.mk (Tstruct type_name)))
in
if check_current_type && f proc_name then Some proc_name
else

@ -112,4 +112,12 @@ public class InconsistentSubclassAnnotation implements InconsistentSubclassAnnot
public String implementInAnotherFile(String s) {
return "";
}
public @Nullable Object overloadedMethod() {
return null;
}
public Object overloadedMethod(Object object) {
return object;
}
}

@ -10,5 +10,10 @@ package codetoanalyze.java.eradicate;
import javax.annotation.Nullable;
public interface InconsistentSubclassAnnotationInterface {
public String implementInAnotherFile(@Nullable String s);
Object overloadedMethod();
Object overloadedMethod(Object object);
}

@ -32,6 +32,7 @@ codetoanalyze/java/eradicate/FieldNotNullable.java, codetoanalyze.java.eradicate
codetoanalyze/java/eradicate/FieldNotNullable.java, codetoanalyze.java.eradicate.TestInitializerBuilder.build():codetoanalyze.java.eradicate.TestInitializer, 2, ERADICATE_CONDITION_REDUNDANT, no_bucket, WARNING, [The condition TestInitializerBuilder.required2 is always true according to the existing annotations.]
codetoanalyze/java/eradicate/InconsistentSubclassAnnotation.java, codetoanalyze.java.eradicate.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/eradicate/InconsistentSubclassAnnotation.java, codetoanalyze.java.eradicate.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/eradicate/InconsistentSubclassAnnotation.java, codetoanalyze.java.eradicate.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/eradicate/InconsistentSubclassAnnotation.java, codetoanalyze.java.eradicate.SubclassExample$B.foo():codetoanalyze.java.eradicate.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/eradicate/InconsistentSubclassAnnotation.java, codetoanalyze.java.eradicate.SubclassExample$C.baz():codetoanalyze.java.eradicate.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/eradicate/InconsistentSubclassAnnotation.java, codetoanalyze.java.eradicate.SubclassExample$D.deref(codetoanalyze.java.eradicate.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(...)`.]

Loading…
Cancel
Save