5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-02 05:11:29 +08:00
wails/v3/internal/parser/models.go
2023-01-18 21:42:49 +11:00

96 lines
2.6 KiB
Go

package parser
import (
"bytes"
"fmt"
"go/ast"
"go/types"
"sort"
"strings"
"unicode"
)
func GenerateModels(context *Context) ([]byte, error) {
var buf bytes.Buffer
var pkgs []Package
specs := context.GetBoundStructs()
for pkg, pkgSpecs := range specs {
pkgs = append(pkgs, Package{Name: pkg, Specs: pkgSpecs})
}
knownStructs := newAllModels(specs)
sort.Slice(pkgs, func(i, j int) bool { return pkgs[i].Name < pkgs[j].Name })
for _, pkg := range pkgs {
if _, err := fmt.Fprintf(&buf, "namespace %s {\n", pkg.Name); err != nil {
return nil, err
}
sort.Slice(pkg.Specs, func(i, j int) bool { return pkg.Specs[i].Name.Name < pkg.Specs[j].Name.Name })
for _, spec := range pkg.Specs {
if structType, ok := spec.Type.(*ast.StructType); ok {
if _, err := fmt.Fprintf(&buf, " class %s {\n", spec.Name.Name); err != nil {
return nil, err
}
for _, field := range structType.Fields.List {
// Ignore field names that have a lower case first letter
if !unicode.IsUpper(rune(field.Names[0].Name[0])) {
continue
}
// Get the Go type of the field
goType := types.ExprString(field.Type)
// Check if the type is an array
if arrayType, ok := field.Type.(*ast.ArrayType); ok {
// Get the element type of the array
elementType := types.ExprString(arrayType.Elt)
// Look up the corresponding TypeScript type
tsType, ok := goToTS[elementType]
if !ok {
// strip off the * prefix if it is there
if strings.HasPrefix(elementType, "*") {
elementType = elementType[1:]
}
if knownStructs.exists(elementType) {
tsType = elementType
} else {
tsType = "any"
}
}
// Output the field as an array of the corresponding TypeScript type
if _, err := fmt.Fprintf(&buf, " %s: %s[];\n", field.Names[0].Name, tsType); err != nil {
return nil, err
}
} else {
// strip off the * prefix if it is there
if strings.HasPrefix(goType, "*") {
goType = goType[1:]
}
// Look up the corresponding TypeScript type
tsType, ok := goToTS[goType]
if !ok {
if knownStructs.exists(goType) {
tsType = goType
} else {
tsType = "any"
}
}
// Output the field as the corresponding TypeScript type
if _, err := fmt.Fprintf(&buf, " %s: %s;\n", field.Names[0].Name, tsType); err != nil {
return nil, err
}
}
}
if _, err := fmt.Fprintf(&buf, " }\n"); err != nil {
return nil, err
}
}
}
if _, err := fmt.Fprintf(&buf, "}\n\n"); err != nil {
return nil, err
}
}
return buf.Bytes(), nil
}