Skip to content

Commit 584bcad

Browse files
authored
fix(compiler): Report Win32 instead of Cygwin in JS compiler (#1251)
fix(compiler): Move Filename usage to Filepath.String & normalize separators
1 parent d4cb8ab commit 584bcad

File tree

10 files changed

+92
-73
lines changed

10 files changed

+92
-73
lines changed

compiler/src/codegen/compcore.re

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3806,7 +3806,7 @@ let compile_wasm_module = (~env=?, ~name=?, prog) => {
38063806
ignore @@
38073807
Module.add_debug_info_filename(
38083808
wasm_mod,
3809-
Filename.basename(Option.get(name)),
3809+
Filepath.String.basename(Option.get(name)),
38103810
);
38113811
};
38123812
let default_features = [

compiler/src/codegen/emitmod.re

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ let emit_module = ({asm, signature}, outfile) => {
2222
};
2323
let source_map_name =
2424
if (Config.source_map^) {
25-
Some(Filename.basename(outfile) ++ ".map");
25+
Some(Filepath.String.basename(outfile) ++ ".map");
2626
} else {
2727
None;
2828
};

compiler/src/compile.re

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ open Grain_typed;
33
open Grain_middle_end;
44
open Grain_codegen;
55
open Grain_linking;
6+
open Grain_utils;
67
open Optimize;
78

89
type input_source =
@@ -39,21 +40,14 @@ type error =
3940

4041
exception InlineFlagsError(Location.t, error);
4142

42-
/** `remove_extension` new enough that we should just use this */
43-
44-
let safe_remove_extension = name =>
45-
try(Filename.chop_extension(name)) {
46-
| Invalid_argument(_) => name
47-
};
48-
4943
let default_output_filename = name =>
50-
safe_remove_extension(name) ++ ".gr.wasm";
44+
Filepath.String.remove_extension(name) ++ ".gr.wasm";
5145

5246
let default_assembly_filename = name =>
53-
safe_remove_extension(name) ++ ".wast";
47+
Filepath.String.remove_extension(name) ++ ".wast";
5448

5549
let default_mashtree_filename = name =>
56-
safe_remove_extension(name) ++ ".mashtree";
50+
Filepath.String.remove_extension(name) ++ ".mashtree";
5751

5852
let compile_prog = p =>
5953
Compcore.module_to_bytes @@ Compcore.compile_wasm_module(p);

compiler/src/linking/link.re

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ let is_grain_module = mod_name => {
4747
};
4848

4949
let wasi_polyfill_module = () => {
50-
Filename.remove_extension(Option.get(Config.wasi_polyfill_path()))
50+
Filepath.String.remove_extension(Option.get(Config.wasi_polyfill_path()))
5151
++ ".gr.wasm";
5252
};
5353

@@ -59,7 +59,7 @@ let is_wasi_polyfill_module = mod_path => {
5959
mod_path == wasi_polyfill_module();
6060
};
6161

62-
let new_base_dir = Filename.dirname;
62+
let new_base_dir = Filepath.String.dirname;
6363

6464
let rec build_dependency_graph = (~base_dir, mod_path) => {
6565
let wasm_mod = Hashtbl.find(modules, mod_path);
@@ -591,7 +591,7 @@ let link_modules = ({asm: wasm_mod, signature}) => {
591591

592592
G.add_vertex(dependency_graph, main_module);
593593
build_dependency_graph(
594-
~base_dir=Filename.dirname(main_module),
594+
~base_dir=Filepath.String.dirname(main_module),
595595
main_module,
596596
);
597597
let dependencies =

compiler/src/typed/env.re

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,7 @@ let check_consistency = ps =>
749749
| Some(crc) =>
750750
let resolved_file_name =
751751
Module_resolution.resolve_unit(
752-
~base_dir=Filename.dirname(ps.ps_filename),
752+
~base_dir=Filepath.String.dirname(ps.ps_filename),
753753
name,
754754
);
755755
Consistbl.check(crc_units, resolved_file_name, crc, ps.ps_filename);

compiler/src/typed/module_resolution.re

Lines changed: 29 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,11 @@ let read_file_cmi = f => {
5050
};
5151

5252
let get_output_name = name => {
53-
let name =
54-
try(Filename.chop_extension(name)) {
55-
| Invalid_argument(_) => name
56-
};
57-
name ++ ".gr.wasm";
53+
Filepath.String.remove_extension(name) ++ ".gr.wasm";
5854
};
5955

6056
let find_ext_in_dir = (dir, name) => {
61-
let fullname = Filename.concat(dir, name);
57+
let fullname = Filepath.String.concat(dir, name);
6258
let rec process_ext =
6359
fun
6460
| [] => None
@@ -68,9 +64,6 @@ let find_ext_in_dir = (dir, name) => {
6864
process_ext;
6965
};
7066

71-
let is_relpath = path =>
72-
Filename.is_relative(path) && !Filename.is_implicit(path);
73-
7467
let find_in_path_uncap = (~exts=[], base_dir, path, name) => {
7568
let rec try_dir =
7669
fun
@@ -81,14 +74,14 @@ let find_in_path_uncap = (~exts=[], base_dir, path, name) => {
8174
| None => try_dir(rem)
8275
};
8376
};
84-
if (!Filename.is_relative(name) && Grain_utils.Fs_access.file_exists(name)) {
77+
if (!Filepath.String.is_relative(name) && Fs_access.file_exists(name)) {
8578
(
8679
name,
87-
Filename.dirname(name),
88-
Filename.remove_extension(Filename.basename(name)),
89-
Filename.extension(name),
80+
Filepath.String.dirname(name),
81+
Filepath.String.(remove_extension(basename(name))),
82+
Filepath.String.extension(name),
9083
);
91-
} else if (is_relpath(name)) {
84+
} else if (Filepath.String.is_relpath(name)) {
9285
try_dir([base_dir]);
9386
} else {
9487
try(try_dir(path)) {
@@ -103,25 +96,18 @@ module PathTbl = {
10396

10497
let add: (t('a), (string, string), 'a) => unit =
10598
(tbl, (dir, unit_name), v) => {
106-
let dir = Grain_utils.Filepath.String.realpath_quick(dir);
107-
Hashtbl.add(
108-
tbl,
109-
Grain_utils.Filepath.String.smart_cat(dir, unit_name),
110-
v,
111-
);
99+
let dir = Filepath.String.realpath_quick(dir);
100+
Hashtbl.add(tbl, Filepath.String.smart_cat(dir, unit_name), v);
112101
};
113102

114103
let find_opt:
115104
(~disable_relpath: bool=?, t('a), string, list(string), string) =>
116105
option('a) =
117106
(~disable_relpath=false, tbl, base_path, path, unit_name) =>
118-
if (!disable_relpath && is_relpath(unit_name)) {
107+
if (!disable_relpath && Filepath.String.is_relpath(unit_name)) {
119108
Hashtbl.find_opt(
120109
tbl,
121-
Grain_utils.Filepath.String.canonicalize_relpath(
122-
base_path,
123-
unit_name,
124-
),
110+
Filepath.String.canonicalize_relpath(base_path, unit_name),
125111
);
126112
} else {
127113
List.fold_left(
@@ -131,9 +117,7 @@ module PathTbl = {
131117
| None =>
132118
Hashtbl.find_opt(
133119
tbl,
134-
Grain_utils.Filepath.String.(
135-
smart_cat(realpath_quick(elt), unit_name)
136-
),
120+
Filepath.String.(smart_cat(realpath_quick(elt), unit_name)),
137121
)
138122
}
139123
},
@@ -169,8 +153,8 @@ let current_resolution_table = () => {
169153

170154
let log_resolution = (unit_name, dir, basename) => {
171155
let resolution =
172-
Grain_utils.Filepath.(
173-
to_string @@ String.derelativize @@ Filename.concat(dir, basename)
156+
Filepath.(
157+
to_string @@ String.derelativize @@ String.concat(dir, basename)
174158
);
175159
PathTbl.add(current_resolution_table(), (dir, unit_name), resolution);
176160
resolution;
@@ -179,12 +163,12 @@ let log_resolution = (unit_name, dir, basename) => {
179163
let resolve_unit = (~search_path=?, ~cache=true, ~base_dir=?, unit_name) => {
180164
let base_dir =
181165
switch (base_dir) {
182-
| None => Filename.dirname(current_filename^())
166+
| None => Filepath.String.dirname(current_filename^())
183167
| Some(bd) => bd
184168
};
185169
let path =
186170
switch (search_path) {
187-
| None => Grain_utils.Config.module_search_path()
171+
| None => Config.module_search_path()
188172
| Some(p) => p
189173
};
190174
switch (
@@ -199,8 +183,8 @@ let resolve_unit = (~search_path=?, ~cache=true, ~base_dir=?, unit_name) => {
199183
if (cache) {
200184
log_resolution(unit_name, dir, basename);
201185
} else {
202-
Grain_utils.Filepath.(
203-
to_string @@ String.derelativize @@ Filename.concat(dir, basename)
186+
Filepath.(
187+
to_string @@ String.derelativize @@ String.concat(dir, basename)
204188
);
205189
};
206190
};
@@ -259,19 +243,19 @@ let located_to_out_file_name = (~base=?, located) => {
259243
| GrainModule(_, Some(outpath))
260244
| WasmModule(outpath) => outpath
261245
};
262-
Grain_utils.Filepath.(to_string(String.derelativize(~base?, ret)));
246+
Filepath.to_string(Filepath.String.derelativize(~base?, ret));
263247
};
264248

265249
let locate_unit_object_file = (~path=?, ~base_dir=?, unit_name) => {
266250
let base_dir =
267251
switch (base_dir) {
268-
| None => Filename.dirname(current_filename^())
252+
| None => Filepath.String.dirname(current_filename^())
269253
| Some(bd) => bd
270254
};
271255
let path =
272256
switch (path) {
273257
| Some(p) => p
274-
| None => Grain_utils.Config.module_search_path()
258+
| None => Config.module_search_path()
275259
};
276260
located_to_out_file_name(locate_module(base_dir, path, unit_name));
277261
};
@@ -289,7 +273,7 @@ module Dependency_graph =
289273

290274
let rec get_dependencies: (t, string => option(t)) => list(t) =
291275
(dn, lookup) => {
292-
let base_dir = Filename.dirname(dn.dn_file_name);
276+
let base_dir = Filepath.String.dirname(dn.dn_file_name);
293277
let active_search_path = Config.module_search_path();
294278
let located = dn.dn_latest_resolution^;
295279

@@ -372,7 +356,7 @@ module Dependency_graph =
372356
// all dependencies have expected CRC, and the module was compiled with
373357
// the current compiler configuration. Otherwise, we need to recompile.
374358
let config_sum = Cmi_format.config_sum();
375-
let base_dir = Filename.dirname(srcpath);
359+
let base_dir = Filepath.String.dirname(srcpath);
376360
dn.dn_up_to_date :=
377361
(
378362
switch (read_file_cmi(objpath)) {
@@ -419,7 +403,7 @@ module Dependency_graph =
419403
| Some(WasmModule(_)) =>
420404
failwith("impossible: compile_module > WasmModule")
421405
| Some(GrainModule(srcpath, _)) =>
422-
Grain_utils.Filepath.(to_string(String.derelativize(srcpath)))
406+
Filepath.to_string(Filepath.String.derelativize(srcpath))
423407
};
424408
let outpath = get_output_name(srcpath);
425409
let loc = Option.value(loc, ~default=Grain_parsing.Location.dummy_loc);
@@ -429,8 +413,8 @@ module Dependency_graph =
429413
| Seq.Cons((parent, unit_name), _) => unit_name
430414
};
431415
with_preserve_unit^(~loc, chosen_unit_name, srcpath, () =>
432-
Grain_utils.Warnings.with_preserve_warnings(() =>
433-
Grain_utils.Config.preserve_config(() =>
416+
Warnings.with_preserve_warnings(() =>
417+
Config.preserve_config(() =>
434418
compile_module_dependency^(srcpath, outpath)
435419
)
436420
)
@@ -439,7 +423,7 @@ module Dependency_graph =
439423
dn.dn_up_to_date := true;
440424
PathTbl.add(
441425
current_located_module_cache(),
442-
(Filename.dirname(outpath), chosen_unit_name),
426+
(Filepath.String.dirname(outpath), chosen_unit_name),
443427
GrainModule(srcpath, Some(outpath)),
444428
);
445429
};
@@ -448,8 +432,8 @@ module Dependency_graph =
448432
let locate_module_file = (~loc, ~disable_relpath=false, unit_name) => {
449433
/* NOTE: We need to take care here to *not* wrap get_up_to_date with this try/with, since
450434
it will falsely raise No_module_file if a Not_found is raised during the compilation */
451-
let base_dir = Filename.dirname(current_filename^());
452-
let path = Grain_utils.Config.module_search_path();
435+
let base_dir = Filepath.String.dirname(current_filename^());
436+
let path = Config.module_search_path();
453437
let located =
454438
try(locate_module(~disable_relpath, base_dir, path, unit_name)) {
455439
| Not_found => error(No_module_file(unit_name, None))

compiler/src/typed/module_resolution.rei

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,3 @@ let current_unit_name: ref(unit => string);
2828
let current_filename: ref(unit => string);
2929

3030
let dump_dependency_graph: unit => unit;
31-
32-
let is_relpath: string => bool;

compiler/src/utils/filepath.re

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ let derelativize = (~base=?, fname: Fp.firstClass) => {
2626
};
2727
};
2828

29+
// All uses of `Filename` from OCaml should be constrained to this file because we need to do
30+
// normalization on the filepaths those functions produce.
2931
module String = {
3032
// This module is converting strings into Fp.t and then back into Strings
3133
// TODO(#216): We should consider switching to type safe Fp.t where ever filepaths are used
@@ -85,6 +87,44 @@ module String = {
8587
String.capitalize_ascii(name);
8688
};
8789

90+
let normalize_separators = path =>
91+
if (Sys.unix) {
92+
path;
93+
} else {
94+
// If we aren't on a Unix-style system, convert `\\` separators to `/`
95+
// This is needed because using `Filename` from OCaml stdlib doesn't get along with Fp
96+
let windows_sep = Str.regexp("\\");
97+
let normal_sep = "/";
98+
Str.global_replace(windows_sep, normal_sep, path);
99+
};
100+
101+
// TODO(#216): We should consider switching to type safe Fp.t where ever filepaths are used
102+
let concat = (p1, p2) => {
103+
normalize_separators(Filename.concat(p1, p2));
104+
};
105+
106+
// TODO(#216): We should consider switching to type safe Fp.t where ever filepaths are used
107+
let dirname = path => {
108+
normalize_separators(Filename.dirname(path));
109+
};
110+
111+
// TODO(#216): We should consider switching to type safe Fp.t where ever filepaths are used
112+
let basename = Filename.basename;
113+
114+
// TODO: This is poorly named
115+
// TODO(#216): We should consider switching to type safe Fp.t where ever filepaths are used
116+
let is_relpath = path =>
117+
Filename.is_relative(path) && !Filename.is_implicit(path);
118+
119+
// TODO(#216): We should consider switching to type safe Fp.t where ever filepaths are used
120+
let is_relative = Filename.is_relative;
121+
122+
// TODO(#216): We should consider switching to type safe Fp.t where ever filepaths are used
123+
let check_suffix = Filename.check_suffix;
124+
125+
// TODO(#216): We should consider switching to type safe Fp.t where ever filepaths are used
126+
let extension = Filename.extension;
127+
88128
// TODO(#216): Turn this into a function that only operates on Fp
89129
let realpath = path => {
90130
switch (Fp.testForPath(path)) {
@@ -108,11 +148,12 @@ module String = {
108148
// TODO(#216): Turn this into a function that only operates on Fp
109149
let smart_cat = (dir, file) => {
110150
switch (Fp.absoluteCurrentPlatform(dir)) {
111-
| None => Filename.concat(dir, file)
151+
| None => concat(dir, file)
112152
| Some(abspath) =>
113-
switch (Fp.relative(file)) {
114-
| None => Filename.concat(to_string(abspath), file)
115-
| Some(relpath) => to_string(Fp.join(abspath, relpath))
153+
switch (Fp.testForPath(file)) {
154+
| None => concat(dir, file)
155+
| Some(Absolute(path)) => to_string(path)
156+
| Some(Relative(relpath)) => to_string(Fp.join(abspath, relpath))
116157
}
117158
};
118159
};
@@ -133,9 +174,6 @@ module String = {
133174
};
134175
smart_cat(abs_base_path, unit_name);
135176
};
136-
137-
// TODO(#216): Replace this with the `get_cwd` that operates on Fp
138-
let get_cwd = () => Sys.getcwd();
139177
};
140178

141179
module Args = {

compiler/src/utils/hacks.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
//Provides: os_type
2+
var os_type = (globalThis.process &&
3+
globalThis.process.platform &&
4+
globalThis.process.platform == "win32") ? "Win32" : "Unix";
5+
16
//Provides: unix_opendir
27
//Requires: caml_jsstring_of_string
38
//Requires: make_unix_err_args, caml_raise_with_args, caml_named_value

0 commit comments

Comments
 (0)