Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changes/printed-string-escaping.fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Print the `@as` names of fields and constructors and the strings of externals as they are written, so that non-ASCII letters are no longer turned into escapes that read back as other characters in error messages, hover and generated interfaces.
3 changes: 2 additions & 1 deletion compiler/ml/printtyp.ml
Original file line number Diff line number Diff line change
Expand Up @@ -945,7 +945,8 @@ and tree_of_constructor ?printing_context ~layout ~position cd =
let as_annotation = function
| Variant_runtime.Null -> "@as(null)"
| Undefined -> "@as(undefined)"
| String s -> Printf.sprintf "@as(%S)" s
| String s ->
Printf.sprintf "@as(\"%s\")" (String_literal.encode_js_string s)
| Int i -> Printf.sprintf "@as(%d)" i
| Float f -> Printf.sprintf "@as(%s)" f
| Bool b -> Printf.sprintf "@as(%b)" b
Expand Down
11 changes: 9 additions & 2 deletions compiler/syntax/src/res_outcome_printer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ let collect_arrow_args (out_type : Outcometree.out_type) =
| Otyp_arrow (args, ret) -> (args, ret)
| _ -> ([], out_type)

let print_string_literal_doc s =
Doc.text ("\"" ^ String_literal.encode_js_string s ^ "\"")

let rec collect_functor_args (out_module_type : Outcometree.out_module_type)
args =
match out_module_type with
Expand Down Expand Up @@ -398,7 +401,12 @@ and print_record_decl_row_doc (name, runtime_name, mut, opt, arg) =
[
(match runtime_name with
| Some runtime_name ->
Doc.text ("@as(\"" ^ String.escaped runtime_name ^ "\") ")
Doc.concat
[
Doc.text "@as(";
print_string_literal_doc runtime_name;
Doc.text ") ";
]
| None -> Doc.nil);
(if mut then Doc.text "mutable " else Doc.nil);
Printer.print_ident_like ~allow_uident:false name;
Expand Down Expand Up @@ -454,7 +462,6 @@ let print_type_parameter_doc (typ, (co, cn)) =

(* Print a digested FFI declaration as the surface attributes the user
wrote; the stored form is the declaration itself. *)
let print_string_literal_doc s = Doc.text ("\"" ^ String.escaped s ^ "\"")

let print_inline_const_doc (c : External_ffi_types.inline_const) =
match c with
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

We've found a bug for you!
/.../fixtures/as_names_printed_as_written.res:5:5-7:1

3 │ module M: {
4 │ type t = | @as("é") A({@as("prénom") name: string}) | @as("a\"b") B
5 │ } = {
6 │  type t = | @as("é") A({@as("prénom") name: int}) | @as("a\"b") B
7 │ }
8 │

Signature mismatch:

Actual declaration (/.../fixtures/as_names_printed_as_written.res:6:3-66):
type t = @as("é") A({@as("prénom") name: int}) | @as("a\"b") B

Expected declaration (/.../fixtures/as_names_printed_as_written.res:4:3-69):
type t = @as("é") A({@as("prénom") name: string}) | @as("a\"b") B

The records of constructor A differ:
The types for field name are not equal.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

We've found a bug for you!
/.../fixtures/external_strings_printed_as_written.res:5:5-8:1

3 │ @module("ünïcode") @scope("ëxtra")
4 │ external f: int => int = "f"
5 │ } = {
6 │  @module("ünïcode") @scope("ëxtra")
7 │  external f: string => int = "f"
8 │ }
9 │

Signature mismatch:

Actual declaration (/.../fixtures/external_strings_printed_as_written.res:6:3-7:33):
@val @module("ünïcode") @scope("ëxtra") external f: string => int = "f"

Expected declaration (/.../fixtures/external_strings_printed_as_written.res:3:3-4:30):
@val @module("ünïcode") @scope("ëxtra") external f: int => int = "f"
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// The @as names of constructors and fields print as they are written in
// source, non-ASCII letters and quotes included
module M: {
type t = | @as("é") A({@as("prénom") name: string}) | @as("a\"b") B
} = {
type t = | @as("é") A({@as("prénom") name: int}) | @as("a\"b") B
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// The strings of a printed external print as they are written in source
module M: {
@module("ünïcode") @scope("ëxtra")
external f: int => int = "f"
} = {
@module("ünïcode") @scope("ëxtra")
external f: string => int = "f"
}
Loading