Skip to content

Commit eb3fafe

Browse files
author
Hongbo Zhang
committed
add goog module support, -js-module goog:, add magic number
1 parent ab2b47a commit eb3fafe

32 files changed

+327
-135
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,6 @@ osc
5555
jscomp/pre_load.js
5656
boot
5757
*.dump
58+
5859
coverage
59-
*.log
60+
*.log

jscomp/config_util.ml

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,23 @@ let find_cmj file =
3737
Js_cmj_format.from_file f
3838
| exception Not_found ->
3939
(* TODO: add an logger module *)
40+
let target = String.uncapitalize (Filename.basename file) in
4041
begin match
41-
String_map.find (String.uncapitalize (Filename.basename file))
42+
String_map.find target
4243
Js_cmj_datasets.cmj_data_sets with
4344
| v
44-
-> Lazy.force v
45+
->
46+
begin match Lazy.force v with
47+
| exception _
48+
->
49+
Ext_log.warn __LOC__
50+
"@[%s corrupted in database, when looking %s while compiling %s please update @]" file target (Lam_current_unit.get_file ()) ;
51+
Js_cmj_format.no_pure_dummy; (* FIXME *)
52+
| v -> v
53+
end
4554
| exception Not_found
4655
->
4756
Ext_log.warn __LOC__ "@[%s not found @]" file ;
48-
Js_cmj_format.dummy (); (* FIXME *)
57+
Js_cmj_format.no_pure_dummy (* FIXME *)
4958
end
5059
end

jscomp/js_cmj_format.ml

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,52 @@ type effect = string option
3131

3232
type cmj_table = {
3333
values : cmj_value String_map.t;
34-
pure : effect;
34+
effect : effect;
35+
goog_package : string option;
3536
}
3637

37-
let dummy ?(pure=Some "dummy") () =
38-
{ values = String_map.empty ; pure }
38+
let cmj_magic_number = "BUCKLE20160310"
39+
let cmj_magic_number_length =
40+
String.length cmj_magic_number
3941

40-
let from_file name : cmj_table = Ext_marshal.from_file name
42+
let pure_dummy =
43+
{
44+
values = String_map.empty;
45+
effect = None;
46+
goog_package = None
47+
}
4148

42-
let from_string s : cmj_table = Marshal.from_string s 0
49+
let no_pure_dummy =
50+
{
51+
values = String_map.empty;
52+
effect = (Some "");
53+
goog_package = None
54+
}
4355

44-
let to_file name v = Ext_marshal.to_file name v
56+
57+
58+
let from_file name : cmj_table =
59+
let ic = open_in_bin name in
60+
let buffer = really_input_string ic cmj_magic_number_length in
61+
if buffer <> cmj_magic_number then
62+
failwith
63+
("cmj files have incompatible versions, please rebuilt using the new compiler : "
64+
^ __LOC__)
65+
else
66+
(input_value ic : cmj_table)
67+
68+
69+
let from_string s : cmj_table =
70+
let magic_number = String.sub s 0 cmj_magic_number_length in
71+
if magic_number = cmj_magic_number then
72+
Marshal.from_string s cmj_magic_number_length
73+
else
74+
failwith
75+
("cmj files have incompatible versions, please rebuilt using the new compiler : "
76+
^ __LOC__)
77+
78+
let to_file name (v : cmj_table) =
79+
let oc = open_out_bin name in
80+
output_string oc cmj_magic_number;
81+
output_value oc v;
82+
close_out oc

jscomp/js_cmj_format.mli

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,13 @@ type effect = string option
5353

5454
type cmj_table = {
5555
values : cmj_value String_map.t;
56-
pure : effect
56+
effect : effect;
57+
goog_package : string option
5758
}
5859

59-
val dummy : ?pure:string option -> unit -> cmj_table
60+
val pure_dummy : cmj_table
61+
val no_pure_dummy : cmj_table
62+
6063

6164
val from_file : string -> cmj_table
6265
val from_string : string -> cmj_table

jscomp/js_config.ml

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,36 @@
2222
type env =
2323
| Browser
2424
| NodeJS
25-
25+
| Goog of string option
2626

2727
let default_env = ref NodeJS
2828

2929
let get_env () = !default_env
3030

