5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-04 09:39:56 +08:00
wails/v3/internal/generator/service.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

103 lines
2.4 KiB
Go

package generator
import (
"go/types"
"path/filepath"
)
// generateService collects information
// and generates JS/TS binding code
// for the given service type object.
func (generator *Generator) generateService(obj *types.TypeName) {
generator.logger.Debugf(
"discovered service type %s from package %s",
obj.Name(),
obj.Pkg().Path(),
)
success := false
defer func() {
if !success {
generator.logger.Errorf(
"package %s: type %s: service code generation failed",
obj.Pkg().Path(),
obj.Name(),
)
}
}()
// Collect service information.
info := generator.collector.Service(obj).Collect()
if info == nil {
return
}
if info.IsEmpty() {
if !info.HasInternalMethods {
generator.logger.Infof(
"package %s: type %s: service has no valid exported methods, skipping",
obj.Pkg().Path(),
obj.Name(),
)
}
success = true
return
}
// Check for standard filename collisions.
filename := generator.renderer.ServiceFile(info.Name)
switch filename {
case generator.renderer.ModelsFile():
generator.logger.Errorf(
"package %s: type %s: service filename collides with models filename; please rename the type or choose a different filename for models",
obj.Pkg().Path(),
obj.Name(),
)
return
case generator.renderer.IndexFile():
if !generator.options.NoIndex {
generator.logger.Errorf(
"package %s: type %s: service filename collides with JS/TS index filename; please rename the type or choose a different filename for JS/TS indexes",
obj.Pkg().Path(),
obj.Name(),
)
return
}
}
// Check for upper/lower-case filename collisions.
path := filepath.Join(info.Imports.Self, filename)
if other, present := generator.serviceFiles.LoadOrStore(path, obj); present {
generator.logger.Errorf(
"package %s: type %s: service filename collides with filename for service %s; please avoid multiple services whose names differ only in case",
obj.Pkg().Path(),
obj.Name(),
other.(*types.TypeName).Name(),
)
return
}
// Create service file.
file, err := generator.creator.Create(path)
if err != nil {
generator.logger.Errorf("%v", err)
return
}
defer func() {
if err := file.Close(); err != nil {
generator.logger.Errorf("%v", err)
success = false
}
}()
// Render service code.
err = generator.renderer.Service(file, info)
if err != nil {
generator.logger.Errorf("%v", err)
return
}
success = true
}