Library to inline out-of-line mod items and resolve #[path = "..."]
dtolnay opened this issue · comments
In dtolnay/cargo-expand#11 I need to be able to take a source file as a syn::File
and transitively expand every mod m;
into mod m { ... }
with its contents drawn from the right file.
Concretely we'll be replacing the content
field of every ItemMod
with Some if it is None.
Example input:
src/lib.rs
#[cfg(feature = "m1")]
mod m1;
#[cfg_attr(feature = "m2", path = "m2.rs")]
#[cfg_attr(not(feature = "m2"), path = "empty.rs")]
mod placeholder;
src/m1.rs
struct M1;
src/m2.rs
//! module level doc comment
struct M2;
src/empty.rs
// empty file
The result will look like:
#[cfg(feature = "m1")]
mod m1 {
struct M1;
}
#[cfg(feature = "m2")]
mod placeholder {
//! module level doc comment
struct M2;
}
#[cfg(not(feature = "m2"))]
mod placeholder {
}
Possible API:
pub fn parse_and_inline_modules(root: &std::path::Path) -> syn::File;
I'll take a look at this one.
Should this be done recursively?
How should not-found files be handled? They could be made into empty modules, or the top-line API could be changed to return a Result
.
Yes I would like it to be recursive.
For my use case I would want not-found modules to simply stay as mod m;
and for the top-level API to be infallible. Performing this transformation 100% correctly requires more parts of a compiler (including name resolution and macro expansion), so since only an approximation is being implemented, there is no meaningful way that a caller could handle failures.
Found a couple bugs; filing them over in the crate repo.
@dpc is https://docs.rs/syn-inline-mod sufficient for your use case or do you need it to be integrated into a cli?
@dtolnay After I'll figure out how to convert it to string, and how to find entry points to a given crate, I'll be all set. :)
@dpc I've been calling into_token_stream().to_string()
on the syn::File
instance to get the results into a string.
I don't know what is the best way to find out the crate entry point. This may be a Cargo feature request. The following might work for now:
cargo +nightly build -Z unstable-options --build-plan \
| jq -r '.invocations[-1].args[2]'
Thanks!
Added link in the readme. Nicely done!