3131
let set_env env = default_env := env
32-
32+
let cmd_set_module str =
33+
match str with
34+
| "commonjs" -> default_env := NodeJS
35+
| "amdjs" ->
36+
default_env := Browser
37+
| _ ->
38+
if Ext_string.starts_with str "goog" then
39+
let len = String.length str in
40+
if len = 4 then
41+
default_env := Goog (Some "")
42+
else
43+
if str.[4] = ':' && len > 5 then
44+
default_env := Goog (Some (Ext_string.tail_from str 5 ))
45+
else
46+
raise (Arg.Bad (Printf.sprintf "invalid module system %s" str))
47+
else
48+
raise (Arg.Bad (Printf.sprintf "invalid module system %s" str))
49+
50+
let get_goog_package_name () =
51+
match !default_env with
52+
| Goog x -> x
53+
| Browser | NodeJS -> None
54+
3355
let stdlib_set = String_set.of_list [
3456
"arg";
3557
"gc";
@@ -133,3 +155,5 @@ let internalMod = "Caml_internalMod"
133155
let bigarray = "Caml_bigarray"
134156
let unix = "Caml_unix"
135157
let int64 = "Caml_int64"
158+
159+

jscomp/js_config.mli

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@
2121
type env =
2222
| Browser
2323
| NodeJS
24-
24+
| Goog of string option
2525

2626
val get_env : unit -> env
27-
27+
val get_goog_package_name : unit -> string option
2828
val set_env : env -> unit
29-
29+
val cmd_set_module : string -> unit
3030
val runtime_set : String_set.t
3131
val stdlib_set : String_set.t
3232

jscomp/js_dump.ml

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ module L = struct
6161
let return = "return"
6262
let eq = "="
6363
let require = "require"
64+
let goog_require = "goog.require"
65+
let goog_module = "goog.module"
66+
let lparen = "("
67+
let rparen = ")"
6468
let exports = "exports"
6569
let dot = "."
6670
let comma = ","
@@ -1425,7 +1429,7 @@ let exports cxt f (idents : Ident.t list) =
14251429

14261430

14271431
(* Node style *)
1428-
let requires cxt f (modules : (Ident.t * string) list ) =
1432+
let requires require_lit cxt f (modules : (Ident.t * string) list ) =
14291433
P.newline f ;
14301434
(* the context used to print the following program *)
14311435
let outer_cxt, reversed_list, margin =
@@ -1443,7 +1447,7 @@ let requires cxt f (modules : (Ident.t * string) list ) =
14431447
P.nspace f (margin - String.length s + 1) ;
14441448
P.string f L.eq;
14451449
P.space f;
1446-
P.string f L.require;
1450+
P.string f require_lit;
14471451
P.paren_group f 0 @@ (fun _ ->
14481452
pp_string f ~utf:true ~quote:(best_string_quote s) file );
14491453
semi f ;
@@ -1457,8 +1461,18 @@ let program f cxt ( x : J.program ) =
14571461
let () = P.force_newline f in
14581462
exports cxt f x.exports
14591463

1464+
let goog_program f goog_package x =
1465+
P.newline f ;
1466+
P.string f L.goog_module;
1467+
P.string f "(";
1468+
P.string f (Printf.sprintf "%S" goog_package);
1469+
P.string f ")";
1470+
semi f ;
1471+
let cxt = requires L.goog_require ( Ext_pp_scope.empty) f x.J.modules in
1472+
program f cxt x.program
1473+
14601474
let node_program f ( x : J.deps_program) =
1461-
let cxt = requires ( Ext_pp_scope.empty) f x.modules in
1475+
let cxt = requires L.require ( Ext_pp_scope.empty) f x.modules in
14621476
program f cxt x.program
14631477

14641478

@@ -1515,7 +1529,18 @@ let pp_deps_program ( program : J.deps_program) (f : Ext_pp.t) =
15151529
node_program f program
15161530
(* amd_program f program *)
15171531
| _ -> amd_program f program
1518-
end ) ;
1532+
end
1533+
| Goog opt ->
1534+
let goog_package =
1535+
let v = Lam_current_unit.get_module_name () in
1536+
match opt with
1537+
| None
1538+
| Some ""
1539+
-> v
1540+
| Some x -> x ^ "." ^ v
1541+
in
1542+
goog_program f goog_package program
1543+
) ;
15191544
P.newline f ;
15201545
P.string f (
15211546
match program.side_effect with

jscomp/js_main.ml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,16 @@ module Options = Main_args.Make_bytecomp_options (struct
144144
let anonymous = anonymous
145145
end)
146146

147+
148+
let buckle_script_flags =
149+
("-js-module", Arg.String Js_config.cmd_set_module,
150+
" set module system: commonjs (default), amdjs, google:package_name")
151+
:: Options.list
152+
147153
let main () =
148154
try
149155
readenv ppf Before_args;
150-
Arg.parse Options.list anonymous usage;
156+
Arg.parse buckle_script_flags anonymous usage;
151157
readenv ppf Before_link;
152158
if
153159
List.length (List.filter (fun x -> !x)

jscomp/js_program_loader.ml

Lines changed: 57 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -23,61 +23,72 @@
2323
module E = Js_exp_make
2424
module S = Js_stmt_make
2525

26-
type module_id = Lam_module_ident.t
26+
2727

2828
open Js_output.Ops
2929

30-
let string_of_module_id (x : module_id) : string =
30+
let string_of_module_id (x : Lam_module_ident.t) : string =
3131
match x.kind with
3232
| Runtime
3333
| Ml ->
3434
let id = x.id in
3535
let file = Printf.sprintf "%s.js" id.name in
3636
begin match Js_config.get_env () with
37-
| Browser
38-
(* In browser *)
39-
->
40-
let target = String.uncapitalize file in
41-
if String_set.mem target Js_config.runtime_set then
42-
"./runtime/" ^ Filename.chop_extension target
43-
else
44-
"./stdlib/" ^ Filename.chop_extension target
45-
| NodeJS ->
46-
if Ext_string.starts_with id.name "Caml_" then
47-
let path =
48-
(* For the runtime, only [JS] files are needed, and
49-
unlike the stdlib, [osc] have some pre-built knowledge
50-
about where it is, since in general, [runtime]
51-
is *transparent* to the user
52-
*)
53-
match Sys.getenv "OCAML_JS_RUNTIME_PATH" with
54-
| exception Not_found ->
55-
Filename.concat
56-
(Filename.dirname (Filename.dirname Sys.executable_name))
57-
"runtime"
58-
| f -> f in
59-
Ext_filename.node_relative_path !Location.input_name
60-
(Filename.concat path (String.uncapitalize id.name))
61-
else
62-
begin match Config_util.find file with
63-
(* for some primitive files, no cmj support *)
64-
| exception Not_found ->
65-
Ext_log.warn __LOC__ "@[%s not found in search path - while compiling %s @] "
66-
file !Location.input_name ;
67-
Printf.sprintf "%s"
68-
(String.uncapitalize id.name)
69-
(* maybe from third party library*)
70-
(* Check: be consistent when generating js files
71-
A.ml -> a.js
72-
a.ml -> a.js
73-
check generated [js] file if it's capital or not
74-
Actually, we can not tell its original name just from [id],
75-
so we just always general litte_case.js
76-
*)
77-
| path ->
78-
Ext_filename.node_relative_path !Location.input_name path
79-
80-
end
37+
| Goog _ ->
38+
(*TODO: we should store
39+
the goog module name in the [cmj] file
40+
*)
41+
let base = String.uncapitalize id.name in
42+
begin match Lam_compile_env.get_goog_package_name x with
43+
| None
44+
| Some "" ->
45+
base
46+
| Some v -> v ^ "." ^ base
47+
end
48+
| Browser
49+
(* In browser *)
50+
->
51+
let target = String.uncapitalize file in
52+
if String_set.mem target Js_config.runtime_set then
53+
"./runtime/" ^ Filename.chop_extension target
54+
else
55+
"./stdlib/" ^ Filename.chop_extension target
56+
| NodeJS ->
57+
if Ext_string.starts_with id.name "Caml_" then
58+
let path =
59+
(* For the runtime, only [JS] files are needed, and
60+
unlike the stdlib, [osc] have some pre-built knowledge
61+
about where it is, since in general, [runtime]
62+
is *transparent* to the user
63+
*)
64+
match Sys.getenv "OCAML_JS_RUNTIME_PATH" with
65+
| exception Not_found ->
66+
Filename.concat
67+
(Filename.dirname (Filename.dirname Sys.executable_name))
68+
"runtime"
69+
| f -> f in
70+
Ext_filename.node_relative_path !Location.input_name
71+
(Filename.concat path (String.uncapitalize id.name))
72+
else
73+
begin match Config_util.find file with
74+
(* for some primitive files, no cmj support *)
75+
| exception Not_found ->
76+
Ext_log.warn __LOC__ "@[%s not found in search path - while compiling %s @] "
77+
file !Location.input_name ;
78+
Printf.sprintf "%s"
79+
(String.uncapitalize id.name)
80+
(* maybe from third party library*)
81+
(* Check: be consistent when generating js files
82+
A.ml -> a.js
83+
a.ml -> a.js
84+
check generated [js] file if it's capital or not
85+
Actually, we can not tell its original name just from [id],
86+
so we just always general litte_case.js
87+
*)
88+
| path ->
89+
Ext_filename.node_relative_path !Location.input_name path
90+
91+
end
8192
end
8293
| External name -> name
8394

0 commit comments

Comments
 (0)