mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-02 03:01:45 +08:00
Fix differeng bugs when generating bindings (#2326)
* Bindings: work in better typescript generation * More work on generating typescript * Bindings: fix a couple of failing tests * Binding: fix map bindings * Bindings: comment out debug statement * Bindings: misc cleanup
This commit is contained in:
parent
180eef34a2
commit
88549a14ac
64
v2/internal/binding/binding_test/binding_type_alias_test.go
Normal file
64
v2/internal/binding/binding_test/binding_type_alias_test.go
Normal file
@ -0,0 +1,64 @@
|
||||
package binding_test
|
||||
|
||||
import (
|
||||
"github.com/wailsapp/wails/v2/internal/binding/binding_test/binding_test_import/int_package"
|
||||
"io/fs"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/binding"
|
||||
"github.com/wailsapp/wails/v2/internal/logger"
|
||||
)
|
||||
|
||||
const expectedTypeAliasBindings = `// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
import {binding_test} from '../models';
|
||||
import {int_package} from '../models';
|
||||
|
||||
export function Map():Promise<{[key: string]: string}>;
|
||||
|
||||
export function MapAlias():Promise<binding_test.MapAlias>;
|
||||
|
||||
export function MapWithImportedStructValue():Promise<{[key: string]: int_package.SomeStruct}>;
|
||||
|
||||
export function Slice():Promise<Array<string>>;
|
||||
|
||||
export function SliceImportedStruct():Promise<Array<int_package.SomeStruct>>;
|
||||
`
|
||||
|
||||
type AliasTest struct{}
|
||||
type MapAlias map[string]string
|
||||
|
||||
func (h *AliasTest) Map() map[string]string { return nil }
|
||||
func (h *AliasTest) MapAlias() MapAlias { return nil }
|
||||
func (h *AliasTest) MapWithImportedStructValue() map[string]int_package.SomeStruct { return nil }
|
||||
func (h *AliasTest) Slice() []string { return nil }
|
||||
func (h *AliasTest) SliceImportedStruct() []int_package.SomeStruct { return nil }
|
||||
|
||||
func TestAliases(t *testing.T) {
|
||||
// given
|
||||
generationDir := t.TempDir()
|
||||
|
||||
// setup
|
||||
testLogger := &logger.Logger{}
|
||||
b := binding.NewBindings(testLogger, []interface{}{&AliasTest{}}, []interface{}{}, false)
|
||||
|
||||
// then
|
||||
err := b.GenerateGoBindings(generationDir)
|
||||
if err != nil {
|
||||
t.Fatalf("could not generate the Go bindings: %v", err)
|
||||
}
|
||||
|
||||
// then
|
||||
rawGeneratedBindings, err := fs.ReadFile(os.DirFS(generationDir), "binding_test/AliasTest.d.ts")
|
||||
if err != nil {
|
||||
t.Fatalf("could not read the generated bindings: %v", err)
|
||||
}
|
||||
|
||||
// then
|
||||
generatedBindings := string(rawGeneratedBindings)
|
||||
if generatedBindings != expectedTypeAliasBindings {
|
||||
t.Fatalf("the generated bindings does not match the expected ones.\nWanted:\n%s\n\nGot:\n%s", expectedTypeAliasBindings,
|
||||
generatedBindings)
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
@ -14,6 +15,22 @@ import (
|
||||
"github.com/leaanthony/slicer"
|
||||
)
|
||||
|
||||
var mapRegex *regexp.Regexp
|
||||
var keyPackageIndex int
|
||||
var keyTypeIndex int
|
||||
var valueArrayIndex int
|
||||
var valuePackageIndex int
|
||||
var valueTypeIndex int
|
||||
|
||||
func init() {
|
||||
mapRegex = regexp.MustCompile(`(?:map\[(?:(?P<keyPackage>\w+)\.)?(?P<keyType>\w+)])?(?P<valueArray>\[])?(?:(?P<valuePackage>\w+)\.)?(?P<valueType>.+)`)
|
||||
keyPackageIndex = mapRegex.SubexpIndex("keyPackage")
|
||||
keyTypeIndex = mapRegex.SubexpIndex("keyType")
|
||||
valueArrayIndex = mapRegex.SubexpIndex("valueArray")
|
||||
valuePackageIndex = mapRegex.SubexpIndex("valuePackage")
|
||||
valueTypeIndex = mapRegex.SubexpIndex("valueType")
|
||||
}
|
||||
|
||||
func (b *Bindings) GenerateGoBindings(baseDir string) error {
|
||||
store := b.db.store
|
||||
var obfuscatedBindings map[string]int
|
||||
@ -128,56 +145,85 @@ func (b *Bindings) GenerateGoBindings(baseDir string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func goTypeToJSDocType(input string, importNamespaces *slicer.StringSlicer) string {
|
||||
// Verifying this first to ensure we are not converting a type
|
||||
// coming from a package that has a name matching a golang type, such as:
|
||||
// - interactor -> int
|
||||
// - mapper -> map
|
||||
if strings.ContainsRune(input, '.') {
|
||||
namespace := getPackageName(input)
|
||||
importNamespaces.Add(namespace)
|
||||
return namespace + "." + strings.Split(input, ".")[1]
|
||||
func fullyQualifiedName(packageName string, typeName string) string {
|
||||
if len(packageName) > 0 {
|
||||
return packageName + "." + typeName
|
||||
}
|
||||
|
||||
switch true {
|
||||
case input == "interface {}" || input == "interface{}":
|
||||
case len(typeName) == 0:
|
||||
return ""
|
||||
case typeName == "interface{}" || typeName == "interface {}":
|
||||
return "any"
|
||||
case input == "string":
|
||||
case typeName == "string":
|
||||
return "string"
|
||||
case input == "error":
|
||||
case typeName == "error":
|
||||
return "Error"
|
||||
case
|
||||
strings.HasPrefix(input, "int"),
|
||||
strings.HasPrefix(input, "uint"),
|
||||
strings.HasPrefix(input, "float"):
|
||||
strings.HasPrefix(typeName, "int"),
|
||||
strings.HasPrefix(typeName, "uint"),
|
||||
strings.HasPrefix(typeName, "float"):
|
||||
return "number"
|
||||
case input == "bool":
|
||||
case typeName == "bool":
|
||||
return "boolean"
|
||||
case input == "[]byte":
|
||||
return "string"
|
||||
case strings.HasPrefix(input, "map"):
|
||||
temp := strings.TrimPrefix(input, "map[")
|
||||
// Split the string into the key and value types
|
||||
tempSplit := strings.SplitN(temp, "]", 2)
|
||||
if len(tempSplit) < 2 {
|
||||
panic("Invalid map type provided: " + input)
|
||||
}
|
||||
keyType := tempSplit[0]
|
||||
valueType := tempSplit[1]
|
||||
return fmt.Sprintf("{[key: %s]: %s}", goTypeToJSDocType(keyType, importNamespaces), goTypeToJSDocType(valueType, importNamespaces))
|
||||
case strings.HasPrefix(input, "[]"):
|
||||
arrayType := goTypeToJSDocType(input[2:], importNamespaces)
|
||||
return "Array<" + arrayType + ">"
|
||||
default:
|
||||
return "any"
|
||||
}
|
||||
}
|
||||
|
||||
func goTypeToTypescriptType(input string, importNamespaces *slicer.StringSlicer) string {
|
||||
if strings.HasPrefix(input, "[]") {
|
||||
arrayType := goTypeToJSDocType(input[2:], importNamespaces)
|
||||
return "Array<" + arrayType + ">"
|
||||
func arrayifyValue(valueArray string, valueType string) string {
|
||||
if len(valueArray) == 0 {
|
||||
return valueType
|
||||
}
|
||||
|
||||
return "Array<" + valueType + ">"
|
||||
}
|
||||
|
||||
func goTypeToJSDocType(input string, importNamespaces *slicer.StringSlicer) string {
|
||||
matches := mapRegex.FindStringSubmatch(input)
|
||||
keyPackage := matches[keyPackageIndex]
|
||||
keyType := matches[keyTypeIndex]
|
||||
valueArray := matches[valueArrayIndex]
|
||||
valuePackage := matches[valuePackageIndex]
|
||||
valueType := matches[valueTypeIndex]
|
||||
//fmt.Printf("input=%s, keyPackage=%s, keyType=%s, valueArray=%s, valuePackage=%s, valueType=%s\n",
|
||||
// input,
|
||||
// keyPackage,
|
||||
// keyType,
|
||||
// valueArray,
|
||||
// valuePackage,
|
||||
// valueType)
|
||||
|
||||
// byte array is special case
|
||||
if valueArray == "[]" && valueType == "byte" {
|
||||
return "string"
|
||||
}
|
||||
|
||||
// if any packages, make sure they're saved
|
||||
if len(keyPackage) > 0 {
|
||||
importNamespaces.Add(keyPackage)
|
||||
}
|
||||
|
||||
if len(valuePackage) > 0 {
|
||||
importNamespaces.Add(valuePackage)
|
||||
}
|
||||
|
||||
key := fullyQualifiedName(keyPackage, keyType)
|
||||
var value string
|
||||
if strings.HasPrefix(valueType, "map") {
|
||||
value = goTypeToJSDocType(valueType, importNamespaces)
|
||||
} else {
|
||||
value = fullyQualifiedName(valuePackage, valueType)
|
||||
}
|
||||
|
||||
if len(key) > 0 {
|
||||
return fmt.Sprintf("{[key: %s]: %s}", key, arrayifyValue(valueArray, value))
|
||||
}
|
||||
|
||||
return arrayifyValue(valueArray, value)
|
||||
}
|
||||
|
||||
func goTypeToTypescriptType(input string, importNamespaces *slicer.StringSlicer) string {
|
||||
return goTypeToJSDocType(input, importNamespaces)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user