Skip to content

Commit

Permalink
checkers: supported generics for typeDefFirst and paramTypeCombine (#…
Browse files Browse the repository at this point in the history
…1239)

Fixes #1193
  • Loading branch information
mcdoker18 committed Aug 9, 2022
1 parent af0e6d7 commit f1528e1
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 4 deletions.
11 changes: 7 additions & 4 deletions checkers/paramTypeCombine_checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/go-critic/go-critic/checkers/internal/astwalk"
"github.com/go-critic/go-critic/framework/linter"
"github.com/go-toolsmith/astcopy"
"github.com/go-toolsmith/astequal"
)

Expand Down Expand Up @@ -38,10 +39,12 @@ func (c *paramTypeCombineChecker) VisitFuncDecl(decl *ast.FuncDecl) {
}

func (c *paramTypeCombineChecker) optimizeFuncType(f *ast.FuncType) *ast.FuncType {
return &ast.FuncType{
Params: c.optimizeParams(f.Params),
Results: c.optimizeParams(f.Results),
}
optimizedParamFunc := astcopy.FuncType(f)

optimizedParamFunc.Params = c.optimizeParams(f.Params)
optimizedParamFunc.Results = c.optimizeParams(f.Results)

return optimizedParamFunc
}
func (c *paramTypeCombineChecker) optimizeParams(params *ast.FieldList) *ast.FieldList {
// To avoid false positives, skip unnamed param lists.
Expand Down
17 changes: 17 additions & 0 deletions checkers/testdata/paramTypeCombine/negative_tests_go118.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//go:build go1.18
// +build go1.18

package checker_test

func genericGood1[T any](a T, b, c int) {}
func genericGood2[T any](a, b T, c int) {}
func genericGood3[T any](a T) {}
func genericGood4[T any]() {}
func genericGood5[T any, Y any](a, b T, c int, d, e Y) {}

func genericUnnamed[T any](T, T) {}

func genericUnnamedResults[T any]() (T, T) {
var t T
return t, t
}
21 changes: 21 additions & 0 deletions checkers/testdata/paramTypeCombine/positive_tests_go118.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//go:build go1.18
// +build go1.18

package checker_test

/*! func[T any]() (a T, b T, c T) could be replaced with func[T any]() (a, b, c T) */
func genericSimple1[T any]() (a T, b T, c T) { return a, b, c }

/*! func[T any](a T, b T, c T) could be replaced with func[T any](a, b, c T) */
func genericSimple2[T any](a T, b T, c T) {}

/*! func[T any, Y any](a T, b T, c int, d Y, e Y) could be replaced with func[T any, Y any](a, b T, c int, d, e Y) */
func genericMixed1[T any, Y any](a T, b T, c int, d Y, e Y) {}

/*! func[T any, Y any]() (a T, b T, c int, d Y, e Y) could be replaced with func[T any, Y any]() (a, b T, c int, d, e Y) */
func genericMixed2[T any, Y any]() (a T, b T, c int, d Y, e Y) { return a, b, c, d, e }

/*! func[T any](a T, b T, c int, d int32, e int32) (f int64, g int64, h T, k T) could be replaced with func[T any](a, b T, c int, d, e int32) (f, g int64, h, k T) */
func genericMixed3[T any](a T, b T, c int, d int32, e int32) (f int64, g int64, h T, k T) {
return f, g, h, k
}
14 changes: 14 additions & 0 deletions checkers/testdata/typeDefFirst/negative_tests_go118.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//go:build go1.18
// +build go1.18

package checker_test

type genericNegativeStruct[T any] struct{ _ []T }

func (_ genericNegativeStruct[T]) Method() {}
func (_ *genericNegativeStruct[T]) MethodWithRef() {}

type multiGenericNegativeStruct[T any, X any] struct{ _ []T }

func (_ multiGenericNegativeStruct[T, X]) Method() {}
func (_ *multiGenericNegativeStruct[T, X]) MethodWithRef() {}
14 changes: 14 additions & 0 deletions checkers/testdata/typeDefFirst/positive_tests_go118.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//go:build go1.18
// +build go1.18

package checker_test

func (_ genericPositiveStruct[T]) Method() {}

/*! definition of type 'genericPositiveStruct' should appear before its methods */
type genericPositiveStruct[T any] struct{ _ []T }

func (_ *multiGenericPositiveStruct[T, X]) MethodWithRef() {}

/*! definition of type 'multiGenericPositiveStruct' should appear before its methods */
type multiGenericPositiveStruct[T any, X any] struct{ _ []T }
5 changes: 5 additions & 0 deletions checkers/typeDefFirst_checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

"github.com/go-critic/go-critic/checkers/internal/astwalk"
"github.com/go-critic/go-critic/framework/linter"
"golang.org/x/exp/typeparams"
)

func init() {
Expand Down Expand Up @@ -78,6 +79,10 @@ func (c *typeDefFirstChecker) receiverType(e ast.Expr) string {
return c.receiverType(e.X)
case *ast.Ident:
return e.Name
case *ast.IndexExpr:
return c.receiverType(e.X)
case *typeparams.IndexListExpr:
return c.receiverType(e.X)
default:
panic("unreachable")
}
Expand Down

0 comments on commit f1528e1

Please sign in to comment.