Aboriginal Generics: the future is here!
Inspired by this gem of an idea (click the image to go to the original comment):
Installation
go get github.com/vasilevp/aboriginal/cmd/aboriginal
Example Usage
command line
aboriginal -i ᐸinput_fileᐳ -o ᐸoutput_fileᐳ
You can omit both -i
and -o
, in which case STDIN/STDOUT will be used.
go:generate example
Create main.go
with the following contents:
//go:generate aboriginal -i main.go -o main.gen.go
package main
import "fmt"
type T interface{} // template argument placeholder
type OptionalᐸTᐳ struct {
Value T
Valid bool
}
func main() {
optInt := Optionalᐸintᐳ{
Value: 42,
Valid: true,
}
fmt.Printf("%T %+v\n", optInt, optInt)
optFloat := Optionalᐸfloat64ᐳ{
Value: 42.42,
Valid: true,
}
fmt.Printf("%T %+v\n", optFloat, optFloat)
}
Then run it by calling
go generate && go run *.go
You should get the following output:
main.Optionalᐸintᐳ {Value:42 Valid:true}
main.Optionalᐸfloat64ᐳ {Value:42.42 Valid:true}
How does it work?
The algorithm is fairly simple:
- Parse the source file
- Remember all struct declarations of the form
XᐸTᐳ
- For any reference to
XᐸYᐳ
, whereY
is an arbitrary type, generate an implementation ofXᐸTᐳ
, replacingT
withY
for all member types (verbatim) - Additionally, if there are any known methods defined for
XᐸTᐳ
, generate implementations for those as well, replacingXᐸTᐳ
withXᐸYᐳ
in receiver type - Run
imports.Process()
(the core ofgoimports
) on the resulting file to fix any unused imports (necessary since all imports are copied verbatim from the original file)
TODO
- Implement basic generic generation
- Implement generic methods support
- Implement proper import handling (sort of works)
- Implement generic functions
Disclaimer
This project is a joke. Please, for the love of go, don't use in production.