@@ -31,6 +31,73 @@ module SourceFileExtractor = struct
31
31
! res)
32
32
end
33
33
34
+ module AttributesUtils : sig
35
+ type t
36
+
37
+ val make : string list -> t
38
+
39
+ val contains : string -> t -> bool
40
+
41
+ val toString : t -> string
42
+ end = struct
43
+ type attribute = {line : int ; offset : int ; name : string }
44
+ type t = attribute list
45
+ type parseState = Search | Collect of int
46
+
47
+ let make lines =
48
+ let makeAttr lineIdx attrOffsetStart attrOffsetEnd line =
49
+ {
50
+ line = lineIdx;
51
+ offset = attrOffsetStart;
52
+ name = String. sub line attrOffsetStart (attrOffsetEnd - attrOffsetStart);
53
+ }
54
+ in
55
+ let res = ref [] in
56
+ lines
57
+ |> List. iteri (fun lineIdx line ->
58
+ let state = ref Search in
59
+ for i = 0 to String. length line - 1 do
60
+ let ch = line.[i] in
61
+ match (! state, ch) with
62
+ | Search , '@' -> state := Collect i
63
+ | Collect attrOffset , ' ' ->
64
+ res := makeAttr lineIdx attrOffset i line :: ! res;
65
+ state := Search
66
+ | Search , _ | Collect _ , _ -> ()
67
+ done ;
68
+
69
+ match ! state with
70
+ | Collect attrOffset ->
71
+ res :=
72
+ makeAttr lineIdx attrOffset (String. length line) line :: ! res
73
+ | _ -> () );
74
+ ! res |> List. rev
75
+
76
+ let contains attributeForSearch t =
77
+ t |> List. exists (fun {name} -> name = attributeForSearch)
78
+
79
+ let toString t =
80
+ match t with
81
+ | [] -> " "
82
+ | {line} :: _ ->
83
+ let prevLine = ref line in
84
+ let buffer = ref " " in
85
+ let res = ref [] in
86
+ t
87
+ |> List. iter (fun attr ->
88
+ let {line; offset; name} = attr in
89
+
90
+ if line <> ! prevLine then (
91
+ res := ! buffer :: ! res;
92
+ buffer := " " ;
93
+ prevLine := line);
94
+
95
+ let indent = String. make (offset - String. length ! buffer) ' ' in
96
+ buffer := ! buffer ^ indent ^ name);
97
+ res := ! buffer :: ! res;
98
+ ! res |> List. rev |> String. concat " \n "
99
+ end
100
+
34
101
let printSignature ~extractor ~signature =
35
102
let objectPropsToFun objTyp ~rhs ~makePropsType =
36
103
let propsTbl = Hashtbl. create 1 in
@@ -84,6 +151,17 @@ let printSignature ~extractor ~signature =
84
151
|> Res_doc. toString ~width: ! Res_cli.ResClflags. width
85
152
in
86
153
154
+ let genSigStrForInlineAttr lines attributes id vd =
155
+ let divider = if List. length lines > 1 then " \n " else " " in
156
+
157
+ let sigStr =
158
+ sigItemToString
159
+ (Printtyp. tree_of_value_description id {vd with val_kind = Val_reg })
160
+ in
161
+
162
+ (attributes |> AttributesUtils. toString) ^ divider ^ sigStr ^ " \n "
163
+ in
164
+
87
165
let buf = Buffer. create 10 in
88
166
89
167
let getComponentType (typ : Types.type_expr ) =
@@ -162,15 +240,22 @@ let printSignature ~extractor ~signature =
162
240
Buffer. add_string buf " \n "
163
241
in
164
242
processSignature ~indent rest
165
- | Sig_value (_id, {val_kind = Val_prim prim; val_loc}) :: items
243
+ | Sig_value (id, ( {val_kind = Val_prim prim; val_loc} as vd) ) :: items
166
244
when prim.prim_native_name <> " " && prim.prim_native_name.[0 ] = '\132' ->
167
- (* Rescript primitive name, e.g. @val external ...
168
- Copy the external declaration verbatim from the implementation file *)
245
+ (* Rescript primitive name, e.g. @val external ... *)
169
246
let lines =
170
247
let posStart, posEnd = Loc. range val_loc in
171
248
extractor |> SourceFileExtractor. extract ~pos Start ~pos End
172
249
in
173
- Buffer. add_string buf ((lines |> String. concat " \n " ) ^ " \n " );
250
+ let attributes = AttributesUtils. make lines in
251
+
252
+ if AttributesUtils. contains " @inline" attributes then
253
+ (* Generate type signature for @inline declaration *)
254
+ Buffer. add_string buf (genSigStrForInlineAttr lines attributes id vd)
255
+ else
256
+ (* Copy the external declaration verbatim from the implementation file *)
257
+ Buffer. add_string buf ((lines |> String. concat " \n " ) ^ " \n " );
258
+
174
259
processSignature ~indent items
175
260
| Sig_value (id , vd ) :: items ->
176
261
let newItemStr =
0 commit comments