Skip to content

Commit ab3f687

Browse files
cristianocmununki
andauthored
Alllow .res files in stdlib (rescript-lang#5714)
* Alllow .res files in stdlib Files in stdlib use ocamldep to figure out dependencies. Allow .res files and temporarily convert them to .ml to feed them to ocamldep * The dependencies in others/ were processed twice in parallel... * format * Dedicated bsc option to stop after parsing. So one can convert to .ml without ovewrtiting ".cm*" files. * Use a temporary dir to avoid touching the jscomp/others dir. * Remove the async changes. No need to protect now that a temporary dir is used for temporary .ml files. Of course, it would be nice to clean up the build, separately. * Update scripts/ninja.js more idiomatic path parse Co-authored-by: woonki <woonki.moon@gmail.com> * small clean up refactor * temp dir * Clean up ninja as per the review comments. * Remove example files from stdlib. * deep clean * shell and format Co-authored-by: woonki <woonki.moon@gmail.com>
1 parent 0328c92 commit ab3f687

10 files changed

+217
-168
lines changed

jscomp/core/js_implementation.ml

+76-73
Original file line numberDiff line numberDiff line change
@@ -45,39 +45,41 @@ let process_with_gentype cmt_file =
4545
if !Clflags.bs_gentype then GenTypeMain.processCmtFile cmt_file
4646

4747
let after_parsing_sig ppf outputprefix ast =
48-
Ast_config.iter_on_bs_config_sigi ast;
49-
if !Js_config.modules then
50-
output_deps_set !Location.input_name
51-
(Ast_extract.read_parse_and_extract Mli ast);
52-
(if !Js_config.binary_ast then
53-
let sourcefile = !Location.input_name in
54-
Binary_ast.write_ast Mli ~sourcefile
55-
~output:(outputprefix ^ Literals.suffix_iast)
56-
(* to support relocate to another directory *)
57-
ast);
58-
if !Js_config.as_pp then (
59-
output_string stdout Config.ast_intf_magic_number;
60-
output_value stdout (!Location.input_name : string);
61-
output_value stdout ast);
62-
if !Js_config.syntax_only then Warnings.check_fatal ()
63-
else
64-
let modulename = module_of_filename outputprefix in
65-
Lam_compile_env.reset ();
66-
let initial_env = Res_compmisc.initial_env () in
67-
Env.set_unit_name modulename;
68-
let tsg = Typemod.transl_signature initial_env ast in
69-
if !Clflags.dump_typedtree then fprintf ppf "%a@." Printtyped.interface tsg;
70-
let sg = tsg.sig_type in
71-
ignore (Includemod.signatures initial_env sg sg);
72-
Delayed_checks.force_delayed_checks ();
73-
Warnings.check_fatal ();
74-
let deprecated = Builtin_attributes.deprecated_of_sig ast in
75-
let sg =
76-
Env.save_signature ~deprecated sg modulename (outputprefix ^ ".cmi")
77-
in
78-
Typemod.save_signature modulename tsg outputprefix !Location.input_name
79-
initial_env sg;
80-
process_with_gentype (outputprefix ^ ".cmti")
48+
if !Clflags.only_parse = false then (
49+
Ast_config.iter_on_bs_config_sigi ast;
50+
if !Js_config.modules then
51+
output_deps_set !Location.input_name
52+
(Ast_extract.read_parse_and_extract Mli ast);
53+
(if !Js_config.binary_ast then
54+
let sourcefile = !Location.input_name in
55+
Binary_ast.write_ast Mli ~sourcefile
56+
~output:(outputprefix ^ Literals.suffix_iast)
57+
(* to support relocate to another directory *)
58+
ast);
59+
if !Js_config.as_pp then (
60+
output_string stdout Config.ast_intf_magic_number;
61+
output_value stdout (!Location.input_name : string);
62+
output_value stdout ast);
63+
if !Js_config.syntax_only then Warnings.check_fatal ()
64+
else
65+
let modulename = module_of_filename outputprefix in
66+
Lam_compile_env.reset ();
67+
let initial_env = Res_compmisc.initial_env () in
68+
Env.set_unit_name modulename;
69+
let tsg = Typemod.transl_signature initial_env ast in
70+
if !Clflags.dump_typedtree then
71+
fprintf ppf "%a@." Printtyped.interface tsg;
72+
let sg = tsg.sig_type in
73+
ignore (Includemod.signatures initial_env sg sg);
74+
Delayed_checks.force_delayed_checks ();
75+
Warnings.check_fatal ();
76+
let deprecated = Builtin_attributes.deprecated_of_sig ast in
77+
let sg =
78+
Env.save_signature ~deprecated sg modulename (outputprefix ^ ".cmi")
79+
in
80+
Typemod.save_signature modulename tsg outputprefix !Location.input_name
81+
initial_env sg;
82+
process_with_gentype (outputprefix ^ ".cmti"))
8183

8284
let interface ~parser ppf ?outputprefix fname =
8385
let outputprefix =
@@ -126,48 +128,49 @@ let no_export (rest : Parsetree.structure) : Parsetree.structure =
126128
| _ -> rest
127129

128130
let after_parsing_impl ppf outputprefix (ast : Parsetree.structure) =
129-
Js_config.all_module_aliases :=
130-
!Clflags.assume_no_mli = Mli_non_exists && all_module_alias ast;
131-
Ast_config.iter_on_bs_config_stru ast;
132-
let ast = if !Js_config.no_export then no_export ast else ast in
133-
if !Js_config.modules then
134-
output_deps_set !Location.input_name
135-
(Ast_extract.read_parse_and_extract Ml ast);
136-
(if !Js_config.binary_ast then
137-
let sourcefile = !Location.input_name in
138-
Binary_ast.write_ast ~sourcefile Ml
139-
~output:(outputprefix ^ Literals.suffix_ast)
140-
ast);
141-
if !Js_config.as_pp then (
142-
output_string stdout Config.ast_impl_magic_number;
143-
output_value stdout (!Location.input_name : string);
144-
output_value stdout ast);
145-
if !Js_config.syntax_only then Warnings.check_fatal ()
146-
else
147-
let modulename = Ext_filename.module_name outputprefix in
148-
Lam_compile_env.reset ();
149-
let env = Res_compmisc.initial_env () in
150-
Env.set_unit_name modulename;
151-
let typedtree, coercion, _, _ =
152-
Typemod.type_implementation_more
153-
?check_exists:(if !Js_config.force_cmi then None else Some ())
154-
!Location.input_name outputprefix modulename env ast
155-
in
156-
let typedtree_coercion = (typedtree, coercion) in
157-
print_if ppf Clflags.dump_typedtree Printtyped.implementation_with_coercion
158-
typedtree_coercion;
159-
(if !Js_config.cmi_only then Warnings.check_fatal ()
131+
if !Clflags.only_parse = false then (
132+
Js_config.all_module_aliases :=
133+
!Clflags.assume_no_mli = Mli_non_exists && all_module_alias ast;
134+
Ast_config.iter_on_bs_config_stru ast;
135+
let ast = if !Js_config.no_export then no_export ast else ast in
136+
if !Js_config.modules then
137+
output_deps_set !Location.input_name
138+
(Ast_extract.read_parse_and_extract Ml ast);
139+
(if !Js_config.binary_ast then
140+
let sourcefile = !Location.input_name in
141+
Binary_ast.write_ast ~sourcefile Ml
142+
~output:(outputprefix ^ Literals.suffix_ast)
143+
ast);
144+
if !Js_config.as_pp then (
145+
output_string stdout Config.ast_impl_magic_number;
146+
output_value stdout (!Location.input_name : string);
147+
output_value stdout ast);
148+
if !Js_config.syntax_only then Warnings.check_fatal ()
160149
else
161-
let lambda, exports =
162-
Translmod.transl_implementation modulename typedtree_coercion
163-
in
164-
let js_program =
165-
print_if_pipe ppf Clflags.dump_rawlambda Printlambda.lambda lambda
166-
|> Lam_compile_main.compile outputprefix exports
150+
let modulename = Ext_filename.module_name outputprefix in
151+
Lam_compile_env.reset ();
152+
let env = Res_compmisc.initial_env () in
153+
Env.set_unit_name modulename;
154+
let typedtree, coercion, _, _ =
155+
Typemod.type_implementation_more
156+
?check_exists:(if !Js_config.force_cmi then None else Some ())
157+
!Location.input_name outputprefix modulename env ast
167158
in
168-
if not !Js_config.cmj_only then
169-
Lam_compile_main.lambda_as_module js_program outputprefix);
170-
process_with_gentype (outputprefix ^ ".cmt")
159+
let typedtree_coercion = (typedtree, coercion) in
160+
print_if ppf Clflags.dump_typedtree
161+
Printtyped.implementation_with_coercion typedtree_coercion;
162+
(if !Js_config.cmi_only then Warnings.check_fatal ()
163+
else
164+
let lambda, exports =
165+
Translmod.transl_implementation modulename typedtree_coercion
166+
in
167+
let js_program =
168+
print_if_pipe ppf Clflags.dump_rawlambda Printlambda.lambda lambda
169+
|> Lam_compile_main.compile outputprefix exports
170+
in
171+
if not !Js_config.cmj_only then
172+
Lam_compile_main.lambda_as_module js_program outputprefix);
173+
process_with_gentype (outputprefix ^ ".cmt"))
171174

172175
let implementation ~parser ppf ?outputprefix fname =
173176
let outputprefix =

jscomp/main/builtin_cmi_datasets.ml

+3-3
Large diffs are not rendered by default.

jscomp/main/rescript_compiler_main.ml

+3
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,9 @@ let buckle_script_flags : (string * Bsc_args.spec * string) array =
423423
"-format", string_call format_file,
424424
"*internal* Format as Res syntax";
425425

426+
"-only-parse", set Clflags.only_parse,
427+
"*internal* stop after parsing";
428+
426429
"-where", unit_call print_standard_library,
427430
"*internal* Print location of standard library and exit";
428431

jscomp/ml/clflags.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ let dump_parsetree = ref false (* -dparsetree *)
2525
and dump_typedtree = ref false (* -dtypedtree *)
2626
and dump_rawlambda = ref false (* -drawlambda *)
2727
and dump_lambda = ref false (* -dlambda *)
28-
28+
and only_parse = ref false (* -only-parse *)
2929

3030
let dont_write_files = ref false (* set to true under ocamldoc *)
3131

jscomp/ml/clflags.mli

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ val dump_lambda : bool ref
2424
val dont_write_files : bool ref
2525
val keep_docs : bool ref
2626
val keep_locs : bool ref
27+
val only_parse : bool ref
2728

2829

2930
val parse_color_setting : string -> Misc.Color.setting option

lib/4.06.1/unstable/all_ounit_tests.ml

+2-1
Original file line numberDiff line numberDiff line change
@@ -9143,6 +9143,7 @@ val dump_lambda : bool ref
91439143
val dont_write_files : bool ref
91449144
val keep_docs : bool ref
91459145
val keep_locs : bool ref
9146+
val only_parse : bool ref
91469147

91479148

91489149
val parse_color_setting : string -> Misc.Color.setting option
@@ -9191,7 +9192,7 @@ let dump_parsetree = ref false (* -dparsetree *)
91919192
and dump_typedtree = ref false (* -dtypedtree *)
91929193
and dump_rawlambda = ref false (* -drawlambda *)
91939194
and dump_lambda = ref false (* -dlambda *)
9194-
9195+
and only_parse = ref false (* -only-parse *)
91959196

91969197
let dont_write_files = ref false (* set to true under ocamldoc *)
91979198

lib/4.06.1/unstable/js_compiler.ml

+5-4
Large diffs are not rendered by default.

lib/4.06.1/unstable/js_playground_compiler.ml

+5-4
Large diffs are not rendered by default.

lib/4.06.1/whole_compiler.ml

+84-77
Large diffs are not rendered by default.

scripts/ninja.js

+37-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/usr/bin/env node
22
//@ts-check
33

4+
var os = require("os");
45
var fs = require("fs");
56
var path = require("path");
67
var cp = require("child_process");
@@ -585,25 +586,53 @@ function sourceToTarget(y) {
585586
*/
586587
function ocamlDepForBscAsync(files, dir, depsMap) {
587588
return new Promise((resolve, reject) => {
589+
var tmpdir = null;
590+
const mlfiles = []; // convert .res files to temporary .ml files in tmpdir
591+
files.forEach(f => {
592+
const { name, ext } = path.parse(f);
593+
if (ext === ".res" || ext === ".resi") {
594+
const mlname = ext === ".resi" ? name + ".mli" : name + ".ml";
595+
if (tmpdir == null) {
596+
tmpdir = fs.mkdtempSync(path.join(os.tmpdir(), "resToMl"));
597+
}
598+
try {
599+
const mlfile = path.join(tmpdir, mlname);
600+
cp.execSync(`${bsc_exe} -dsource -only-parse ${f} 2>${mlfile}`, {
601+
cwd: dir,
602+
shell: "true",
603+
encoding: "ascii",
604+
});
605+
mlfiles.push(mlfile);
606+
} catch (err) {
607+
console.log(err);
608+
}
609+
}
610+
});
611+
const minusI = tmpdir == null ? "" : `-I ${tmpdir}`;
588612
cp.exec(
589-
`ocamldep.opt -allow-approx -one-line -native ${files.join(" ")}`,
613+
`ocamldep.opt -allow-approx -one-line ${minusI} -native ${files.join(
614+
" "
615+
)} ${mlfiles.join(" ")}`,
590616
{
591617
cwd: dir,
592618
encoding: "ascii",
593619
},
594620
function (error, stdout, stderr) {
621+
if (tmpdir != null) {
622+
fs.rmSync(tmpdir, { recursive: true, force: true });
623+
}
595624
if (error !== null) {
596625
return reject(error);
597626
} else {
598-
var pairs = stdout.split("\n").map(x => x.split(":"));
627+
const pairs = stdout.split("\n").map(x => x.split(":"));
599628
pairs.forEach(x => {
600629
var deps;
601-
let source = replaceCmj(x[0]);
630+
let source = replaceCmj(path.basename(x[0]));
602631
if (x[1] !== undefined && (deps = x[1].trim())) {
603632
deps = deps.split(" ");
604633
updateDepsKVsByFile(
605634
source,
606-
deps.map(x => replaceCmj(x)),
635+
deps.map(x => replaceCmj(path.basename(x))),
607636
depsMap
608637
);
609638
}
@@ -1014,7 +1043,10 @@ ${ninjaQuickBuidList([
10141043
var jsPrefixSourceFiles = othersDirFiles.filter(
10151044
x =>
10161045
x.startsWith("js") &&
1017-
(x.endsWith(".ml") || x.endsWith(".mli")) &&
1046+
(x.endsWith(".ml") ||
1047+
x.endsWith(".mli") ||
1048+
x.endsWith(".res") ||
1049+
x.endsWith(".resi")) &&
10181050
!x.includes(".cppo") &&
10191051
!x.includes(".pp") &&
10201052
!x.includes("#") &&

0 commit comments

Comments
 (0)