Skip to content

Commit 6926f33

Browse files
committed
move to use dedicated @gentype.satisfies
1 parent 13ade8c commit 6926f33

File tree

16 files changed

+116
-42
lines changed

16 files changed

+116
-42
lines changed

compiler/gentype/Annotation.ml

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,14 @@ let tag_is_tag s = s = "tag"
2929
let tag_is_unboxed s = s = "unboxed" || s = "ocaml.unboxed"
3030
let tag_is_gentype_import s = s = "genType.import" || s = "gentype.import"
3131
let tag_is_gentype_opaque s = s = "genType.opaque" || s = "gentype.opaque"
32+
let tag_is_gentype_satisfies s = s = "genType.satisfies" || s = "gentype.satisfies"
3233

3334
let tag_is_one_of_the_gentype_annotations s =
34-
tag_is_gentype s || tag_is_gentype_as s || tag_is_gentype_import s
35+
tag_is_gentype s
36+
|| tag_is_gentype_as s
37+
|| tag_is_gentype_import s
3538
|| tag_is_gentype_opaque s
39+
|| tag_is_gentype_satisfies s
3640

3741
let tag_is_gentype_ignore_interface s =
3842
s = "genType.ignoreInterface" || s = "gentype.ignoreInterface"
@@ -169,6 +173,25 @@ let get_attribute_import_renaming attributes =
169173
(Some import_string, gentype_as_renaming, None, Some rename_string)
170174
| _ -> (None, gentype_as_renaming, None, None)
171175

176+
let get_attribute_satisfies attributes =
177+
match attributes |> get_attribute_payload tag_is_gentype_satisfies with
178+
| Some (_loc, TuplePayload payloads) -> (
179+
let strings =
180+
payloads
181+
|> List.fold_left
182+
(fun acc p ->
183+
match p with
184+
| StringPayload s -> s :: acc
185+
| _ -> acc)
186+
[]
187+
|> List.rev
188+
in
189+
match strings with
190+
| [] -> None
191+
| import_str :: path -> Some (import_str, path))
192+
| Some (_loc, StringPayload s) -> Some (s, [])
193+
| _ -> None
194+
172195
let get_tag attributes =
173196
match attributes |> get_attribute_payload tag_is_tag with
174197
| Some (_, StringPayload s) -> Some s

compiler/gentype/EmitJs.ml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,11 @@ let emit_translation_as_string ~(config : Config.t) ~file_name
680680
~input_cmt_translate_type_declarations ~output_file_relative ~resolver
681681
~type_name_is_interface
682682
in
683+
let emitters =
684+
match config.emit_satisfies_helper with
685+
| true -> EmitType.emit_satisfies_helper ~emitters
686+
| false -> emitters
687+
in
683688
let env, emitters =
684689
export_from_type_declarations
685690
|> emit_export_from_type_declarations ~config ~emitters ~env

compiler/gentype/EmitType.ml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,12 @@ let require ~early =
424424
let emit_import_react ~emitters =
425425
"import * as React from 'react';" |> require ~early:true ~emitters
426426

427+
let emit_satisfies_helper ~emitters =
428+
let alias =
429+
"export type $RescriptTypeSatisfiesTypeScriptType<RescriptType, TypeScriptType extends RescriptType> = TypeScriptType;"
430+
in
431+
Emitters.export_early ~emitters alias
432+
427433
let emit_import_type_as ~emitters ~config ~type_name ~as_type_name
428434
~type_name_is_interface ~import_path =
429435
let type_name = sanitize_type_name type_name in

compiler/gentype/GenTypeCommon.ml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,10 +180,13 @@ let ident ?(builtin = true) ?(type_args = []) name =
180180
Ident {builtin; name; type_args}
181181

182182
let sanitize_type_name name =
183-
name
184-
|> String.map (function
185-
| '\'' -> '_'
186-
| c -> c)
183+
(* Preserve TS import("...") expressions intact. *)
184+
if String.length name >= 7 && String.sub name 0 7 = "import(" then name
185+
else
186+
name
187+
|> String.map (function
188+
| '\'' -> '_'
189+
| c -> c)
187190
let unknown = ident "unknown"
188191
let bigint_t = ident "BigInt"
189192
let boolean_t = ident "boolean"

