Repository: go-critic/go-critic (go)

Issue:
Consider ignoring some common methods in hugeParam checker
For example, `String() string` method sometimes is defined on the value to make it possible to pass it as `%s` value.

```
package main

import "fmt"

type examplePtr struct{}

func (*examplePtr) String() string { return "PTR" }

type exampleValue struct{}

func (exampleValue) String() string { return "VALUE" }

func main() {
	ptr1 := examplePtr{}
	ptr2 := &examplePtr{}
	val1 := exampleValue{}
	val2 := &exampleValue{}
	fmt.Printf("%s %s %s %s\n", ptr1, ptr2, val1, val2)
}
```
https://go.dev/play/p/s7MxcI4YVWX
For ptr receiver, `ptr1` will not produce `PTR` string.


Pull request description:
checkers/hugeParam: ignore method String() string.
Fixes #1168.

Patch:
diff --git a/checkers/hugeParam_checker.go b/checkers/hugeParam_checker.go
index 3b7f1d1..7b7a3c5 100644
--- a/checkers/hugeParam_checker.go
+++ b/checkers/hugeParam_checker.go
@@ -5,6 +5,8 @@ import (
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
 	"github.com/go-critic/go-critic/linter"
+
+	"github.com/go-toolsmith/astcast"
 )
 
 func init() {
@@ -39,12 +41,30 @@ type hugeParamChecker struct {
 func (c *hugeParamChecker) VisitFuncDecl(decl *ast.FuncDecl) {
 	// TODO(quasilyte): maybe it's worthwhile to permit skipping
 	// test files for this checker?
+	if c.isImplementStringer(decl) {
+		return
+	}
+
 	if decl.Recv != nil {
 		c.checkParams(decl.Recv.List)
 	}
 	c.checkParams(decl.Type.Params.List)
 }
 
+// isImplementStringer check method signature is: String() string.
+func (*hugeParamChecker) isImplementStringer(decl *ast.FuncDecl) bool {
+	if decl.Recv != nil &&
+		decl.Name.Name == "String" &&
+		decl.Type != nil &&
+		len(decl.Type.Params.List) == 0 &&
+		len(decl.Type.Results.List) == 1 &&
+		astcast.ToIdent(decl.Type.Results.List[0].Type).Name == "string" {
+		return true
+	}
+
+	return false
+}
+
 func (c *hugeParamChecker) checkParams(params []*ast.Field) {
 	for _, p := range params {
 		for _, id := range p.Names {


Test patch:
diff --git a/checkers/testdata/hugeParam/negative_tests.go b/checkers/testdata/hugeParam/negative_tests.go
index 6bd3eca..b2b4eaf 100644
--- a/checkers/testdata/hugeParam/negative_tests.go
+++ b/checkers/testdata/hugeParam/negative_tests.go
@@ -17,3 +17,6 @@ func bigStructPtr2(x, y *bigStruct) {}
 func mixedBigObjectsPtr(x *bigStruct, y *[20][]int) {}
 
 func (x *bigStruct) bigRecvPtr(y *[2]bigStruct) {}
+
+// String must be ignored #1168.
+func (x bigStruct) String() string { return "" }