5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-04 23:11:53 +08:00
wails/v3/internal/generator/render/functions.go
Fabio Massaioli 37673eb24d
[v3] Fix binding generator bugs and prepare for Go 1.24 (#4045)
* Rename predicates source file

* Overhaul and document type predicates

* Fix model collection logic for named types

* Fix map key type rendering

* Fix map creation code

* Fix rendering of structs that implement marshaler interfaces

* Fix type cycle detection to take type args into account

* Fix enum and typeparam field initialisation

* Improve unsupported type warnings

* Remove internal models file

* Deduplicate template code

* Accept generic aliases in static analyser

* Support new `encoding/json` flag `omitzero`

* Handle special cases when rendering generic aliases

* Update npm test dependencies

* Test class aliases and implicit private dependencies

* Test marshaler combinations

* Test map key types

* Remove bad map keys from unrelated tests

* Test service discovery through generic aliases

* Test generic aliases

* Test warning messages

* Disable go1.24 tests

* Update changelog

* Restore rendering of injected lines in index file

* Test directives

* Add wails:ignore directive

* Fix typo

* Move injections to the bottom of service files

* Handle errors from closing files

* Do not emit messages when services define only lifecycle methods

* Add internal directive for services and models

* Update changelog

* Fix error in service templates

* Test internal directive on services/models

* Fix error in index template

* Base testdata updates

* Testdata for class aliases and implicit private dependencies

* Testdata for marshaler combinations

* Testdata for map key types

* Testdata for bad map key fixes

* Add weakly typed enums aka alias constants

* Testdata for enum and typeparam field fixes

* Testdata for generic aliases

* Testdata for warning messages

* Testdata for directives

* Testdata for weakly typed enums

* Update binding example

* Update services example

* Remove go1.24 testdata

* Update cli doc

* Fix analyser tests

* Fix windows tests... hopefully

* go mod tidy on examples

* Update bindings guide

---------

Co-authored-by: Lea Anthony <lea.anthony@gmail.com>
2025-02-09 09:44:34 +11:00

108 lines
2.6 KiB
Go

package render
import (
"fmt"
"go/types"
"math/big"
"strconv"
"strings"
"text/template"
"github.com/wailsapp/wails/v3/internal/generator/collect"
)
// tmplFunctions holds a map of utility functions
// that should be available in every template.
var tmplFunctions = template.FuncMap{
"fixext": fixext,
"hasdoc": hasdoc,
"isjsdocid": isjsdocid,
"isjsdocobj": isjsdocobj,
"istpalias": istpalias,
"jsdoc": jsdoc,
"jsdocline": jsdocline,
"jsid": jsid,
"jsimport": jsimport,
"jsparam": jsparam,
"jsvalue": jsvalue,
"modelinfo": modelinfo,
"typeparam": typeparam,
"unalias": types.Unalias,
}
// fixext replaces a *.ts extension with *.js in the given string.
// This is necessary to allow emitting javascript with the Typescript compiler.
func fixext(path string) string {
if strings.HasSuffix(path, ".ts") {
return path[:len(path)-3] + ".js"
} else {
return path
}
}
// jsimport formats an external import name
// by joining the name with its occurrence index.
// Names are modified even when the index is 0
// to avoid collisions with Go identifiers.
func jsimport(info collect.ImportInfo) string {
return fmt.Sprintf("%s$%d", info.Name, info.Index)
}
// jsparam renders the JS name of a parameter.
// Blank parameters are replaced with a dollar sign followed by the given index.
// Non-blank parameters are escaped by [jsid].
func jsparam(index int, param *collect.ParamInfo) string {
if param.Blank {
return "$" + strconv.Itoa(index)
} else {
return jsid(param.Name)
}
}
// typeparam renders the TS name of a type parameter.
// Blank parameters are replaced with a double dollar sign
// followed by the given index.
// Non-blank parameters are escaped with jsid.
func typeparam(index int, param string) string {
if param == "" || param == "_" {
return "$$" + strconv.Itoa(index)
} else {
return jsid(param)
}
}
// jsvalue renders a Go constant value to its Javascript representation.
func jsvalue(value any) string {
switch v := value.(type) {
case bool:
if v {
return "true"
} else {
return "false"
}
case string:
return fmt.Sprintf(`"%s"`, template.JSEscapeString(v))
case int64:
return strconv.FormatInt(v, 10)
case *big.Int:
return v.String()
case *big.Float:
return v.Text('e', -1)
case *big.Rat:
return v.RatString()
}
// Fall back to undefined.
return "(void(0))"
}
// istpalias determines whether typ is an alias
// that when uninstantiated resolves to a typeparam.
func istpalias(typ types.Type) bool {
if alias, ok := typ.(*types.Alias); ok {
return collect.IsTypeParam(alias.Origin())
}
return false
}