Skip to content

Commit 2f09b39

Browse files
davidpichardiefacebook-github-bot
authored andcommitted
New java source parser for declaration locations (experimental)
Summary: The current source parser is based on ocamllex only. In order to track field declaration locations, we propose a new parser using ocamllex/menhir. This is a more ambitious project that closely follows the official Java syntax. Reviewed By: jvillard Differential Revision: D24858280 fbshipit-source-id: 22d6766e5
1 parent 02625ac commit 2f09b39

File tree

15 files changed

+1185
-8
lines changed

15 files changed

+1185
-8
lines changed

infer/man/man1/infer-full.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1566,6 +1566,10 @@ INTERNAL OPTIONS
15661566
--java-jar-compiler-reset
15671567
Cancel the effect of --java-jar-compiler.
15681568

1569+
--java-source-parser-experimental
1570+
Activates: The experimental Java source parser for declaration
1571+
locations. (Conversely: --no-java-source-parser-experimental)
1572+
15691573
--java-version-reset
15701574
Cancel the effect of --java-version.
15711575

infer/src/base/Config.ml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1460,6 +1460,11 @@ and java_jar_compiler =
14601460
~meta:"path" "Specify the Java compiler jar used to generate the bytecode"
14611461

14621462

1463+
and java_source_parser_experimental =
1464+
CLOpt.mk_bool ~long:"java-source-parser-experimental"
1465+
"The experimental Java source parser for declaration locations."
1466+
1467+
14631468
and java_version =
14641469
CLOpt.mk_int_opt ~long:"java-version" ?default:Version.java_version
14651470
~in_help:InferCommand.[(Capture, manual_java); (Analyze, manual_java)]
@@ -2927,6 +2932,8 @@ and java_debug_source_file_info = !java_debug_source_file_info
29272932

29282933
and java_jar_compiler = !java_jar_compiler
29292934

2935+
and java_source_parser_experimental = !java_source_parser_experimental
2936+
29302937
and java_version = !java_version
29312938

29322939
and javac_classes_out = !javac_classes_out

infer/src/base/Config.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,8 @@ val java_debug_source_file_info : string option
344344

345345
val java_jar_compiler : string option
346346

347+
val java_source_parser_experimental : bool
348+
347349
val java_version : int option
348350

349351
val javac_classes_out : string

infer/src/infer.ml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,9 @@ let () =
157157
| _ when Config.test_determinator && not Config.process_clang_ast ->
158158
TestDeterminator.compute_and_emit_test_to_run ()
159159
| _ when Option.is_some Config.java_debug_source_file_info ->
160-
JSourceFileInfo.debug_on_file (Option.value_exn Config.java_debug_source_file_info)
160+
if Config.java_source_parser_experimental then
161+
JSourceLocations.debug_on_file (Option.value_exn Config.java_debug_source_file_info)
162+
else JSourceFileInfo.debug_on_file (Option.value_exn Config.java_debug_source_file_info)
161163
| Analyze ->
162164
run Driver.Analyze
163165
| Capture | Compile | Run ->

infer/src/java/JavaFrontendStubs.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,7 @@ end
1616
module JSourceFileInfo = struct
1717
let debug_on_file _ = ()
1818
end
19+
20+
module JSourceLocations = struct
21+
let debug_on_file _ = ()
22+
end

infer/src/java/JavaFrontendStubs.mli

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,7 @@ end
2222
module JSourceFileInfo : sig
2323
val debug_on_file : string -> unit
2424
end
25+
26+
module JSourceLocations : sig
27+
val debug_on_file : string -> unit
28+
end

infer/src/java/dune.in

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
*)
88
(* NOTE: prepend dune.common to this file! *)
99

10-
let lexer = "(ocamllex jSourceFileInfo)"
10+
let lexer = "(ocamllex jSourceLexer jSourceFileInfo)"
11+
let jparser = "(menhir (modules jSourceParser))"
1112

1213
let java =
1314
Printf.sprintf
@@ -30,4 +31,4 @@ let java =
3031
let documentation = "(documentation (package infer) (mld_files JavaFrontend))"
3132

3233
;;
33-
Jbuild_plugin.V1.send (String.concat "\n" [lexer; java; documentation])
34+
Jbuild_plugin.V1.send (String.concat "\n" [lexer; jparser; java; documentation])

infer/src/java/jFrontend.ml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,9 @@ let compute_source_icfg program tenv source_basename package_opt source_file =
217217
if test node then try procedure cn node with Bir.Subroutine -> ()
218218
in
219219
(* we must set the java location for all classes in the source file before translation *)
220-
JSourceFileInfo.collect_class_location program source_file ;
220+
if Config.java_source_parser_experimental then
221+
JSourceLocations.collect_class_location program source_file
222+
else JSourceFileInfo.collect_class_location program source_file ;
221223
let () =
222224
JBasics.ClassMap.iter
223225
(select

infer/src/java/jSourceAST.ml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
(*
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*)
7+
8+
open! IStd
9+
10+
type location = {line: int; col: int}
11+
12+
type class_kind = Class of string | Interface of string | AnonymousClass | Enum of string
13+
14+
type class_or_interface =
15+
{location: location; kind: class_kind; inner_elements: class_or_interface list}
16+
17+
type file_content = {package: string option; classes: class_or_interface list}
18+
19+
type context = {prefix: string; mutable counter: int}
20+
21+
let name_of_kind context = function
22+
| Class id | Interface id | Enum id ->
23+
id
24+
| AnonymousClass ->
25+
context.counter <- context.counter + 1 ;
26+
string_of_int context.counter
27+
28+
29+
let rec iter ~action_on_class_location context {location; kind; inner_elements} =
30+
let previous_prefix = context.prefix in
31+
let name = name_of_kind context kind in
32+
let context = {prefix= Printf.sprintf "%s%s$" context.prefix name; counter= 0} in
33+
let classname = previous_prefix ^ name in
34+
let col = location.col in
35+
let line = location.line in
36+
let _ = action_on_class_location ~classname ~col ~line in
37+
List.iter inner_elements ~f:(iter ~action_on_class_location context)
38+
39+
40+
let iter_on_declarations ~action_on_class_location {package; classes} =
41+
let prefix = Option.fold ~init:"" ~f:(fun _ s -> s ^ ".") package in
42+
let context = {prefix; counter= 0} in
43+
List.iter classes ~f:(iter ~action_on_class_location context)

infer/src/java/jSourceAST.mli

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
(*
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*)
7+
8+
open! IStd
9+
10+
type location = {line: int; col: int}
11+
12+
type class_kind = Class of string | Interface of string | AnonymousClass | Enum of string
13+
14+
type class_or_interface =
15+
{location: location; kind: class_kind; inner_elements: class_or_interface list}
16+
17+
type file_content = {package: string option; classes: class_or_interface list}
18+
19+
val iter_on_declarations :
20+
action_on_class_location:(classname:string -> col:int -> line:int -> unit) -> file_content -> unit

0 commit comments

Comments
 (0)