Skip to content

Commit ea03be8

Browse files
committed
Another attemt at canonical path simplification
The previous version would resolve the canonical path, then try to move as much of it into the identifier as possible. For example, if a module in, say, `Base.String` was referencing a type `t` in `Base.Buffer`, it would resolve `Base.Buffer.t` (the canonical path), then see if `Buffer.t` was the same thing, then check just `t`, where in these cases, `Base`, then `Buffer`, then `t` are fully qualified but not fully rendered identifiers. Unfortunately if the canonical path was not expanded we'd end up with the wrong path rendered. For example, `Caml.Buffer` is an alias to `Stdlib.Buffer`, but it is marked as canonical. We would then end up with `Stdlib.Buffer` where we would have liked `Caml.Buffer` or even just `Buffer` to have appeared.
1 parent 98f34d0 commit ea03be8

File tree

2 files changed

+91
-70
lines changed

2 files changed

+91
-70
lines changed

src/xref2/tools.ml

Lines changed: 91 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -147,48 +147,6 @@ let prefix_signature (path, sg) =
147147
in
148148
{ sg with items }
149149

150-
let simplify_resolved_module_path :
151-
Env.t -> Cpath.Resolved.module_ -> Cpath.Resolved.module_ =
152-
fun env cpath ->
153-
let path = Lang_of.(Path.resolved_module empty cpath) in
154-
let id = Odoc_model.Paths.Path.Resolved.Module.identifier path in
155-
let rec check_ident id =
156-
match Env.(lookup_by_id s_module) id env with
157-
| Some _ -> `Identifier id
158-
| None -> (
159-
match id with
160-
| `Module ((#Odoc_model.Paths.Identifier.Module.t as parent), name) ->
161-
`Module (`Module (check_ident parent), name)
162-
| _ -> failwith "Bad canonical path")
163-
in
164-
check_ident id
165-
166-
let simplify_resolved_module_type_path :
167-
Env.t -> Cpath.Resolved.module_type -> Cpath.Resolved.module_type =
168-
fun env cpath ->
169-
let path = Lang_of.(Path.resolved_module_type empty cpath) in
170-
let id = Odoc_model.Paths.Path.Resolved.ModuleType.identifier path in
171-
match Env.(lookup_by_id s_module_type) id env with
172-
| Some _ -> `Identifier id
173-
| None -> (
174-
match cpath with
175-
| `ModuleType (`Module m, p) ->
176-
`ModuleType (`Module (simplify_resolved_module_path env m), p)
177-
| _ -> cpath)
178-
179-
let simplify_resolved_type_path :
180-
Env.t -> Cpath.Resolved.type_ -> Cpath.Resolved.type_ =
181-
fun env cpath ->
182-
let path = Lang_of.(Path.resolved_type empty cpath) in
183-
let id = Odoc_model.Paths.Path.Resolved.Type.identifier path in
184-
match Env.(lookup_by_id s_type) id env with
185-
| Some _ -> `Identifier id
186-
| None -> (
187-
match cpath with
188-
| `Type (`Module m, p) ->
189-
`Type (`Module (simplify_resolved_module_path env m), p)
190-
| _ -> cpath)
191-
192150
open Errors.Tools_error
193151

