mirror of
https://github.com/wailsapp/wails.git
synced 2026-03-14 14:45:49 +01:00
Support generating enums from imported package
This commit is contained in:
parent
e0b8da86ed
commit
cdf4bdd2ba
9 changed files with 105 additions and 67 deletions
|
|
@ -46,8 +46,7 @@ func TestGenerateBindings(t *testing.T) {
|
|||
{
|
||||
"testdata/enum_from_imported_package",
|
||||
map[string]string{
|
||||
"main": getFile("testdata/enum_from_imported_package/bindings_main.js"),
|
||||
"services": getFile("testdata/enum_from_imported_package/bindings_services.js"),
|
||||
"main": getFile("testdata/enum_from_imported_package/bindings_main.js"),
|
||||
},
|
||||
true,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ func pkgAlias(fullPkg string) string {
|
|||
}
|
||||
|
||||
func GenerateModels(models map[packagePath]map[structName]*StructDef, enums map[packagePath]map[string]*TypeDef, options *flags.GenerateBindingsOptions) (string, error) {
|
||||
if models == nil {
|
||||
if models == nil && enums == nil {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
|
|
@ -71,6 +71,9 @@ func GenerateModels(models map[packagePath]map[structName]*StructDef, enums map[
|
|||
for pkg := range models {
|
||||
keys = append(keys, pkg)
|
||||
}
|
||||
for pkg := range enums {
|
||||
keys = append(keys, pkg)
|
||||
}
|
||||
|
||||
sort.Slice(keys, func(i, j int) bool {
|
||||
return pkgAlias(keys[i]) < pkgAlias(keys[j])
|
||||
|
|
|
|||
|
|
@ -99,6 +99,18 @@ func TestGenerateModels(t *testing.T) {
|
|||
dir: "testdata/enum",
|
||||
want: getFile("testdata/enum/models.js"),
|
||||
},
|
||||
{
|
||||
name: "enum from imported package",
|
||||
dir: "testdata/enum_from_imported_package",
|
||||
want: getFile("testdata/enum_from_imported_package/models.ts"),
|
||||
useTypescript: true,
|
||||
},
|
||||
{
|
||||
name: "enum from imported package",
|
||||
dir: "testdata/enum_from_imported_package",
|
||||
want: getFile("testdata/enum_from_imported_package/models.js"),
|
||||
useTypescript: false,
|
||||
},
|
||||
{
|
||||
name: "enum interface",
|
||||
dir: "testdata/enum-interface",
|
||||
|
|
|
|||
|
|
@ -403,6 +403,7 @@ func (p *Project) parseDirectory(dir string) (map[string]*ParsedPackage, error)
|
|||
StructCache: make(map[structName]*StructDef),
|
||||
TypeCache: make(map[string]*TypeDef),
|
||||
}
|
||||
p.parseTypes(map[string]*ParsedPackage{packageName: parsedPackage})
|
||||
p.packageCache[packageName] = parsedPackage
|
||||
result[packageName] = parsedPackage
|
||||
}
|
||||
|
|
@ -413,6 +414,8 @@ func (p *Project) findApplicationNewCalls(pkgs map[string]*ParsedPackage) (err e
|
|||
|
||||
var callFound bool
|
||||
|
||||
p.parseTypes(pkgs)
|
||||
|
||||
for _, pkg := range pkgs {
|
||||
thisPackage := pkg.Pkg
|
||||
// Iterate through the package's files
|
||||
|
|
@ -701,6 +704,14 @@ func (p *Project) parseParameterType(field *ast.Field, pkg *ParsedPackage) *Para
|
|||
log.Fatal(err)
|
||||
}
|
||||
result.IsStruct = p.getStructDef(t.Sel.Name, extPackage)
|
||||
if !result.IsStruct {
|
||||
// Check if it's a type alias
|
||||
typeDef, ok := extPackage.TypeCache[t.Sel.Name]
|
||||
if ok {
|
||||
typeDef.ShouldGenerate = true
|
||||
result.IsEnum = true
|
||||
}
|
||||
}
|
||||
result.Package = extPackage.Path
|
||||
case *ast.ArrayType:
|
||||
result.IsSlice = true
|
||||
|
|
@ -814,8 +825,13 @@ func (p *Project) getParsedPackageFromName(packageName string, currentPackage *P
|
|||
Path: path,
|
||||
Dir: dir,
|
||||
StructCache: make(map[string]*StructDef),
|
||||
TypeCache: make(map[string]*TypeDef),
|
||||
}
|
||||
p.packageCache[path] = result
|
||||
|
||||
// Parse types
|
||||
p.parseTypes(map[string]*ParsedPackage{path: result})
|
||||
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
|
|
@ -832,7 +848,7 @@ func getPackageDir(importPath string) (string, error) {
|
|||
}
|
||||
|
||||
func (p *Project) getPackageFromPath(packagedir string, packagepath string) (*ast.Package, error) {
|
||||
impPkg, err := parser.ParseDir(token.NewFileSet(), packagedir, nil, parser.AllErrors)
|
||||
impPkg, err := parser.ParseDir(token.NewFileSet(), packagedir, nil, parser.AllErrors|parser.ParseComments)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -1074,6 +1090,42 @@ func (p *Project) RelativePackageDir(path string) string {
|
|||
return strings.TrimPrefix(path, p.Path)
|
||||
}
|
||||
|
||||
func (p *Project) parseTypes(pkgs map[string]*ParsedPackage) {
|
||||
for _, pkg := range pkgs {
|
||||
thisPackage := pkg.Pkg
|
||||
// Iterate through the package's files
|
||||
for _, file := range thisPackage.Files {
|
||||
// Use an ast.Inspector to find the calls to application.New
|
||||
ast.Inspect(file, func(n ast.Node) bool {
|
||||
// Check for const declaration
|
||||
genDecl, ok := n.(*ast.GenDecl)
|
||||
if ok {
|
||||
switch genDecl.Tok {
|
||||
case token.TYPE:
|
||||
var comments []string
|
||||
if genDecl.Doc != nil {
|
||||
comments = CommentGroupToText(genDecl.Doc)
|
||||
}
|
||||
for _, spec := range genDecl.Specs {
|
||||
if typeSpec, ok := spec.(*ast.TypeSpec); ok {
|
||||
p.parseTypeDeclaration(typeSpec, pkg, comments)
|
||||
}
|
||||
}
|
||||
case token.CONST:
|
||||
p.parseConstDeclaration(genDecl, pkg)
|
||||
default:
|
||||
}
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
}
|
||||
p.addTypes(pkg.Path, pkg.TypeCache)
|
||||
}
|
||||
}
|
||||
|
||||
func getTypeString(expr ast.Expr) string {
|
||||
switch t := expr.(type) {
|
||||
case *ast.Ident:
|
||||
|
|
|
|||
|
|
@ -2,13 +2,17 @@
|
|||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
/**
|
||||
* @typedef {import('./models').services.Title} servicesTitle
|
||||
*/
|
||||
|
||||
export const GreetService = {
|
||||
|
||||
/**
|
||||
* GreetService.Greet
|
||||
* Greet does XYZ
|
||||
* @param name {string}
|
||||
* @param title {Title}
|
||||
* @param title {servicesTitle}
|
||||
* @returns {Promise<string>}
|
||||
**/
|
||||
Greet: function(name, title) { return wails.CallByID(1411160069, ...Array.prototype.slice.call(arguments, 0)); },
|
||||
|
|
|
|||
|
|
@ -2,13 +2,17 @@
|
|||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
/**
|
||||
* @typedef {import('./models').services.Title} servicesTitle
|
||||
*/
|
||||
|
||||
export const GreetService = {
|
||||
|
||||
/**
|
||||
* GreetService.Greet
|
||||
* Greet does XYZ
|
||||
* @param name {string}
|
||||
* @param title {Title}
|
||||
* @param title {servicesTitle}
|
||||
* @returns {Promise<string>}
|
||||
**/
|
||||
Greet: function(name, title) { return wails.CallByName("main.GreetService.Greet", ...Array.prototype.slice.call(arguments, 0)); },
|
||||
|
|
|
|||
|
|
@ -1,22 +0,0 @@
|
|||
// @ts-check
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
/**
|
||||
* @typedef {import('./models').services.Address} servicesAddress
|
||||
*/
|
||||
|
||||
|
||||
window.go = window.go || {};
|
||||
window.go.services = {
|
||||
OtherService: {
|
||||
|
||||
/**
|
||||
* OtherService.Yay
|
||||
*
|
||||
*
|
||||
* @returns {Promise<servicesAddress>}
|
||||
**/
|
||||
Yay: function() { return wails.CallByID(302702907, ...Array.prototype.slice.call(arguments, 0)); },
|
||||
},
|
||||
};
|
||||
17
v3/internal/parser/testdata/enum_from_imported_package/models.js
vendored
Normal file
17
v3/internal/parser/testdata/enum_from_imported_package/models.js
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
// @ts-check
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
// Defining the services namespace
|
||||
export const services = {};
|
||||
|
||||
// Simulating the enum with an object
|
||||
services.Title = {
|
||||
// Mister is a title
|
||||
Mister: "Mr",
|
||||
Miss: "Miss",
|
||||
Ms: "Ms",
|
||||
Mrs: "Mrs",
|
||||
Dr: "Dr",
|
||||
};
|
||||
|
||||
|
|
@ -2,46 +2,15 @@
|
|||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
export namespace main {
|
||||
|
||||
export class Person {
|
||||
name: string;
|
||||
address: services.Address;
|
||||
|
||||
constructor(source: Partial<Person> = {}) {
|
||||
const { name = "", address = null } = source;
|
||||
this.name = name;
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
static createFrom(source: string | object = {}): Person {
|
||||
let parsedSource = typeof source === 'string' ? JSON.parse(source) : source;
|
||||
return new Person(parsedSource as Partial<Person>);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export namespace services {
|
||||
|
||||
export class Address {
|
||||
street: string;
|
||||
state: string;
|
||||
country: string;
|
||||
|
||||
constructor(source: Partial<Address> = {}) {
|
||||
const { street = "", state = "", country = "" } = source;
|
||||
this.street = street;
|
||||
this.state = state;
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
static createFrom(source: string | object = {}): Address {
|
||||
let parsedSource = typeof source === 'string' ? JSON.parse(source) : source;
|
||||
return new Address(parsedSource as Partial<Address>);
|
||||
}
|
||||
|
||||
export enum Title {
|
||||
// Mister is a title
|
||||
Mister = "Mr",
|
||||
Miss = "Miss",
|
||||
Ms = "Ms",
|
||||
Mrs = "Mrs",
|
||||
Dr = "Dr",
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue