5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-04 02:51:56 +08:00
wails/v2/pkg/parser/parser.go
Lea Anthony 62374b9b53
Js package generation (#554)
* WIP

* Generation of index.js

* Add RelativeToCwd

* Add JSDoc comments

* Convert to ES6 syntax

* Fix typo

* Initial generation of typescript declarations

* Typescript improvements

* Improved @returns jsdoc

* Improved declaration files

* Simplified output

* Rename file

* Tidy up

* Revert "Simplified output"

This reverts commit 15cdf7382b.

* Now parsing actual code

* Support Array types

* Reimagined parser

* Wrap parsing in Parser

* Rewritten module generator (TS Only)

* Final touches

* Slight refactor to improve output

* Struct comments. External struct literal binding

* Reworked project parser *working*

* remove debug info

* Refactor of parser

* remove the spew

* Better Ts support

* Better project generation logic

* Support local functions in bind()

* JS Object generation. Linting.

* Support json tags in module generation

* Updated mod files

* Support vscode file generation

* Better global.d.ts

* add ts-check to templates

* Support TS declaration files

* improved 'generate' command for module
2020-11-15 09:25:38 +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
}