194152
type resolve_module_result =
@@ -937,18 +895,94 @@ and reresolve_module : Env.t -> Cpath.Resolved.module_ -> Cpath.Resolved.module_
937895
`Hidden p'
938896
| `Canonical (p, `Resolved p2) ->
939897
`Canonical (reresolve_module env p, `Resolved (reresolve_module env p2))
940-
| `Canonical (p, p2) -> (
941-
match
942-
resolve_module ~mark_substituted:true ~add_canonical:false env p2
943-
with
944-
| Ok (p2', _) ->
945-
`Canonical
946-
( reresolve_module env p,
947-
`Resolved (simplify_resolved_module_path env p2') )
948-
| Error _ -> `Canonical (reresolve_module env p, p2)
949-
| exception _ -> `Canonical (reresolve_module env p, p2))
898+
| `Canonical (p, p2) ->
899+
`Canonical (reresolve_module env p, handle_canonical_module env p2)
950900
| `OpaqueModule m -> `OpaqueModule (reresolve_module env m)
951901

902+
and handle_canonical_module env p2 =
903+
let resolve p =
904+
match resolve_module ~mark_substituted:true ~add_canonical:false env p with
905+
| Ok (p, _) -> Some p
906+
| Error _ -> None
907+
in
908+
let rec get_cpath = function
909+
| `Root _ as p -> resolve p
910+
| `Dot (p, n) -> (
911+
match get_cpath p with
912+
| None -> None
913+
| Some parent -> (
914+
let fallback = `Dot (`Resolved parent, n) in
915+
match parent with
916+
| `Identifier pid -> (
917+
let p' =
918+
`Identifier
919+
( `Module
920+
( (pid :> Odoc_model.Paths.Identifier.Signature.t),
921+
Odoc_model.Names.ModuleName.make_std n ),
922+
false )
923+
in
924+
match resolve p' with None -> resolve fallback | x -> x)
925+
| _ -> resolve fallback))
926+
| _ -> None
927+
in
928+
match get_cpath p2 with Some p -> `Resolved p | None -> p2
929+
930+
and handle_canonical_module_type env p2 =
931+
let resolve p =
932+
match
933+
resolve_module_type ~mark_substituted:true ~add_canonical:false env p
934+
with
935+
| Ok (p, _) -> `Resolved p
936+
| Error _ -> p2
937+
in
938+
match p2 with
939+
| `Dot (p, n) -> (
940+
match handle_canonical_module env p with
941+
| `Resolved r as p' -> (
942+
let fallback = `Dot (p', n) in
943+
match r with
944+
| `Identifier pid -> (
945+
let p' =
946+
`Identifier
947+
( `ModuleType
948+
( (pid :> Odoc_model.Paths.Identifier.Signature.t),
949+
Odoc_model.Names.ModuleTypeName.make_std n ),
950+
false )
951+
in
952+
match resolve p' with
953+
| `Resolved _ as x -> x
954+
| _ -> resolve fallback)
955+
| _ -> resolve fallback)
956+
| _ -> p2)
957+
| _ -> p2
958+
959+
and handle_canonical_type env p2 =
960+
let resolve p =
961+
match resolve_type ~add_canonical:false env p with
962+
| Ok (p, _) -> `Resolved p
963+
| Error _ -> p2
964+
in
965+
match p2 with
966+
| `Dot (p, n) -> (
967+
match handle_canonical_module env p with
968+
| `Resolved r as p' -> (
969+
let fallback = `Dot (p', n) in
970+
match r with
971+
| `Identifier pid -> (
972+
let p' =
973+
`Identifier
974+
( `Type
975+
( (pid :> Odoc_model.Paths.Identifier.Signature.t),
976+
Odoc_model.Names.TypeName.make_std n ),
977+
false )
978+
in
979+
match resolve p' with
980+
| `Resolved _ as x -> x
981+
| _ -> resolve fallback)
982+
| _ -> resolve fallback)
983+
| _ -> p2)
984+
| _ -> p2
985+
952986
and reresolve_module_type :
953987
Env.t -> Cpath.Resolved.module_type -> Cpath.Resolved.module_type =
954988
fun env path ->
@@ -959,16 +993,9 @@ and reresolve_module_type :
959993
| `CanonicalModuleType (p1, `Resolved p2) ->
960994
`CanonicalModuleType
961995
(reresolve_module_type env p1, `Resolved (reresolve_module_type env p2))
962-
| `CanonicalModuleType (p1, p2) -> (
963-
match
964-
resolve_module_type ~mark_substituted:true ~add_canonical:false env p2
965-
with
966-
| Ok (p2', _) ->
967-
`CanonicalModuleType
968-
( reresolve_module_type env p1,
969-
`Resolved (simplify_resolved_module_type_path env p2') )
970-
| Error _ -> `CanonicalModuleType (reresolve_module_type env p1, p2)
971-
| exception _ -> `CanonicalModuleType (reresolve_module_type env p1, p2))
996+
| `CanonicalModuleType (p1, p2) ->
997+
`CanonicalModuleType
998+
(reresolve_module_type env p1, handle_canonical_module_type env p2)
972999
| `SubstT (p1, p2) ->
9731000
`SubstT (reresolve_module_type env p1, reresolve_module_type env p2)
9741001
| `OpaqueModuleType m -> `OpaqueModuleType (reresolve_module_type env m)
@@ -979,14 +1006,8 @@ and reresolve_type : Env.t -> Cpath.Resolved.type_ -> Cpath.Resolved.type_ =
9791006
match path with
9801007
| `Identifier _ | `Local _ -> path
9811008
| `Substituted s -> `Substituted (reresolve_type env s)
982-
| `CanonicalType (p1, p2) -> (
983-
match resolve_type ~add_canonical:false env p2 with
984-
| Ok (p, _) ->
985-
`CanonicalType
986-
( reresolve_type env p1,
987-
`Resolved (simplify_resolved_type_path env p) )
988-
| Error _ -> `CanonicalType (reresolve_type env p1, p2)
989-
| exception _ -> `CanonicalType (reresolve_type env p1, p2))
1009+
| `CanonicalType (p1, p2) ->
1010+
`CanonicalType (reresolve_type env p1, handle_canonical_type env p2)
9901011
| `Type (p, n) -> `Type (reresolve_parent env p, n)
9911012
| `Class (p, n) -> `Class (reresolve_parent env p, n)
9921013
| `ClassType (p, n) -> `ClassType (reresolve_parent env p, n)
File renamed without changes.

0 commit comments

Comments
 (0)