Files
wails/v2/pkg/parser/parseStruct.go
2020-11-07 07:03:04 +11:00

94 lines
2.2 KiB
Go

package parser
import (
"go/ast"
)
// getCachedStruct attempts to get an already parsed struct from the
// struct cache
func (p *Parser) getCachedStruct(packageName string, structName string) *Struct {
fqn := packageName + "." + structName
return p.parsedStructs[fqn]
}
// ParseStruct will attempt to parse the given struct using
// the package it references
func (p *Parser) ParseStruct(packageName string, structName string) (*Struct, error) {
// Check the cache
result := p.getCachedStruct(packageName, structName)
if result != nil {
return result, nil
}
// Find the package
pkg := p.getPackageByName(packageName)
if pkg == nil {
// TODO: Find package via imports?
println("Cannot find package", packageName)
return nil, nil
}
// Iterate through the whole package looking for the bound structs
for _, fileAst := range pkg.Syntax {
// Track errors
var parseError error
ast.Inspect(fileAst, func(n ast.Node) bool {
if genDecl, ok := n.(*ast.GenDecl); ok {
for _, spec := range genDecl.Specs {
if typeSpec, ok := spec.(*ast.TypeSpec); ok {
if structType, ok := typeSpec.Type.(*ast.StructType); ok {
structDefinitionName := typeSpec.Name.Name
if structDefinitionName == structName {
// Create the new struct
result = p.newStruct(pkg, structDefinitionName)
// Save comments
result.Comments = p.parseComments(genDecl.Doc)
parseError = p.parseStructMethods(result)
if parseError != nil {
return false
}
// Parse the struct fields
parseError = p.parseStructFields(structType, result)
// Cache this struct
key := result.FullyQualifiedName()
p.parsedStructs[key] = result
return false
}
}
}
}
}
return true
})
// If we got an error, return it
if parseError != nil {
return nil, parseError
}
}
return result, nil
}
func (p *Parser) parseStructFields(structType *ast.StructType, boundStruct *Struct) error {
// Parse the fields
for _, field := range structType.Fields.List {
fields, err := p.parseField(field, boundStruct.Package.Name)
if err != nil {
return err
}
boundStruct.Fields = append(boundStruct.Fields, fields...)
}
return nil
}