Skip to content

Commit

Permalink
Properly support enums
Browse files Browse the repository at this point in the history
  • Loading branch information
VojtechVitek committed Sep 1, 2023
1 parent b761d1a commit 54d3296
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 44 deletions.
5 changes: 1 addition & 4 deletions internal/parser/enums.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,11 @@ import (
// // new = 3
// type Status gospeak.Enum[int]
func (p *Parser) CollectEnums() error {

debug := spew.NewDefaultConfig()
debug.DisableMethods = true
debug.DisablePointerAddresses = true
debug.Indent = "\t"
debug.SortKeys = true
//panic(debug.Sdump(p.Pkg.Syntax))

gospeakImportFound := false
for _, file := range p.Pkg.Syntax {
Expand All @@ -49,8 +47,6 @@ func (p *Parser) CollectEnums() error {
if typeDeclaration, ok := decl.(*ast.GenDecl); ok && typeDeclaration.Tok == token.TYPE {
for _, spec := range typeDeclaration.Specs {
if typeSpec, ok := spec.(*ast.TypeSpec); ok {
//panic(debug.Sdump(typeSpec))

selExpr, ok := typeSpec.Type.(*ast.SelectorExpr)
if !ok {
continue
Expand Down Expand Up @@ -108,6 +104,7 @@ func (p *Parser) CollectEnums() error {
}

p.Schema.Types = append(p.Schema.Types, enumType)
p.ParsedEnumTypes[fmt.Sprintf("%v.%v", p.Pkg.PkgPath, enumName)] = enumType
}
}
}
Expand Down
17 changes: 14 additions & 3 deletions internal/parser/named.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ func (p *Parser) ParseNamedType(typeName string, typ types.Type) (varType *schem
}
}

if enum, ok := p.ParsedEnumTypes[typ.String()]; ok {
fmt.Printf("%#v", enum.Name)
// TODO(webrpc): Currently, the enum.Type holds the underlying backend
// type (ie. int64) but instead we want the "string" type in JSON.
return &schema.VarType{
Expr: enum.Name,
Type: schema.T_String,
}, nil
}

// If the type implements encoding.TextMarshaler, it's a string.
if isTextMarshaler(v, pkg) {
return &schema.VarType{
Expand Down Expand Up @@ -85,9 +95,10 @@ func (p *Parser) ParseNamedType(typeName string, typ types.Type) (varType *schem
}

var elem types.Type
// = u.Elem().Underlying()
// NOTE: Calling the above assignment fails to build with this error:
// "u.Elem undefined (type types.Type has no field or method Elem)"
// NOTE: As of Go 1.21, the following assignment
// var elem types.Type = u.Elem().Underlying()
// fails with syntax error:
// "u.Elem undefined (type types.Type has no field or method Elem)"
// even though both *types.Slice and *types.Array have the .Elem() method.
switch underlyingElem := u.(type) {
case *types.Slice:
Expand Down
27 changes: 24 additions & 3 deletions internal/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ import (
type Parser struct {
Schema *schema.WebRPCSchema

// Cache for already parsed types, to improve performance & so we can traverse circular dependencies.
ParsedTypes map[types.Type]*schema.VarType
ParsedTypeNames map[string]struct{}
// Cache parsed types to improve performance and so we can traverse circular dependencies.
ParsedTypes map[types.Type]*schema.VarType

ParsedEnumTypes map[string]*schema.Type // Helps lookup enum types by pkg easily.

InlineMode bool // When traversing `json:",inline"`, we don't want to store the struct type as WebRPC message.
ImportedPaths map[string]struct{}
Expand All @@ -25,3 +26,23 @@ type Parser struct {

Pkg *packages.Package
}

func New(pkg *packages.Package) *Parser {
return &Parser{
Schema: &schema.WebRPCSchema{
WebrpcVersion: "v1",
SchemaName: "",
SchemaVersion: "",
},
SchemaPkgName: pkg.PkgPath,
ParsedTypes: map[types.Type]*schema.VarType{},
Pkg: pkg,
ParsedEnumTypes: map[string]*schema.Type{},

// TODO: Change this to map[*types.Package]string so we can rename duplicated pkgs?
ImportedPaths: map[string]struct{}{
// Initial schema file's package name artificially set by golang.org/x/tools/go/packages.
"command-line-arguments": {},
},
}
}
20 changes: 3 additions & 17 deletions internal/parser/test/struct_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,23 +133,9 @@ func testParser(srcCode string) (*parser.Parser, error) {

_, _ = gospeak.CollectInterfaces(pkg)

p := &parser.Parser{
Schema: &schema.WebRPCSchema{
WebrpcVersion: "v1",
SchemaName: "TestAPI",
SchemaVersion: "v0.0.1",
},
SchemaPkgName: pkg.PkgPath,
ParsedTypes: map[types.Type]*schema.VarType{},
ParsedTypeNames: map[string]struct{}{},
Pkg: pkg,

// TODO: Change this to map[*types.Package]string so we can rename duplicated pkgs?
ImportedPaths: map[string]struct{}{
// Initial Schema file's package name artificially set by golang.org/x/tools/go/packages.
"command-line-arguments": {},
},
}
p := parser.New(pkg)
p.Schema.SchemaName = "TestAPI"
p.Schema.SchemaVersion = "v0.0.1"

return p, nil
}
Expand Down
19 changes: 2 additions & 17 deletions parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,23 +101,8 @@ func Parse(filePath string) ([]*Target, error) {
}

// Miss.
p := &parser.Parser{
Schema: &schema.WebRPCSchema{
WebrpcVersion: "v1",
SchemaName: target.InterfaceName,
SchemaVersion: "vTODO",
},
SchemaPkgName: pkg.PkgPath,
ParsedTypes: map[types.Type]*schema.VarType{},
ParsedTypeNames: map[string]struct{}{},
Pkg: pkg,

// TODO: Change this to map[*types.Package]string so we can rename duplicated pkgs?
ImportedPaths: map[string]struct{}{
// Initial schema file's package name artificially set by golang.org/x/tools/go/packages.
"command-line-arguments": {},
},
}
p := parser.New(pkg)
p.Schema.SchemaName = target.InterfaceName

if err := p.CollectEnums(); err != nil {
return nil, fmt.Errorf("collecting enums: %w", err)
Expand Down

0 comments on commit 54d3296

Please sign in to comment.