Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Path-references lookup to pages #1150

Merged
merged 12 commits into from
Jul 12, 2024
Merged

Conversation

Julow
Copy link
Collaborator

@Julow Julow commented Jun 21, 2024

This implements the resolving of some path-references using the new Named_roots mechanism recently added.

This is work in progress. Currently, current-package and absolute references are resolved from pages. On top of #1142

@Julow Julow changed the title Path-references lookup Path-references lookup to pages Jul 3, 2024
@Julow Julow marked this pull request as ready for review July 3, 2024 14:27
@Julow
Copy link
Collaborator Author

Julow commented Jul 3, 2024

This should be ready for review.

This is based on top of #1142 and #1151 and implements absolute, relative, current-package-relative path-references to pages.

| Forward

type path_query = [ `Page | `Unit ] * Reference.tag_page_path * string list
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curry curry, curry!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(this is not a comment asking for any change. I was just amused at seeing the input of the function being a tuple)

src/odoc/resolver.ml Outdated Show resolved Hide resolved
Comment on lines 448 to 587
(* Do not implement [lookup_path] in compile mode, as that might return
different results depending on the compilation order. *)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is also true for environments for impl, and compile env for pages.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes but they are implemented in compile mode. Hopefully not used.

src/xref2/ref_tools.ml Outdated Show resolved Hide resolved
These references are resolved using the 'Named_roots' mechanism
introduced recently.

This only handles current-package references from pages, as the current
root is not detected yet when resolving from modules.

The resolving takes place in Resolver, which takes a simpler
'path_query' type.
Note: By name lookups are not implemented yet.
Copy link
Collaborator

@panglesd panglesd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice!

@@ -389,53 +418,125 @@ let add_unit_to_cache u =
in
Hashtbl.add unit_cache target_name [ u ]

let lookup_path _ap ~pages ~libs:_ ~hierarchy (kind, tag, path) =
let module Env = Odoc_xref2.Env in
let ( >>= ) x f = match x with Some x' -> f x' | None -> None in
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There now is an OptionMonad in the Odoc_utils library to open for that!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just realized how ridiculous the interface is and how hard it makes error propagation. I'll revamp the interface.

let pages = Named_roots.create ~current_root:current_package page_roots
and libs = Named_roots.create ~current_root:current_lib lib_roots in
let hierarchy =
match Named_roots.find_by_path pages ~path:(Fpath.v ".") with
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, by using a bug you uncovered its existence!

As I though it, find_by_path was supposed to only return files (and not directories).
I think it is fine for it to return directories, but in this case we need to check that the output is a file (using Sys.is_regular_file f or not (Sys.is_directory f))

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we want a directory. This requires a path that will be used to resolve relative references later, it is not expected to be a page.

Elsewhere, the lookup function loads the page/unit files before returning a positive result so no need to check that at any place. The lookup can't succeed on a directory.

match Hierarchy.resolve_relative hierarchy path with
| Ok path -> load_page path
| Error `Escape_hierarchy ->
Env.Path_not_found (* TODO: propagate more information *))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Writing a comment here not to forget this TODO.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be part of improving error propagation in the resolver (cf comment #1150 (comment)) that I would prefer to think about later.

match hierarchy with
| Some hierarchy -> (
match Hierarchy.resolve_relative hierarchy path with
| Ok path -> load_page path
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if Sys.is_directory path then Env.Path_directory else load_page path

(this check should probably be in load_page maybe)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes!

Though this would be detected while loading the page, but the error is not propagated and is instead printed as a warning outside of the usual warning mechanisms.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No! I think this should be reported by the load_page function. Sys.is_directory is just an other point where an exception can be raised and an other inconsistency.
That code have a TODO that I would leave for later.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't see a TODO yet on this specific error...

The problem is that if you have a directory with the specific name page-directory.odoc, then you might have an uncaught exception when resolving {!./page-directory}:

Error while unmarshalling "h/pkg/doc/page-directory.odoc": Sys_error("Is a directory")

I'm happy to leave a better error reporting for later, but I would really prefer to merge without the risk of uncaught exceptions when resolving references... (note that when we lookup for assets, the right of having a directory referenced will be much higher).

Copy link
Collaborator Author

@Julow Julow Jul 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not an uncaught exception but a very badly reported expected error.

I agree this should be checked eventually but without a way to propagate the errors correctly, this will just slightly improve a very bad error message.
In any case, I don't want to spam the code with this kind of checks. This check must happen just before loading the file, not elsewhere.

I'm doing the required refactoring to make this possible.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh indeed, that's not an uncaught exception. It was obvious from the message and I missed the "catch all exceptions" in load_...

Thanks for doing the refactoring!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the interface of the resolver completely in order to pass the errors. Which I leave for later.

src/xref2/ref_tools.ml Outdated Show resolved Hide resolved
The lookup_path code is refactored into the OptionMonad style until
better error propagation is implemented.
Remove the 'lookup_path' function and change 'lookup_page' and
'lookup_unit' to handle by-name and by-path lookups.

This removes the dependent query and result type that are annoying to
work with and allow to propagate errors from the resolver in a unified
way.
Copy link
Collaborator

@panglesd panglesd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once CI is happy, I think this is ready for merge!

@Julow
Copy link
Collaborator Author

Julow commented Jul 12, 2024

CI was not happy.

@panglesd panglesd merged commit 13200ed into ocaml:master Jul 12, 2024
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants