From ab9076301540d3a794c21f7fe4f87166a1d3bcf8 Mon Sep 17 00:00:00 2001
From: raeperd <41039751+raeperd@users.noreply.github.com>
Date: Sun, 15 Sep 2024 06:31:45 +0900
Subject: [PATCH] Add recvcheck linter (#5014)

---
 .golangci.next.reference.yml                  |  2 ++
 go.mod                                        |  1 +
 go.sum                                        |  2 ++
 jsonschema/golangci.next.jsonschema.json      |  1 +
 pkg/golinters/recvcheck/recvcheck.go          | 19 +++++++++++++++++++
 .../recvcheck/recvcheck_integration_test.go   | 11 +++++++++++
 pkg/golinters/recvcheck/testdata/recvcheck.go | 14 ++++++++++++++
 pkg/lint/lintersdb/builder_linter.go          |  7 +++++++
 8 files changed, 57 insertions(+)
 create mode 100644 pkg/golinters/recvcheck/recvcheck.go
 create mode 100644 pkg/golinters/recvcheck/recvcheck_integration_test.go
 create mode 100644 pkg/golinters/recvcheck/testdata/recvcheck.go

diff --git a/.golangci.next.reference.yml b/.golangci.next.reference.yml
index 4d5d5c88..9f7ca0f0 100644
--- a/.golangci.next.reference.yml
+++ b/.golangci.next.reference.yml
@@ -2689,6 +2689,7 @@ linters:
     - promlinter
     - protogetter
     - reassign
+    - recvcheck
     - revive
     - rowserrcheck
     - sloglint
@@ -2804,6 +2805,7 @@ linters:
     - promlinter
     - protogetter
     - reassign
+    - recvcheck
     - revive
     - rowserrcheck
     - sloglint
diff --git a/go.mod b/go.mod
index 051df607..813bb1b8 100644
--- a/go.mod
+++ b/go.mod
@@ -86,6 +86,7 @@ require (
 	github.com/pelletier/go-toml/v2 v2.2.3
 	github.com/polyfloyd/go-errorlint v1.6.0
 	github.com/quasilyte/go-ruleguard/dsl v0.3.22
+	github.com/raeperd/recvcheck v0.1.2
 	github.com/ryancurrah/gomodguard v1.3.5
 	github.com/ryanrolds/sqlclosecheck v0.5.1
 	github.com/sanposhiho/wastedassign/v2 v2.0.7
diff --git a/go.sum b/go.sum
index a8b2a42c..79a674ce 100644
--- a/go.sum
+++ b/go.sum
@@ -458,6 +458,8 @@ github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 h1:TCg2WBOl
 github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0=
 github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4lu7Gd+PU1fV2/qnDNfzT635KRSObncs=
 github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ=
+github.com/raeperd/recvcheck v0.1.2 h1:SjdquRsRXJc26eSonWIo8b7IMtKD3OAT2Lb5G3ZX1+4=
+github.com/raeperd/recvcheck v0.1.2/go.mod h1:n04eYkwIR0JbgD73wT8wL4JjPC3wm0nFtzBnWNocnYU=
 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
 github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
diff --git a/jsonschema/golangci.next.jsonschema.json b/jsonschema/golangci.next.jsonschema.json
index e137b14c..ebe16acc 100644
--- a/jsonschema/golangci.next.jsonschema.json
+++ b/jsonschema/golangci.next.jsonschema.json
@@ -388,6 +388,7 @@
             "promlinter",
             "protogetter",
             "reassign",
+            "recvcheck",
             "revive",
             "rowserrcheck",
             "scopelint",
diff --git a/pkg/golinters/recvcheck/recvcheck.go b/pkg/golinters/recvcheck/recvcheck.go
new file mode 100644
index 00000000..8b030f15
--- /dev/null
+++ b/pkg/golinters/recvcheck/recvcheck.go
@@ -0,0 +1,19 @@
+package recvcheck
+
+import (
+	"github.com/raeperd/recvcheck"
+	"golang.org/x/tools/go/analysis"
+
+	"github.com/golangci/golangci-lint/pkg/goanalysis"
+)
+
+func New() *goanalysis.Linter {
+	a := recvcheck.Analyzer
+
+	return goanalysis.NewLinter(
+		a.Name,
+		a.Doc,
+		[]*analysis.Analyzer{a},
+		nil,
+	).WithLoadMode(goanalysis.LoadModeTypesInfo)
+}
diff --git a/pkg/golinters/recvcheck/recvcheck_integration_test.go b/pkg/golinters/recvcheck/recvcheck_integration_test.go
new file mode 100644
index 00000000..7e0931b1
--- /dev/null
+++ b/pkg/golinters/recvcheck/recvcheck_integration_test.go
@@ -0,0 +1,11 @@
+package recvcheck_test
+
+import (
+	"testing"
+
+	"github.com/golangci/golangci-lint/test/testshared/integration"
+)
+
+func TestFromTestdata(t *testing.T) {
+	integration.RunTestdata(t)
+}
diff --git a/pkg/golinters/recvcheck/testdata/recvcheck.go b/pkg/golinters/recvcheck/testdata/recvcheck.go
new file mode 100644
index 00000000..9dea954e
--- /dev/null
+++ b/pkg/golinters/recvcheck/testdata/recvcheck.go
@@ -0,0 +1,14 @@
+//golangcitest:args -Erecvcheck
+package testdata
+
+import "fmt"
+
+type Bar struct{} // want `the methods of "Bar" use pointer receiver and non-pointer receiver.`
+
+func (b Bar) A() {
+	fmt.Println("A")
+}
+
+func (b *Bar) B() {
+	fmt.Println("B")
+}
diff --git a/pkg/lint/lintersdb/builder_linter.go b/pkg/lint/lintersdb/builder_linter.go
index c06cd9a0..837eaf03 100644
--- a/pkg/lint/lintersdb/builder_linter.go
+++ b/pkg/lint/lintersdb/builder_linter.go
@@ -85,6 +85,7 @@ import (
 	"github.com/golangci/golangci-lint/pkg/golinters/promlinter"
 	"github.com/golangci/golangci-lint/pkg/golinters/protogetter"
 	"github.com/golangci/golangci-lint/pkg/golinters/reassign"
+	"github.com/golangci/golangci-lint/pkg/golinters/recvcheck"
 	"github.com/golangci/golangci-lint/pkg/golinters/revive"
 	"github.com/golangci/golangci-lint/pkg/golinters/rowserrcheck"
 	"github.com/golangci/golangci-lint/pkg/golinters/sloglint"
@@ -657,6 +658,12 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
 			WithLoadForGoAnalysis().
 			WithURL("https://github.com/curioswitch/go-reassign"),
 
+		linter.NewConfig(recvcheck.New()).
+			WithSince("v1.62.0").
+			WithPresets(linter.PresetBugs).
+			WithLoadForGoAnalysis().
+			WithURL("https://github.com/raeperd/recvcheck"),
+
 		linter.NewConfig(revive.New(&cfg.LintersSettings.Revive)).
 			WithSince("v1.37.0").
 			WithPresets(linter.PresetStyle, linter.PresetMetaLinter).