compiler/gentype/GenTypeConfig.ml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ type t = {
1717
bs_dependencies: string list;
1818
mutable emit_import_curry: bool;
1919
mutable emit_import_react: bool;
20+
mutable emit_satisfies_helper: bool;
2021
mutable emit_type_prop_done: bool;
2122
mutable everything: bool;
2223
export_interfaces: bool;
@@ -37,6 +38,7 @@ let default =
3738
bs_dependencies = [];
3839
emit_import_curry = false;
3940
emit_import_react = false;
41+
emit_satisfies_helper = false;
4042
emit_type_prop_done = false;
4143
everything = false;
4244
export_interfaces = false;
@@ -228,6 +230,7 @@ let read_config ~get_config_file ~namespace =
228230
suffix;
229231
emit_import_curry = false;
230232
emit_import_react = false;
233+
emit_satisfies_helper = false;
231234
emit_type_prop_done = false;
232235
everything;
233236
export_interfaces;

compiler/gentype/TranslateTypeDeclarations.ml

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,30 @@ let traslate_declaration_kind ~config ~loc ~output_file_relative ~resolver
6262
let import_string_opt, name_as, _import_exact_opt, remote_export_name_opt =
6363
type_attributes |> Annotation.get_attribute_import_renaming
6464
in
65+
let satisfies_opt = type_attributes |> Annotation.get_attribute_satisfies in
66+
let annotation_for_export =
67+
match satisfies_opt with
68+
| Some _ -> Annotation.GenType
69+
| None -> annotation
70+
in
71+
let apply_satisfies_wrapper type_ =
72+
match satisfies_opt with
73+
| None -> type_
74+
| Some (import_str, path) ->
75+
(* Ensure we emit the helper once. *)
76+
config.emit_satisfies_helper <- true;
77+
let import_path = ImportPath.from_string_unsafe import_str in
78+
let import_path_str = ImportPath.emit import_path in
79+
let inline_import =
80+
let base = "import(\"" ^ import_path_str ^ "\")" in
81+
match path with
82+
| [] -> base
83+
| _ -> base ^ "." ^ String.concat "." path
84+
in
85+
let ts_type = ident ~builtin:true inline_import in
86+
ident ~builtin:true ~type_args:[type_; ts_type]
87+
"$RescriptTypeSatisfiesTypeScriptType"
88+
in
6589
let unboxed_annotation =
6690
type_attributes |> Annotation.has_attribute Annotation.tag_is_unboxed
6791
in
@@ -75,8 +99,11 @@ let traslate_declaration_kind ~config ~loc ~output_file_relative ~resolver
7599
(translation : TranslateTypeExprFromTypes.translation) =
76100
let export_from_type_declaration =
77101
type_name
78-
|> create_export_type_from_type_declaration ~annotation ~loc ~name_as
79-
~opaque ~type_:translation.type_ ~type_env ~doc_string ~type_vars
102+
|> create_export_type_from_type_declaration ~annotation:annotation_for_export
103+
~loc ~name_as
104+
~opaque
105+
~type_:(apply_satisfies_wrapper translation.type_)
106+
~type_env ~doc_string ~type_vars
80107
in
81108
let import_types =
82109
translation.dependencies
@@ -220,7 +247,8 @@ let traslate_declaration_kind ~config ~loc ~output_file_relative ~resolver
220247
~polymorphic:true ~tag:None ~unboxed:false
221248
| _ -> translation.type_
222249
in
223-
{translation with type_} |> handle_general_declaration
250+
{translation with type_ = apply_satisfies_wrapper type_}
251+
|> handle_general_declaration
224252
|> return_type_declaration
225253
| RecordDeclarationFromTypes label_declarations, None ->
226254
let {TranslateTypeExprFromTypes.dependencies; type_} =
@@ -235,8 +263,10 @@ let traslate_declaration_kind ~config ~loc ~output_file_relative ~resolver
235263
CodeItem.import_types;
236264
export_from_type_declaration =
237265
type_name
238-
|> create_export_type_from_type_declaration ~doc_string ~annotation ~loc
239-
~name_as ~opaque ~type_ ~type_env ~type_vars;
266+
|> create_export_type_from_type_declaration ~doc_string
267+
~annotation:annotation_for_export ~loc
268+
~name_as ~opaque ~type_:(apply_satisfies_wrapper type_)
269+
~type_env ~type_vars;
240270
}
241271
|> return_type_declaration
242272
| VariantDeclarationFromTypes constructor_declarations, None ->
@@ -302,12 +332,12 @@ let traslate_declaration_kind ~config ~loc ~output_file_relative ~resolver
302332
loc;
303333
name_as;
304334
opaque;
305-
type_ = variant_typ;
335+
type_ = apply_satisfies_wrapper variant_typ;
306336
type_vars;
307337
resolved_type_name;
308338
doc_string;
309339
};
310-
annotation;
340+
annotation = annotation_for_export;
311341
}
312342
in
313343
let import_types =

lib/rescript.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
69167
1+
45559

tests/gentype_tests/genimport-single/src/AriaComponents.gen.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33
/* eslint-disable */
44
/* tslint:disable */
55

6-
import type {GroupRenderProps as GroupRenderProps$TypeScript} from 'react-aria-components';
6+
export type $RescriptTypeSatisfiesTypeScriptType<RescriptType, TypeScriptType extends RescriptType> = TypeScriptType;
77

8-
export type groupRenderProps = GroupRenderProps$TypeScript;
8+
export type groupRenderProps = $RescriptTypeSatisfiesTypeScriptType<{
9+
readonly isHovered: boolean;
10+
readonly isFocusWithin: boolean;
11+
readonly isFocusVisible: boolean;
12+
readonly isDisabled: boolean;
13+
readonly isInvalid: boolean
14+
},import("react-aria-components").GroupRenderProps>;

tests/gentype_tests/genimport-single/src/AriaComponents.res

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@genType.import(("react-aria-components", "GroupRenderProps"))
1+
@gentype.satisfies(("react-aria-components", "GroupRenderProps"))
22
type groupRenderProps = {
33
isHovered: bool,
44
isFocusWithin: bool,

tests/gentype_tests/typescript-react-example/src/ImportHookDefault.gen.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
/* eslint-disable */
44
/* tslint:disable */
55

6-
import {default as makeNotChecked} from './hookExample';
6+
import {make as makeNotChecked} from './hookExample';
77

88
import {default as defaultNotChecked} from './hookExample';
99

0 commit comments

Comments
 (0)