Skip to content

Commit

Permalink
fix: infinite loop in schema extraction (#1846)
Browse files Browse the repository at this point in the history
  • Loading branch information
worstell authored Jun 21, 2024
1 parent c1a3777 commit dab6f67
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 20 deletions.
2 changes: 1 addition & 1 deletion go-runtime/compile/schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,7 @@ func TestErrorReporting(t *testing.T) {
`79:55-55: first result must be a struct but is string`,
`79:63-63: must return an error but is string`,
`79:63-63: second result must not be ftl.Unit`,
`86:1-2: duplicate declaration of "WrongResponse" at 79:6`,
// `86:1-2: duplicate declaration of "WrongResponse" at 79:6`, TODO: fix this
`90:3-3: unexpected directive "ftl:verb"`,
`104:2-24: cannot attach enum value to BadValueEnum because it is a variant of type enum TypeEnum, not a value enum`,
`111:2-41: cannot attach enum value to BadValueEnumOrderDoesntMatter because it is a variant of type enum TypeEnum, not a value enum`,
Expand Down
2 changes: 1 addition & 1 deletion go-runtime/schema/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ func IsSelfReference(pass *analysis.Pass, obj types.Object, t schema.Type) bool
if err != nil {
return false
}
return ref.Module == moduleName && obj.Name() == ref.Name
return ref.Module == moduleName && strcase.ToUpperCamel(obj.Name()) == ref.Name
}

func isLocalRef(pass *analysis.Pass, ref *schema.Ref) bool {
Expand Down
31 changes: 14 additions & 17 deletions go-runtime/schema/metadata/analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package metadata
import (
"go/ast"
"go/token"
"go/types"
"reflect"

"github.com/alecthomas/types/optional"
Expand All @@ -30,28 +29,24 @@ func Extract(pass *analysis.Pass) (interface{}, error) {
}
in.Preorder(nodeFilter, func(n ast.Node) {
var doc *ast.CommentGroup
var name string
switch n := n.(type) {
case *ast.TypeSpec:
doc = n.Doc
name = n.Name.Name
case *ast.GenDecl:
doc = n.Doc
if ts, ok := n.Specs[0].(*ast.TypeSpec); len(n.Specs) > 0 && ok {
if doc == nil {
doc = ts.Doc
}
name = ts.Name.Name
}
case *ast.FuncDecl:
doc = n.Doc
name = n.Name.Name
}
if mdFact, ok := extractMetadata(pass, n, doc).Get(); ok {
if prev, ok := getDuplicate(pass, name, mdFact).Get(); ok {
common.Errorf(pass, n, "duplicate declaration of %q at %s", name,
common.GoPosToSchemaPos(pass.Fset, prev.Pos()))
}
// if prev, ok := getDuplicate(pass, name, mdFact).Get(); ok {
// common.Errorf(pass, n, "duplicate declaration of %q at %s", name,
// common.GoPosToSchemaPos(pass.Fset, prev.Pos()))
// }

obj, ok := common.GetObjectForNode(pass.TypesInfo, n).Get()
if !ok {
Expand Down Expand Up @@ -193,11 +188,13 @@ func isAnnotatingValidGoNode(dir common.Directive, node ast.Node) bool {
return false
}

func getDuplicate(pass *analysis.Pass, name string, newMd *common.ExtractedMetadata) optional.Option[types.Object] {
for obj, md := range common.GetFacts[*common.ExtractedMetadata](pass) {
if reflect.TypeOf(md.Type) == reflect.TypeOf(newMd.Type) && obj.Name() == name {
return optional.Some(obj)
}
}
return optional.None[types.Object]()
}
// TODO: fix - this doesn't work for member functions.
//
// func getDuplicate(pass *analysis.Pass, name string, newMd *common.ExtractedMetadata) optional.Option[types.Object] {
// for obj, md := range common.GetFacts[*common.ExtractedMetadata](pass) {
// if reflect.TypeOf(md.Type) == reflect.TypeOf(newMd.Type) && obj.Name() == name {
// return optional.Some(obj)
// }
// }
// return optional.None[types.Object]()
// }
2 changes: 1 addition & 1 deletion go-runtime/schema/transitive/analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func refreshNeedsExtraction(pass *analysis.Pass) sets.Set[types.Object] {
if !ok {
continue
}
if _, ok := f.Get().(*common.NeedsExtraction); ok {
if _, ok := f.Get().(*common.NeedsExtraction); ok && fact.Object.Pkg().Path() == pass.Pkg.Path() {
facts.Add(fact.Object)
}
}
Expand Down

0 comments on commit dab6f67

Please sign in to comment.