[java] Add command-line option to specify external Java packages

Summary: Add a new command-line option `--external-java-packages` which allows the user to specify a list of Java package prefixes for external packages. Then the analysis will not report non-actionable warnings on those packages (e.g., inconsistent `Nullable` annotations in external packages).

Reviewed By: jeremydubreil

Differential Revision: D7126960

fbshipit-source-id: c4f3c7c
master
Tony Hu 7 years ago committed by Facebook Github Bot
parent 9f343853ec
commit 56872d8126

@ -14,5 +14,4 @@
"source_contains": "_SHOULD_SKIP_IMPLEMENTATION_"
}
]
}

@ -1245,6 +1245,14 @@ and eradicate_verbose =
CLOpt.mk_bool ~long:"eradicate-verbose" "Print initial and final typestates"
and external_java_packages =
CLOpt.mk_string_list ~long:"external-java-packages"
~in_help:InferCommand.([(Analyze, manual_java)])
~meta:"prefix"
"Specify a list of Java package prefixes for external Java packages. If set, the analysis \
will not report non-actionable warnings on those packages."
and fail_on_bug =
CLOpt.mk_bool ~deprecated:["-fail-on-bug"] ~long:"fail-on-issue" ~default:false
~in_help:InferCommand.([(Run, manual_generic)])
@ -2417,6 +2425,8 @@ and eradicate_debug = !eradicate_debug
and eradicate_verbose = !eradicate_verbose
and external_java_packages = !external_java_packages
and fail_on_bug = !fail_on_bug
and fcp_apple_clang = !fcp_apple_clang
@ -2818,3 +2828,12 @@ let pp_simple = ref true
let reset_abs_val () = abs_val := abs_val_orig
let run_with_abs_val_equal_zero f x = set_reference_and_call_function abs_val 0 f x
(** Check if a Java package is external to the repository *)
let java_package_is_external package =
match external_java_packages with
| [] ->
false
| _ ->
List.exists external_java_packages ~f:(fun (prefix: string) ->
String.is_prefix package ~prefix )

@ -679,3 +679,6 @@ val print_usage_exit : unit -> 'a
(** Miscellanous *)
val register_late_epilogue : (unit -> unit) -> unit
val java_package_is_external : string -> bool
(** Check if a Java package is external to the repository *)

@ -151,31 +151,24 @@ let pretty_field_name proc_data field_name =
Typ.Fieldname.to_string field_name
(* Checks if a field name stems from a class outside domain of what is analyzed by
* Infer, by seeing if we can get an on-demand summary for it. *)
let is_outside_codebase proc_desc tenv field_name =
match Procdesc.get_proc_name proc_desc with
(* Checks if a field name stems from a class outside the domain of what is analyzed by Infer *)
let is_outside_codebase proc_name field_name =
match proc_name with
| Typ.Procname.Java _ ->
let class_name = Typ.Fieldname.Java.get_class field_name in
let class_type = Typ.Name.Java.from_string class_name in
let class_struct = Tenv.lookup tenv class_type in
let first_method =
Option.bind ~f:(fun (cls: Typ.Struct.t) -> List.hd cls.methods) class_struct
in
let summary =
Option.bind ~f:(Ondemand.analyze_proc_name ~caller_pdesc:proc_desc) first_method
in
Option.is_none summary
let package, _ = Typ.Name.Java.split_classname class_name in
Option.exists ~f:Config.java_package_is_external package
| _ ->
false
let checker {Callbacks.summary; proc_desc; tenv} =
let annotation = Localise.nullable_annotation_name (Procdesc.get_proc_name proc_desc) in
let proc_name = Procdesc.get_proc_name proc_desc in
let annotation = Localise.nullable_annotation_name proc_name in
let report astate (proc_data: extras ProcData.t) =
let report_access_path ap udchain =
match AccessPath.get_field_and_annotation ap proc_data.tenv with
| Some (field_name, _) when is_outside_codebase proc_desc tenv field_name ->
| Some (field_name, _) when is_outside_codebase proc_name field_name ->
(* Skip reporting when the field is outside the analyzed codebase *)
()
| Some (field_name, _) when Typ.Fieldname.Java.is_captured_parameter field_name ->

@ -17,5 +17,8 @@
"sources": ["UserDefinedSource1", "UserDefinedSource2"],
"sink": "UserDefinedSink"
}
],
"external-java-packages": [
"external."
]
}

@ -14,6 +14,6 @@ INFER_OPTIONS = \
--suggest-nullable --check-nullable --racerd \
INFERPRINT_OPTIONS = --issues-tests
SOURCES = $(wildcard *.java)
SOURCES = $(wildcard *.java) $(wildcard $(TESTS_DIR)/external/library/*.java)
include $(TESTS_DIR)/javac.make

@ -8,6 +8,8 @@
*/
package codetoanalyze.java.checkers;
import external.library.SomeClass;
import javax.annotation.Nullable;
public class NullableSuggest {
@ -126,4 +128,13 @@ public class NullableSuggest {
};
}
boolean checkExternalFieldForNullOk(SomeClass parameter) {
if (parameter.field == null) {
// Does not report here. The field belongs to an external library so the
// warning would not be actionable.
return true;
}
return false;
}
}

@ -0,0 +1,15 @@
/*
* Copyright (c) 2018 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package external.library;
public class SomeClass {
public Object field;
}
Loading…
Cancel
Save