HaxeFoundation / haxe

Haxe - The Cross-Platform Toolkit
https://haxe.org
6.17k stars 655 forks source link

[ide] poor/no completion for expression macro arguments #9421

Open nadako opened 4 years ago

nadako commented 4 years ago

7885 seems related, but i think we should do something here for better IDE support of macro methods:

Consider this situation:

class Main {
    #if !macro
    static function main() {
        f(|
    }
    #end

    static macro function f(a, b) {
        trace("call", a, b);
        return macro null;
    }
}

Invoking toplevel completion will NOT call the macro, thus we can't wrap given EDisplay into some typecheck to trigger completion.

If we now type the first argument, e.g. f(1,| and invoke toplevel completion, the macro will be called and will receive EConst(1), EDisplay(DKMarked).

So it is only possible to provide completion for the last argument, unless we use rest macro arguments (Array<Expr>), in which case it will correctly pass all of the arguments (but that's extra work for the macro authors and it still shows ugly in signature help, so it's not really an option)

Maybe we could always call the macro but pass missing arguments as EDisplay(DKMissing) or something?

PS It's not super high priority, but I'm still labeling it with hf-partner, because I want to have a simple macro method with 3 arguments and I want IDE features to work for it :)

nadako commented 4 years ago

BTW I'm pretty sure the related code is somewhere near my macroContext.ml changes of #9410

RealyUniqueName commented 3 years ago

duplicates #7699?

Simn commented 2 years ago

I'm not sure what to do with this. Inventing arguments so that the macro gets called sounds like it could lead to quite a bit of confusion and overall messiness if you actually try to run it.

Given that macro arguments can result in some very domain-specific completion results, I wonder if we should think about something along the lines of display overloads for macros. This would allow the typer to consider all arguments optional and always commit to the call, which could then handle display in whatever way. I would have to think this through though because I literally just had this idea while starting this paragraph.