Conversation
We were simply missing the code to do this!
When dealing with classes, the typedtree contains a number of ways to
refer to the type. For example, compiling this:
```ocaml
class type u = object end
```
results in a typedtree containing:
```
Typedtree.Tsig_class_type
[{Typedtree.ci_virt = Asttypes.Concrete; ci_params = [];
ci_id_name = {Asttypes.txt = ...; loc = ...}; ci_id_class = u/13[14];
ci_id_class_type = u/12[14]; ci_id_object = u/11[14];
ci_id_typehash = #u/10[14];
...
```
these ids may be referenced later in the file, for example:
```ocaml
val g : #u
```
results in:
```
Typedtree.sig_desc =
Typedtree.Tsig_value
{Typedtree.val_id = g/14;
val_name =
{Asttypes.txt = "g";
loc = ...
val_desc =
{Typedtree.ctyp_desc =
Typedtree.Ttyp_class (Path.Pident #u/10[17],
{Asttypes.txt = Longident.Lident "u";
...
```
so the Path.Pident is referring to `#u/10` in this case. When odoc
reads this these idents are turned into odoc `Identifiers`.
Concretely, we add a map from each of the four idents `u/13`, `u/12`,
`u/11` and `#u/10` to the same identifier, so we end up dropping the
explicit '#'.
In contrast, when the path is within a module `M`, and we reference the
class type like `val g : #M.u`, we get this path instead:
`Path.Pdot (Path.Pident M, "#u")`
Internally, odoc turns this into the identifier
`Doc(Identifier M, "#u")` - ie, we don't currently drop the hash. This
patch addresses this by explicitly removing the hash from paths with a
Dot constructor.
| | Path.Pident id -> read_class_type_ident env id | ||
| #if OCAML_VERSION >= (4,8,0) | ||
| | Path.Pdot(p, s) -> `Dot(read_module env p, s) | ||
| | Path.Pdot(p, s) -> `Dot(read_module env p, strip_hash s) |
There was a problem hiding this comment.
We could have a function for that (read_type_path p s) and a bit of documentation. Also should it be called in Fragment.read_type ?
There was a problem hiding this comment.
Good point, I'll check for fragments. Do you mean a function to return `Dot(...)? Might have to have some annoying coercions, but I can see how it looks.
There was a problem hiding this comment.
Do you mean a function to return `Dot(...)?
Yes but if the type is annoying, that's not a big deal. Perhaps abstracting strip_hash behind a read_type_name s would be enough to justify it.
There was a problem hiding this comment.
I don't think you can specify '#' in fragments, so that's probably fine.
There was a problem hiding this comment.
and I'm not keen on the function for reading `Dot, mostly because we wouldn't want to call it from read_module and read_module_type. I'll add some documentation though.
CHANGES: Additions - New subcommand to resolve references (@panglesd, @lubega-simon, ocaml/odoc#812) - Improved rendering of long signatures (@panglesd, ocaml/odoc#782) - Handle comments attached to open statement as floating comment, instead of dropping them (@panglesd, ocaml/odoc#797) - Empty includes (containing entirely shadowed entries) are now hidden (@panglesd, ocaml/odoc#798) Bugs fixed - Fix a missing Result constructor during compile. This will cause some functor arguments to have different filenames (@jonludlam, ocaml/odoc#795) - Better memory/disk space usage when handling module alias chains (@jonludlam, ocaml/odoc#799) - Resolving class-type paths (ie., `val x : #c`) (@jonludlam, ocaml/odoc#809) - Skip top-level attributes while extracting the top comment. Fix top-comment extraction with PPX preprocessing (@jorisgio, ocaml/odoc#819) - Better handling of @canonical tags (@jonludlam, ocaml/odoc#820) - css: improved layout (@jonludlam, @Julow, ocaml/odoc#822)
Fixes for handling class type paths.
Closes: #804