mirror of
https://github.com/wavetermdev/wails.git
synced 2026-04-22 15:26:15 -07:00
Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 536ae4ca68 | |||
| e302d11f12 | |||
| eb670f4ba1 | |||
| 5e0ce40b41 | |||
| 26530a0f5a | |||
| 7340247e25 | |||
| f1a7f1b781 | |||
| 71aa7c9731 | |||
| 868b769e7f | |||
| 8dc8c8e15e | |||
| da90e74268 | |||
| 443ea46d1d | |||
| 00c458f948 | |||
| 33855ff01d | |||
| f9ffe915f2 | |||
| 91676080eb | |||
| 6afb5260a7 | |||
| 0f80f031fd | |||
| ecc1791420 | |||
| 4a8917ecbc | |||
| cc1a6a3d50 | |||
| cd11c0a83c | |||
| 8fd0e06c24 | |||
| 4e5be36459 | |||
| 6bfd654ec8 | |||
| dc0d99a8e9 | |||
| b606561f8d | |||
| d0769ecd1c | |||
| 95bb15eef4 | |||
| 93aa8345dc | |||
| e1279a054f |
@@ -61,7 +61,7 @@ var jsReservedKeywords []string = []string{
|
||||
"typeof",
|
||||
"var",
|
||||
"void",
|
||||
"volotile",
|
||||
"volatile",
|
||||
"while",
|
||||
"with",
|
||||
"yield",
|
||||
|
||||
+2
-2
@@ -4,8 +4,8 @@ Informal and incomplete list of things needed in v3.
|
||||
|
||||
## General
|
||||
|
||||
- [ ] Generate Bindings
|
||||
- [ ] Generate TS Models
|
||||
- [x] Generate Bindings
|
||||
- [x] Generate TS Models
|
||||
- [ ] Dev Mode
|
||||
- [ ] Generate Info.Plist from `info.json`
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package main
|
||||
|
||||
type Person struct {
|
||||
name string
|
||||
}
|
||||
|
||||
type GreetService struct {
|
||||
}
|
||||
|
||||
func (*GreetService) Greet(name string) string {
|
||||
return "Hello " + name
|
||||
}
|
||||
|
||||
func (*GreetService) GreetPerson(person Person) string {
|
||||
return "Hello " + person.name
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body>
|
||||
HELLO!
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,43 @@
|
||||
// @ts-check
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Ă‚ MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
import {main} from './models';
|
||||
|
||||
function GreetService(method) {
|
||||
return {
|
||||
packageName: "main",
|
||||
serviceName: "GreetService",
|
||||
methodName: method,
|
||||
args: Array.prototype.slice.call(arguments, 1),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* GreetService.Greet
|
||||
*
|
||||
* @param name {string}
|
||||
* @returns {Promise<string>}
|
||||
**/
|
||||
function Greet(name) {
|
||||
return wails.Call(GreetService("Greet", name));
|
||||
}
|
||||
|
||||
/**
|
||||
* GreetService.GreetPerson
|
||||
*
|
||||
* @param person {main.Person}
|
||||
* @returns {Promise<string>}
|
||||
**/
|
||||
function GreetPerson(person) {
|
||||
return wails.Call(GreetService("GreetPerson", person));
|
||||
}
|
||||
|
||||
window.go = window.go || {};
|
||||
window.go.main = {
|
||||
GreetService: {
|
||||
Greet,
|
||||
GreetPerson,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
module binding
|
||||
|
||||
go 1.20
|
||||
|
||||
require github.com/wailsapp/wails/v3 v3.0.0-alpha.0
|
||||
|
||||
require (
|
||||
github.com/imdario/mergo v0.3.12 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/leaanthony/slicer v1.5.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/samber/lo v1.37.0 // indirect
|
||||
github.com/wailsapp/mimetype v1.4.1 // indirect
|
||||
github.com/wailsapp/wails/v2 v2.3.2-0.20230117193915-45c3a501d9e6 // indirect
|
||||
golang.org/x/exp v0.0.0-20220930202632-ec3f01382ef9 // indirect
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
|
||||
)
|
||||
|
||||
replace github.com/wailsapp/wails/v3 => ../..
|
||||
replace github.com/wailsapp/wails/v2 => ../../../v2
|
||||
@@ -1,14 +1,31 @@
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
||||
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/leaanthony/slicer v1.5.0 h1:aHYTN8xbCCLxJmkNKiLB6tgcMARl4eWmH9/F+S/0HtY=
|
||||
github.com/leaanthony/slicer v1.5.0/go.mod h1:FwrApmf8gOrpzEWM2J/9Lh79tyq8KTX5AzRtwV7m4AY=
|
||||
github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/samber/lo v1.37.0 h1:XjVcB8g6tgUp8rsPsJ2CvhClfImrpL04YpQHXeHPhRw=
|
||||
github.com/samber/lo v1.37.0/go.mod h1:9vaz2O4o8oOnK23pd2TrXufcbdbJIa3b6cstBWKpopA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs=
|
||||
github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o=
|
||||
github.com/wailsapp/wails/v2 v2.3.2-0.20230117193915-45c3a501d9e6 h1:Wn+nhnS+VytzE0PegUzSh4T3hXJCtggKGD/4U5H9+wQ=
|
||||
github.com/wailsapp/wails/v2 v2.3.2-0.20230117193915-45c3a501d9e6/go.mod h1:zlNLI0E2c2qA6miiuAHtp0Bac8FaGH0tlhA19OssR/8=
|
||||
github.com/wailsapp/wails/v3 v3.0.0-alpha.0 h1:T5gqG98Xr8LBf69oxlPkhpsFD59w2SnqUZk6XHj8Zoc=
|
||||
github.com/wailsapp/wails/v3 v3.0.0-alpha.0/go.mod h1:OAfO5bP0TSUvCIHZYc6Dqfow/9RqxzHvYtmhWPpo1c0=
|
||||
golang.org/x/exp v0.0.0-20220930202632-ec3f01382ef9 h1:RjggHMcaTVp0LOVZcW0bo8alwHrOaCrGUDgfWUHhnN4=
|
||||
golang.org/x/exp v0.0.0-20220930202632-ec3f01382ef9/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
|
||||
golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
@@ -20,3 +37,4 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
|
||||
@@ -1,25 +1,31 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"embed"
|
||||
_ "embed"
|
||||
"log"
|
||||
|
||||
"github.com/wailsapp/wails/v3/examples/binding/services"
|
||||
|
||||
"github.com/wailsapp/wails/v3/pkg/application"
|
||||
)
|
||||
|
||||
type localStruct struct{}
|
||||
//go:embed assets
|
||||
var assets embed.FS
|
||||
|
||||
func main() {
|
||||
app := application.New(application.Options{
|
||||
Bind: []interface{}{
|
||||
&localStruct{},
|
||||
&services.GreetService{},
|
||||
&GreetService{},
|
||||
},
|
||||
Mac: application.MacOptions{
|
||||
ApplicationShouldTerminateAfterLastWindowClosed: true,
|
||||
},
|
||||
})
|
||||
|
||||
app.NewWebviewWindow()
|
||||
app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{
|
||||
Assets: application.AssetOptions{
|
||||
FS: assets,
|
||||
},
|
||||
})
|
||||
|
||||
err := app.Run()
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
// @ts-check
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Ă‚ MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
export namespace main {
|
||||
|
||||
export class Person {
|
||||
name: string; // Warning: this is unexported in the Go struct.
|
||||
|
||||
static createFrom(source: any = {}) {
|
||||
return new Person(source);
|
||||
}
|
||||
|
||||
constructor(source: any = {}) {
|
||||
if ('string' === typeof source) {
|
||||
source = JSON.parse(source);
|
||||
}
|
||||
|
||||
this.name = source["name"]
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
// Code generated by tygo. DO NOT EDIT.
|
||||
|
||||
//////////
|
||||
// source: person.go
|
||||
|
||||
export interface Person {
|
||||
Name: string;
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
package models
|
||||
|
||||
type Person struct {
|
||||
Name string
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"github.com/wailsapp/wails/v3/examples/binding/models"
|
||||
)
|
||||
|
||||
type GreetService struct {
|
||||
SomeVariable int
|
||||
lowercase string
|
||||
Parent *models.Person
|
||||
}
|
||||
|
||||
func (*GreetService) Greet(name string) string {
|
||||
return "Hello " + name
|
||||
}
|
||||
|
||||
func (g *GreetService) GetPerson() *models.Person {
|
||||
return g.Parent
|
||||
}
|
||||
|
||||
func (g *GreetService) SetPerson(person *models.Person) {
|
||||
g.Parent = person
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
// Code generated by tygo. DO NOT EDIT.
|
||||
|
||||
//////////
|
||||
// source: GreetService.go
|
||||
|
||||
export interface GreetService {
|
||||
SomeVariable: number /* int */;
|
||||
Parent?: any /* models.Person */;
|
||||
}
|
||||
@@ -17,7 +17,7 @@ func main() {
|
||||
},
|
||||
})
|
||||
// Create window
|
||||
app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{
|
||||
myWindow := app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{
|
||||
Title: "Plain Bundle",
|
||||
CSS: `body { background-color: rgba(255, 255, 255, 0); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; user-select: none; -ms-user-select: none; -webkit-user-select: none; } .main { color: white; margin: 20%; }`,
|
||||
Mac: application.MacWindow{
|
||||
@@ -25,7 +25,6 @@ func main() {
|
||||
Backdrop: application.MacBackdropTranslucent,
|
||||
TitleBar: application.MacTitleBarHiddenInsetUnified,
|
||||
},
|
||||
|
||||
URL: "/",
|
||||
Assets: application.AssetOptions{
|
||||
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
@@ -4,6 +4,7 @@ go 1.19
|
||||
|
||||
require (
|
||||
github.com/go-task/task/v3 v3.20.0
|
||||
github.com/google/go-cmp v0.5.9
|
||||
github.com/jackmordaunt/icns/v2 v2.2.1
|
||||
github.com/json-iterator/go v1.1.12
|
||||
github.com/leaanthony/clir v1.6.0
|
||||
@@ -12,17 +13,14 @@ require (
|
||||
github.com/matryer/is v1.4.0
|
||||
github.com/pterm/pterm v0.12.51
|
||||
github.com/samber/lo v1.37.0
|
||||
github.com/stretchr/testify v1.8.1
|
||||
github.com/tc-hib/winres v0.1.6
|
||||
github.com/wailsapp/wails/v2 v2.3.2-0.20230117193915-45c3a501d9e6
|
||||
golang.org/x/tools v0.1.12
|
||||
)
|
||||
|
||||
require (
|
||||
atomicgo.dev/cursor v0.1.1 // indirect
|
||||
atomicgo.dev/keyboard v0.2.8 // indirect
|
||||
github.com/containerd/console v1.0.3 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/fatih/color v1.13.0 // indirect
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
|
||||
github.com/gookit/color v1.5.2 // indirect
|
||||
@@ -38,7 +36,6 @@ require (
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/radovskyb/watcher v1.0.7 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/sajari/fuzzy v1.0.0 // indirect
|
||||
@@ -46,7 +43,6 @@ require (
|
||||
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect
|
||||
golang.org/x/exp v0.0.0-20220930202632-ec3f01382ef9 // indirect
|
||||
golang.org/x/image v0.5.0 // indirect
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
||||
golang.org/x/net v0.7.0 // indirect
|
||||
golang.org/x/sync v0.1.0 // indirect
|
||||
golang.org/x/sys v0.5.0 // indirect
|
||||
|
||||
@@ -26,6 +26,7 @@ github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg78
|
||||
github.com/go-task/task/v3 v3.20.0 h1:pTavuhP+AiEpKLzh5I6Lja9Ux7ypYO5QMsEPTbhYEDc=
|
||||
github.com/go-task/task/v3 v3.20.0/go.mod h1:y7rWakbLR5gFElGgo6rA2dyr6vU/zNIDVfn3S4Of6OI=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ=
|
||||
github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo=
|
||||
@@ -111,7 +112,6 @@ github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
@@ -120,7 +120,6 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/tc-hib/winres v0.1.6 h1:qgsYHze+BxQPEYilxIz/KCQGaClvI2+yLBAZs+3+0B8=
|
||||
github.com/tc-hib/winres v0.1.6/go.mod h1:pe6dOR40VOrGz8PkzreVKNvEKnlE8t4yR8A8naL+t7A=
|
||||
github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs=
|
||||
@@ -137,7 +136,6 @@ golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+o
|
||||
golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.5.0 h1:5JMiNunQeQw++mMOz48/ISeNu3Iweh/JaZU8ZLqHRrI=
|
||||
golang.org/x/image v0.5.0/go.mod h1:FVC7BI/5Ym8R25iw5OLsgshdUBbT1h5jZTpA+mvAdZ4=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
@@ -181,7 +179,6 @@ golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
||||
@@ -1,42 +1,15 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/wailsapp/wails/v3/internal/parser"
|
||||
)
|
||||
import "github.com/wailsapp/wails/v3/internal/parser"
|
||||
|
||||
type GenerateBindingsOptions struct {
|
||||
Silent bool `name:"silent" description:"Silent mode"`
|
||||
ModelsFilename string `name:"m" description:"The filename for the models file" default:"models.ts"`
|
||||
BindingsFilename string `name:"b" description:"The filename for the bindings file" default:"bindings.js"`
|
||||
ProjectDirectory string `name:"d" description:"The project directory" default:"."`
|
||||
ProjectDirectory string `name:"p" description:"The project directory" default:"."`
|
||||
OutputDirectory string `name:"d" description:"The output directory" default:"."`
|
||||
}
|
||||
|
||||
func GenerateBindings(options *GenerateBindingsOptions) error {
|
||||
|
||||
parserContext, err := parser.ParseDirectory(options.ProjectDirectory)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error parsing project: %v", err)
|
||||
}
|
||||
|
||||
// Generate models
|
||||
modelsData, err := parser.GenerateModels(parserContext)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error generating models: %v", err)
|
||||
}
|
||||
|
||||
var modelsFileData bytes.Buffer
|
||||
modelsFileData.WriteString(`// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Ă‚ MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
`)
|
||||
modelsFileData.Write(modelsData)
|
||||
err = os.WriteFile(options.ModelsFilename, modelsFileData.Bytes(), 0755)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error writing models file: %v", err)
|
||||
}
|
||||
println("Generated models file '" + options.ModelsFilename + "'")
|
||||
return nil
|
||||
return parser.GenerateBindingsAndModels(options.ProjectDirectory, options.OutputDirectory)
|
||||
}
|
||||
|
||||
@@ -7,17 +7,61 @@ This package contains the static analyser used for parsing Wails projects so tha
|
||||
|
||||
## Implemented
|
||||
|
||||
- [x] Parsing of structs
|
||||
- [x] Generation of models
|
||||
- [ ] Bound types
|
||||
- [x] Struct Literal Pointer
|
||||
- [ ] Variable
|
||||
- [ ] Assignment
|
||||
- [x] Struct Literal Pointer
|
||||
- [ ] Function
|
||||
- [ ] Same package
|
||||
- [ ] Different package
|
||||
- [ ] Function
|
||||
|
||||
- [x] Parsing of bound methods
|
||||
- [x] Method names
|
||||
- [x] Method parameters
|
||||
- [x] Zero parameters
|
||||
- [x] Single input parameter
|
||||
- [x] Single output parameter
|
||||
- [x] Multiple input parameters
|
||||
- [x] Multiple output parameters
|
||||
- [x] Named output parameters
|
||||
- [x] int/8/16/32/64
|
||||
- [x] Pointer
|
||||
- [x] uint/8/16/32/64
|
||||
- [x] Pointer
|
||||
- [x] float
|
||||
- [x] Pointer
|
||||
- [x] string
|
||||
- [x] Pointer
|
||||
- [x] bool
|
||||
- [x] Pointer
|
||||
- [x] Struct
|
||||
- [x] Pointer
|
||||
- [x] Slices
|
||||
- [x] Pointer
|
||||
- [x] Maps
|
||||
- [x] Pointer
|
||||
- [x] Model Parsing
|
||||
- [x] In same package
|
||||
- [x] In different package
|
||||
- [x] Multiple named fields, e.g. one,two,three string
|
||||
- [x] Scalars
|
||||
- [x] Arrays
|
||||
- [x] Maps
|
||||
- [x] Structs
|
||||
- [x] Recursive
|
||||
- [x] Anonymous
|
||||
- [ ] Generation of models
|
||||
- [x] Scalars
|
||||
- [ ] Arrays
|
||||
- [ ] Maps
|
||||
- [x] Structs
|
||||
- [ ] Generation of bindings
|
||||
|
||||
## Limitations
|
||||
|
||||
There are many ways to write a Go program so there are many different program structures that we would need to support. This is a work in progress and will be improved over time. The current limitations are:
|
||||
There are many ways to write a Go program so there are many program structures that we would need to support. This is a work in progress and will be improved over time. The current limitations are:
|
||||
|
||||
- The call to `application.New()` must be in the `main` package
|
||||
- Bound structs must be declared as struct literals
|
||||
|
||||
@@ -0,0 +1,285 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
const header = `// @ts-check
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Ă‚ MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
`
|
||||
|
||||
const helperTemplate = `function {{structName}}(method) {
|
||||
return {
|
||||
packageName: "{{packageName}}",
|
||||
serviceName: "{{structName}}",
|
||||
methodName: method,
|
||||
args: Array.prototype.slice.call(arguments, 1),
|
||||
};
|
||||
}
|
||||
`
|
||||
|
||||
func GenerateHelper(packageName, structName string) string {
|
||||
result := strings.ReplaceAll(helperTemplate, "{{packageName}}", packageName)
|
||||
result = strings.ReplaceAll(result, "{{structName}}", structName)
|
||||
return result
|
||||
}
|
||||
|
||||
const bindingTemplate = `
|
||||
/**
|
||||
* {{structName}}.{{methodName}}
|
||||
* Comments
|
||||
* @param name {string}
|
||||
* @returns {Promise<string>}
|
||||
**/
|
||||
function {{methodName}}({{inputs}}) {
|
||||
return wails.Call({{structName}}("{{methodName}}"{{args}}));
|
||||
}
|
||||
`
|
||||
|
||||
var reservedWords = []string{
|
||||
"abstract",
|
||||
"arguments",
|
||||
"await",
|
||||
"boolean",
|
||||
"break",
|
||||
"byte",
|
||||
"case",
|
||||
"catch",
|
||||
"char",
|
||||
"class",
|
||||
"const",
|
||||
"continue",
|
||||
"debugger",
|
||||
"default",
|
||||
"delete",
|
||||
"do",
|
||||
"double",
|
||||
"else",
|
||||
"enum",
|
||||
"eval",
|
||||
"export",
|
||||
"extends",
|
||||
"false",
|
||||
"final",
|
||||
"finally",
|
||||
"float",
|
||||
"for",
|
||||
"function",
|
||||
"goto",
|
||||
"if",
|
||||
"implements",
|
||||
"import",
|
||||
"in",
|
||||
"instanceof",
|
||||
"int",
|
||||
"interface",
|
||||
"let",
|
||||
"long",
|
||||
"native",
|
||||
"new",
|
||||
"null",
|
||||
"package",
|
||||
"private",
|
||||
"protected",
|
||||
"public",
|
||||
"return",
|
||||
"short",
|
||||
"static",
|
||||
"super",
|
||||
"switch",
|
||||
"synchronized",
|
||||
"this",
|
||||
"throw",
|
||||
"throws",
|
||||
"transient",
|
||||
"true",
|
||||
"try",
|
||||
"typeof",
|
||||
"var",
|
||||
"void",
|
||||
"volatile",
|
||||
"while",
|
||||
"with",
|
||||
"yield",
|
||||
"object",
|
||||
}
|
||||
|
||||
func sanitiseJSVarName(name string) string {
|
||||
// if the name is a reserved word, prefix with an
|
||||
// underscore
|
||||
if lo.Contains(reservedWords, name) {
|
||||
return "_" + name
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
func GenerateBinding(structName string, method *BoundMethod) (string, []string) {
|
||||
var models []string
|
||||
result := strings.ReplaceAll(bindingTemplate, "{{structName}}", structName)
|
||||
result = strings.ReplaceAll(result, "{{methodName}}", method.Name)
|
||||
comments := strings.TrimSpace(method.DocComment)
|
||||
result = strings.ReplaceAll(result, "Comments", comments)
|
||||
var params string
|
||||
for _, input := range method.Inputs {
|
||||
pkgName := getPackageName(input)
|
||||
if pkgName != "" {
|
||||
models = append(models, pkgName)
|
||||
}
|
||||
params += " * @param " + sanitiseJSVarName(input.Name) + " {" + input.JSType() + "}\n"
|
||||
}
|
||||
params = strings.TrimSuffix(params, "\n")
|
||||
if len(params) == 0 {
|
||||
params = " *"
|
||||
}
|
||||
result = strings.ReplaceAll(result, " * @param name {string}", params)
|
||||
var inputs string
|
||||
for _, input := range method.Inputs {
|
||||
pkgName := getPackageName(input)
|
||||
if pkgName != "" {
|
||||
models = append(models, pkgName)
|
||||
}
|
||||
inputs += sanitiseJSVarName(input.Name) + ", "
|
||||
}
|
||||
inputs = strings.TrimSuffix(inputs, ", ")
|
||||
args := inputs
|
||||
if len(args) > 0 {
|
||||
args = ", " + args
|
||||
}
|
||||
result = strings.ReplaceAll(result, "{{inputs}}", inputs)
|
||||
result = strings.ReplaceAll(result, "{{args}}", args)
|
||||
|
||||
// outputs
|
||||
var returns string
|
||||
if len(method.Outputs) == 0 {
|
||||
returns = " * @returns {Promise<void>}"
|
||||
} else {
|
||||
returns = " * @returns {Promise<"
|
||||
for _, output := range method.Outputs {
|
||||
pkgName := getPackageName(output)
|
||||
if pkgName != "" {
|
||||
models = append(models, pkgName)
|
||||
}
|
||||
jsType := output.JSType()
|
||||
if jsType == "error" {
|
||||
jsType = "void"
|
||||
}
|
||||
returns += jsType + ", "
|
||||
}
|
||||
returns = strings.TrimSuffix(returns, ", ")
|
||||
returns += ">}"
|
||||
}
|
||||
result = strings.ReplaceAll(result, " * @returns {Promise<string>}", returns)
|
||||
|
||||
return result, lo.Uniq(models)
|
||||
}
|
||||
|
||||
func getPackageName(input *Parameter) string {
|
||||
if !input.Type.IsStruct {
|
||||
return ""
|
||||
}
|
||||
result := input.Type.Package
|
||||
if result == "" {
|
||||
result = "main"
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func normalisePackageNames(packageNames []string) map[string]string {
|
||||
// We iterate over the package names and determine if any of them
|
||||
// have a forward slash. If this is the case, we assume that the
|
||||
// package name is the last element of the path. If this has already
|
||||
// been found, then we need to add a digit to the end of the package
|
||||
// name to make it unique. We return a map of the original package
|
||||
// name to the new package name.
|
||||
var result = make(map[string]string)
|
||||
var packagesConverted = make(map[string]struct{})
|
||||
var count = 1
|
||||
for _, packageName := range packageNames {
|
||||
var originalPackageName = packageName
|
||||
if strings.Contains(packageName, "/") {
|
||||
parts := strings.Split(packageName, "/")
|
||||
packageName = parts[len(parts)-1]
|
||||
}
|
||||
if _, ok := packagesConverted[packageName]; ok {
|
||||
// We've already seen this package name. Add a digit
|
||||
// to the end of the package name to make it unique
|
||||
count += 1
|
||||
packageName += strconv.Itoa(count)
|
||||
|
||||
}
|
||||
packagesConverted[packageName] = struct{}{}
|
||||
result[originalPackageName] = packageName
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func GenerateBindings(bindings map[string]map[string][]*BoundMethod) map[string]string {
|
||||
|
||||
var result = make(map[string]string)
|
||||
|
||||
var normalisedPackageNames = normalisePackageNames(lo.Keys(bindings))
|
||||
// sort the bindings keys
|
||||
packageNames := lo.Keys(bindings)
|
||||
sort.Strings(packageNames)
|
||||
for _, packageName := range packageNames {
|
||||
var allModels []string
|
||||
|
||||
packageBindings := bindings[packageName]
|
||||
structNames := lo.Keys(packageBindings)
|
||||
sort.Strings(structNames)
|
||||
for _, structName := range structNames {
|
||||
result[normalisedPackageNames[packageName]] += GenerateHelper(normalisedPackageNames[packageName], structName)
|
||||
methods := packageBindings[structName]
|
||||
sort.Slice(methods, func(i, j int) bool {
|
||||
return methods[i].Name < methods[j].Name
|
||||
})
|
||||
for _, method := range methods {
|
||||
thisBinding, models := GenerateBinding(structName, method)
|
||||
result[normalisedPackageNames[packageName]] += thisBinding
|
||||
allModels = append(allModels, models...)
|
||||
}
|
||||
}
|
||||
|
||||
result[normalisedPackageNames[packageName]] += `
|
||||
window.go = window.go || {};
|
||||
`
|
||||
// Iterate over the sorted struct keys
|
||||
result[normalisedPackageNames[packageName]] += "window.go." + normalisedPackageNames[packageName] + " = {\n"
|
||||
for _, structName := range structNames {
|
||||
result[normalisedPackageNames[packageName]] += " " + structName + ": {\n"
|
||||
methods := packageBindings[structName]
|
||||
sort.Slice(methods, func(i, j int) bool {
|
||||
return methods[i].Name < methods[j].Name
|
||||
})
|
||||
for _, method := range methods {
|
||||
result[normalisedPackageNames[packageName]] += " " + method.Name + ",\n"
|
||||
}
|
||||
result[normalisedPackageNames[packageName]] += " },\n"
|
||||
}
|
||||
result[normalisedPackageNames[packageName]] += "};\n"
|
||||
|
||||
// add imports
|
||||
if len(allModels) > 0 {
|
||||
allModels := lo.Uniq(allModels)
|
||||
var models []string
|
||||
for _, model := range allModels {
|
||||
models = append(models, normalisedPackageNames[model])
|
||||
}
|
||||
sort.Strings(models)
|
||||
result[normalisedPackageNames[packageName]] += "\n"
|
||||
imports := "import {" + strings.Join(models, ", ") + "} from './models';\n"
|
||||
result[normalisedPackageNames[packageName]] = imports + "\n" + result[normalisedPackageNames[packageName]]
|
||||
}
|
||||
|
||||
result[normalisedPackageNames[packageName]] = header + result[normalisedPackageNames[packageName]]
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"io/fs"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
)
|
||||
|
||||
//go:embed testdata
|
||||
var testdata embed.FS
|
||||
|
||||
func getFile(filename string) string {
|
||||
// get the file from the testdata FS
|
||||
file, err := fs.ReadFile(testdata, filename)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return string(file)
|
||||
}
|
||||
|
||||
func TestGenerateBindings(t *testing.T) {
|
||||
|
||||
tests := []struct {
|
||||
dir string
|
||||
want map[string]string
|
||||
}{
|
||||
{
|
||||
"testdata/function_single",
|
||||
map[string]string{
|
||||
"main": getFile("testdata/function_single/bindings_main.js"),
|
||||
},
|
||||
},
|
||||
{
|
||||
"testdata/function_from_imported_package",
|
||||
map[string]string{
|
||||
"main": getFile("testdata/function_from_imported_package/bindings_main.js"),
|
||||
"services": getFile("testdata/function_from_imported_package/bindings_services.js"),
|
||||
},
|
||||
},
|
||||
{
|
||||
"testdata/variable_single",
|
||||
map[string]string{
|
||||
"main": getFile("testdata/variable_single/bindings_main.js"),
|
||||
},
|
||||
},
|
||||
{
|
||||
"testdata/variable_single_from_function",
|
||||
map[string]string{
|
||||
"main": getFile("testdata/variable_single_from_function/bindings_main.js"),
|
||||
},
|
||||
},
|
||||
{
|
||||
"testdata/variable_single_from_other_function",
|
||||
map[string]string{
|
||||
"main": getFile("testdata/variable_single_from_other_function/bindings_main.js"),
|
||||
"services": getFile("testdata/variable_single_from_other_function/bindings_services.js"),
|
||||
},
|
||||
},
|
||||
{
|
||||
"testdata/struct_literal_single",
|
||||
map[string]string{
|
||||
"main": getFile("testdata/struct_literal_single/bindings_main.js"),
|
||||
},
|
||||
},
|
||||
{
|
||||
"testdata/struct_literal_multiple",
|
||||
map[string]string{
|
||||
"main": getFile("testdata/struct_literal_multiple/bindings_main.js"),
|
||||
},
|
||||
},
|
||||
{
|
||||
"testdata/struct_literal_multiple_other",
|
||||
map[string]string{
|
||||
"main": getFile("testdata/struct_literal_multiple_other/bindings_main.js"),
|
||||
"services": getFile("testdata/struct_literal_multiple_other/bindings_services.js"),
|
||||
},
|
||||
},
|
||||
{
|
||||
"testdata/struct_literal_multiple_files",
|
||||
map[string]string{
|
||||
"main": getFile("testdata/struct_literal_multiple_files/bindings_main.js"),
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.dir, func(t *testing.T) {
|
||||
// Run parser on directory
|
||||
project, err := ParseProject(tt.dir)
|
||||
if err != nil {
|
||||
t.Errorf("ParseProject() error = %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Generate Bindings
|
||||
got := GenerateBindings(project.BoundMethods)
|
||||
|
||||
for name, binding := range got {
|
||||
// check if the binding is in the expected bindings
|
||||
expected, ok := tt.want[name]
|
||||
if !ok {
|
||||
err = os.WriteFile(tt.dir+"/bindings_"+name+".got.js", []byte(binding), 0644)
|
||||
if err != nil {
|
||||
t.Errorf("os.WriteFile() error = %v", err)
|
||||
return
|
||||
}
|
||||
t.Errorf("GenerateBindings() unexpected binding = %v", name)
|
||||
return
|
||||
}
|
||||
// compare the binding
|
||||
if diff := cmp.Diff(expected, binding); diff != "" {
|
||||
err = os.WriteFile(tt.dir+"/bindings_"+name+".got.js", []byte(binding), 0644)
|
||||
if err != nil {
|
||||
t.Errorf("os.WriteFile() error = %v", err)
|
||||
return
|
||||
}
|
||||
t.Fatalf("GenerateBindings() mismatch (-want +got):\n%s", diff)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user