-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix miscellaneous bindings and typescript export bugs #3978
Merged
Merged
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
42c3e07
Do not attempt to export fields that cannot be json-encoded
pbnjay f9d053a
update changelog w/ PR
pbnjay e8110bc
also skip UnsafePointers
pbnjay a4345e5
WIP to allow conversion from Go generic types to typescript
pbnjay 3fbb230
support for non-primitive generics also :)
pbnjay 48a8268
fix generic types in parameters / return args
pbnjay 82a4952
fixes a namespacing bug when mapping to pointer to struct
pbnjay 2d7ffaa
fixing invalid knownstructs
pbnjay 9e26774
found a place it mattered, pushing the star replacement to the genera…
pbnjay 75fc0f5
descend as much as necessary to find structs
pbnjay 2813db4
accidently reverted other fix
pbnjay bf6867f
switch syntax for typescript record outputs
pbnjay c0f22a7
better handle edge cases for nested arrays and slices
pbnjay 203abce
lots o tests
pbnjay 7ac3c8c
Merge branch 'master' into fix-generic-exports
pbnjay 4e17993
Merge branch 'master' into fix-generic-exports
leaanthony 676e6ed
Merge branch 'master' into fix-generic-exports
pbnjay 0248bd8
update changelog
pbnjay c91b54e
Merge branch 'master' into fix-generic-exports
leaanthony File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
126 changes: 126 additions & 0 deletions
126
v2/internal/binding/binding_test/binding_deepelements_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
package binding_test | ||
|
||
// Issues 2303, 3442, 3709 | ||
|
||
type DeepMessage struct { | ||
Msg string | ||
} | ||
|
||
type DeepElements struct { | ||
Single []int | ||
Double [][]string | ||
FourDouble [4][]float64 | ||
DoubleFour [][4]int64 | ||
Triple [][][]int | ||
|
||
SingleMap map[string]int | ||
SliceMap map[string][]int | ||
DoubleSliceMap map[string][][]int | ||
|
||
ArrayMap map[string][4]int | ||
DoubleArrayMap1 map[string][4][]int | ||
DoubleArrayMap2 map[string][][4]int | ||
DoubleArrayMap3 map[string][4][4]int | ||
|
||
OneStructs []*DeepMessage | ||
TwoStructs [3][]*DeepMessage | ||
ThreeStructs [][][]DeepMessage | ||
MapStructs map[string][]*DeepMessage | ||
MapTwoStructs map[string][4][]DeepMessage | ||
MapThreeStructs map[string][][7][]*DeepMessage | ||
} | ||
|
||
func (x DeepElements) Get() DeepElements { | ||
return x | ||
} | ||
|
||
var DeepElementsTest = BindingTest{ | ||
name: "DeepElements", | ||
structs: []interface{}{ | ||
&DeepElements{}, | ||
}, | ||
exemptions: nil, | ||
shouldError: false, | ||
want: ` | ||
export namespace binding_test { | ||
|
||
export class DeepMessage { | ||
Msg: string; | ||
|
||
static createFrom(source: any = {}) { | ||
return new DeepMessage(source); | ||
} | ||
|
||
constructor(source: any = {}) { | ||
if ('string' === typeof source) source = JSON.parse(source); | ||
this.Msg = source["Msg"]; | ||
} | ||
} | ||
export class DeepElements { | ||
Single: number[]; | ||
Double: string[][]; | ||
FourDouble: number[][]; | ||
DoubleFour: number[][]; | ||
Triple: number[][][]; | ||
SingleMap: Record<string, number>; | ||
SliceMap: Record<string, number[]>; | ||
DoubleSliceMap: Record<string, number[][]>; | ||
ArrayMap: Record<string, number[]>; | ||
DoubleArrayMap1: Record<string, number[][]>; | ||
DoubleArrayMap2: Record<string, number[][]>; | ||
DoubleArrayMap3: Record<string, number[][]>; | ||
OneStructs: DeepMessage[]; | ||
TwoStructs: DeepMessage[][]; | ||
ThreeStructs: DeepMessage[][][]; | ||
MapStructs: Record<string, DeepMessage[]>; | ||
MapTwoStructs: Record<string, DeepMessage[][]>; | ||
MapThreeStructs: Record<string, DeepMessage[][][]>; | ||
|
||
static createFrom(source: any = {}) { | ||
return new DeepElements(source); | ||
} | ||
|
||
constructor(source: any = {}) { | ||
if ('string' === typeof source) source = JSON.parse(source); | ||
this.Single = source["Single"]; | ||
this.Double = source["Double"]; | ||
this.FourDouble = source["FourDouble"]; | ||
this.DoubleFour = source["DoubleFour"]; | ||
this.Triple = source["Triple"]; | ||
this.SingleMap = source["SingleMap"]; | ||
this.SliceMap = source["SliceMap"]; | ||
this.DoubleSliceMap = source["DoubleSliceMap"]; | ||
this.ArrayMap = source["ArrayMap"]; | ||
this.DoubleArrayMap1 = source["DoubleArrayMap1"]; | ||
this.DoubleArrayMap2 = source["DoubleArrayMap2"]; | ||
this.DoubleArrayMap3 = source["DoubleArrayMap3"]; | ||
this.OneStructs = this.convertValues(source["OneStructs"], DeepMessage); | ||
this.TwoStructs = this.convertValues(source["TwoStructs"], DeepMessage); | ||
this.ThreeStructs = this.convertValues(source["ThreeStructs"], DeepMessage); | ||
this.MapStructs = this.convertValues(source["MapStructs"], DeepMessage[], true); | ||
this.MapTwoStructs = this.convertValues(source["MapTwoStructs"], DeepMessage[][], true); | ||
this.MapThreeStructs = this.convertValues(source["MapThreeStructs"], DeepMessage[][][], true); | ||
} | ||
|
||
convertValues(a: any, classs: any, asMap: boolean = false): any { | ||
if (!a) { | ||
return a; | ||
} | ||
if (a.slice && a.map) { | ||
return (a as any[]).map(elem => this.convertValues(elem, classs)); | ||
} else if ("object" === typeof a) { | ||
if (asMap) { | ||
for (const key of Object.keys(a)) { | ||
a[key] = new classs(a[key]); | ||
} | ||
return a; | ||
} | ||
return new classs(a); | ||
} | ||
return a; | ||
} | ||
} | ||
|
||
} | ||
`, | ||
} |
154 changes: 154 additions & 0 deletions
154
v2/internal/binding/binding_test/binding_generics_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
package binding_test | ||
|
||
import "github.com/wailsapp/wails/v2/internal/binding/binding_test/binding_test_import/float_package" | ||
|
||
// Issues 3900, 3371, 2323 (no TS generics though) | ||
|
||
type ListData[T interface{}] struct { | ||
Total int64 `json:"Total"` | ||
TotalPage int64 `json:"TotalPage"` | ||
PageNum int `json:"PageNum"` | ||
List []T `json:"List,omitempty"` | ||
} | ||
|
||
func (x ListData[T]) Get() ListData[T] { | ||
return x | ||
} | ||
|
||
var Generics1Test = BindingTest{ | ||
name: "Generics1", | ||
structs: []interface{}{ | ||
&ListData[string]{}, | ||
}, | ||
exemptions: nil, | ||
shouldError: false, | ||
want: ` | ||
export namespace binding_test { | ||
|
||
export class ListData_string_ { | ||
Total: number; | ||
TotalPage: number; | ||
PageNum: number; | ||
List?: string[]; | ||
|
||
static createFrom(source: any = {}) { | ||
return new ListData_string_(source); | ||
} | ||
|
||
constructor(source: any = {}) { | ||
if ('string' === typeof source) source = JSON.parse(source); | ||
this.Total = source["Total"]; | ||
this.TotalPage = source["TotalPage"]; | ||
this.PageNum = source["PageNum"]; | ||
this.List = source["List"]; | ||
} | ||
} | ||
|
||
} | ||
`, | ||
} | ||
|
||
var Generics2Test = BindingTest{ | ||
name: "Generics2", | ||
structs: []interface{}{ | ||
&ListData[float_package.SomeStruct]{}, | ||
&ListData[*float_package.SomeStruct]{}, | ||
}, | ||
exemptions: nil, | ||
shouldError: false, | ||
want: ` | ||
export namespace binding_test { | ||
|
||
export class ListData__github_com_wailsapp_wails_v2_internal_binding_binding_test_binding_test_import_float_package_SomeStruct_ { | ||
Total: number; | ||
TotalPage: number; | ||
PageNum: number; | ||
List?: float_package.SomeStruct[]; | ||
|
||
static createFrom(source: any = {}) { | ||
return new ListData__github_com_wailsapp_wails_v2_internal_binding_binding_test_binding_test_import_float_package_SomeStruct_(source); | ||
} | ||
|
||
constructor(source: any = {}) { | ||
if ('string' === typeof source) source = JSON.parse(source); | ||
this.Total = source["Total"]; | ||
this.TotalPage = source["TotalPage"]; | ||
this.PageNum = source["PageNum"]; | ||
this.List = this.convertValues(source["List"], float_package.SomeStruct); | ||
} | ||
|
||
convertValues(a: any, classs: any, asMap: boolean = false): any { | ||
if (!a) { | ||
return a; | ||
} | ||
if (a.slice && a.map) { | ||
return (a as any[]).map(elem => this.convertValues(elem, classs)); | ||
} else if ("object" === typeof a) { | ||
if (asMap) { | ||
for (const key of Object.keys(a)) { | ||
a[key] = new classs(a[key]); | ||
} | ||
return a; | ||
} | ||
return new classs(a); | ||
} | ||
return a; | ||
} | ||
} | ||
export class ListData_github_com_wailsapp_wails_v2_internal_binding_binding_test_binding_test_import_float_package_SomeStruct_ { | ||
Total: number; | ||
TotalPage: number; | ||
PageNum: number; | ||
List?: float_package.SomeStruct[]; | ||
|
||
static createFrom(source: any = {}) { | ||
return new ListData_github_com_wailsapp_wails_v2_internal_binding_binding_test_binding_test_import_float_package_SomeStruct_(source); | ||
} | ||
|
||
constructor(source: any = {}) { | ||
if ('string' === typeof source) source = JSON.parse(source); | ||
this.Total = source["Total"]; | ||
this.TotalPage = source["TotalPage"]; | ||
this.PageNum = source["PageNum"]; | ||
this.List = this.convertValues(source["List"], float_package.SomeStruct); | ||
} | ||
|
||
convertValues(a: any, classs: any, asMap: boolean = false): any { | ||
if (!a) { | ||
return a; | ||
} | ||
if (a.slice && a.map) { | ||
return (a as any[]).map(elem => this.convertValues(elem, classs)); | ||
} else if ("object" === typeof a) { | ||
if (asMap) { | ||
for (const key of Object.keys(a)) { | ||
a[key] = new classs(a[key]); | ||
} | ||
return a; | ||
} | ||
return new classs(a); | ||
} | ||
return a; | ||
} | ||
} | ||
|
||
} | ||
|
||
export namespace float_package { | ||
|
||
export class SomeStruct { | ||
string: string; | ||
|
||
static createFrom(source: any = {}) { | ||
return new SomeStruct(source); | ||
} | ||
|
||
constructor(source: any = {}) { | ||
if ('string' === typeof source) source = JSON.parse(source); | ||
this.string = source["string"]; | ||
} | ||
} | ||
|
||
} | ||
`, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package binding_test | ||
|
||
import ( | ||
"unsafe" | ||
) | ||
|
||
// Issues 3755, 3809 | ||
|
||
type Ignored struct { | ||
Valid bool | ||
Total func() int `json:"Total"` | ||
UnsafeP unsafe.Pointer | ||
Complex64 complex64 `json:"Complex"` | ||
Complex128 complex128 | ||
StringChan chan string | ||
} | ||
|
||
func (x Ignored) Get() Ignored { | ||
return x | ||
} | ||
|
||
var IgnoredTest = BindingTest{ | ||
name: "Ignored", | ||
structs: []interface{}{ | ||
&Ignored{}, | ||
}, | ||
exemptions: nil, | ||
shouldError: false, | ||
want: ` | ||
export namespace binding_test { | ||
|
||
export class Ignored { | ||
Valid: boolean; | ||
|
||
static createFrom(source: any = {}) { | ||
return new Ignored(source); | ||
} | ||
|
||
constructor(source: any = {}) { | ||
if ('string' === typeof source) source = JSON.parse(source); | ||
this.Valid = source["Valid"]; | ||
} | ||
} | ||
|
||
} | ||
`, | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
line 284 throws away the rest, we want to keep them