From 8d1f4e86f3ff39aeeb3f499c3267a45b6c1bba19 Mon Sep 17 00:00:00 2001 From: Alexander Stanko Date: Tue, 21 Apr 2020 19:10:27 +0700 Subject: [PATCH] docgen: add package name to types --- docgen/docgen.go | 24 ++++++++++++++++---- docgen/docgen_test.go | 53 ++++++++++++++++++++++++++++++++++++++----- 2 files changed, 66 insertions(+), 11 deletions(-) diff --git a/docgen/docgen.go b/docgen/docgen.go index 12d77ae24..d13176a67 100644 --- a/docgen/docgen.go +++ b/docgen/docgen.go @@ -20,6 +20,7 @@ type TypeName string type Context struct { Variables map[Identifier]*Type `json:"variables"` Types map[TypeName]*Type `json:"types"` + pkgPath string } type Type struct { @@ -52,6 +53,7 @@ func CreateDoc(i interface{}) *Context { c := &Context{ Variables: make(map[Identifier]*Type), Types: make(map[TypeName]*Type), + pkgPath: dereference(reflect.TypeOf(i)).PkgPath(), } for name, t := range conf.CreateTypesTable(i) { @@ -102,9 +104,7 @@ func (c *Context) use(t reflect.Type, ops ...option) *Type { methods = append(methods, m) } - for t.Kind() == reflect.Ptr { - t = t.Elem() - } + t = dereference(t) // Only named types will have methods defined on them. // It maybe not even struct, but we gonna call then @@ -169,8 +169,12 @@ func (c *Context) use(t reflect.Type, ops ...option) *Type { } appendix: - name := TypeName(t.Name()) - anonymous := name == "" + + name := TypeName(t.String()) + if c.pkgPath == t.PkgPath() { + name = TypeName(t.Name()) + } + anonymous := t.Name() == "" a, ok := c.Types[name] @@ -219,3 +223,13 @@ func isPrivate(s string) bool { func isProtobuf(s string) bool { return strings.HasPrefix(s, "XXX_") } + +func dereference(t reflect.Type) reflect.Type { + if t == nil { + return nil + } + if t.Kind() == reflect.Ptr { + t = dereference(t.Elem()) + } + return t +} diff --git a/docgen/docgen_test.go b/docgen/docgen_test.go index 47a155556..82608e551 100644 --- a/docgen/docgen_test.go +++ b/docgen/docgen_test.go @@ -1,13 +1,13 @@ package docgen_test import ( - "github.com/stretchr/testify/require" - "math" - "testing" - . "github.com/antonmedv/expr/docgen" "github.com/sanity-io/litter" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "math" + "testing" + "time" ) type Tweet struct { @@ -21,6 +21,15 @@ type Env struct { MaxSize int32 } Env map[string]interface{} + // NOTE: conflicting type name + TimeWeekday time.Weekday + Weekday Weekday +} + +type Weekday int + +func (Weekday) String() string { + return "" } type Duration int @@ -64,6 +73,14 @@ func TestCreateDoc(t *testing.T) { }, Return: &Type{Kind: "struct", Name: "Duration"}, }, + "TimeWeekday": { + Name: "time.Weekday", + Kind: "struct", + }, + "Weekday": { + Name: "Weekday", + Kind: "struct", + }, }, Types: map[TypeName]*Type{ "Tweet": { @@ -85,6 +102,30 @@ func TestCreateDoc(t *testing.T) { }, }, }, + "time.Weekday": { + Kind: "struct", + Fields: map[Identifier]*Type{ + "String": { + Kind: "func", + Arguments: []*Type{}, + Return: &Type{ + Kind: "string", + }, + }, + }, + }, + "Weekday": { + Kind: "struct", + Fields: map[Identifier]*Type{ + "String": { + Kind: "func", + Arguments: []*Type{}, + Return: &Type{ + Kind: "string", + }, + }, + }, + }, }, } @@ -108,7 +149,7 @@ func TestCreateDoc_FromMap(t *testing.T) { Kind: "array", Type: &Type{ Kind: "struct", - Name: "Tweet", + Name: "docgen_test.Tweet", }, }, "Config": { @@ -127,7 +168,7 @@ func TestCreateDoc_FromMap(t *testing.T) { }, }, Types: map[TypeName]*Type{ - "Tweet": { + "docgen_test.Tweet": { Kind: "struct", Fields: map[Identifier]*Type{ "Size": {Kind: "int"},