Add generate constants tool

This commit is contained in:
Lea Anthony 2023-09-13 16:45:19 +10:00
commit c1d85bd3d9
No known key found for this signature in database
GPG key ID: 33DAF7BB90A58405
4 changed files with 135 additions and 0 deletions

View file

@ -41,6 +41,7 @@ func main() {
generate.NewSubCommandFunction("icons", "Generate icons", commands.GenerateIcons)
generate.NewSubCommandFunction("syso", "Generate Windows .syso file", commands.GenerateSyso)
generate.NewSubCommandFunction("bindings", "Generate bindings + models", commands.GenerateBindings)
generate.NewSubCommandFunction("constants", "Generate JS constants from Go", commands.GenerateConstants)
plugin := app.NewSubCommand("plugin", "Plugin tools")
//plugin.NewSubCommandFunction("list", "List plugins", commands.PluginList)
plugin.NewSubCommandFunction("init", "Initialise a new plugin", commands.PluginInit)

View file

@ -0,0 +1,25 @@
package commands
import (
"github.com/wailsapp/wails/v3/internal/parser"
"os"
)
type GenerateConstantsOptions struct {
ConstantsFilename string `name:"f" description:"The filename for the models file" default:"constants.go"`
OutputFilename string `name:"o" description:"The output file" default:"constants.js"`
}
func GenerateConstants(options *GenerateConstantsOptions) error {
goData, err := os.ReadFile(options.ConstantsFilename)
if err != nil {
return err
}
result, err := parser.GenerateConstants(goData)
if err != nil {
return err
}
return os.WriteFile(options.OutputFilename, []byte(result), 0644)
}

View file

@ -0,0 +1,54 @@
package parser
import (
"fmt"
"go/ast"
"go/parser"
"go/token"
"strings"
)
func GenerateConstants(goData []byte) (string, error) {
// Create a new token file set and parser
fs := token.NewFileSet()
f, err := parser.ParseFile(fs, "", goData, parser.AllErrors)
if err != nil {
return "", err
}
// Extract constant declarations and generate JavaScript constants
var jsConstants []string
for _, decl := range f.Decls {
if gd, ok := decl.(*ast.GenDecl); ok && gd.Tok == token.CONST {
for _, spec := range gd.Specs {
if vs, ok := spec.(*ast.ValueSpec); ok {
for i, name := range vs.Names {
value := vs.Values[i]
if value != nil {
jsConstants = append(jsConstants, fmt.Sprintf("export const %s = %s;", name.Name, jsValue(value)))
}
}
}
}
}
}
// Join the JavaScript constants into a single string
jsCode := strings.Join(jsConstants, "\n")
return jsCode, nil
}
func jsValue(expr ast.Expr) string {
// Implement conversion from Go constant value to JavaScript value here.
// You can add more cases for different types if needed.
switch e := expr.(type) {
case *ast.BasicLit:
return e.Value
case *ast.Ident:
return e.Name
default:
return ""
}
}

View file

@ -0,0 +1,55 @@
package parser
import "testing"
func TestGenerateConstants(t *testing.T) {
tests := []struct {
name string
goData []byte
want string
wantErr bool
}{
{
name: "int",
goData: []byte(`package test
const one = 1`),
want: "export const one = 1;",
wantErr: false,
},
{
name: "float",
goData: []byte(`package test
const one_point_five = 1.5`),
want: "export const one_point_five = 1.5;",
wantErr: false,
},
{
name: "string",
goData: []byte(`package test
const one_as_a_string = "1"`),
want: `export const one_as_a_string = "1";`,
wantErr: false,
},
{
name: "nested",
goData: []byte(`package test
const (
one_as_a_string = "1"
)`),
want: `export const one_as_a_string = "1";`,
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := GenerateConstants(tt.goData)
if (err != nil) != tt.wantErr {
t.Errorf("GenerateConstants() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("GenerateConstants() got = %v, want %v", got, tt.want)
}
})
}
}