Added package empty
This package adds the code generation for package empty, which provides structs that has no-op asserter methods for ease of use. The package demonstrates one of the many possible use cases of having a repository ready for code generation.
This commit is contained in:
parent
2d93bf62ea
commit
25980eb794
|
@ -0,0 +1,85 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/dave/jennifer/jen"
|
||||
"github.com/diamondburned/cchat/cmd/internal/cchat-generator/genutils"
|
||||
"github.com/diamondburned/cchat/repository"
|
||||
)
|
||||
|
||||
const OutputDir = "."
|
||||
|
||||
func init() {
|
||||
log.SetFlags(0)
|
||||
}
|
||||
|
||||
var comment = repository.Comment{Raw: `
|
||||
Package empty provides no-op asserter method implementations of interfaces
|
||||
in cchat.
|
||||
`}
|
||||
|
||||
func main() {
|
||||
pk, ok := repository.Main[repository.RootPath]
|
||||
if !ok {
|
||||
log.Fatalf("Failed to find main namespace %q\n", repository.RootPath)
|
||||
}
|
||||
|
||||
gen := jen.NewFile("empty")
|
||||
gen.HeaderComment("DO NOT EDIT: THIS FILE IS GENERATED!")
|
||||
gen.PackageComment(comment.GoString(1))
|
||||
|
||||
for _, iface := range pk.Interfaces {
|
||||
// Skip structs without asserter methods.
|
||||
if !hasAsserter(iface) {
|
||||
continue
|
||||
}
|
||||
|
||||
gen.Commentf("%[1]s provides no-op asserters for cchat.%[1]s.", iface.Name)
|
||||
gen.Type().Id(iface.Name).Struct()
|
||||
gen.Line()
|
||||
|
||||
for _, method := range iface.Methods {
|
||||
am, ok := method.(repository.AsserterMethod)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
name := fmt.Sprintf("As%s", am.ChildType)
|
||||
gen.Comment(fmt.Sprintf("%s returns nil.", name))
|
||||
|
||||
stmt := jen.Func()
|
||||
stmt.Parens(jen.Id(iface.Name))
|
||||
stmt.Id(fmt.Sprintf("As%s", am.ChildType))
|
||||
stmt.Params()
|
||||
stmt.Add(genutils.GenerateExternType(am))
|
||||
stmt.Values(jen.Return(jen.Nil()))
|
||||
|
||||
gen.Add(stmt)
|
||||
}
|
||||
|
||||
gen.Line()
|
||||
}
|
||||
|
||||
f, err := os.Create("empty.go")
|
||||
if err != nil {
|
||||
log.Fatalln("Failed to create output file:", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
if err := gen.Render(f); err != nil {
|
||||
log.Fatalln("Failed to render output:", err)
|
||||
}
|
||||
}
|
||||
|
||||
func hasAsserter(iface repository.Interface) bool {
|
||||
for _, method := range iface.Methods {
|
||||
if _, isA := method.(repository.AsserterMethod); isA {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
|
@ -4,6 +4,7 @@ import (
|
|||
"sort"
|
||||
|
||||
"github.com/dave/jennifer/jen"
|
||||
"github.com/diamondburned/cchat/cmd/internal/cchat-generator/genutils"
|
||||
"github.com/diamondburned/cchat/repository"
|
||||
)
|
||||
|
||||
|
@ -45,7 +46,7 @@ func generateEnums(enums []repository.Enumeration) jen.Code {
|
|||
stmt.Line()
|
||||
stmt.Line()
|
||||
|
||||
var recv = recvName(enum.Name)
|
||||
var recv = genutils.RecvName(enum.Name)
|
||||
|
||||
if enum.Bitwise {
|
||||
fn := stmt.Func()
|
|
@ -4,6 +4,7 @@ import (
|
|||
"sort"
|
||||
|
||||
"github.com/dave/jennifer/jen"
|
||||
"github.com/diamondburned/cchat/cmd/internal/cchat-generator/genutils"
|
||||
"github.com/diamondburned/cchat/repository"
|
||||
)
|
||||
|
||||
|
@ -71,7 +72,7 @@ func generateInterfaces(ifaces []repository.Interface) jen.Code {
|
|||
stmt.Params(generateContainerFuncReturns(method)...)
|
||||
case repository.AsserterMethod:
|
||||
stmt.Params()
|
||||
stmt.Params(generateType(method))
|
||||
stmt.Params(genutils.GenerateType(method))
|
||||
stmt.Comment("// Optional")
|
||||
default:
|
||||
continue
|
||||
|
@ -108,9 +109,9 @@ func generateFuncParamErr(param repository.NamedType, genErr bool) []jen.Code {
|
|||
|
||||
func generateFuncParam(param repository.NamedType) jen.Code {
|
||||
if param.Name == "" {
|
||||
return generateType(param)
|
||||
return genutils.GenerateType(param)
|
||||
}
|
||||
return jen.Id(param.Name).Add(generateType(param))
|
||||
return jen.Id(param.Name).Add(genutils.GenerateType(param))
|
||||
}
|
||||
|
||||
func generateFuncParams(params []repository.NamedType, withError bool) []jen.Code {
|
||||
|
@ -151,7 +152,7 @@ func generateContainerFuncParams(method repository.ContainerMethod) []jen.Code {
|
|||
if method.HasContext {
|
||||
stmt.Qual("context", "Context")
|
||||
}
|
||||
stmt.Add(generateType(method))
|
||||
stmt.Add(genutils.GenerateType(method))
|
||||
|
||||
return stmt
|
||||
}
|
|
@ -4,6 +4,7 @@ import (
|
|||
"sort"
|
||||
|
||||
"github.com/dave/jennifer/jen"
|
||||
"github.com/diamondburned/cchat/cmd/internal/cchat-generator/genutils"
|
||||
"github.com/diamondburned/cchat/repository"
|
||||
)
|
||||
|
||||
|
@ -35,7 +36,7 @@ func generateErrorStructs(errStructs []repository.ErrorStruct) jen.Code {
|
|||
stmt.Line()
|
||||
stmt.Line()
|
||||
|
||||
var recv = recvName(errStruct.Name)
|
||||
var recv = genutils.RecvName(errStruct.Name)
|
||||
|
||||
stmt.Func()
|
||||
stmt.Params(jen.Id(recv).Id(errStruct.Name))
|
||||
|
@ -81,7 +82,7 @@ func generateStruct(s repository.Struct) jen.Code {
|
|||
if field.Name != "" {
|
||||
stmt.Id(field.Name)
|
||||
}
|
||||
stmt.Add(generateType(field))
|
||||
stmt.Add(genutils.GenerateType(field))
|
||||
group.Add(stmt)
|
||||
}
|
||||
})
|
|
@ -4,6 +4,7 @@ import (
|
|||
"sort"
|
||||
|
||||
"github.com/dave/jennifer/jen"
|
||||
"github.com/diamondburned/cchat/cmd/internal/cchat-generator/genutils"
|
||||
"github.com/diamondburned/cchat/repository"
|
||||
)
|
||||
|
||||
|
@ -20,22 +21,10 @@ func generateTypeAlises(aliases []repository.TypeAlias) jen.Code {
|
|||
stmt.Line()
|
||||
}
|
||||
|
||||
stmt.Type().Id(alias.Name).Op("=").Add(generateType(alias))
|
||||
stmt.Type().Id(alias.Name).Op("=").Add(genutils.GenerateType(alias))
|
||||
stmt.Line()
|
||||
stmt.Line()
|
||||
}
|
||||
|
||||
return stmt
|
||||
}
|
||||
|
||||
type qualer interface {
|
||||
Qual() (path, name string)
|
||||
}
|
||||
|
||||
func generateType(t qualer) jen.Code {
|
||||
path, name := t.Qual()
|
||||
if path == "" {
|
||||
return jen.Id(name)
|
||||
}
|
||||
return jen.Qual(path, name)
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package genutils
|
||||
|
||||
import (
|
||||
"unicode"
|
||||
|
||||
"github.com/dave/jennifer/jen"
|
||||
"github.com/diamondburned/cchat/repository"
|
||||
)
|
||||
|
||||
type Qualer interface {
|
||||
Qual() (path, name string)
|
||||
}
|
||||
|
||||
// GenerateType generates a jen.Qual from the given Qualer.
|
||||
func GenerateType(t Qualer) jen.Code {
|
||||
path, name := t.Qual()
|
||||
if path == "" {
|
||||
return jen.Id(name)
|
||||
}
|
||||
return jen.Qual(path, name)
|
||||
}
|
||||
|
||||
// GenerateExternType generates a jen.Qual from the given Qualer, except if
|
||||
// the path is empty, RootPath is used instead.
|
||||
func GenerateExternType(t Qualer) jen.Code {
|
||||
path, name := t.Qual()
|
||||
if path == "" {
|
||||
return jen.Qual(repository.RootPath, name)
|
||||
}
|
||||
return jen.Qual(path, name)
|
||||
}
|
||||
|
||||
// RecvName is used to get the receiver variable name. It returns the first
|
||||
// letter lower-cased. It does NOT do length checking. It only works with ASCII.
|
||||
func RecvName(name string) string {
|
||||
return string(unicode.ToLower(rune(name[0])))
|
||||
}
|
|
@ -5,7 +5,6 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/dave/jennifer/jen"
|
||||
"github.com/diamondburned/cchat/repository"
|
||||
|
@ -48,12 +47,6 @@ func trimPrefix(rootPrefix, path string) string {
|
|||
return strings.Trim(strings.TrimPrefix(path, rootPrefix), "/")
|
||||
}
|
||||
|
||||
// recvName is used to get the receiver variable name. It returns the first
|
||||
// letter lower-cased. It does NOT do length checking. It only works with ASCII.
|
||||
func recvName(name string) string {
|
||||
return string(unicode.ToLower(rune(name[0])))
|
||||
}
|
||||
|
||||
func generate(pkgPath string, repo repository.Package) *jen.File {
|
||||
gen := jen.NewFilePath(pkgPath)
|
||||
gen.HeaderComment("DO NOT EDIT: THIS FILE IS GENERATED!")
|
|
@ -1,3 +1,3 @@
|
|||
package cchat
|
||||
|
||||
//go:generate go run ./cmd/cchat-generator
|
||||
//go:generate go run ./cmd/internal/cchat-generator
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
//go:generate go run ./generator.go
|
||||
|
|
|
@ -5,7 +5,7 @@ package repository
|
|||
const RootPath = "github.com/diamondburned/cchat"
|
||||
|
||||
var Main = Packages{
|
||||
"github.com/diamondburned/cchat/text": {
|
||||
MakePath("text"): {
|
||||
Comment: Comment{`
|
||||
Package text provides a rich text API for cchat interfaces to use.
|
||||
`},
|
||||
|
@ -210,7 +210,7 @@ var Main = Packages{
|
|||
Name: "MentionInfo",
|
||||
},
|
||||
Returns: []NamedType{{
|
||||
Type: "(github.com/diamondburned/cchat/text).Rich",
|
||||
Type: MakeQual("text", "Rich"),
|
||||
}},
|
||||
},
|
||||
},
|
||||
|
@ -462,7 +462,7 @@ var Main = Packages{
|
|||
`},
|
||||
NamedType: NamedType{
|
||||
Name: "Text",
|
||||
Type: "(github.com/diamondburned/cchat/text).Rich",
|
||||
Type: MakeQual("text", "Rich"),
|
||||
},
|
||||
}, {
|
||||
Comment: Comment{`
|
||||
|
@ -472,7 +472,7 @@ var Main = Packages{
|
|||
`},
|
||||
NamedType: NamedType{
|
||||
Name: "Secondary",
|
||||
Type: "(github.com/diamondburned/cchat/text).Rich",
|
||||
Type: MakeQual("text", "Rich"),
|
||||
},
|
||||
}, {
|
||||
Comment: Comment{`
|
||||
|
@ -545,7 +545,7 @@ var Main = Packages{
|
|||
GetterMethod{
|
||||
method: method{Name: "Name"},
|
||||
Returns: []NamedType{{
|
||||
Type: "(github.com/diamondburned/cchat/text).Rich",
|
||||
Type: MakeQual("text", "Rich"),
|
||||
}},
|
||||
},
|
||||
AsserterMethod{
|
||||
|
@ -1366,7 +1366,7 @@ var Main = Packages{
|
|||
GetterMethod{
|
||||
method: method{Name: "Content"},
|
||||
Returns: []NamedType{{
|
||||
Type: "(github.com/diamondburned/cchat/text).Rich",
|
||||
Type: MakeQual("text", "Rich"),
|
||||
}},
|
||||
},
|
||||
GetterMethod{
|
||||
|
@ -1396,7 +1396,7 @@ var Main = Packages{
|
|||
GetterMethod{
|
||||
method: method{Name: "Content"},
|
||||
Returns: []NamedType{{
|
||||
Type: "(github.com/diamondburned/cchat/text).Rich",
|
||||
Type: MakeQual("text", "Rich"),
|
||||
}},
|
||||
},
|
||||
},
|
||||
|
@ -1422,7 +1422,7 @@ var Main = Packages{
|
|||
SetterMethod{
|
||||
method: method{Name: "SetLabel"},
|
||||
Parameters: []NamedType{{
|
||||
Type: "(github.com/diamondburned/cchat/text).Rich",
|
||||
Type: MakeQual("text", "Rich"),
|
||||
}},
|
||||
},
|
||||
},
|
||||
|
@ -1650,7 +1650,7 @@ var Main = Packages{
|
|||
Name: "Secondary",
|
||||
},
|
||||
Returns: []NamedType{{
|
||||
Type: "(github.com/diamondburned/cchat/text).Rich",
|
||||
Type: MakeQual("text", "Rich"),
|
||||
}},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -1,9 +1,22 @@
|
|||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// MakePath returns RootPath joined with relPath.
|
||||
func MakePath(relPath string) string {
|
||||
return path.Join(RootPath, relPath)
|
||||
}
|
||||
|
||||
// MakeQual returns a qualified identifier that is the full path and name of
|
||||
// something.
|
||||
func MakeQual(relPath, name string) string {
|
||||
return fmt.Sprintf("(%s).%s", MakePath(relPath), name)
|
||||
}
|
||||
|
||||
// Packages maps Go module paths to packages.
|
||||
type Packages map[string]Package
|
||||
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
// DO NOT EDIT: THIS FILE IS GENERATED!
|
||||
|
||||
// Package empty provides no-op asserter method implementations of interfaces in
|
||||
// cchat.
|
||||
package empty
|
||||
|
||||
import cchat "github.com/diamondburned/cchat"
|
||||
|
||||
// Namer provides no-op asserters for cchat.Namer.
|
||||
type Namer struct{}
|
||||
|
||||
// AsIconer returns nil.
|
||||
func (Namer) AsIconer() cchat.Iconer { return nil }
|
||||
|
||||
// Service provides no-op asserters for cchat.Service.
|
||||
type Service struct{}
|
||||
|
||||
// AsConfigurator returns nil.
|
||||
func (Service) AsConfigurator() cchat.Configurator { return nil }
|
||||
|
||||
// AsSessionRestorer returns nil.
|
||||
func (Service) AsSessionRestorer() cchat.SessionRestorer { return nil }
|
||||
|
||||
// Session provides no-op asserters for cchat.Session.
|
||||
type Session struct{}
|
||||
|
||||
// AsCommander returns nil.
|
||||
func (Session) AsCommander() cchat.Commander { return nil }
|
||||
|
||||
// AsSessionSaver returns nil.
|
||||
func (Session) AsSessionSaver() cchat.SessionSaver { return nil }
|
||||
|
||||
// Commander provides no-op asserters for cchat.Commander.
|
||||
type Commander struct{}
|
||||
|
||||
// AsCompleter returns nil.
|
||||
func (Commander) AsCompleter() cchat.Completer { return nil }
|
||||
|
||||
// Server provides no-op asserters for cchat.Server.
|
||||
type Server struct{}
|
||||
|
||||
// AsLister returns nil.
|
||||
func (Server) AsLister() cchat.Lister { return nil }
|
||||
|
||||
// AsMessenger returns nil.
|
||||
func (Server) AsMessenger() cchat.Messenger { return nil }
|
||||
|
||||
// AsCommander returns nil.
|
||||
func (Server) AsCommander() cchat.Commander { return nil }
|
||||
|
||||
// AsConfigurator returns nil.
|
||||
func (Server) AsConfigurator() cchat.Configurator { return nil }
|
||||
|
||||
// Messenger provides no-op asserters for cchat.Messenger.
|
||||
type Messenger struct{}
|
||||
|
||||
// AsSender returns nil.
|
||||
func (Messenger) AsSender() cchat.Sender { return nil }
|
||||
|
||||
// AsEditor returns nil.
|
||||
func (Messenger) AsEditor() cchat.Editor { return nil }
|
||||
|
||||
// AsActioner returns nil.
|
||||
func (Messenger) AsActioner() cchat.Actioner { return nil }
|
||||
|
||||
// AsNicknamer returns nil.
|
||||
func (Messenger) AsNicknamer() cchat.Nicknamer { return nil }
|
||||
|
||||
// AsBacklogger returns nil.
|
||||
func (Messenger) AsBacklogger() cchat.Backlogger { return nil }
|
||||
|
||||
// AsMemberLister returns nil.
|
||||
func (Messenger) AsMemberLister() cchat.MemberLister { return nil }
|
||||
|
||||
// AsUnreadIndicator returns nil.
|
||||
func (Messenger) AsUnreadIndicator() cchat.UnreadIndicator { return nil }
|
||||
|
||||
// AsTypingIndicator returns nil.
|
||||
func (Messenger) AsTypingIndicator() cchat.TypingIndicator { return nil }
|
||||
|
||||
// Sender provides no-op asserters for cchat.Sender.
|
||||
type Sender struct{}
|
||||
|
||||
// AsCompleter returns nil.
|
||||
func (Sender) AsCompleter() cchat.Completer { return nil }
|
||||
|
||||
// MemberSection provides no-op asserters for cchat.MemberSection.
|
||||
type MemberSection struct{}
|
||||
|
||||
// AsMemberDynamicSection returns nil.
|
||||
func (MemberSection) AsMemberDynamicSection() cchat.MemberDynamicSection { return nil }
|
||||
|
||||
// SendableMessage provides no-op asserters for cchat.SendableMessage.
|
||||
type SendableMessage struct{}
|
||||
|
||||
// AsNoncer returns nil.
|
||||
func (SendableMessage) AsNoncer() cchat.Noncer { return nil }
|
||||
|
||||
// AsAttachments returns nil.
|
||||
func (SendableMessage) AsAttachments() cchat.Attachments { return nil }
|
|
@ -0,0 +1,3 @@
|
|||
package main
|
||||
|
||||
//go:generate go run ../../cmd/internal/cchat-empty-gen
|
Loading…
Reference in New Issue