rust-lang / rustdoc-types

Rustdoc's JSON output interface
Apache License 2.0
28 stars 15 forks source link

Add utility for retrieving full import paths #20

Closed makspll closed 2 weeks ago

makspll commented 1 year ago

As discussed in here: https://github.com/rust-lang/rust/issues/104651#issuecomment-1328115787

It would be useful to provide a utility function to retrieve import paths for items.

aDotInTheVoid commented 1 year ago

As discussed in #5, I'd think this crate should remain as a pure reexport of rustdoc-json. That said I think theirs room for a rustdoc-json-utils (or similar) crate that would have common functionality like this (and probably also a loader that gives good errors on version mismatch)

makspll commented 1 year ago

That's a fair choice, anybody willing to take that crate on?

obi1kenobi commented 6 months ago

Just noticed this issue -- cargo-semver-checks needed this functionality too, and I implemented it via a combination of crates:

I don't have time to fully write up the cargo-semver-checks architecture or its internal crates, but the functionality is there and I've described some of it in blog posts. It even accounts for glob imports, cases of ambiguity, and namespace-specific edge cases (e.g. function and type names are not in the same namespace).

You probably would need to use the Trustfall query engine to use it in the best way, unless you wanted to fork those crates and use the underlying code directly (which you are of course welcome to do if you don't mind maintaining a fork).

Boscop commented 2 weeks ago

Any update on this? Is it possible to retrieve the full import paths now? :)

obi1kenobi commented 2 weeks ago

Only via trustfall-rustdoc-adapter and/or trustfall-rustdoc, AFAIK.

I would be very surprised if the algorithm ever ships as part of rustdoc-types, since it's extremely complex and is subject to design decisions like "what to do about items with infinitely many paths." I don't think a one-size-fits-all approach is possible, so I don't think rustdoc-types is likely to ship something here.

If you're interested in reusing some of my work, I'd be happy to point you in the right direction.

Enselic commented 2 weeks ago

For completeness and future reference: The public-api crate also has this capability and is also an option for you.

Boscop commented 2 weeks ago

@obi1kenobi Yes, I'd be very interested in this functionality, it's totally fine with me if I have to depend on trustfall crates for this, I'd really appreciate if you can point me in the right direction 🙂🙏

obi1kenobi commented 2 weeks ago

Oh neat, I didn't know that public-api also computes full import paths! I wasn't able to find that functionality in the docs, but perhaps I just looked in the wrong place.

@obi1kenobi Yes, I'd be very interested in this functionality, it's totally fine with me if I have to depend on trustfall crates for this, I'd really appreciate if you can point me in the right direction 🙂🙏

If you know you are working with a specific rustdoc format version (e.g. v34), you'd use the corresponding major version of trustfall-rustdoc-adapter (e.g. v34.x.y):

Of course now that you have Trustfall adapter, you can also use it to run Trustfall queries over the rustdoc as well — the same queries as in the playground.

And if you aren't sure which exact rustdoc format version you'll get, the trustfall-rustdoc allows abstracting across multiple versions and running queries over whichever one you happen to get.

obi1kenobi commented 2 weeks ago

Two more notes:

#[doc(hidden)]
mod hidden {
    pub struct Example;
}

// Users can import this as `my_crate::Example`,
// which does not pass through any `doc(hidden)` components.
// So this is public API!
pub use hidden::Example;
Enselic commented 2 weeks ago

To clarify: In the public-api crate there is currently no API for "give me all paths to the item with ID foo", but if you list the public API you will get all paths to an item. (So maybe it's of no good use to you after all.)

Example

For this crate:

pub mod first_path {
    pub fn the_item() {}
}

pub mod second_path {
    pub use crate::first_path::the_item;
}

All (both) paths to the public item are listed:

$ cargo public-api
pub mod diff_test
pub mod diff_test::first_path
pub fn diff_test::first_path::the_item()
pub mod diff_test::second_path
pub fn diff_test::second_path::the_item()

And we also handle infinite export loops. But we currently don't handle doc(hidden) properly.

(The example use the cargo public-api CLI, but it is essentially a CLI for the public-api crate.)