mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-03 06:51:26 +08:00
fix: blank namespaces, unknown structs
This commit is contained in:
parent
dce5fd442f
commit
43f8a1f773
@ -84,29 +84,34 @@ func (b *Bindings) ToJSON() (string, error) {
|
|||||||
func (b *Bindings) WriteModels(modelsDir string) error {
|
func (b *Bindings) WriteModels(modelsDir string) error {
|
||||||
models := map[string]string{}
|
models := map[string]string{}
|
||||||
var seen slicer.StringSlicer
|
var seen slicer.StringSlicer
|
||||||
|
allStructNames := b.getAllStructNames()
|
||||||
for packageName, structsToGenerate := range b.structsToGenerateTS {
|
for packageName, structsToGenerate := range b.structsToGenerateTS {
|
||||||
thisPackageCode := ""
|
thisPackageCode := ""
|
||||||
|
w := typescriptify.New()
|
||||||
|
w.Namespace = packageName
|
||||||
|
w.WithBackupDir("")
|
||||||
|
w.KnownStructs = allStructNames
|
||||||
for structName, structInterface := range structsToGenerate {
|
for structName, structInterface := range structsToGenerate {
|
||||||
fqstructname := packageName + "." + structName
|
fqstructname := packageName + "." + structName
|
||||||
if seen.Contains(fqstructname) {
|
if seen.Contains(fqstructname) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
w := typescriptify.New()
|
|
||||||
w.Namespace = packageName
|
|
||||||
w.WithBackupDir("")
|
|
||||||
w.Add(structInterface)
|
w.Add(structInterface)
|
||||||
str, err := w.Convert(nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
thisPackageCode += str
|
|
||||||
seen.AddSlice(w.GetGeneratedStructs())
|
|
||||||
}
|
}
|
||||||
|
str, err := w.Convert(nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
thisPackageCode += str
|
||||||
|
seen.AddSlice(w.GetGeneratedStructs())
|
||||||
models[packageName] = thisPackageCode
|
models[packageName] = thisPackageCode
|
||||||
}
|
}
|
||||||
|
|
||||||
var modelsData bytes.Buffer
|
var modelsData bytes.Buffer
|
||||||
for packageName, modelData := range models {
|
for packageName, modelData := range models {
|
||||||
|
if strings.TrimSpace(modelData) == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
modelsData.WriteString("export namespace " + packageName + " {\n")
|
modelsData.WriteString("export namespace " + packageName + " {\n")
|
||||||
sc := bufio.NewScanner(strings.NewReader(modelData))
|
sc := bufio.NewScanner(strings.NewReader(modelData))
|
||||||
for sc.Scan() {
|
for sc.Scan() {
|
||||||
@ -156,17 +161,55 @@ func (b *Bindings) AddStructToGenerateTS(packageName string, structName string,
|
|||||||
sName := strings.Split(fqname, ".")[1]
|
sName := strings.Split(fqname, ".")[1]
|
||||||
pName := getPackageName(fqname)
|
pName := getPackageName(fqname)
|
||||||
a := reflect.New(field.Type)
|
a := reflect.New(field.Type)
|
||||||
s := reflect.Indirect(a).Interface()
|
if b.hasExportedJSONFields(field.Type) {
|
||||||
b.AddStructToGenerateTS(pName, sName, s)
|
s := reflect.Indirect(a).Interface()
|
||||||
|
b.AddStructToGenerateTS(pName, sName, s)
|
||||||
|
}
|
||||||
} else if kind == reflect.Ptr && field.Type.Elem().Kind() == reflect.Struct {
|
} else if kind == reflect.Ptr && field.Type.Elem().Kind() == reflect.Struct {
|
||||||
fqname := field.Type.String()
|
fqname := field.Type.String()
|
||||||
sName := strings.Split(fqname, ".")[1]
|
sName := strings.Split(fqname, ".")[1]
|
||||||
pName := getPackageName(fqname)
|
pName := getPackageName(fqname)
|
||||||
typ := field.Type.Elem()
|
typ := field.Type.Elem()
|
||||||
a := reflect.New(typ)
|
a := reflect.New(typ)
|
||||||
s := reflect.Indirect(a).Interface()
|
if b.hasExportedJSONFields(typ) {
|
||||||
b.AddStructToGenerateTS(pName, sName, s)
|
s := reflect.Indirect(a).Interface()
|
||||||
|
b.AddStructToGenerateTS(pName, sName, s)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *Bindings) getAllStructNames() *slicer.StringSlicer {
|
||||||
|
var result slicer.StringSlicer
|
||||||
|
for packageName, structsToGenerate := range b.structsToGenerateTS {
|
||||||
|
for structName := range structsToGenerate {
|
||||||
|
result.Add(packageName + "." + structName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Bindings) hasExportedJSONFields(typeOf reflect.Type) bool {
|
||||||
|
for i := 0; i < typeOf.NumField(); i++ {
|
||||||
|
jsonFieldName := ""
|
||||||
|
f := typeOf.Field(i)
|
||||||
|
jsonTag := f.Tag.Get("json")
|
||||||
|
if len(jsonTag) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
jsonTagParts := strings.Split(jsonTag, ",")
|
||||||
|
if len(jsonTagParts) > 0 {
|
||||||
|
jsonFieldName = jsonTagParts[0]
|
||||||
|
}
|
||||||
|
for _, t := range jsonTagParts {
|
||||||
|
if t == "-" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if jsonFieldName != "" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
@ -3,6 +3,7 @@ package typescriptify
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/leaanthony/slicer"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
@ -97,7 +98,8 @@ type TypeScriptify struct {
|
|||||||
// throwaway, used when converting
|
// throwaway, used when converting
|
||||||
alreadyConverted map[string]bool
|
alreadyConverted map[string]bool
|
||||||
|
|
||||||
Namespace string
|
Namespace string
|
||||||
|
KnownStructs *slicer.StringSlicer
|
||||||
}
|
}
|
||||||
|
|
||||||
func New() *TypeScriptify {
|
func New() *TypeScriptify {
|
||||||
@ -134,7 +136,7 @@ func New() *TypeScriptify {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func deepFields(typeOf reflect.Type) []reflect.StructField {
|
func (t *TypeScriptify) deepFields(typeOf reflect.Type) []reflect.StructField {
|
||||||
fields := make([]reflect.StructField, 0)
|
fields := make([]reflect.StructField, 0)
|
||||||
|
|
||||||
if typeOf.Kind() == reflect.Ptr {
|
if typeOf.Kind() == reflect.Ptr {
|
||||||
@ -147,16 +149,20 @@ func deepFields(typeOf reflect.Type) []reflect.StructField {
|
|||||||
|
|
||||||
for i := 0; i < typeOf.NumField(); i++ {
|
for i := 0; i < typeOf.NumField(); i++ {
|
||||||
f := typeOf.Field(i)
|
f := typeOf.Field(i)
|
||||||
|
|
||||||
kind := f.Type.Kind()
|
kind := f.Type.Kind()
|
||||||
|
isPointer := kind == reflect.Ptr && f.Type.Elem().Kind() == reflect.Struct
|
||||||
if f.Anonymous && kind == reflect.Struct {
|
if f.Anonymous && kind == reflect.Struct {
|
||||||
//fmt.Println(v.Interface())
|
//fmt.Println(v.Interface())
|
||||||
fields = append(fields, deepFields(f.Type)...)
|
fields = append(fields, t.deepFields(f.Type)...)
|
||||||
} else if f.Anonymous && kind == reflect.Ptr && f.Type.Elem().Kind() == reflect.Struct {
|
} else if f.Anonymous && isPointer {
|
||||||
//fmt.Println(v.Interface())
|
//fmt.Println(v.Interface())
|
||||||
fields = append(fields, deepFields(f.Type.Elem())...)
|
fields = append(fields, t.deepFields(f.Type.Elem())...)
|
||||||
} else {
|
} else {
|
||||||
fields = append(fields, f)
|
// Check we have a json tag
|
||||||
|
jsonTag := t.getJSONFieldName(f, isPointer)
|
||||||
|
if jsonTag != "" {
|
||||||
|
fields = append(fields, f)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -348,7 +354,6 @@ func (t *TypeScriptify) Convert(customCode map[string]string) (string, error) {
|
|||||||
result += "\n" + strings.Trim(typeScriptCode, " "+t.Indent+"\r\n")
|
result += "\n" + strings.Trim(typeScriptCode, " "+t.Indent+"\r\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("t.structTypes: %+v\n", t.structTypes)
|
|
||||||
for _, strctTyp := range t.structTypes {
|
for _, strctTyp := range t.structTypes {
|
||||||
typeScriptCode, err := t.convertType(depth, strctTyp.Type, customCode)
|
typeScriptCode, err := t.convertType(depth, strctTyp.Type, customCode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -561,6 +566,10 @@ func (t *TypeScriptify) convertType(depth int, typeOf reflect.Type, customCode m
|
|||||||
if _, found := t.alreadyConverted[typeOf.String()]; found { // Already converted
|
if _, found := t.alreadyConverted[typeOf.String()]; found { // Already converted
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
fields := t.deepFields(typeOf)
|
||||||
|
if len(fields) == 0 {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
t.logf(depth, "Converting type %s", typeOf.String())
|
t.logf(depth, "Converting type %s", typeOf.String())
|
||||||
if strings.ContainsRune(typeOf.String(), '.') {
|
if strings.ContainsRune(typeOf.String(), '.') {
|
||||||
namespace := strings.Split(typeOf.String(), ".")[0]
|
namespace := strings.Split(typeOf.String(), ".")[0]
|
||||||
@ -589,7 +598,6 @@ func (t *TypeScriptify) convertType(depth int, typeOf reflect.Type, customCode m
|
|||||||
namespace: t.Namespace,
|
namespace: t.Namespace,
|
||||||
}
|
}
|
||||||
|
|
||||||
fields := deepFields(typeOf)
|
|
||||||
for _, field := range fields {
|
for _, field := range fields {
|
||||||
isPtr := field.Type.Kind() == reflect.Ptr
|
isPtr := field.Type.Kind() == reflect.Ptr
|
||||||
if isPtr {
|
if isPtr {
|
||||||
@ -620,7 +628,10 @@ func (t *TypeScriptify) convertType(depth int, typeOf reflect.Type, customCode m
|
|||||||
if typeScriptChunk != "" {
|
if typeScriptChunk != "" {
|
||||||
result = typeScriptChunk + "\n" + result
|
result = typeScriptChunk + "\n" + result
|
||||||
}
|
}
|
||||||
builder.AddStructField(jsonFieldName, field)
|
isKnownType := t.KnownStructs.Contains(getStructFQN(field.Type.String()))
|
||||||
|
println("KnownStructs:", t.KnownStructs.Join("\t"))
|
||||||
|
println(getStructFQN(field.Type.String()))
|
||||||
|
builder.AddStructField(jsonFieldName, field, !isKnownType)
|
||||||
} else if field.Type.Kind() == reflect.Map {
|
} else if field.Type.Kind() == reflect.Map {
|
||||||
t.logf(depth, "- map field %s.%s", typeOf.Name(), field.Name)
|
t.logf(depth, "- map field %s.%s", typeOf.Name(), field.Name)
|
||||||
// Also convert map key types if needed
|
// Also convert map key types if needed
|
||||||
@ -756,11 +767,11 @@ func (t *typeScriptClassBuilder) AddSimpleArrayField(fieldName string, field ref
|
|||||||
if len(fieldName) > 0 {
|
if len(fieldName) > 0 {
|
||||||
strippedFieldName := strings.ReplaceAll(fieldName, "?", "")
|
strippedFieldName := strings.ReplaceAll(fieldName, "?", "")
|
||||||
if len(opts.TSType) > 0 {
|
if len(opts.TSType) > 0 {
|
||||||
t.addField(fieldName, opts.TSType)
|
t.addField(fieldName, opts.TSType, false)
|
||||||
t.addInitializerFieldLine(strippedFieldName, fmt.Sprintf("source[\"%s\"]", strippedFieldName))
|
t.addInitializerFieldLine(strippedFieldName, fmt.Sprintf("source[\"%s\"]", strippedFieldName))
|
||||||
return nil
|
return nil
|
||||||
} else if len(typeScriptType) > 0 {
|
} else if len(typeScriptType) > 0 {
|
||||||
t.addField(fieldName, fmt.Sprint(typeScriptType, strings.Repeat("[]", arrayDepth)))
|
t.addField(fieldName, fmt.Sprint(typeScriptType, strings.Repeat("[]", arrayDepth)), false)
|
||||||
t.addInitializerFieldLine(strippedFieldName, fmt.Sprintf("source[\"%s\"]", strippedFieldName))
|
t.addInitializerFieldLine(strippedFieldName, fmt.Sprintf("source[\"%s\"]", strippedFieldName))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -779,7 +790,7 @@ func (t *typeScriptClassBuilder) AddSimpleField(fieldName string, field reflect.
|
|||||||
|
|
||||||
if len(typeScriptType) > 0 && len(fieldName) > 0 {
|
if len(typeScriptType) > 0 && len(fieldName) > 0 {
|
||||||
strippedFieldName := strings.ReplaceAll(fieldName, "?", "")
|
strippedFieldName := strings.ReplaceAll(fieldName, "?", "")
|
||||||
t.addField(fieldName, typeScriptType)
|
t.addField(fieldName, typeScriptType, false)
|
||||||
if opts.TSTransform == "" {
|
if opts.TSTransform == "" {
|
||||||
t.addInitializerFieldLine(strippedFieldName, fmt.Sprintf("source[\"%s\"]", strippedFieldName))
|
t.addInitializerFieldLine(strippedFieldName, fmt.Sprintf("source[\"%s\"]", strippedFieldName))
|
||||||
} else {
|
} else {
|
||||||
@ -795,26 +806,31 @@ func (t *typeScriptClassBuilder) AddSimpleField(fieldName string, field reflect.
|
|||||||
|
|
||||||
func (t *typeScriptClassBuilder) AddEnumField(fieldName string, field reflect.StructField) {
|
func (t *typeScriptClassBuilder) AddEnumField(fieldName string, field reflect.StructField) {
|
||||||
fieldType := field.Type.Name()
|
fieldType := field.Type.Name()
|
||||||
t.addField(fieldName, t.prefix+fieldType+t.suffix)
|
t.addField(fieldName, t.prefix+fieldType+t.suffix, false)
|
||||||
strippedFieldName := strings.ReplaceAll(fieldName, "?", "")
|
strippedFieldName := strings.ReplaceAll(fieldName, "?", "")
|
||||||
t.addInitializerFieldLine(strippedFieldName, fmt.Sprintf("source[\"%s\"]", strippedFieldName))
|
t.addInitializerFieldLine(strippedFieldName, fmt.Sprintf("source[\"%s\"]", strippedFieldName))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *typeScriptClassBuilder) AddStructField(fieldName string, field reflect.StructField) {
|
func (t *typeScriptClassBuilder) AddStructField(fieldName string, field reflect.StructField, isAnyType bool) {
|
||||||
strippedFieldName := strings.ReplaceAll(fieldName, "?", "")
|
strippedFieldName := strings.ReplaceAll(fieldName, "?", "")
|
||||||
namespace := strings.Split(field.Type.String(), ".")[0]
|
namespace := strings.Split(field.Type.String(), ".")[0]
|
||||||
fqname := field.Type.Name()
|
fqname := "any"
|
||||||
|
classname := "null"
|
||||||
|
fqname = field.Type.Name()
|
||||||
if namespace != t.namespace {
|
if namespace != t.namespace {
|
||||||
fqname = field.Type.String()
|
fqname = field.Type.String()
|
||||||
}
|
}
|
||||||
t.addField(fieldName, fqname)
|
if !isAnyType {
|
||||||
t.addInitializerFieldLine(strippedFieldName, fmt.Sprintf("this.convertValues(source[\"%s\"], %s)", strippedFieldName, fqname))
|
classname = fqname
|
||||||
|
}
|
||||||
|
t.addField(fieldName, fqname, isAnyType)
|
||||||
|
t.addInitializerFieldLine(strippedFieldName, fmt.Sprintf("this.convertValues(source[\"%s\"], %s)", strippedFieldName, classname))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *typeScriptClassBuilder) AddArrayOfStructsField(fieldName string, field reflect.StructField, arrayDepth int) {
|
func (t *typeScriptClassBuilder) AddArrayOfStructsField(fieldName string, field reflect.StructField, arrayDepth int) {
|
||||||
fieldType := field.Type.Elem().Name()
|
fieldType := field.Type.Elem().Name()
|
||||||
strippedFieldName := strings.ReplaceAll(fieldName, "?", "")
|
strippedFieldName := strings.ReplaceAll(fieldName, "?", "")
|
||||||
t.addField(fieldName, fmt.Sprint(t.prefix+fieldType+t.suffix, strings.Repeat("[]", arrayDepth)))
|
t.addField(fieldName, fmt.Sprint(t.prefix+fieldType+t.suffix, strings.Repeat("[]", arrayDepth)), false)
|
||||||
t.addInitializerFieldLine(strippedFieldName, fmt.Sprintf("this.convertValues(source[\"%s\"], %s)", strippedFieldName, t.prefix+fieldType+t.suffix))
|
t.addInitializerFieldLine(strippedFieldName, fmt.Sprintf("this.convertValues(source[\"%s\"], %s)", strippedFieldName, t.prefix+fieldType+t.suffix))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -823,8 +839,12 @@ func (t *typeScriptClassBuilder) addInitializerFieldLine(fld, initializer string
|
|||||||
t.constructorBody = append(t.constructorBody, fmt.Sprint(t.indent, t.indent, "this.", fld, " = ", initializer, ";"))
|
t.constructorBody = append(t.constructorBody, fmt.Sprint(t.indent, t.indent, "this.", fld, " = ", initializer, ";"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *typeScriptClassBuilder) addField(fld, fldType string) {
|
func (t *typeScriptClassBuilder) addField(fld, fldType string, isAnyType bool) {
|
||||||
t.fields = append(t.fields, fmt.Sprint(t.indent, fld, ": ", fldType, ";"))
|
if isAnyType {
|
||||||
|
t.fields = append(t.fields, fmt.Sprint(t.indent, "// Go type: ", fldType, "\n", t.indent, fld, ": any;"))
|
||||||
|
} else {
|
||||||
|
t.fields = append(t.fields, fmt.Sprint(t.indent, fld, ": ", fldType, ";"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func indentLines(str string, i int) string {
|
func indentLines(str string, i int) string {
|
||||||
@ -834,3 +854,9 @@ func indentLines(str string, i int) string {
|
|||||||
}
|
}
|
||||||
return strings.Join(lines, "\n")
|
return strings.Join(lines, "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getStructFQN(in string) string {
|
||||||
|
result := strings.ReplaceAll(in, "[]", "")
|
||||||
|
result = strings.ReplaceAll(result, "*", "")
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user