1
1
open SharedTypes
2
2
3
- let codeBlock code = Printf. sprintf " ```rescript\n %s\n ```" code
4
-
5
- (* Light weight, hopefully-enough-for-the-purpose fn to encode URI components.
6
- Built to handle the reserved characters listed in
7
- https://en.wikipedia.org/wiki/Percent-encoding. Note that this function is not
8
- general purpose, rather it's currently only for URL encoding the argument list
9
- passed to command links in markdown. *)
10
- let encodeURIComponent text =
11
- let ln = String. length text in
12
- let buf = Buffer. create ln in
13
- let rec loop i =
14
- if i < ln then (
15
- (match text.[i] with
16
- | '"' -> Buffer. add_string buf " %22"
17
- | '\' ' -> Buffer. add_string buf " %22"
18
- | ':' -> Buffer. add_string buf " %3A"
19
- | ';' -> Buffer. add_string buf " %3B"
20
- | '/' -> Buffer. add_string buf " %2F"
21
- | '\\' -> Buffer. add_string buf " %5C"
22
- | ',' -> Buffer. add_string buf " %2C"
23
- | '&' -> Buffer. add_string buf " %26"
24
- | '[' -> Buffer. add_string buf " %5B"
25
- | ']' -> Buffer. add_string buf " %5D"
26
- | '#' -> Buffer. add_string buf " %23"
27
- | '$' -> Buffer. add_string buf " %24"
28
- | '+' -> Buffer. add_string buf " %2B"
29
- | '=' -> Buffer. add_string buf " %3D"
30
- | '?' -> Buffer. add_string buf " %3F"
31
- | '@' -> Buffer. add_string buf " %40"
32
- | '%' -> Buffer. add_string buf " %25"
33
- | c -> Buffer. add_char buf c);
34
- loop (i + 1 ))
35
- in
36
- loop 0 ;
37
- Buffer. contents buf
38
-
39
- type link = {startPos : Protocol .position ; file : string ; label : string }
40
-
41
- let linkToCommandArgs link =
42
- Printf. sprintf " [\" %s\" ,%i,%i]" link.file link.startPos.line
43
- link.startPos.character
44
-
45
- let makeGotoCommand link =
46
- Printf. sprintf " [%s](command:rescript-vscode.go_to_location?%s)" link.label
47
- (encodeURIComponent (linkToCommandArgs link))
48
-
49
3
let showModuleTopLevel ~docstring ~name (topLevel : Module.item list ) =
50
4
let contents =
51
5
topLevel
@@ -60,7 +14,9 @@ let showModuleTopLevel ~docstring ~name (topLevel : Module.item list) =
60
14
(* TODO indent *)
61
15
|> String. concat " \n "
62
16
in
63
- let full = codeBlock (" module " ^ name ^ " = {" ^ " \n " ^ contents ^ " \n }" ) in
17
+ let full =
18
+ Markdown. codeBlock (" module " ^ name ^ " = {" ^ " \n " ^ contents ^ " \n }" )
19
+ in
64
20
let doc =
65
21
match docstring with
66
22
| [] -> " "
@@ -80,11 +36,62 @@ let rec showModule ~docstring ~(file : File.t) ~name
80
36
| Some {item = Ident path } ->
81
37
Some (" Unable to resolve module reference " ^ Path. name path)
82
38
39
+ type extractedType = {
40
+ name : string ;
41
+ path : Path .t ;
42
+ decl : Types .type_declaration ;
43
+ env : SharedTypes.QueryEnv .t ;
44
+ loc : Warnings .loc ;
45
+ }
46
+
47
+ let findRelevantTypesFromType ~file ~package typ =
48
+ (* Expand definitions of types mentioned in typ.
49
+ If typ itself is a record or variant, search its body *)
50
+ let env = QueryEnv. fromFile file in
51
+ let envToSearch, typesToSearch =
52
+ match typ |> Shared. digConstructor with
53
+ | Some path -> (
54
+ let labelDeclarationsTypes lds =
55
+ lds |> List. map (fun (ld : Types.label_declaration ) -> ld.ld_type)
56
+ in
57
+ match References. digConstructor ~env ~package path with
58
+ | None -> (env, [typ])
59
+ | Some (env1 , {item = {decl} } ) -> (
60
+ match decl.type_kind with
61
+ | Type_record (lds , _ ) -> (env1, typ :: (lds |> labelDeclarationsTypes))
62
+ | Type_variant cds ->
63
+ ( env1,
64
+ cds
65
+ |> List. map (fun (cd : Types.constructor_declaration ) ->
66
+ let fromArgs =
67
+ match cd.cd_args with
68
+ | Cstr_tuple ts -> ts
69
+ | Cstr_record lds -> lds |> labelDeclarationsTypes
70
+ in
71
+ typ
72
+ ::
73
+ (match cd.cd_res with
74
+ | None -> fromArgs
75
+ | Some t -> t :: fromArgs))
76
+ |> List. flatten )
77
+ | _ -> (env, [typ])))
78
+ | None -> (env, [typ])
79
+ in
80
+ let fromConstructorPath ~env path =
81
+ match References. digConstructor ~env ~package path with
82
+ | None -> None
83
+ | Some (env , {name = {txt} ; extentLoc; item = {decl} } ) ->
84
+ if Utils. isUncurriedInternal path then None
85
+ else Some {name = txt; env; loc = extentLoc; decl; path}
86
+ in
87
+ let constructors = Shared. findTypeConstructors typesToSearch in
88
+ constructors |> List. filter_map (fromConstructorPath ~env: envToSearch)
89
+
83
90
let newHover ~full :{file; package} ~supportsMarkdownLinks locItem =
84
91
match locItem.locType with
85
92
| TypeDefinition (name , decl , _stamp ) ->
86
93
let typeDef = Shared. declToString name decl in
87
- Some (codeBlock typeDef)
94
+ Some (Markdown. codeBlock typeDef)
88
95
| LModule (Definition (stamp, _tip)) | LModule (LocalReference (stamp, _tip))
89
96
-> (
90
97
match Stamps. findModule file.stamps stamp with
@@ -132,7 +139,7 @@ let newHover ~full:{file; package} ~supportsMarkdownLinks locItem =
132
139
| Typed (_ , _ , Definition (_ , (Field _ | Constructor _ ))) -> None
133
140
| Constant t ->
134
141
Some
135
- (codeBlock
142
+ (Markdown. codeBlock
136
143
(match t with
137
144
| Const_int _ -> " int"
138
145
| Const_char _ -> " char"
@@ -142,81 +149,25 @@ let newHover ~full:{file; package} ~supportsMarkdownLinks locItem =
142
149
| Const_int64 _ -> " int64"
143
150
| Const_nativeint _ -> " int" ))
144
151
| Typed (_ , t , locKind ) ->
145
- let fromConstructorPath ~env path =
146
- match References. digConstructor ~env ~package path with
147
- | None -> None
148
- | Some (env , {extentLoc; item = {decl} } ) ->
149
- if Utils. isUncurriedInternal path then None
150
- else
151
- Some
152
- ( decl
153
- |> Shared. declToString ~print NameAsIs:true
154
- (SharedTypes. pathIdentToString path),
155
- extentLoc,
156
- env )
157
- in
158
152
let fromType ~docstring typ =
159
- let typeString = codeBlock (typ |> Shared. typeToString) in
153
+ let typeString = Markdown. codeBlock (typ |> Shared. typeToString) in
154
+ let types = findRelevantTypesFromType typ ~file ~package in
160
155
let typeDefinitions =
161
- (* Expand definitions of types mentioned in typ.
162
- If typ itself is a record or variant, search its body *)
163
- let env = QueryEnv. fromFile file in
164
- let envToSearch, typesToSearch =
165
- match typ |> Shared. digConstructor with
166
- | Some path -> (
167
- let labelDeclarationsTypes lds =
168
- lds |> List. map (fun (ld : Types.label_declaration ) -> ld.ld_type)
169
- in
170
- match References. digConstructor ~env ~package path with
171
- | None -> (env, [typ])
172
- | Some (env1 , {item = {decl} } ) -> (
173
- match decl.type_kind with
174
- | Type_record (lds , _ ) ->
175
- (env1, typ :: (lds |> labelDeclarationsTypes))
176
- | Type_variant cds ->
177
- ( env1,
178
- cds
179
- |> List. map (fun (cd : Types.constructor_declaration ) ->
180
- let fromArgs =
181
- match cd.cd_args with
182
- | Cstr_tuple ts -> ts
183
- | Cstr_record lds -> lds |> labelDeclarationsTypes
184
- in
185
- typ
186
- ::
187
- (match cd.cd_res with
188
- | None -> fromArgs
189
- | Some t -> t :: fromArgs))
190
- |> List. flatten )
191
- | _ -> (env, [typ])))
192
- | None -> (env, [typ])
193
- in
194
- let constructors = Shared. findTypeConstructors typesToSearch in
195
- constructors
196
- |> List. filter_map (fun constructorPath ->
197
- match
198
- constructorPath |> fromConstructorPath ~env: envToSearch
199
- with
200
- | None -> None
201
- | Some (typString , extentLoc , env ) ->
202
- let startLine, startCol = Pos. ofLexing extentLoc.loc_start in
203
- let linkToTypeDefinitionStr =
204
- if supportsMarkdownLinks then
205
- " \n Go to: "
206
- ^ makeGotoCommand
207
- {
208
- label = " Type definition" ;
209
- file = Uri. toString env.file.uri;
210
- startPos = {line = startLine; character = startCol};
211
- }
212
- else " "
213
- in
214
- Some
215
- (Shared. markdownSpacing ^ codeBlock typString
216
- ^ linkToTypeDefinitionStr ^ " \n\n ---\n " ))
156
+ types
157
+ |> List. map (fun {decl; env; loc; path} ->
158
+ let linkToTypeDefinitionStr =
159
+ if supportsMarkdownLinks then
160
+ Markdown. goToDefinitionText ~env ~pos: loc.Warnings. loc_start
161
+ else " "
162
+ in
163
+ " \n " ^ Markdown. spacing
164
+ ^ Markdown. codeBlock
165
+ (decl
166
+ |> Shared. declToString ~print NameAsIs:true
167
+ (SharedTypes. pathIdentToString path))
168
+ ^ linkToTypeDefinitionStr ^ " \n " ^ Markdown. divider)
217
169
in
218
- let typeString = typeString :: typeDefinitions |> String. concat " \n\n " in
219
- (typeString, docstring)
170
+ (typeString :: typeDefinitions |> String. concat " \n " , docstring)
220
171
in
221
172
let parts =
222
173
match References. definedForLoc ~file ~package locKind with
@@ -238,9 +189,9 @@ let newHover ~full:{file; package} ~supportsMarkdownLinks locItem =
238
189
|> List. map (fun (t , _ ) -> Shared. typeToString t)
239
190
|> String. concat " , " |> Printf. sprintf " (%s)"
240
191
in
241
- typeString :: codeBlock (txt ^ argsString) :: docstring
192
+ typeString :: Markdown. codeBlock (txt ^ argsString) :: docstring
242
193
| `Field ->
243
194
let typeString, docstring = t |> fromType ~docstring in
244
195
typeString :: docstring)
245
196
in
246
- Some (String. concat " \n\n " parts)
197
+ Some (String. concat " \n\n " parts)
0 commit comments