5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-06 16:49:12 +08:00
wails/v3/internal/generator/collect/index.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

122 lines
2.9 KiB
Go

package collect
import (
"slices"
"strings"
)
// PackageIndex lists all services, models and unexported models
// to be generated from a single package.
//
// When obtained through a call to [PackageInfo.Index],
// each service and model appears at most once;
// services and models are sorted
// by internal property (all exported first), then by name.
type PackageIndex struct {
Package *PackageInfo
Services []*ServiceInfo
HasExportedServices bool // If true, there is at least one exported service.
Models []*ModelInfo
HasExportedModels bool // If true, there is at least one exported model.
}
// Index computes a [PackageIndex] for the selected language from the list
// of generated services and models and regenerates cached stats.
//
// Services and models appear at most once in the returned slices;
// services are sorted by name;
// exported models precede all unexported ones
// and both ranges are sorted by name.
//
// Index calls info.Collect, and therefore provides the same guarantees.
// It is safe for concurrent use.
func (info *PackageInfo) Index(TS bool) (index *PackageIndex) {
// Init index.
index = &PackageIndex{
Package: info.Collect(),
}
// Init stats
stats := &Stats{
NumPackages: 1,
}
// Gather services.
for _, value := range info.services.Range {
service := value.(*ServiceInfo)
if !service.IsEmpty() {
index.Services = append(index.Services, service)
// Mark presence of exported services
if !service.Internal {
index.HasExportedServices = true
}
// Update service stats.
stats.NumServices++
stats.NumMethods += len(service.Methods)
}
}
// Sort services by internal property (exported first), then by name.
slices.SortFunc(index.Services, func(s1 *ServiceInfo, s2 *ServiceInfo) int {
if s1 == s2 {
return 0
}
if s1.Internal != s2.Internal {
if s1.Internal {
return 1
} else {
return -1
}
}
return strings.Compare(s1.Name, s2.Name)
})
// Gather models.
for _, value := range info.models.Range {
model := value.(*ModelInfo)
index.Models = append(index.Models, model)
// Mark presence of exported models
if !model.Internal {
index.HasExportedModels = true
}
// Update model stats.
if len(model.Values) > 0 {
stats.NumEnums++
} else {
stats.NumModels++
}
}
// Sort models by internal property (exported first), then by name.
slices.SortFunc(index.Models, func(m1 *ModelInfo, m2 *ModelInfo) int {
if m1 == m2 {
return 0
}
if m1.Internal != m2.Internal {
if m1.Internal {
return 1
} else {
return -1
}
}
return strings.Compare(m1.Name, m2.Name)
})
// Cache stats
info.stats.Store(stats)
return
}
// IsEmpty returns true if the given index
// contains no data for the selected language.
func (index *PackageIndex) IsEmpty() bool {
return !index.HasExportedServices && !index.HasExportedModels && len(index.Package.Injections) == 0
}