Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 32 additions & 22 deletions common/enum/generictype/generictype.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,25 +174,31 @@ var Root = &GenericType{
kinds: []string{},
}

// genericTypeLookup provides fast mapping from reflect.Kind to GenericType.
var genericTypeLookup map[string]*GenericType
// lookupByKind provides lookups from reflect.Kind.String to GenericType.
var lookupByKind map[string]*GenericType

// init() initializes the genericTypeLookup map.
// lookupByType provides lookups from generic type string to GenericType.
var lookupByType map[string]*GenericType

// init() initializes the lookupByKind map.
func init() {
genericTypeLookup = map[string]*GenericType{}
pathDefaultLookup = map[string]string{}
lookupByKind = map[string]*GenericType{}
lookupByType = map[string]*GenericType{}

// mapTypes is a utility function to create map entries for the given GenericType.
mapTypes := func(t *GenericType) {
for _, k := range t.kinds {
// Panic if duplicate type mappings exist.
if genericTypeLookup[k] != nil {
panic(fmt.Sprintf("duplicate GenericType mapping for %q", t))
if lookupByKind[k] != nil {
panic(fmt.Sprintf("duplicate lookupByKind mapping for %q", k))
}
genericTypeLookup[k] = t
lookupByKind[k] = t
}

pathDefaultLookup[t.String()] = t.PathDefault()
if lookupByType[t.String()] != nil {
panic(fmt.Sprintf("duplicate lookupByType mapping for %q", t.String()))
}
lookupByType[t.String()] = t
}

mapTypes(Invalid)
Expand All @@ -210,11 +216,13 @@ func init() {

mapTypes(Interface)
mapTypes(Pointer)

mapTypes(Root)
}

// GenericTypeOf returns the GenericType of the given reflect.Value.
func GenericTypeOf(v reflect.Value) *GenericType {
if t := genericTypeLookup[v.Kind().String()]; t != nil {
if t := lookupByKind[v.Kind().String()]; t != nil {
if t == Invalid {
// Return invalid types immediately.
return t
Expand All @@ -223,7 +231,7 @@ func GenericTypeOf(v reflect.Value) *GenericType {
// Look for special types.
if v.Type().PkgPath() != "" {
fullPath := FullPathOf(v)
if specialType := genericTypeLookup[fullPath]; specialType != nil {
if specialType := lookupByKind[fullPath]; specialType != nil {
return specialType
}
}
Expand All @@ -242,6 +250,19 @@ func GenericTypeOf(v reflect.Value) *GenericType {
return Invalid
}

// FromType returns the GenericType associated with a given string or nil if not found.
func FromType(typeString string) *GenericType {
return lookupByType[typeString]
}

// PathDefaultOfType returns the path default for a given generic type string.
func PathDefaultOfType(typeString string) string {
if gt := FromType(typeString); gt != nil {
return gt.PathDefault()
}
return typeString
}

// FullPathOf returns the full package path for a Value.
func FullPathOf(v reflect.Value) string {
return fmt.Sprintf("%s.%s", v.Type().PkgPath(), v.Type().Name())
Expand All @@ -259,14 +280,3 @@ func tryConversion(v reflect.Value, t reflect.Type) (newValue reflect.Value, ok

return v.Convert(t), true
}

// pathDefaultLookup provides fast mapping from genericType.String to pathDefault
var pathDefaultLookup map[string]string

// PathDefaultOfType returns the path default for a given generic type string.
func PathDefaultOfType(typeString string) string {
if p := pathDefaultLookup[typeString]; p != "" {
return p
}
return typeString
}
6 changes: 1 addition & 5 deletions common/types/typenode.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ type TypeNode struct {
Nullable bool `json:",omitempty"`

// Generic type of element.
TypeCategory string
Type string
Type string

// TypeRef holds the name of a type (e.g. struct)
TypeRef string `json:",omitempty"`
Expand Down Expand Up @@ -69,7 +68,6 @@ func NewRootNode(name, dialect string) *TypeNode {
r := NewTypeNode(name, dialect)

r.Type = generictype.Root.String()
r.TypeCategory = generictype.Root.Category().String()

return r
}
Expand Down Expand Up @@ -194,7 +192,6 @@ func (t *TypeNode) Copy() *TypeNode {
n.Parent = nil
n.Description = t.Description
n.Type = t.Type
n.TypeCategory = t.TypeCategory
n.TypeRef = t.TypeRef
n.Error = t.Error
n.MetaKey = t.MetaKey
Expand Down Expand Up @@ -222,7 +219,6 @@ func (t *TypeNode) CopyWithoutNative() *TypeNode {
n.Parent = nil
n.Description = t.Description
n.Type = t.Type
n.TypeCategory = t.TypeCategory
n.TypeRef = t.TypeRef
n.Error = t.Error
n.MetaKey = t.MetaKey
Expand Down
17 changes: 9 additions & 8 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,6 @@ package main
import (
"encoding/json"
"fmt"
"github.com/ghodss/yaml"
"github.com/gitmann/b9schema-golang/common/util"
"github.com/gitmann/b9schema-golang/fixtures"
"github.com/gitmann/b9schema-golang/reflector"
"github.com/gitmann/b9schema-golang/renderer"
"github.com/gitmann/b9schema-golang/renderer/openapi"
"github.com/gitmann/b9schema-golang/renderer/simple"
"io"
"os"
"os/exec"
Expand All @@ -18,6 +11,14 @@ import (
"testing"
"time"
"unsafe"

"github.com/ghodss/yaml"
"github.com/gitmann/b9schema-golang/common/util"
"github.com/gitmann/b9schema-golang/fixtures"
"github.com/gitmann/b9schema-golang/reflector"
"github.com/gitmann/b9schema-golang/renderer"
"github.com/gitmann/b9schema-golang/renderer/openapi"
"github.com/gitmann/b9schema-golang/renderer/simple"
)

const (
Expand Down Expand Up @@ -3186,7 +3187,7 @@ func validateOpenAPI(t *testing.T, name, yamlStr string) bool {
}

if err := cmd.Start(); err != nil {
t.Errorf("TEST_FAIL %s: cmd start err=%s", name, err)
t.Errorf("TEST_FAIL %s: cmd start err=%s\nIs swagger-cli installed? 'npm install -g @apidevtools/swagger-cli'", name, err)
return false
}

Expand Down
1 change: 0 additions & 1 deletion reflector/reflector.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ func (r *Reflector) reflectTypeImpl(ancestorTypeRef types.AncestorTypeRef, curre
// Get generic type for value.
genericType := generictype.GenericTypeOf(v)
currentElem.Type = genericType.String()
currentElem.TypeCategory = genericType.Category().String()

// ERROR CHECKING
// Check for invalid types. These may panic on some operations so we exit quickly with minimal reflection.
Expand Down
8 changes: 6 additions & 2 deletions renderer/simple/simple.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,12 @@ func (r *SimpleRenderer) Path(t *types.TypeNode) []string {
}

// Type.
var typePart string
if t.TypeCategory == typecategory.Invalid.String() {
var typePart, typeCategory string
if gt := generictype.FromType(t.Type); gt != nil {
typeCategory = gt.Category().String()
}

if typeCategory == typecategory.Invalid.String() {
typePart = t.Type
} else {
typePart = generictype.PathDefaultOfType(t.Type)
Expand Down