-
Notifications
You must be signed in to change notification settings - Fork 125
/
jsUtils.ml
70 lines (62 loc) · 2.85 KB
/
jsUtils.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
(*
Copyright © 2011 MLstate
This file is part of OPA.
OPA is free software: you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License, version 3, as published by
the Free Software Foundation.
OPA is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
more details.
You should have received a copy of the GNU Affero General Public License
along with OPA. If not, see <http://www.gnu.org/licenses/>.
*)
module J = JsAst
let arguments_ident = JsCons.Ident.native "arguments"
let maybe_globalize_ident local_vars = function
| J.ExprIdent _ as i -> i
| J.Native (`global,_) as i -> i
| J.Native (`local,j) as i ->
if JsIdentSet.mem i local_vars then i else J.Native (`global,j)
let collect_local_var local_vars stm =
(* not going inside the functions that are inside expressions on purpose.
* The identifiers defined there are not in scope *)
JsWalk.OnlyStatement.fold
(fun local_vars -> function
| J.Js_function (_,name,_,_)
| J.Js_var (_,name,_) -> JsIdentSet.add name local_vars
| _ -> local_vars) local_vars stm
let collect_local_vars local_vars stms =
List.fold_left collect_local_var local_vars stms
let globalize_native_ident stm =
JsWalk.TStatement.map_context_down (* map_down actually *)
(fun local_vars stm ->
match stm with
| J.Js_function (label,name,params,body) ->
let fname = maybe_globalize_ident local_vars name in
let local_vars = JsIdentSet.add arguments_ident local_vars in
let local_vars = List.fold_left (fun local_vars i -> JsIdentSet.add i local_vars) local_vars params in
let local_vars = collect_local_vars local_vars body in
let stm = if name == fname then stm else J.Js_function (label,fname,params,body) in
local_vars, stm
| J.Js_var (label,name,o) ->
let fname = maybe_globalize_ident local_vars name in
let stm = if name == fname then stm else J.Js_var (label,fname, o) in
local_vars, stm
| _ ->
local_vars, stm
)
(fun local_vars e ->
match e with
| J.Je_function (_,_,params,body) ->
let local_vars = JsIdentSet.add arguments_ident local_vars in
let local_vars = List.fold_left (fun local_vars i -> JsIdentSet.add i local_vars) local_vars params in
let local_vars = collect_local_vars local_vars body in
local_vars, e
| J.Je_ident (label,name) ->
let fname = maybe_globalize_ident local_vars name in
let e = if name == fname then e else J.Je_ident (label,fname) in
local_vars, e
| _ ->
local_vars, e
) JsIdentSet.empty stm