Files
wails/v2/pkg/parser/parser.go
2020-11-14 13:52:01 +11:00

123 lines
2.4 KiB
Go

// Package parser provides the ability to parse the data that is bound in Wails projects.
// Using this, it can also generate a Javascript module that represents the DTOs used, as
// well as providing wrappers for bound methods.
package parser
import (
"go/token"
"github.com/pkg/errors"
"golang.org/x/tools/go/packages"
)
// Parser is the Wails project parser
type Parser struct {
// Placeholders for Go's parser
fileSet *token.FileSet
// The packages we parse
// The map key is the package ID
packages map[string]*Package
}
// NewParser creates a new Wails project parser
func NewParser() *Parser {
return &Parser{
fileSet: token.NewFileSet(),
packages: make(map[string]*Package),
}
}
// ParseProject will parse the Wails project in the given directory
func (p *Parser) ParseProject(dir string) error {
var err error
err = p.loadPackages(dir)
if err != nil {
return err
}
// Find all the bound structs
for _, pkg := range p.packages {
err = p.findBoundStructs(pkg)
if err != nil {
return err
}
}
// Parse the structs
for _, pkg := range p.packages {
err = p.parseBoundStructs(pkg)
if err != nil {
return err
}
}
// Resolve package names
// We do this because some packages may have the same name
p.resolvePackageNames()
return nil
}
func (p *Parser) loadPackages(projectPath string) error {
mode := packages.NeedName |
packages.NeedFiles |
packages.NeedSyntax |
packages.NeedTypes |
packages.NeedImports |
packages.NeedTypesInfo |
packages.NeedModule
cfg := &packages.Config{Fset: p.fileSet, Mode: mode, Dir: projectPath}
pkgs, err := packages.Load(cfg, "./...")
if err != nil {
return errors.Wrap(err, "Problem loading packages")
}
// Check for errors
var parseError error
for _, pkg := range pkgs {
for _, err := range pkg.Errors {
if parseError == nil {
parseError = errors.New(err.Error())
} else {
parseError = errors.Wrap(parseError, err.Error())
}
}
}
if parseError != nil {
return parseError
}
// Create a map of packages
for _, pkg := range pkgs {
p.packages[pkg.ID] = newPackage(pkg)
}
return nil
}
func (p *Parser) getPackageByID(id string) *Package {
return p.packages[id]
}
func (p *Parser) packagesToGenerate() []*Package {
var result []*Package
for _, pkg := range p.packages {
if pkg.ShouldGenerate() {
result = append(result, pkg)
}
}
return result
}
type ParserReport struct {
Packages []*Package
}