racer-rust / racer

Rust Code Completion utility
MIT License
3.36k stars 278 forks source link

Proposed Solution for Items Created From Macros #1039

Closed Leguu closed 5 years ago

Leguu commented 5 years ago

Before beginning, I'd just like to say that racer is the best rust crate I've ever used. I'm not exactly great at coding, so please tell me if anything I say is not possible.

A short example, where ba~ would be autocompleted to bar.

create_class!(Zed);

fn main() {
    Zed { ba~: String::from("Test") };
}

#[macro_export]
macro_rules! create_class {
    ($name:ident) => {
        pub struct $name {
            pub bar: String,
        }
    };
}

One proposed solution was to expand the macro. In the past, concerns have been raised about expanding macros, saying that they may be performance-unfriendly. Instead of expanding the macros, why not keep them and instead autocomplete directly from them?

Thus the macro is equivalent to:

// `Name` is arbitrary
struct Name {
    pub bar: String,
}

Where Zed is now an Identifier. After looking through the source code of racer, this solution might need a new MatchType - but I'm not sure. Anyway... Zed can autocomplete from Name, but because it is not a Name, it can be allowed to autocomplete from impls too:

// Somewhere else in the project
impl Zed {
    fn new() -> Self {
        Zed {
            bar: String::from("Test")
        }
    }
}

Thus: create_class!(Tut); create_class!(Ohn); create_class!(Arr); Generates 3 new identifiers. All autocomplete from the same struct Name, instead of 3 different structs being generated. Perhaps, instead of even generating the struct Name, the Identifiers can autocomplete directly from the macro, no generation required.

Thoughts? I would want to help implement it, but I would need help - since I'm not extremely familiar this.

Thank you

Leguu commented 5 years ago

Also in issues: https://github.com/racer-rust/racer/issues/337, https://github.com/racer-rust/racer/issues/491, https://github.com/racer-rust/racer/issues/389.

kngwyu commented 5 years ago

Thanks for your idea.

Instead of expanding the macros, why not keep them and instead autocomplete directly from them?

But then, how we should parse the macro? It's difficult to treat it as a normal Rust code snippet, since we use compiler's parser.

Leguu commented 5 years ago

It could be that instead of autocompleting from them directly, to just expand it once and reuse that expansion every time the macro is reused. If not that, then couldn't we extract the needed needed code (Like the struct) from inside the macro?

I didn't know it was based on the compiler's parser - I'll look at how that works too to get a better idea.

kngwyu commented 5 years ago

to just expand it once and reuse that expansion every time the macro is reused.

It can be very slow and... personally I'm against supporting macro expansion or so. It's really difficult even for other newer tools like rust-analyzer or so and, our code base is too crafty to add such a complex feature.

Leguu commented 5 years ago

All right - you probably know the project better than me, so I'll be closing the issue now. Thanks~