11open SharedTypes
22
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-
493let showModuleTopLevel ~docstring ~name (topLevel : Module.item list ) =
504 let contents =
515 topLevel
@@ -60,7 +14,9 @@ let showModuleTopLevel ~docstring ~name (topLevel : Module.item list) =
6014 (* TODO indent *)
6115 |> String. concat " \n "
6216 in
63- let full = codeBlock (" module " ^ name ^ " = {" ^ " \n " ^ contents ^ " \n }" ) in
17+ let full =
18+ Markdown. codeBlock (" module " ^ name ^ " = {" ^ " \n " ^ contents ^ " \n }" )
19+ in
6420 let doc =
6521 match docstring with
6622 | [] -> " "
@@ -80,11 +36,62 @@ let rec showModule ~docstring ~(file : File.t) ~name
8036 | Some {item = Ident path } ->
8137 Some (" Unable to resolve module reference " ^ Path. name path)
8238
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+
8390let newHover ~full :{file; package} ~supportsMarkdownLinks locItem =
8491 match locItem.locType with
8592 | TypeDefinition (name , decl , _stamp ) ->
8693 let typeDef = Shared. declToString name decl in
87- Some (codeBlock typeDef)
94+ Some (Markdown. codeBlock typeDef)
8895 | LModule (Definition (stamp, _tip)) | LModule (LocalReference (stamp, _tip))
8996 -> (
9097 match Stamps. findModule file.stamps stamp with
@@ -132,7 +139,7 @@ let newHover ~full:{file; package} ~supportsMarkdownLinks locItem =
132139 | Typed (_ , _ , Definition (_ , (Field _ | Constructor _ ))) -> None
133140 | Constant t ->
134141 Some
135- (codeBlock
142+ (Markdown. codeBlock
136143 (match t with
137144 | Const_int _ -> " int"
138145 | Const_char _ -> " char"
@@ -142,81 +149,25 @@ let newHover ~full:{file; package} ~supportsMarkdownLinks locItem =
142149 | Const_int64 _ -> " int64"
143150 | Const_nativeint _ -> " int" ))
144151 | 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
158152 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
160155 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)
217169 in
218- let typeString = typeString :: typeDefinitions |> String. concat " \n\n " in
219- (typeString, docstring)
170+ (typeString :: typeDefinitions |> String. concat " \n " , docstring)
220171 in
221172 let parts =
222173 match References. definedForLoc ~file ~package locKind with
@@ -238,9 +189,9 @@ let newHover ~full:{file; package} ~supportsMarkdownLinks locItem =
238189 |> List. map (fun (t , _ ) -> Shared. typeToString t)
239190 |> String. concat " , " |> Printf. sprintf " (%s)"
240191 in
241- typeString :: codeBlock (txt ^ argsString) :: docstring
192+ typeString :: Markdown. codeBlock (txt ^ argsString) :: docstring
242193 | `Field ->
243194 let typeString, docstring = t |> fromType ~docstring in
244195 typeString :: docstring)
245196 in
246- Some (String. concat " \n\n " parts)
197+ Some (String. concat " \n\n " parts)
0 commit comments