5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-02 05:11:29 +08:00

Merge remote-tracking branch 'origin/feature/v3-parser' into feature/v3-parser

This commit is contained in:
Lea Anthony 2023-02-28 20:35:39 +11:00
commit 8dc8c8e15e
5 changed files with 226 additions and 0 deletions

View File

@ -1,5 +1,45 @@
package parser
import (
"io"
"text/template"
)
type ModelDefinitions struct {
Package string
Models map[string]*StructDef
}
func GenerateModel(wr io.Writer, def *ModelDefinitions) error {
tmpl, err := template.New("model.ts.tmpl").ParseFiles("templates/model.ts.tmpl")
if err != nil {
println("Unable to create class template: " + err.Error())
return err
}
err = tmpl.ExecuteTemplate(wr, "model.ts.tmpl", def)
if err != nil {
println("Problem executing template: " + err.Error())
return err
}
return nil
}
//func GenerateClass(wr io.Writer, def *StructDef) error {
// tmpl, err := template.New("class.ts.tmpl").ParseFiles("templates/class.ts.tmpl")
// if err != nil {
// println("Unable to create class template: " + err.Error())
// return err
// }
//
// err = tmpl.ExecuteTemplate(wr, "class.ts.tmpl", def)
// if err != nil {
// println("Problem executing template: " + err.Error())
// return err
// }
// return nil
//}
//
//import (
// "bytes"

View File

@ -0,0 +1,133 @@
package parser
import (
"github.com/google/go-cmp/cmp"
"strings"
"testing"
)
const expected = `
export namespace main {
export class Person {
name: string;
parent: Person;
details: anon1;
address: package.Address;
static createFrom(source: any = {}) {
return new Person(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) {
source = JSON.parse(source);
}
this.name = source["name"]
this.parent = source["parent"]
this.details = source["details"]
this.address = source["address"]
}
}
export class anon1 {
age: int;
address: string;
static createFrom(source: any = {}) {
return new anon1(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) {
source = JSON.parse(source);
}
this.age = source["age"]
this.address = source["address"]
}
}
}
`
func TestGenerateClass(t *testing.T) {
person := StructDef{
Name: "Person",
Fields: []*Field{
{
Name: "Name",
Type: &ParameterType{
Name: "string",
},
},
{
Name: "Parent",
Type: &ParameterType{
Name: "Person",
IsStruct: true,
IsPointer: true,
Package: "main",
},
},
{
Name: "Details",
Type: &ParameterType{
Name: "anon1",
IsStruct: true,
Package: "main",
},
},
{
Name: "Address",
Type: &ParameterType{
Name: "Address",
IsStruct: true,
IsPointer: true,
Package: "github.com/some/other/package",
},
},
},
}
anon1 := StructDef{
Name: "anon1",
Fields: []*Field{
{
Name: "Age",
Type: &ParameterType{
Name: "int",
},
},
{
Name: "Address",
Type: &ParameterType{
Name: "string",
},
},
},
}
var builder strings.Builder
models := make(map[string]*StructDef)
models["Person"] = &person
models["anon1"] = &anon1
def := ModelDefinitions{
Package: "main",
Models: models,
}
err := GenerateModel(&builder, &def)
if err != nil {
t.Fatal(err)
}
text := builder.String()
println("Built string")
println(text)
if diff := cmp.Diff(expected, text); diff != "" {
t.Errorf("GenerateClass() failed:\n" + diff)
}
}

View File

@ -11,6 +11,7 @@ import (
"path/filepath"
"reflect"
"strconv"
"strings"
)
type packagePath = string
@ -49,6 +50,21 @@ type Field struct {
Type *ParameterType
}
func (f *Field) JSName() string {
return strings.ToLower(f.Name[0:1]) + f.Name[1:]
}
func (f *Field) JSDef(pkg string) string {
name := f.JSName()
if f.Type.Package == "" || f.Type.Package == pkg {
return fmt.Sprintf("%s: %s;", name, f.Type.Name)
}
parts := strings.Split(f.Type.Package, "/")
return fmt.Sprintf("%s: %s.%s;", name, parts[len(parts)-1], f.Type.Name)
}
type ParsedPackage struct {
Pkg *ast.Package
Name string

View File

@ -0,0 +1,16 @@
export class {{.Name}} {
{{range .Fields}}{{.}}
{{end}}
static createFrom(source: any = {}) {
return new {{.Name}}(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) {
source = JSON.parse(source);
}
{{range .Fields}}this.{{jsName .}} = source["{{jsName .}}"]
{{end}}
}
}

View File

@ -0,0 +1,21 @@
{{$pkg := .Package}}
export namespace {{.Package}} {
{{range $name, $def := .Models}}
export class {{$def.Name}} {
{{range $def.Fields}}{{.JSDef $pkg}}
{{end}}
static createFrom(source: any = {}) {
return new {{$def.Name}}(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) {
source = JSON.parse(source);
}
{{range $def.Fields}}this.{{.JSName}} = source["{{.JSName}}"]
{{end}}
}
}
{{end}}
}