josharian / impl

impl generates method stubs for implementing an interface.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Add support for generics

paddycarver opened this issue · comments

commented

With the release of Go 1.18, interface types can now have type constraints. It would be neat to be able to specify these type constraints when generating the implementation.

Maybe I'm missing something, but impl generates methods, and as of Go 1.18, there are no generic methods.

commented

Sorry, this probably would've been more helpful with an example, huh?

type Parser[Result any] interface {
    Parse(in []byte) (Result, error)
}

That's valid in Go 1.18, but I can't use impl to generate an implementation of, say github.com/my/package.Parser[string]. You get interface Parser[string] not found: type Parser[string] not found in github.com/my/package.

I would expect it to generate (assuming it was run with s stringParser):

func (s stringParser) Parse(in []byte) (string, error) {
    panic("not implemented")
}

Ah! I see. So you'd also have to tell impl the intended type of Result.

I see the usefulness, although I'm a bit worried about the command line API. There can be an unlimited number of type parameters. Using order isn't a great API, but naming them gets awkward. At some point it'll be easier to write the implementation stubs by hand. :P

I'm not spending much time on impl at this point. If there's a path forward that is simple and clear, I'm happy to review it. If not, I will probably wait until popular demand grows larger. :)

commented

So I think my preferred way of invoking it would be to just attach the type parameter to the interface type. I don't use impl on the command line, I use it through vim-go, so what it would look like there is:

:GoImpl s stringParser github.com/my/package.Parser[string]

I don't know what the command line equivalent is, sadly. :(

But the above could read that it wants a string from the type parameter, and I think that's a semi-standard way to refer to type parameters? It matches how I'd declare a variable of that type with those parameters, at least: https://go.dev/play/p/XldKb_P2Uvp It was also my first instinct for how to go about doing that.

I haven't looked at impl's source, but would you be amenable to a PR for that functionality if I ever got around to implementing it? (Can't promise I will, but in case I get the time. 😄)

That works for me. I would review such a PR, with the caveat that my turnaround time is typically O(weeks) or even O(months). I'm not proud of that...just being honest.

commented

The transparency is appreciated and no judgment. Appreciate the willingness to look at it, if I (or someone else) can find the time and energy to put something together :)

commented

I've opened #49 with my implementation of this feature. I've added some test cases, but was unable to get a test case for a qualified interface working in an automated fashion; the full path worked, and the unqualifed interface worked, but the qualified one couldn't find the testdata package. I have verified it manually, though that's not ideal and it has only been tested with an interface that accepts two type parameters (that's all I had handy).