diff --git a/compiler/bin-js_of_ocaml/cmd_arg.ml b/compiler/bin-js_of_ocaml/cmd_arg.ml index 98d1cfee8a..8e01f358b2 100644 --- a/compiler/bin-js_of_ocaml/cmd_arg.ml +++ b/compiler/bin-js_of_ocaml/cmd_arg.ml @@ -308,13 +308,10 @@ let options = in Some ( sm_output_file - , { Source_map.Standard.version = 3 - ; file + , { Source_map.Standard.empty with + file ; sourceroot = sourcemap_root - ; sources = [] ; sources_content = (if sourcemap_don't_inline_content then None else Some []) - ; names = [] - ; mappings = Source_map.Mappings.empty } ) else None in @@ -537,13 +534,10 @@ let options_runtime_only = in Some ( sm_output_file - , { Source_map.Standard.version = 3 - ; file + , { Source_map.Standard.empty with + file ; sourceroot = sourcemap_root - ; sources = [] ; sources_content = (if sourcemap_don't_inline_content then None else Some []) - ; names = [] - ; mappings = Source_map.Mappings.empty } ) else None in diff --git a/compiler/bin-js_of_ocaml/link.ml b/compiler/bin-js_of_ocaml/link.ml index 6b0f8add7f..09ebb39b82 100644 --- a/compiler/bin-js_of_ocaml/link.ml +++ b/compiler/bin-js_of_ocaml/link.ml @@ -102,13 +102,10 @@ let options = in Some ( sm_output_file - , { Source_map.Standard.version = 3 - ; file + , { Source_map.Standard.empty with + file ; sourceroot = sourcemap_root - ; sources = [] ; sources_content = Some [] - ; names = [] - ; mappings = Source_map.Mappings.empty } ) else None in diff --git a/compiler/lib/js_output.ml b/compiler/lib/js_output.ml index d2f1b51991..f5198c1aa2 100644 --- a/compiler/lib/js_output.ml +++ b/compiler/lib/js_output.ml @@ -125,6 +125,8 @@ module Make (D : sig val get_name_index : string -> int + val hidden_location : Source_map.map + val source_map_enabled : bool val accept_unnamed_var : bool @@ -159,7 +161,7 @@ struct then match loc with | N | U | Pi { Parse_info.src = None | Some ""; _ } -> - push_mapping (PP.pos f) (Source_map.Gen { gen_line = -1; gen_col = -1 }) + push_mapping (PP.pos f) hidden_location | Pi { Parse_info.src = Some file; line; col; _ } -> push_mapping (PP.pos f) @@ -201,10 +203,15 @@ struct (match loc with | None | Some { Parse_info.src = Some "" | None; _ } -> (* Use a dummy location. It is going to be ignored anyway *) + let ori_source = + match hidden_location with + | Source_map.Gen_Ori { ori_source; _ } -> ori_source + | _ -> 0 + in Source_map.Gen_Ori_Name { gen_line = -1 ; gen_col = -1 - ; ori_source = 0 + ; ori_source ; ori_line = 1 ; ori_col = 0 ; ori_name = get_name_index nm @@ -2040,6 +2047,7 @@ let program ?(accept_unnamed_var = false) f ?source_map p = | None | Some { Source_map.Standard.sources_content = None; _ } -> None | Some { Source_map.Standard.sources_content = Some _; _ } -> Some (ref []) in + let blackbox_file = "/builtin/blackbox.ml" in let push_mapping, get_file_index, get_name_index, source_map_enabled = let source_map_enabled = match source_map with @@ -2066,7 +2074,9 @@ let program ?(accept_unnamed_var = false) f ?source_map p = match Builtins.find file with | Some f -> Some (Builtins.File.content f) | None -> - if Sys.file_exists file && not (Sys.is_directory file) + if String.equal file blackbox_file + then Some "(* generated code *)" + else if Sys.file_exists file && not (Sys.is_directory file) then let content = Fs.read_file file in Some content @@ -2094,6 +2104,15 @@ let program ?(accept_unnamed_var = false) f ?source_map p = pos) , source_map_enabled ) in + let hidden_location = + Source_map.Gen_Ori + { gen_line = -1 + ; gen_col = -1 + ; ori_source = get_file_index blackbox_file + ; ori_line = 1 + ; ori_col = 0 + } + in let module O = Make (struct let push_mapping = push_mapping @@ -2101,6 +2120,8 @@ let program ?(accept_unnamed_var = false) f ?source_map p = let get_file_index = get_file_index + let hidden_location = hidden_location + let source_map_enabled = source_map_enabled let accept_unnamed_var = accept_unnamed_var @@ -2128,6 +2149,11 @@ let program ?(accept_unnamed_var = false) f ?source_map p = | None -> filename | Some _ -> Filename.concat "/builtin" filename) in + let ignore_list = + List.filter sources ~f:(fun filename -> + String.length filename >= 9 + && String.equal (String.sub filename ~pos:0 ~len:9) "/builtin/") + in let sm_mappings = Source_map.Mappings.decode sm.mappings in let mappings = List.rev_append_map !temp_mappings sm_mappings ~f:(fun (pos, m) -> @@ -2146,7 +2172,14 @@ let program ?(accept_unnamed_var = false) f ?source_map p = { gen_line; gen_col; ori_source; ori_line; ori_col; ori_name }) in let mappings = Source_map.Mappings.encode mappings in - Some { sm with Source_map.Standard.sources; names; sources_content; mappings } + Some + { sm with + Source_map.Standard.sources + ; names + ; sources_content + ; mappings + ; ignore_list + } in PP.check f; (if stats () diff --git a/compiler/lib/source_map.ml b/compiler/lib/source_map.ml index 1ae1b2f099..4dbdddd1fb 100644 --- a/compiler/lib/source_map.ml +++ b/compiler/lib/source_map.ml @@ -225,6 +225,11 @@ let string_of_stringlit (`Stringlit s) = | `String s -> s | _ -> invalid () +let int_of_intlit (`Intlit s) = + match Yojson.Safe.from_string s with + | `Int s -> s + | _ -> invalid () + let stringlit name rest : [ `Stringlit of string ] option = try match List.assoc name rest with @@ -256,6 +261,17 @@ let list_stringlit_opt name rest = | _ -> invalid () with Not_found -> None +let list_intlit name rest = + try + match List.assoc name rest with + | `List l -> + Some + (List.map l ~f:(function + | `Intlit _ as s -> s + | _ -> invalid ())) + | _ -> invalid () + with Not_found -> None + module Standard = struct type t = { version : int @@ -265,6 +281,7 @@ module Standard = struct ; sources_content : Source_content.t option list option ; names : string list ; mappings : Mappings.t + ; ignore_list : string list } let empty = @@ -275,6 +292,7 @@ module Standard = struct ; sources_content = None ; names = [] ; mappings = Mappings.empty + ; ignore_list = [] } let maps ~sources_offset ~names_offset x = @@ -400,6 +418,21 @@ module Standard = struct (List.map l ~f:(function | None -> `Null | Some x -> Source_content.to_json x))) ) + ; ( "ignoreList" + , match t.ignore_list with + | [] -> None + | _ -> + Some + (`List + (let s = StringSet.of_list t.ignore_list in + List.filter_map + ~f:(fun x -> x) + (List.mapi + ~f:(fun i nm -> + if StringSet.mem nm s + then Some (`Intlit (string_of_int i)) + else None) + t.sources))) ) ]) let of_json (json : Yojson.Raw.t) = @@ -432,6 +465,17 @@ module Standard = struct | None -> Mappings.empty | Some s -> Mappings.of_string s in + let ignore_list = + let s = + IntSet.of_list + (List.map + ~f:int_of_intlit + (Option.value ~default:[] (list_intlit "ignoreList" rest))) + in + List.filter_map + ~f:(fun x -> x) + (List.mapi ~f:(fun i nm -> if IntSet.mem i s then Some nm else None) sources) + in { version = int_of_float (float_of_string version) ; file ; sourceroot @@ -439,6 +483,7 @@ module Standard = struct ; sources_content ; sources ; mappings + ; ignore_list } | _ -> invalid () diff --git a/compiler/lib/source_map.mli b/compiler/lib/source_map.mli index c00e8872b9..5db9fa0b50 100644 --- a/compiler/lib/source_map.mli +++ b/compiler/lib/source_map.mli @@ -79,6 +79,7 @@ module Standard : sig (** Left uninterpreted, since most useful operations can be performed efficiently directly on the encoded form, and a full decoding can be costly for big sourcemaps. *) + ; ignore_list : string list } val filter_map : t -> f:(int -> int option) -> t diff --git a/compiler/tests-compiler/build_path_prefix_map.ml b/compiler/tests-compiler/build_path_prefix_map.ml index 29f9f7c8c3..13f7cbf86c 100644 --- a/compiler/tests-compiler/build_path_prefix_map.ml +++ b/compiler/tests-compiler/build_path_prefix_map.ml @@ -44,5 +44,6 @@ let%expect_test _ = file: test.js sourceRoot: sources: + - /builtin/blackbox.ml - /dune-root/test.ml |}] diff --git a/compiler/tests-compiler/sourcemap.ml b/compiler/tests-compiler/sourcemap.ml index eccd158695..4cbcbb09d2 100644 --- a/compiler/tests-compiler/sourcemap.ml +++ b/compiler/tests-compiler/sourcemap.ml @@ -82,14 +82,14 @@ let%expect_test _ = 11: (globalThis)); 12: 13: //# sourceMappingURL=test.map - /dune-root/test.ml:1:0 -> 5:7 - null -> 5:17 + /builtin/blackbox.ml:1:0 -> 5:7 + /builtin/blackbox.ml:1:0 -> 5:17 /dune-root/test.ml:1:4 -> 6:12 /dune-root/test.ml:1:7 -> 6:15 /dune-root/test.ml:1:11 -> 6:18 /dune-root/test.ml:1:12 -> 6:28 /dune-root/test.ml:1:12 -> 7:7 - null -> 7:14 + /builtin/blackbox.ml:1:0 -> 7:14 |}] let%expect_test _ = diff --git a/compiler/tests-sourcemap/dump.reference b/compiler/tests-sourcemap/dump.reference index ce5e7fd04c..5feb760f7e 100644 --- a/compiler/tests-sourcemap/dump.reference +++ b/compiler/tests-sourcemap/dump.reference @@ -1,5 +1,4 @@ sourcemap for test.bc.js -/my/sourceRoot#d.ml:1:0 -> 7: var <>runtime = globalThis.jsoo_runtime; /my/sourceRoot#b.ml:1:4 -> 12: function <>f(x){return x - 1 | 0; } /my/sourceRoot#b.ml:1:6 -> 14: function f(<>x){return x - 1 | 0; } /my/sourceRoot#b.ml:1:10 -> 17: function f(x){<>return x - 1 | 0; }