Skip to content

Commit 56872d8

Browse files
dr-hufacebook-github-bot
authored andcommitted
[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
1 parent 9f34385 commit 56872d8

File tree

8 files changed

+60
-17
lines changed

8 files changed

+60
-17
lines changed

.inferconfig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,4 @@
1414
"source_contains": "_SHOULD_SKIP_IMPLEMENTATION_"
1515
}
1616
]
17-
1817
}

infer/src/base/Config.ml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1245,6 +1245,14 @@ and eradicate_verbose =
12451245
CLOpt.mk_bool ~long:"eradicate-verbose" "Print initial and final typestates"
12461246

12471247

1248+
and external_java_packages =
1249+
CLOpt.mk_string_list ~long:"external-java-packages"
1250+
~in_help:InferCommand.([(Analyze, manual_java)])
1251+
~meta:"prefix"
1252+
"Specify a list of Java package prefixes for external Java packages. If set, the analysis \
1253+
will not report non-actionable warnings on those packages."
1254+
1255+
12481256
and fail_on_bug =
12491257
CLOpt.mk_bool ~deprecated:["-fail-on-bug"] ~long:"fail-on-issue" ~default:false
12501258
~in_help:InferCommand.([(Run, manual_generic)])
@@ -2417,6 +2425,8 @@ and eradicate_debug = !eradicate_debug
24172425

24182426
and eradicate_verbose = !eradicate_verbose
24192427

2428+
and external_java_packages = !external_java_packages
2429+
24202430
and fail_on_bug = !fail_on_bug
24212431

24222432
and fcp_apple_clang = !fcp_apple_clang
@@ -2818,3 +2828,12 @@ let pp_simple = ref true
28182828
let reset_abs_val () = abs_val := abs_val_orig
28192829

28202830
let run_with_abs_val_equal_zero f x = set_reference_and_call_function abs_val 0 f x
2831+
2832+
(** Check if a Java package is external to the repository *)
2833+
let java_package_is_external package =
2834+
match external_java_packages with
2835+
| [] ->
2836+
false
2837+
| _ ->
2838+
List.exists external_java_packages ~f:(fun (prefix: string) ->
2839+
String.is_prefix package ~prefix )

infer/src/base/Config.mli

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,3 +679,6 @@ val print_usage_exit : unit -> 'a
679679
(** Miscellanous *)
680680

681681
val register_late_epilogue : (unit -> unit) -> unit
682+
683+
val java_package_is_external : string -> bool
684+
(** Check if a Java package is external to the repository *)

infer/src/checkers/NullabilitySuggest.ml

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -151,31 +151,24 @@ let pretty_field_name proc_data field_name =
151151
Typ.Fieldname.to_string field_name
152152

153153

154-
(* Checks if a field name stems from a class outside domain of what is analyzed by
155-
* Infer, by seeing if we can get an on-demand summary for it. *)
156-
let is_outside_codebase proc_desc tenv field_name =
157-
match Procdesc.get_proc_name proc_desc with
154+
(* Checks if a field name stems from a class outside the domain of what is analyzed by Infer *)
155+
let is_outside_codebase proc_name field_name =
156+
match proc_name with
158157
| Typ.Procname.Java _ ->
159158
let class_name = Typ.Fieldname.Java.get_class field_name in
160-
let class_type = Typ.Name.Java.from_string class_name in
161-
let class_struct = Tenv.lookup tenv class_type in
162-
let first_method =
163-
Option.bind ~f:(fun (cls: Typ.Struct.t) -> List.hd cls.methods) class_struct
164-
in
165-
let summary =
166-
Option.bind ~f:(Ondemand.analyze_proc_name ~caller_pdesc:proc_desc) first_method
167-
in
168-
Option.is_none summary
159+
let package, _ = Typ.Name.Java.split_classname class_name in
160+
Option.exists ~f:Config.java_package_is_external package
169161
| _ ->
170162
false
171163

172164

173165
let checker {Callbacks.summary; proc_desc; tenv} =
174-
let annotation = Localise.nullable_annotation_name (Procdesc.get_proc_name proc_desc) in
166+
let proc_name = Procdesc.get_proc_name proc_desc in
167+
let annotation = Localise.nullable_annotation_name proc_name in
175168
let report astate (proc_data: extras ProcData.t) =
176169
let report_access_path ap udchain =
177170
match AccessPath.get_field_and_annotation ap proc_data.tenv with
178-
| Some (field_name, _) when is_outside_codebase proc_desc tenv field_name ->
171+
| Some (field_name, _) when is_outside_codebase proc_name field_name ->
179172
(* Skip reporting when the field is outside the analyzed codebase *)
180173
()
181174
| Some (field_name, _) when Typ.Fieldname.Java.is_captured_parameter field_name ->

infer/tests/codetoanalyze/java/checkers/.inferconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,8 @@
1717
"sources": ["UserDefinedSource1", "UserDefinedSource2"],
1818
"sink": "UserDefinedSink"
1919
}
20+
],
21+
"external-java-packages": [
22+
"external."
2023
]
2124
}

infer/tests/codetoanalyze/java/checkers/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@ INFER_OPTIONS = \
1414
--suggest-nullable --check-nullable --racerd \
1515

1616
INFERPRINT_OPTIONS = --issues-tests
17-
SOURCES = $(wildcard *.java)
17+
SOURCES = $(wildcard *.java) $(wildcard $(TESTS_DIR)/external/library/*.java)
1818

1919
include $(TESTS_DIR)/javac.make

infer/tests/codetoanalyze/java/checkers/NullableSuggest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
*/
99

1010
package codetoanalyze.java.checkers;
11+
12+
import external.library.SomeClass;
1113
import javax.annotation.Nullable;
1214

1315
public class NullableSuggest {
@@ -126,4 +128,13 @@ void foo() {
126128
};
127129
}
128130

131+
boolean checkExternalFieldForNullOk(SomeClass parameter) {
132+
if (parameter.field == null) {
133+
// Does not report here. The field belongs to an external library so the
134+
// warning would not be actionable.
135+
return true;
136+
}
137+
return false;
138+
}
139+
129140
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*
2+
* Copyright (c) 2018 - present Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD style license found in the
6+
* LICENSE file in the root directory of this source tree. An additional grant
7+
* of patent rights can be found in the PATENTS file in the same directory.
8+
*/
9+
10+
package external.library;
11+
12+
13+
public class SomeClass {
14+
public Object field;
15+
}

0 commit comments

Comments
 (0)