2018-10-20 05:44:13 +09:00
|
|
|
package codegen
|
2018-10-09 05:19:10 +09:00
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/dave/jennifer/jen"
|
|
|
|
)
|
|
|
|
|
2019-01-13 04:53:00 +09:00
|
|
|
// memberType defines the way a method belongs to its struct.
|
2018-10-09 05:19:10 +09:00
|
|
|
type memberType int
|
|
|
|
|
|
|
|
const (
|
|
|
|
this = "this"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2019-01-13 04:53:00 +09:00
|
|
|
// A method is by value.
|
2018-10-09 05:19:10 +09:00
|
|
|
valueMember memberType = iota
|
2019-01-13 04:53:00 +09:00
|
|
|
// A method is by pointer.
|
2018-10-09 05:19:10 +09:00
|
|
|
pointerMember
|
|
|
|
)
|
|
|
|
|
2018-10-10 07:32:37 +09:00
|
|
|
// This returns the string variable used by members to refer to themselves.
|
2018-10-09 05:19:10 +09:00
|
|
|
func This() string {
|
|
|
|
return this
|
|
|
|
}
|
|
|
|
|
2018-10-10 07:32:37 +09:00
|
|
|
// Function represents a free function, not a method, for Go code to be
|
|
|
|
// generated.
|
2018-10-09 05:19:10 +09:00
|
|
|
type Function struct {
|
|
|
|
qual *jen.Statement
|
|
|
|
name string
|
|
|
|
params []jen.Code
|
|
|
|
ret []jen.Code
|
|
|
|
block []jen.Code
|
2019-01-08 06:06:32 +09:00
|
|
|
comment string
|
2018-10-09 05:19:10 +09:00
|
|
|
}
|
|
|
|
|
2018-10-10 07:32:37 +09:00
|
|
|
// NewCommentedFunction creates a new function with a comment.
|
2018-10-09 05:19:10 +09:00
|
|
|
func NewCommentedFunction(pkg, name string,
|
|
|
|
params, ret, block []jen.Code,
|
2019-01-08 06:06:32 +09:00
|
|
|
comment string) *Function {
|
2018-10-09 05:19:10 +09:00
|
|
|
return &Function{
|
|
|
|
qual: jen.Qual(pkg, name),
|
|
|
|
name: name,
|
|
|
|
params: params,
|
|
|
|
ret: ret,
|
|
|
|
block: block,
|
|
|
|
comment: comment,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-10 07:32:37 +09:00
|
|
|
// NewFunction creates a new function without any comments.
|
2018-10-09 05:19:10 +09:00
|
|
|
func NewFunction(pkg, name string,
|
|
|
|
params, ret, block []jen.Code) *Function {
|
|
|
|
return &Function{
|
2019-01-08 06:06:32 +09:00
|
|
|
qual: jen.Qual(pkg, name),
|
|
|
|
name: name,
|
|
|
|
params: params,
|
|
|
|
ret: ret,
|
|
|
|
block: block,
|
2018-10-09 05:19:10 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-05 08:00:51 +09:00
|
|
|
// CloneToPackage copies this Function into a new one defined in the provided
|
|
|
|
// package
|
|
|
|
func (m Function) CloneToPackage(pkg string) *Function {
|
|
|
|
f := m
|
|
|
|
f.qual = jen.Qual(pkg, m.name)
|
|
|
|
return &f
|
|
|
|
}
|
|
|
|
|
2018-10-10 07:32:37 +09:00
|
|
|
// Definition generates the Go code required to define and implement this
|
|
|
|
// function.
|
2018-10-09 05:19:10 +09:00
|
|
|
func (m Function) Definition() jen.Code {
|
|
|
|
stmts := jen.Empty()
|
2019-01-08 06:06:32 +09:00
|
|
|
if len(m.comment) > 0 {
|
2019-01-08 06:39:30 +09:00
|
|
|
stmts = jen.Commentf(insertNewlines(m.comment)).Line()
|
2018-10-09 05:19:10 +09:00
|
|
|
}
|
|
|
|
return stmts.Add(jen.Func().Id(m.name).Params(
|
|
|
|
m.params...,
|
|
|
|
).Params(
|
|
|
|
m.ret...,
|
|
|
|
).Block(
|
|
|
|
m.block...,
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
2018-10-10 07:32:37 +09:00
|
|
|
// Call generates the Go code required to call this function, with qualifier if
|
|
|
|
// required.
|
2018-10-09 05:19:10 +09:00
|
|
|
func (m Function) Call(params ...jen.Code) jen.Code {
|
2018-10-20 05:44:13 +09:00
|
|
|
return m.qual.Clone().Call(params...)
|
2018-10-09 05:19:10 +09:00
|
|
|
}
|
|
|
|
|
2018-10-10 07:32:37 +09:00
|
|
|
// Name returns the identifier of this function.
|
2018-10-09 05:19:10 +09:00
|
|
|
func (m Function) Name() string {
|
|
|
|
return m.name
|
|
|
|
}
|
|
|
|
|
2019-01-04 06:27:14 +09:00
|
|
|
// QualifiedName returns the qualified identifier for this function.
|
|
|
|
func (m Function) QualifiedName() *jen.Statement {
|
|
|
|
return m.qual.Clone()
|
|
|
|
}
|
|
|
|
|
2019-02-07 04:27:19 +09:00
|
|
|
// ToFunctionSignature obtains this function's FunctionSignature.
|
|
|
|
func (m Function) ToFunctionSignature() FunctionSignature {
|
|
|
|
return FunctionSignature{
|
|
|
|
Name: m.Name(),
|
|
|
|
Params: m.params,
|
|
|
|
Ret: m.ret,
|
|
|
|
Comment: m.comment,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-10 07:32:37 +09:00
|
|
|
// Method represents a method on a type, not a free function, for Go code to be
|
|
|
|
// generated.
|
2018-10-09 05:19:10 +09:00
|
|
|
type Method struct {
|
|
|
|
member memberType
|
|
|
|
structName string
|
|
|
|
function *Function
|
|
|
|
}
|
|
|
|
|
2018-10-10 07:32:37 +09:00
|
|
|
// NewCommentedValueMethod defines a commented method for the value of a type.
|
2018-10-09 05:19:10 +09:00
|
|
|
func NewCommentedValueMethod(pkg, name, structName string,
|
|
|
|
params, ret, block []jen.Code,
|
2019-01-08 06:06:32 +09:00
|
|
|
comment string) *Method {
|
2018-10-09 05:19:10 +09:00
|
|
|
return &Method{
|
|
|
|
member: valueMember,
|
|
|
|
structName: structName,
|
|
|
|
function: &Function{
|
|
|
|
qual: jen.Qual(pkg, name),
|
|
|
|
name: name,
|
|
|
|
params: params,
|
|
|
|
ret: ret,
|
|
|
|
block: block,
|
|
|
|
comment: comment,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-10 07:32:37 +09:00
|
|
|
// NewValueMethod defines a method for the value of a type. It is not commented.
|
2018-10-09 05:19:10 +09:00
|
|
|
func NewValueMethod(pkg, name, structName string,
|
|
|
|
params, ret, block []jen.Code) *Method {
|
|
|
|
return &Method{
|
|
|
|
member: valueMember,
|
|
|
|
structName: structName,
|
|
|
|
function: &Function{
|
2019-01-08 06:06:32 +09:00
|
|
|
qual: jen.Qual(pkg, name),
|
|
|
|
name: name,
|
|
|
|
params: params,
|
|
|
|
ret: ret,
|
|
|
|
block: block,
|
2018-10-09 05:19:10 +09:00
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-10 07:32:37 +09:00
|
|
|
// NewCommentedPointerMethod defines a commented method for the pointer to a
|
|
|
|
// type.
|
2018-10-09 05:19:10 +09:00
|
|
|
func NewCommentedPointerMethod(pkg, name, structName string,
|
|
|
|
params, ret, block []jen.Code,
|
2019-01-08 06:06:32 +09:00
|
|
|
comment string) *Method {
|
2018-10-09 05:19:10 +09:00
|
|
|
return &Method{
|
|
|
|
member: pointerMember,
|
|
|
|
structName: structName,
|
|
|
|
function: &Function{
|
|
|
|
qual: jen.Qual(pkg, name),
|
|
|
|
name: name,
|
|
|
|
params: params,
|
|
|
|
ret: ret,
|
|
|
|
block: block,
|
|
|
|
comment: comment,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-10 07:32:37 +09:00
|
|
|
// NewPointerMethod defines a method for the pointer to a type. It is not
|
|
|
|
// commented.
|
2018-10-09 05:19:10 +09:00
|
|
|
func NewPointerMethod(pkg, name, structName string,
|
|
|
|
params, ret, block []jen.Code) *Method {
|
|
|
|
return &Method{
|
|
|
|
member: pointerMember,
|
|
|
|
structName: structName,
|
|
|
|
function: &Function{
|
2019-01-08 06:06:32 +09:00
|
|
|
qual: jen.Qual(pkg, name),
|
|
|
|
name: name,
|
|
|
|
params: params,
|
|
|
|
ret: ret,
|
|
|
|
block: block,
|
2018-10-09 05:19:10 +09:00
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-10 07:32:37 +09:00
|
|
|
// Definition generates the Go code required to define and implement this
|
|
|
|
// method.
|
2018-10-09 05:19:10 +09:00
|
|
|
func (m Method) Definition() jen.Code {
|
|
|
|
comment := jen.Empty()
|
2019-01-08 06:06:32 +09:00
|
|
|
if len(m.function.comment) > 0 {
|
2019-01-08 06:39:30 +09:00
|
|
|
comment = jen.Commentf(insertNewlines(m.function.comment)).Line()
|
2018-10-09 05:19:10 +09:00
|
|
|
}
|
2019-10-20 07:43:21 +09:00
|
|
|
var funcDef *jen.Statement
|
2018-10-09 05:19:10 +09:00
|
|
|
switch m.member {
|
|
|
|
case pointerMember:
|
|
|
|
funcDef = jen.Func().Params(
|
|
|
|
jen.Id(This()).Op("*").Id(m.structName),
|
|
|
|
)
|
|
|
|
case valueMember:
|
|
|
|
funcDef = jen.Func().Params(
|
|
|
|
jen.Id(This()).Id(m.structName),
|
|
|
|
)
|
|
|
|
default:
|
|
|
|
panic("unhandled method memberType")
|
|
|
|
}
|
|
|
|
return comment.Add(funcDef.Id(
|
|
|
|
m.function.name,
|
|
|
|
).Params(
|
|
|
|
m.function.params...,
|
|
|
|
).Params(
|
|
|
|
m.function.ret...,
|
|
|
|
).Block(
|
|
|
|
m.function.block...,
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
2018-10-10 07:32:37 +09:00
|
|
|
// Call generates the Go code required to call this method, with qualifier if
|
|
|
|
// required.
|
2018-10-09 05:19:10 +09:00
|
|
|
func (m Method) Call(on string, params ...jen.Code) jen.Code {
|
2019-01-01 00:49:25 +09:00
|
|
|
return jen.Id(on).Dot(m.function.name).Call(params...)
|
2018-10-09 05:19:10 +09:00
|
|
|
}
|
|
|
|
|
2019-01-01 02:42:39 +09:00
|
|
|
// On generates the Go code that determines the qualified method name on a
|
|
|
|
// specific variable.
|
|
|
|
func (m Method) On(on string) *jen.Statement {
|
|
|
|
return jen.Id(on).Dot(m.function.name)
|
|
|
|
}
|
|
|
|
|
2018-10-10 07:32:37 +09:00
|
|
|
// Name returns the identifier of this function.
|
2018-10-09 05:19:10 +09:00
|
|
|
func (m Method) Name() string {
|
|
|
|
return m.function.name
|
|
|
|
}
|
2018-12-31 00:09:14 +09:00
|
|
|
|
|
|
|
// ToFunctionSignature obtains this method's FunctionSignature.
|
|
|
|
func (m Method) ToFunctionSignature() FunctionSignature {
|
|
|
|
return FunctionSignature{
|
2019-01-08 06:06:32 +09:00
|
|
|
Name: m.Name(),
|
|
|
|
Params: m.function.params,
|
|
|
|
Ret: m.function.ret,
|
|
|
|
Comment: m.function.comment,
|
2018-12-31 00:09:14 +09:00
|
|
|
}
|
|
|
|
}
|