Skip to content
This repository was archived by the owner on Jul 9, 2023. It is now read-only.
This repository was archived by the owner on Jul 9, 2023. It is now read-only.

Query syntax and extractor for syntax tree elements #1

@dtolnay

Description

@dtolnay

For cargo expand I need a library that can index into a syn::File using a string-based query syntax. Roughly:

pub fn select(file: syn::File, query: String) -> Vec<syn::Item>;

Let's consider the following File as input:

mod a {
    mod b {
        trait C {
            fn d() {
                struct E;
            }
            fn f(self) {}
        }
    }
    fn b() {}
}
  1. If I query for "a::b::C" then I should get back:
trait C {
    fn d() {
        struct E;
    }
    fn f(self) {}
}
  1. If I query for "a::b::C::d::E" I should get:
struct E;
  1. If I query for "a::b::C::f" I should get the trait C filtered down to only function f. The trait needs to be included because fn f(self) {} by itself is not a valid top-level Item.
trait C {
    fn f(self) {}
}
  1. If I query for "a::b" I should get back both the mod b and the function b since these are both a::b. One lives in the type namespace and one lives in the value namespace. In general there can be any number of responses to a query.

Also I would like to track and propagate cfg attributes intelligently. For example in the following input:

#[cfg(feature = "g")]
mod imp {
    pub struct H(u8);
}
#[cfg(not(feature = "g"))]
mod imp {
    pub struct H(u16);
}
  1. If I query for "imp::H" I should get:
#[cfg(feature = "g")]
pub struct H(u8);

#[cfg(not(feature = "g"))]
pub struct H(u16);
  1. As a stretch goal, consider supporting wildcard path segments "a::b::_::D" that stand in for any name, and multi wildcards "..::D" where the .. stands in for any number of path segments. These would be similar to * and ** respectively in the wildcard rules of gitignore.

A basic implementation of this exists here in cargo-expand but only supports stepping into modules -- behaviors 1 and 4. It does not support behaviors 2, 3, 5, 6.

This function will be useful outside of cargo-expand so the implementation should go in its own crate.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions