vektra / mockery

A mock code autogenerator for Go
https://vektra.github.io/mockery/
BSD 3-Clause "New" or "Revised" License
6k stars 405 forks source link

Investigate if we can use `GODEBUG=gotypealias=1` to get around type alias sadness #763

Open LandonTClipp opened 7 months ago

LandonTClipp commented 7 months ago

replace-types was added because the Go AST does not have any nodes for type alias, thus the alias gets resolved to its underlying type. Go 1.22 adds a debug feature called gotypealias that seems to provide an explicit node for type aliases. This would potentially allow us to handle aliases automatically and not have it resolved to the real type.

The way to do this would be to modify .mockery.yaml to generate mocks for a type alias that points to an internal package, set GODEBUG=gotypealias=1, and see what happens. If it works then we can just update the docs to let people know.

https://github.com/vektra/mockery/pull/725#issuecomment-1944580275 https://github.com/vektra/mockery/pull/540#issuecomment-1952884200

LandonTClipp commented 7 months ago

I dived into seeing if this is feasible, but it appears not. The gotypelias flag in Go 1.22 only applies to the go/types API. See initial proposal. However the compiler export data format, and importer changes, have not been completed yet. This is necessary because go/packages (which this project uses to parse the type tree) imports the compiler-exported data. So it seems we won't get go/packages support until Go 1.23 at least.

https://github.com/golang/go/issues/64208

LandonTClipp commented 7 months ago

Some additional clarity on where this issue lies. I discovered the gopackages tool that allows you to briefly inspect the syntax of a particular package. You see that when we ask it to print one of our packages that has a type alias on an internal type, the alias is not preserved:

go run golang.org/x/tools/go/packages/gopackages -mode allsyntax github.com/vektra/mockery/v2/pkg/fixtures/example_project/replace_type
Go package "github.com/vektra/mockery/v2/pkg/fixtures/example_project/replace_type":
        package replace_type
        has complete exported type info and typed ASTs
        file /Users/landonclipp/git/LandonTClipp/mockery/pkg/fixtures/example_project/replace_type/rt.go
        import "github.com/vektra/mockery/v2/pkg/fixtures/example_project/replace_type/rti/rt1"
        import "github.com/vektra/mockery/v2/pkg/fixtures/example_project/replace_type/rti/rt2"
        type RType interface{Replace1(f github.com/vektra/mockery/v2/pkg/fixtures/example_project/replace_type/rti/internal.RTInternal1); Replace2(f github.com/vektra/mockery/v2/pkg/fixtures/example_project/replace_type/rti/internal.RTInternal2)}
        method (RType) Replace1(f github.com/vektra/mockery/v2/pkg/fixtures/example_project/replace_type/rti/internal.RTInternal1)
        method (RType) Replace2(f github.com/vektra/mockery/v2/pkg/fixtures/example_project/replace_type/rti/internal.RTInternal2)

This is just further proof that we cannot do anything further until the Go devs update the compiler export format and importers.