From dc0d99a8e94da4908dae8bbb5bfd45af65ea8217 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Tue, 21 Feb 2023 07:52:29 +1100 Subject: [PATCH] Cover all type combinations Fix bug in pointer type resolution --- v3/internal/parser/README.md | 18 +- v3/internal/parser/parser.go | 9 +- .../{parser_test.go => parser_types_test.go} | 475 ++++++++++++++++++ .../testdata/struct_literal_single/main.go | 93 ++++ 4 files changed, 582 insertions(+), 13 deletions(-) rename v3/internal/parser/{parser_test.go => parser_types_test.go} (52%) diff --git a/v3/internal/parser/README.md b/v3/internal/parser/README.md index 7b24c47d1..179bc16f8 100644 --- a/v3/internal/parser/README.md +++ b/v3/internal/parser/README.md @@ -16,23 +16,23 @@ This package contains the static analyser used for parsing Wails projects so tha - [x] Multiple input parameters - [x] Multiple output parameters - [x] Named output parameters - - [x] int + - [x] int/8/16/32/64 + - [x] Pointer + - [x] uint/8/16/32/64 - [x] Pointer - - [x] uint - - [ ] Pointer - [x] float - - [ ] Pointer + - [x] Pointer - [x] string - - [ ] Pointer + - [x] Pointer - [x] bool - - [ ] Pointer + - [x] Pointer - [ ] Struct - [x] Pointer - - [x] Slices - - [ ] Pointer - [x] Recursive + - [x] Slices + - [x] Pointer - [x] Maps - - [ ] Pointer + - [x] Pointer - [ ] Model Parsing - [x] In same package - [ ] In different package diff --git a/v3/internal/parser/parser.go b/v3/internal/parser/parser.go index 14f2aaa90..a9ddab3f2 100644 --- a/v3/internal/parser/parser.go +++ b/v3/internal/parser/parser.go @@ -341,12 +341,13 @@ func (p *Project) parseParameters(params *ast.FieldList, pkg *ParsedPackage) []* } func (p *Project) parseParameterType(field *ast.Field, pkg *ParsedPackage) *ParameterType { - var result ParameterType + result := &ParameterType{} result.Name = getTypeString(field.Type) switch t := field.Type.(type) { case *ast.StarExpr: - result.IsStruct = isStructType(t.X) + result = p.parseParameterType(&ast.Field{Type: t.X}, pkg) result.IsPointer = true + result.IsStruct = isStructType(t.X) case *ast.StructType: result.IsStruct = true case *ast.ArrayType: @@ -365,7 +366,7 @@ func (p *Project) parseParameterType(field *ast.Field, pkg *ParsedPackage) *Para p.getStructDef(result.Name, pkg) } } - return &result + return result } func (p *Project) getStructDef(name string, pkg *ParsedPackage) { @@ -467,7 +468,7 @@ func isStructType(expr ast.Expr) bool { } func getDirectoryForPackage(pkg *ast.Package) string { - for filename, _ := range pkg.Files { + for filename := range pkg.Files { path := filepath.Dir(filename) abs, err := filepath.Abs(path) if err != nil { diff --git a/v3/internal/parser/parser_test.go b/v3/internal/parser/parser_types_test.go similarity index 52% rename from v3/internal/parser/parser_test.go rename to v3/internal/parser/parser_types_test.go index 2800c627a..0a49be04c 100644 --- a/v3/internal/parser/parser_test.go +++ b/v3/internal/parser/parser_types_test.go @@ -166,6 +166,206 @@ func TestParseDirectory(t *testing.T) { }}, }, }, + { + Name: "UIntPointerInAndOutput", + Inputs: []*Parameter{ + { + Name: "in", + Type: &ParameterType{ + Name: "uint", + IsPointer: true, + }, + }, + }, + Outputs: []*Parameter{ + { + Type: &ParameterType{ + Name: "uint", + IsPointer: true, + }, + }, + }, + }, + { + Name: "UInt8PointerInAndOutput", + Inputs: []*Parameter{ + { + Name: "in", + Type: &ParameterType{ + Name: "uint8", + IsPointer: true, + }, + }, + }, + Outputs: []*Parameter{ + { + Type: &ParameterType{ + Name: "uint8", + IsPointer: true, + }, + }, + }, + }, + { + Name: "UInt16PointerInAndOutput", + Inputs: []*Parameter{ + { + Name: "in", + Type: &ParameterType{ + Name: "uint16", + IsPointer: true, + }, + }, + }, + Outputs: []*Parameter{ + { + Type: &ParameterType{ + Name: "uint16", + IsPointer: true, + }, + }, + }, + }, + { + Name: "UInt32PointerInAndOutput", + Inputs: []*Parameter{ + { + Name: "in", + Type: &ParameterType{ + Name: "uint32", + IsPointer: true, + }, + }, + }, + Outputs: []*Parameter{ + { + Type: &ParameterType{ + Name: "uint32", + IsPointer: true, + }, + }, + }, + }, + { + Name: "UInt64PointerInAndOutput", + Inputs: []*Parameter{ + { + Name: "in", + Type: &ParameterType{ + Name: "uint64", + IsPointer: true, + }, + }, + }, + Outputs: []*Parameter{ + { + Type: &ParameterType{ + Name: "uint64", + IsPointer: true, + }, + }, + }, + }, + { + Name: "IntPointerInAndOutput", + Inputs: []*Parameter{ + { + Name: "in", + Type: &ParameterType{ + Name: "int", + IsPointer: true, + }, + }, + }, + Outputs: []*Parameter{ + { + Type: &ParameterType{ + Name: "int", + IsPointer: true, + }, + }, + }, + }, + { + Name: "Int8PointerInAndOutput", + Inputs: []*Parameter{ + { + Name: "in", + Type: &ParameterType{ + Name: "int8", + IsPointer: true, + }, + }, + }, + Outputs: []*Parameter{ + { + Type: &ParameterType{ + Name: "int8", + IsPointer: true, + }, + }, + }, + }, + { + Name: "Int16PointerInAndOutput", + Inputs: []*Parameter{ + { + Name: "in", + Type: &ParameterType{ + Name: "int16", + IsPointer: true, + }, + }, + }, + Outputs: []*Parameter{ + { + Type: &ParameterType{ + Name: "int16", + IsPointer: true, + }, + }, + }, + }, + { + Name: "Int32PointerInAndOutput", + Inputs: []*Parameter{ + { + Name: "in", + Type: &ParameterType{ + Name: "int32", + IsPointer: true, + }, + }, + }, + Outputs: []*Parameter{ + { + Type: &ParameterType{ + Name: "int32", + IsPointer: true, + }, + }, + }, + }, + { + Name: "Int64PointerInAndOutput", + Inputs: []*Parameter{ + { + Name: "in", + Type: &ParameterType{ + Name: "int64", + IsPointer: true, + }, + }, + }, + Outputs: []*Parameter{ + { + Type: &ParameterType{ + Name: "int64", + IsPointer: true, + }, + }, + }, + }, { Name: "IntInIntOut", Inputs: []*Parameter{ @@ -184,6 +384,78 @@ func TestParseDirectory(t *testing.T) { }, }, }, + { + Name: "Int8InIntOut", + Inputs: []*Parameter{ + { + Name: "in", + Type: &ParameterType{ + Name: "int8", + }, + }, + }, + Outputs: []*Parameter{ + { + Type: &ParameterType{ + Name: "int8", + }, + }, + }, + }, + { + Name: "Int16InIntOut", + Inputs: []*Parameter{ + { + Name: "in", + Type: &ParameterType{ + Name: "int16", + }, + }, + }, + Outputs: []*Parameter{ + { + Type: &ParameterType{ + Name: "int16", + }, + }, + }, + }, + { + Name: "Int32InIntOut", + Inputs: []*Parameter{ + { + Name: "in", + Type: &ParameterType{ + Name: "int32", + }, + }, + }, + Outputs: []*Parameter{ + { + Type: &ParameterType{ + Name: "int32", + }, + }, + }, + }, + { + Name: "Int64InIntOut", + Inputs: []*Parameter{ + { + Name: "in", + Type: &ParameterType{ + Name: "int64", + }, + }, + }, + Outputs: []*Parameter{ + { + Type: &ParameterType{ + Name: "int64", + }, + }, + }, + }, { Name: "UIntInUIntOut", Inputs: []*Parameter{ @@ -202,6 +474,78 @@ func TestParseDirectory(t *testing.T) { }, }, }, + { + Name: "UInt8InUIntOut", + Inputs: []*Parameter{ + { + Name: "in", + Type: &ParameterType{ + Name: "uint8", + }, + }, + }, + Outputs: []*Parameter{ + { + Type: &ParameterType{ + Name: "uint8", + }, + }, + }, + }, + { + Name: "UInt16InUIntOut", + Inputs: []*Parameter{ + { + Name: "in", + Type: &ParameterType{ + Name: "uint16", + }, + }, + }, + Outputs: []*Parameter{ + { + Type: &ParameterType{ + Name: "uint16", + }, + }, + }, + }, + { + Name: "UInt32InUIntOut", + Inputs: []*Parameter{ + { + Name: "in", + Type: &ParameterType{ + Name: "uint32", + }, + }, + }, + Outputs: []*Parameter{ + { + Type: &ParameterType{ + Name: "uint32", + }, + }, + }, + }, + { + Name: "UInt64InUIntOut", + Inputs: []*Parameter{ + { + Name: "in", + Type: &ParameterType{ + Name: "uint64", + }, + }, + }, + Outputs: []*Parameter{ + { + Type: &ParameterType{ + Name: "uint64", + }, + }, + }, + }, { Name: "Float32InFloat32Out", Inputs: []*Parameter{ @@ -238,6 +582,46 @@ func TestParseDirectory(t *testing.T) { }, }, }, + { + Name: "PointerFloat32InFloat32Out", + Inputs: []*Parameter{ + { + Name: "in", + Type: &ParameterType{ + Name: "float32", + IsPointer: true, + }, + }, + }, + Outputs: []*Parameter{ + { + Type: &ParameterType{ + Name: "float32", + IsPointer: true, + }, + }, + }, + }, + { + Name: "PointerFloat64InFloat64Out", + Inputs: []*Parameter{ + { + Name: "in", + Type: &ParameterType{ + Name: "float64", + IsPointer: true, + }, + }, + }, + Outputs: []*Parameter{ + { + Type: &ParameterType{ + Name: "float64", + IsPointer: true, + }, + }, + }, + }, { Name: "BoolInBoolOut", Inputs: []*Parameter{ @@ -256,6 +640,46 @@ func TestParseDirectory(t *testing.T) { }, }, }, + { + Name: "PointerBoolInBoolOut", + Inputs: []*Parameter{ + { + Name: "in", + Type: &ParameterType{ + Name: "bool", + IsPointer: true, + }, + }, + }, + Outputs: []*Parameter{ + { + Type: &ParameterType{ + Name: "bool", + IsPointer: true, + }, + }, + }, + }, + { + Name: "PointerStringInStringOut", + Inputs: []*Parameter{ + { + Name: "in", + Type: &ParameterType{ + Name: "string", + IsPointer: true, + }, + }, + }, + Outputs: []*Parameter{ + { + Type: &ParameterType{ + Name: "string", + IsPointer: true, + }, + }, + }, + }, { Name: "StructPointerInputErrorOutput", Inputs: []*Parameter{ @@ -316,6 +740,44 @@ func TestParseDirectory(t *testing.T) { }, Outputs: []*Parameter{}, }, + { + Name: "PointerMapIntInt", + Inputs: []*Parameter{ + { + Name: "in", + Type: &ParameterType{ + Name: "map", + IsPointer: true, + MapKey: &ParameterType{ + Name: "int", + }, + MapValue: &ParameterType{ + Name: "int", + }, + }, + }, + }, + Outputs: []*Parameter{}, + }, + { + Name: "MapIntPointerInt", + Inputs: []*Parameter{ + { + Name: "in", + Type: &ParameterType{ + Name: "map", + MapKey: &ParameterType{ + Name: "int", + IsPointer: true, + }, + MapValue: &ParameterType{ + Name: "int", + }, + }, + }, + }, + Outputs: []*Parameter{}, + }, { Name: "MapIntSliceInt", Inputs: []*Parameter{ @@ -368,6 +830,19 @@ func TestParseDirectory(t *testing.T) { }, }, }, + { + Name: "ArrayInt", + Inputs: []*Parameter{ + { + Name: "in", + Type: &ParameterType{ + Name: "int", + IsSlice: true, + }, + }, + }, + Outputs: []*Parameter{}, + }, }, }, }, diff --git a/v3/internal/parser/testdata/struct_literal_single/main.go b/v3/internal/parser/testdata/struct_literal_single/main.go index 57d5365ee..96732dd4e 100644 --- a/v3/internal/parser/testdata/struct_literal_single/main.go +++ b/v3/internal/parser/testdata/struct_literal_single/main.go @@ -48,24 +48,108 @@ func (*GreetService) IntPointerInputNamedOutputs(in *int) (output *int, err erro return in, nil } +func (*GreetService) UIntPointerInAndOutput(in *uint) *uint { + return in +} + +func (*GreetService) UInt8PointerInAndOutput(in *uint8) *uint8 { + return in +} + +func (*GreetService) UInt16PointerInAndOutput(in *uint16) *uint16 { + return in +} + +func (*GreetService) UInt32PointerInAndOutput(in *uint32) *uint32 { + return in +} + +func (*GreetService) UInt64PointerInAndOutput(in *uint64) *uint64 { + return in +} + +func (*GreetService) IntPointerInAndOutput(in *int) *int { + return in +} + +func (*GreetService) Int8PointerInAndOutput(in *int8) *int8 { + return in +} + +func (*GreetService) Int16PointerInAndOutput(in *int16) *int16 { + return in +} + +func (*GreetService) Int32PointerInAndOutput(in *int32) *int32 { + return in +} + +func (*GreetService) Int64PointerInAndOutput(in *int64) *int64 { + return in +} + func (*GreetService) IntInIntOut(in int) int { return in } +func (*GreetService) Int8InIntOut(in int8) int8 { + return in +} +func (*GreetService) Int16InIntOut(in int16) int16 { + return in +} +func (*GreetService) Int32InIntOut(in int32) int32 { + return in +} +func (*GreetService) Int64InIntOut(in int64) int64 { + return in +} + func (*GreetService) UIntInUIntOut(in uint) uint { return in } + +func (*GreetService) UInt8InUIntOut(in uint8) uint8 { + return in +} +func (*GreetService) UInt16InUIntOut(in uint16) uint16 { + return in +} +func (*GreetService) UInt32InUIntOut(in uint32) uint32 { + return in +} +func (*GreetService) UInt64InUIntOut(in uint64) uint64 { + return in +} + func (*GreetService) Float32InFloat32Out(in float32) float32 { return in } + func (*GreetService) Float64InFloat64Out(in float64) float64 { return in } +func (*GreetService) PointerFloat32InFloat32Out(in *float32) *float32 { + return in +} + +func (*GreetService) PointerFloat64InFloat64Out(in *float64) *float64 { + return in +} + func (*GreetService) BoolInBoolOut(in bool) bool { return in } +func (*GreetService) PointerBoolInBoolOut(in *bool) *bool { + return in +} + +func (*GreetService) PointerStringInStringOut(in *string) *string { + return in +} + func (*GreetService) StructPointerInputErrorOutput(in *Person) error { return nil } @@ -77,6 +161,12 @@ func (*GreetService) StructPointerInputStructPointerOutput(in *Person) *Person { func (*GreetService) MapIntInt(in map[int]int) { } +func (*GreetService) PointerMapIntInt(in *map[int]int) { +} + +func (*GreetService) MapIntPointerInt(in map[*int]int) { +} + func (*GreetService) MapIntSliceInt(in map[int][]int) { } @@ -84,6 +174,9 @@ func (*GreetService) MapIntSliceIntInMapIntSliceIntOut(in map[int][]int) (out ma return nil } +func (*GreetService) ArrayInt(in [4]int) { +} + func main() { app := application.New(application.Options{ Bind: []interface{}{