mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-04 03:10:22 +08:00
175 lines
4.0 KiB
Go
175 lines
4.0 KiB
Go
package parser
|
|
|
|
import (
|
|
"fmt"
|
|
"go/ast"
|
|
"strings"
|
|
)
|
|
|
|
// Method defines a struct method
|
|
type Method struct {
|
|
Name string
|
|
Comments []string
|
|
Inputs []*Field
|
|
Returns []*Field
|
|
}
|
|
|
|
func (p *Parser) parseStructMethods(boundStruct *Struct) error {
|
|
|
|
for _, fileAst := range boundStruct.Package.Gopackage.Syntax {
|
|
|
|
// Track errors
|
|
var parseError error
|
|
|
|
ast.Inspect(fileAst, func(n ast.Node) bool {
|
|
|
|
if funcDecl, ok := n.(*ast.FuncDecl); ok {
|
|
|
|
if funcDecl.Recv == nil {
|
|
return true
|
|
}
|
|
|
|
// This is a struct method
|
|
for _, field := range funcDecl.Recv.List {
|
|
switch f := field.Type.(type) {
|
|
case *ast.StarExpr:
|
|
// This is a struct pointer method
|
|
ident, ok := f.X.(*ast.Ident) // _ ?
|
|
if !ok {
|
|
continue
|
|
}
|
|
|
|
// Check this method is for this struct
|
|
if ident.Name != boundStruct.Name {
|
|
continue
|
|
}
|
|
|
|
// If this method is not Public, ignore
|
|
if string(funcDecl.Name.Name[0]) != strings.ToUpper((string(funcDecl.Name.Name[0]))) {
|
|
continue
|
|
}
|
|
|
|
// Create our struct
|
|
structMethod := &Method{
|
|
Name: funcDecl.Name.Name,
|
|
Comments: parseComments(funcDecl.Doc),
|
|
}
|
|
|
|
// Save the input parameters
|
|
if funcDecl.Type.Params != nil {
|
|
for _, inputField := range funcDecl.Type.Params.List {
|
|
fields, err := p.parseField(fileAst, inputField, boundStruct.Package)
|
|
if err != nil {
|
|
parseError = err
|
|
return false
|
|
}
|
|
|
|
// If this field was a struct, flag that it is used as data
|
|
if len(fields) > 0 {
|
|
if fields[0].Struct != nil {
|
|
fields[0].Struct.IsUsedAsData = true
|
|
}
|
|
}
|
|
|
|
structMethod.Inputs = append(structMethod.Inputs, fields...)
|
|
}
|
|
}
|
|
|
|
// Save the output parameters
|
|
if funcDecl.Type.Results != nil {
|
|
for _, outputField := range funcDecl.Type.Results.List {
|
|
fields, err := p.parseField(fileAst, outputField, boundStruct.Package)
|
|
if err != nil {
|
|
parseError = err
|
|
return false
|
|
}
|
|
|
|
// If this field was a struct, flag that it is used as data
|
|
if len(fields) > 0 {
|
|
if fields[0].Struct != nil {
|
|
fields[0].Struct.IsUsedAsData = true
|
|
}
|
|
}
|
|
|
|
structMethod.Returns = append(structMethod.Returns, fields...)
|
|
}
|
|
}
|
|
|
|
// Append this method to the parsed struct
|
|
boundStruct.Methods = append(boundStruct.Methods, structMethod)
|
|
|
|
default:
|
|
// Unsupported
|
|
continue
|
|
}
|
|
}
|
|
}
|
|
return true
|
|
})
|
|
|
|
// If we got an error, return it
|
|
if parseError != nil {
|
|
return parseError
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// InputsAsTSText generates a string with the method inputs
|
|
// formatted in a way acceptable to Typescript
|
|
func (m *Method) InputsAsTSText(pkgName string) string {
|
|
var inputs []string
|
|
|
|
for _, input := range m.Inputs {
|
|
inputText := fmt.Sprintf("%s: %s", input.Name, goTypeToTS(input, pkgName))
|
|
inputs = append(inputs, inputText)
|
|
}
|
|
|
|
return strings.Join(inputs, ", ")
|
|
}
|
|
|
|
// OutputsAsTSText generates a string with the method inputs
|
|
// formatted in a way acceptable to Javascript
|
|
func (m *Method) OutputsAsTSText(pkgName string) string {
|
|
|
|
if len(m.Returns) == 0 {
|
|
return "void"
|
|
}
|
|
|
|
var result []string
|
|
|
|
for _, output := range m.Returns {
|
|
result = append(result, goTypeToTS(output, pkgName))
|
|
}
|
|
return strings.Join(result, ", ")
|
|
}
|
|
|
|
// OutputsAsTSDeclarationText generates a string with the method inputs
|
|
// formatted in a way acceptable to Javascript
|
|
func (m *Method) OutputsAsTSDeclarationText(pkgName string) string {
|
|
|
|
if len(m.Returns) == 0 {
|
|
return "void"
|
|
}
|
|
|
|
var result []string
|
|
|
|
for _, output := range m.Returns {
|
|
result = append(result, goTypeToTSDeclaration(output, pkgName))
|
|
}
|
|
return strings.Join(result, ", ")
|
|
}
|
|
|
|
// InputsAsJSText generates a string with the method inputs
|
|
// formatted in a way acceptable to Javascript
|
|
func (m *Method) InputsAsJSText() string {
|
|
var inputs []string
|
|
|
|
for _, input := range m.Inputs {
|
|
inputs = append(inputs, input.Name)
|
|
}
|
|
|
|
return strings.Join(inputs, ", ")
|
|
}
|