Skip to content

Commit b1e60a1

Browse files
author
Adam Welc
committed
Added support for recursive and mult-file function definitions
1 parent 77aaa84 commit b1e60a1

File tree

11 files changed

+550
-379
lines changed

11 files changed

+550
-379
lines changed

infer/lib/go/src_to_ast_json.go

Lines changed: 336 additions & 280 deletions
Large diffs are not rendered by default.

infer/src/atd/go_ast_to_json.atd

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
type object_type =
22
[ FuncDecl of func_decl_type
33
| FuncDeclRef of int
4-
| Field of field_type
54
| FieldRef of int
6-
| ValueSpec of value_spec_type
5+
| ValueSpec of value_spec_type
76
| ValueSpecRef of int
87
| AssignStmt of assign_stmt_type
98
| AssignStmtRef of int
@@ -68,7 +67,7 @@ type value_spec_type = {
6867
}
6968

7069
type spec_type =
71-
[ValueSpec of value_spec_type]
70+
[ ValueSpec of value_spec_type ]
7271

7372
type gen_decl_type = {
7473
ln <json name="Ln"> : int;
@@ -77,10 +76,13 @@ type gen_decl_type = {
7776
specs <json name="Specs"> : spec_type list;
7877
}
7978

79+
type func_desc_type =
80+
[ FuncTypeRef of int ]
81+
8082
type func_decl_type = {
8183
uid <json name="Uid"> : int;
8284
name <json name="Name"> : ident_type;
83-
func_type <json name="FuncType"> : func_type_type;
85+
func_desc <json name="FuncDesc"> : func_desc_type;
8486
body <json name="Body"> : block_stmt_type;
8587
}
8688

@@ -109,7 +111,7 @@ type assign_stmt_type = {
109111

110112
type stmt_type =
111113
[ DeclStmt of decl_stmt_type
112-
| ReturnStmt of return_stmt_type
114+
| ReturnStmt of return_stmt_type
113115
| AssignStmt of assign_stmt_type
114116
| BlockStmt of block_stmt_type
115117
| IfStmt of if_stmt_type
@@ -127,9 +129,10 @@ type field_type = {
127129
}
128130

129131
type field_list_el_type =
130-
[ Field of field_type ]
132+
[ FieldRef of int ]
131133

132134
type func_type_type = {
135+
uid <json name="Uid"> : int;
133136
ln <json name="Ln"> : int;
134137
col <json name="Col"> : int;
135138
params <json name="Params"> : field_list_el_type list;
@@ -191,6 +194,17 @@ type empty_stmt_type = {
191194
col <json name="Col"> : int;
192195
}
193196

197+
type func_sig_type = {
198+
name <json name="Name"> : string;
199+
func_desc <json name="FuncDesc"> : func_desc_type;
200+
}
201+
202+
type def_type =
203+
[ FuncType of func_type_type
204+
| Field of field_type ]
205+
194206
type file_type = {
207+
defs <json name="Defs"> : def_type list;
195208
decls <json name="Decls"> : decl_type list;
209+
funcs <json name="Funcs"> : func_sig_type list;
196210
}

infer/src/go/context.ml

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,31 @@ end)
1717

1818
module FuncDeclsMap = IntMap
1919

20+
module FuncTypesMap = IntMap
21+
22+
module FieldsMap = IntMap
23+
2024
module LabeledStmtsMap = IntMap
2125

2226
module LabelNodesMap = IntMap
2327

2428
module NestMap = Procdesc.NodeMap
2529

30+
module FuncSigsMap = Caml.Map.Make(struct
31+
type t = string [@@deriving compare]
32+
end)
33+
34+
type gomodule =
35+
{ mutable func_sigs : (Typ.t) FuncSigsMap.t
36+
; mutable files : string list }
37+
2638
type gocfg =
2739
{ cfg: Cfg.t
2840
; src_file: SourceFile.t
29-
; mutable func_decls: (Procdesc.t) FuncDeclsMap.t }
41+
; mutable func_decls: (Procdesc.t) FuncDeclsMap.t
42+
; mutable func_types: (Go_ast_to_json_t.func_type_type) FuncTypesMap.t
43+
; mutable fields : (Go_ast_to_json_t.field_type) FieldsMap.t
44+
; go_module : gomodule }
3045

3146
type t =
3247
{ proc_desc: Procdesc.t
@@ -59,7 +74,15 @@ let create_context proc_desc go_cfg exit_node =
5974
; exit_node
6075
; go_cfg }
6176

62-
let create_cfg file =
77+
let create_cfg m file =
6378
{ cfg = Cfg.create ()
6479
; src_file = file
65-
; func_decls = FuncDeclsMap.empty }
80+
; func_decls = FuncDeclsMap.empty
81+
; func_types = FuncTypesMap.empty
82+
; fields = FieldsMap.empty
83+
; go_module = m }
84+
85+
let create_module paths =
86+
{ func_sigs = FuncSigsMap.empty
87+
; files = paths }
88+

infer/src/go/context.mli

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,29 @@ module IntMap : Caml.Map.S with type key = int
1414

1515
module FuncDeclsMap : Caml.Map.S with type key = int
1616

17+
module FuncTypesMap : Caml.Map.S with type key = int
18+
19+
module FieldsMap : Caml.Map.S with type key = int
20+
1721
module LabeledStmtsMap : Caml.Map.S with type key = int
1822

1923
module LabelNodesMap : Caml.Map.S with type key = int
2024

2125
module NestMap : Caml.Map.S with type key = Procdesc.Node.t
2226

27+
module FuncSigsMap : Caml.Map.S with type key = string
28+
29+
type gomodule =
30+
{ mutable func_sigs : (Typ.t) FuncSigsMap.t
31+
; mutable files : string list }
32+
2333
type gocfg =
2434
{ cfg: Cfg.t
2535
; src_file: SourceFile.t
26-
; mutable func_decls: (Procdesc.t) FuncDeclsMap.t }
36+
; mutable func_decls: (Procdesc.t) FuncDeclsMap.t
37+
; mutable func_types : (Go_ast_to_json_t.func_type_type) FuncTypesMap.t
38+
; mutable fields : (Go_ast_to_json_t.field_type) FieldsMap.t
39+
; go_module : gomodule }
2740

2841
type t =
2942
{ proc_desc: Procdesc.t
@@ -52,4 +65,6 @@ type t =
5265

5366
val create_context : Procdesc.t -> gocfg -> Procdesc.Node.t -> t
5467

55-
val create_cfg : SourceFile.t -> gocfg
68+
val create_cfg : gomodule -> SourceFile.t -> gocfg
69+
70+
val create_module : string list -> gomodule

infer/src/go/pretty.ml

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,28 @@
11
open! IStd
22
open Go_ast_to_json_t
33

4-
let funcs_map = Int.Table.create () ~size:8
4+
let func_decls_map = Int.Table.create () ~size:8
5+
let func_types_map = Int.Table.create () ~size:8
6+
let fields_map = Int.Table.create () ~size:8
57
let labeled_stmts_map = Int.Table.create () ~size:8
68

79
let concatmap sep fn l = String.concat ~sep:(sep) (List.map ~f:(fn) l)
810

911
let rec pretty_file go_file =
12+
List.iter ~f:(get_def) go_file.defs;
1013
concatmap "\n" pretty_decl go_file.decls
1114

15+
and get_def = function
16+
| `FuncType (t) -> Hashtbl.replace func_types_map t.uid t
17+
| `Field (field) -> Hashtbl.replace fields_map field.uid field
18+
1219
and pretty_decl = function
1320
| `GenDecl (decl) -> pretty_gen_decl decl
14-
| `FuncDecl (decl) -> pretty_func_decl decl
15-
| `FuncDeclRef (ref) ->
16-
(match Hashtbl.find funcs_map ref with
17-
| None -> raise (Failure "Should not happen")
18-
| Some (s) -> s )
21+
| `FuncDecl (decl) -> Hashtbl.replace func_decls_map decl.uid decl; pretty_func_decl decl
22+
| `FuncDeclRef (ref) -> pretty_func_decl (Hashtbl.find_exn func_decls_map ref)
1923

2024
and pretty_func_decl fdecl =
21-
match Hashtbl.find funcs_map fdecl.uid with
22-
| None -> "func " ^ (pretty_ident fdecl.name) ^ (pretty_func_type fdecl.func_type) ^ " {\n" ^ (pretty_stmt_type fdecl.body) ^ "\n}\n"
23-
| Some (s) -> s
25+
"func " ^ (pretty_ident fdecl.name) ^ (pretty_func_type (get_func_type fdecl.func_desc)) ^ " {\n" ^ (pretty_stmt_type fdecl.body) ^ "\n}\n"
2426

2527
and pretty_value_spec (vspec : value_spec_type) : string =
2628
if (List.length vspec.names > 1) then raise (Failure "Only single variable declaration supported for now") else (
@@ -41,7 +43,7 @@ and pretty_value_spec (vspec : value_spec_type) : string =
4143
)
4244

4345
and pretty_spec = function
44-
| `ValueSpec (vspec) -> pretty_value_spec vspec
46+
| `ValueSpec (spec : value_spec_type) -> pretty_value_spec spec
4547

4648
and pretty_gen_decl gdecl =
4749
if (List.length gdecl.specs > 1) then raise (Failure "Only one declaration specification supported for now") else (
@@ -54,13 +56,11 @@ and pretty_ident ident =
5456
| Some (o) ->
5557
match o with
5658
| `FuncDecl (decl) ->
57-
let s = pretty_func_decl decl in
58-
Hashtbl.replace funcs_map ~key:decl.uid ~data:s;
59-
ident.id
59+
Hashtbl.replace func_decls_map decl.uid decl;
60+
ident.id
6061
| `LabeledStmt (stmt) ->
61-
let s = pretty_labeled_stmt stmt in
62-
Hashtbl.replace labeled_stmts_map ~key:stmt.uid ~data:s;
63-
ident.id
62+
Hashtbl.replace labeled_stmts_map stmt.uid stmt;
63+
ident.id
6464
| _ -> ident.id
6565

6666
and pretty_star_expr (expr : star_expr_type) : string =
@@ -77,11 +77,15 @@ and pretty_expr = function
7777
| `BasicLit (lit) -> lit.value
7878
| `CallExpr (expr) -> pretty_call_expr expr
7979

80-
and pretty_res_typ = function
81-
| `Field (field) -> pretty_expr field.t
80+
and get_field = function
81+
| `FieldRef (ref) -> Hashtbl.find_exn fields_map ref
82+
83+
and pretty_res_typ f =
84+
let field = get_field f in
85+
pretty_expr field.t
8286

83-
and pretty_param = function
84-
| `Field (field) ->
87+
and pretty_param f =
88+
let field = get_field f in
8589
if (List.length field.names > 1) then raise (Failure "Function parameter can have only one name") else (
8690
pretty_ident (List.nth_exn field.names 0) ^ " " ^ pretty_expr field.t
8791
)
@@ -91,6 +95,11 @@ and pretty_func_type func_type =
9195
"(" ^ (concatmap ", " pretty_param func_type.params) ^ ") " ^ (pretty_res_typ (List.nth_exn func_type.results 0))
9296
)
9397

98+
and get_func_type = function
99+
| `FuncTypeRef (ref) ->
100+
Hashtbl.find_exn func_types_map ref
101+
102+
94103
and pretty_decl_stmt stmt =
95104
pretty_decl stmt.decl
96105

@@ -128,9 +137,7 @@ and pretty_labeled_stmt stmt =
128137
pretty_ident stmt.label ^ ":\n" ^ pretty_stmt stmt.stmt
129138

130139
and pretty_labeled_stmt_ref ref =
131-
(match Hashtbl.find labeled_stmts_map ref with
132-
| None -> raise (Failure "Should not happen")
133-
| Some (s) -> s )
140+
pretty_labeled_stmt (Hashtbl.find_exn labeled_stmts_map ref)
134141

135142

136143
and pretty_stmt = function
@@ -142,7 +149,7 @@ and pretty_stmt = function
142149
| `ForStmt (stmt) -> pretty_for_stmt stmt
143150
| `IncDecStmt (stmt) -> pretty_inc_dec_stmt stmt
144151
| `BranchStmt (stmt) -> pretty_branch_stmt stmt
145-
| `LabeledStmt (stmt) -> pretty_labeled_stmt stmt
152+
| `LabeledStmt (stmt) -> Hashtbl.replace labeled_stmts_map stmt.uid stmt; pretty_labeled_stmt stmt
146153
| `LabeledStmtRef (ref) -> pretty_labeled_stmt_ref ref
147154
| `EmptyStmt (stmt) -> ""
148155

0 commit comments

Comments
 (0)