@@ -18,7 +18,8 @@ type constructorDoc = {
1818 items : constructorPayload option ;
1919}
2020
21- type valueSignature = {parameters : string list ; returnType : string }
21+ type typeDoc = {path : string ; genericParameters : typeDoc list }
22+ type valueSignature = {parameters : typeDoc list ; returnType : typeDoc }
2223
2324type source = {filepath : string ; line : int ; col : int }
2425
@@ -108,6 +109,19 @@ let stringifyConstructorPayload ~indentation
108109 |> array ) );
109110 ]
110111
112+ let rec stringifyTypeDoc ~indentation (td : typeDoc ) : string =
113+ let open Protocol in
114+ let ps =
115+ match td.genericParameters with
116+ | [] -> None
117+ | ts ->
118+ ts |> List. map (stringifyTypeDoc ~indentation: (indentation + 1 ))
119+ |> fun ts -> Some (array ts)
120+ in
121+
122+ stringifyObject ~indentation: (indentation + 1 )
123+ [(" path" , Some (wrapInQuotes td.path)); (" genericTypeParameters" , ps)]
124+
111125let stringifyDetail ?(indentation = 0 ) (detail : docItemDetail ) =
112126 let open Protocol in
113127 match detail with
@@ -151,7 +165,19 @@ let stringifyDetail ?(indentation = 0) (detail : docItemDetail) =
151165 ])
152166 |> array ) );
153167 ]
154- | Signature {parameters; returnType} -> returnType
168+ | Signature {parameters; returnType} ->
169+ let ps =
170+ match parameters with
171+ | [] -> None
172+ | ps ->
173+ ps |> List. map (stringifyTypeDoc ~indentation: (indentation + 1 ))
174+ |> fun ps -> Some (array ps)
175+ in
176+ stringifyObject ~start OnNewline:false ~indentation
177+ [
178+ (" parameters" , ps);
179+ (" returnType" , Some (stringifyTypeDoc ~indentation returnType));
180+ ]
155181
156182let stringifySource ~indentation source =
157183 let open Protocol in
@@ -320,9 +346,47 @@ let typeDetail typ ~env ~full =
320346 })
321347 | _ -> None
322348
323- let valueDetail (item : SharedTypes.Module.item ) (typ : Types.type_expr ) =
324- let s = Print_tast. print_type_expr typ in
325- Some (Signature {parameters = [] ; returnType = s})
349+ (* split a list into two parts all the items except the last one and the last item *)
350+ let splitLast l =
351+ let rec splitLast ' acc = function
352+ | [] -> failwith " splitLast: empty list"
353+ | [x] -> (List. rev acc, x)
354+ | x :: xs -> splitLast' (x :: acc) xs
355+ in
356+ splitLast' [] l
357+
358+ let isFunction = function
359+ | Path. Pident {name = "function$" } -> true
360+ | _ -> false
361+
362+ let valueDetail (typ : Types.type_expr ) =
363+ Printf. printf " %s\n " (Print_tast. print_type_expr typ);
364+ let rec collectSignatureTypes (typ_desc : Types.type_desc ) =
365+ match typ_desc with
366+ | Tlink t -> collectSignatureTypes t.desc
367+ | Tconstr (path , [t ; _ ], _ ) when isFunction path ->
368+ collectSignatureTypes t.desc
369+ | Tconstr (path , ts , _ ) -> (
370+ let p = Print_tast.Oak. path_to_string path in
371+ match ts with
372+ | [] -> [{path = p; genericParameters = [] }]
373+ | ts ->
374+ let ts =
375+ ts
376+ |> List. concat_map (fun (t : Types.type_expr ) ->
377+ collectSignatureTypes t.desc)
378+ in
379+ [{path = p; genericParameters = ts}])
380+ | Tarrow (_ , t1 , t2 , _ ) ->
381+ collectSignatureTypes t1.desc @ collectSignatureTypes t2.desc
382+ | Tvar None -> [{path = " _" ; genericParameters = [] }]
383+ | _ -> []
384+ in
385+ match collectSignatureTypes typ.desc with
386+ | [] -> None
387+ | ts ->
388+ let parameters, returnType = splitLast ts in
389+ Some (Signature {parameters; returnType})
326390
327391let makeId modulePath ~identifier =
328392 identifier :: modulePath |> List. rev |> SharedTypes. ident
@@ -336,65 +400,6 @@ let getSource ~rootPath ({loc_start} : Location.t) =
336400 in
337401 {filepath; line = line + 1 ; col = col + 1 }
338402
339- let dump ~entryPointFile ~debug =
340- let path =
341- match Filename. is_relative entryPointFile with
342- | true -> Unix. realpath entryPointFile
343- | false -> entryPointFile
344- in
345- if debug then Printf. printf " extracting docs for %s\n " path;
346- let result =
347- match
348- FindFiles. isImplementation path = false
349- && FindFiles. isInterface path = false
350- with
351- | false -> (
352- let path =
353- if FindFiles. isImplementation path then
354- let pathAsResi =
355- (path |> Filename. dirname) ^ " /"
356- ^ (path |> Filename. basename |> Filename. chop_extension)
357- ^ " .resi"
358- in
359- if Sys. file_exists pathAsResi then (
360- if debug then
361- Printf. printf " preferring found resi file for impl: %s\n "
362- pathAsResi;
363- pathAsResi)
364- else path
365- else path
366- in
367- match Cmt. loadFullCmtFromPath ~path with
368- | None ->
369- Error
370- (Printf. sprintf
371- " error: failed to generate doc for %s, try to build the project"
372- path)
373- | Some full ->
374- let file = full.file in
375- let structure = file.structure in
376- let open SharedTypes in
377- let extractDocsForModule (structure : Module.structure ) =
378- structure.items
379- |> List. filter_map (fun (item : Module.item ) ->
380- match item.kind with
381- | Value typ -> (
382- match valueDetail item typ with
383- | Some (Signature {returnType = rt } ) -> Some rt
384- | _ -> None )
385- | _ -> None )
386- |> String. concat " \n "
387- in
388- let docs = extractDocsForModule structure in
389- Ok docs)
390- | true ->
391- Error
392- (Printf. sprintf
393- " error: failed to read %s, expected an .res or .resi file" path)
394- in
395-
396- result
397-
398403let extractDocs ~entryPointFile ~debug =
399404 let path =
400405 match Filename. is_relative entryPointFile with
@@ -471,7 +476,7 @@ let extractDocs ~entryPointFile ~debug =
471476 ^ Shared. typeToString typ;
472477 name = item.name;
473478 deprecated = item.deprecated;
474- detail = valueDetail item typ;
479+ detail = valueDetail typ;
475480 source;
476481 })
477482 | Type (typ , _ ) ->
0 commit comments