From 846fab81b93caec135e8642be782bdaffe8fe2db Mon Sep 17 00:00:00 2001
From: Sven Anderson <sven-github@anderson.de>
Date: Sat, 30 Jul 2022 22:26:33 +0200
Subject: [PATCH] cgo: fix linters ignoring Cgo files (#3025)

---
 pkg/golinters/dupl.go                 |  6 +-----
 pkg/golinters/gci.go                  |  6 +-----
 pkg/golinters/gofmt.go                |  6 +-----
 pkg/golinters/gofumpt.go              |  6 +-----
 pkg/golinters/goimports.go            |  6 +-----
 pkg/golinters/gomodguard.go           |  7 +------
 pkg/golinters/lll.go                  |  6 +-----
 pkg/golinters/misspell.go             |  7 +------
 pkg/golinters/revive.go               |  6 +-----
 pkg/golinters/util.go                 | 17 +++++++++++++++++
 pkg/golinters/wsl.go                  |  6 +-----
 test/run_test.go                      |  8 ++++++--
 test/testdata/cgo_with_issues/main.go | 12 ++++++++++++
 13 files changed, 45 insertions(+), 54 deletions(-)

diff --git a/pkg/golinters/dupl.go b/pkg/golinters/dupl.go
index 8c8d8fe4..fe7b1277 100644
--- a/pkg/golinters/dupl.go
+++ b/pkg/golinters/dupl.go
@@ -55,11 +55,7 @@ func NewDupl(settings *config.DuplSettings) *goanalysis.Linter {
 }
 
 func runDupl(pass *analysis.Pass, settings *config.DuplSettings) ([]goanalysis.Issue, error) {
-	var fileNames []string
-	for _, f := range pass.Files {
-		pos := pass.Fset.PositionFor(f.Pos(), false)
-		fileNames = append(fileNames, pos.Filename)
-	}
+	fileNames := getFileNames(pass)
 
 	issues, err := duplAPI.Run(fileNames, settings.Threshold)
 	if err != nil {
diff --git a/pkg/golinters/gci.go b/pkg/golinters/gci.go
index 82eba2ff..0f719513 100644
--- a/pkg/golinters/gci.go
+++ b/pkg/golinters/gci.go
@@ -83,11 +83,7 @@ func NewGci(settings *config.GciSettings) *goanalysis.Linter {
 }
 
 func runGci(pass *analysis.Pass, lintCtx *linter.Context, cfg *gcicfg.Config, lock *sync.Mutex) ([]goanalysis.Issue, error) {
-	var fileNames []string
-	for _, f := range pass.Files {
-		pos := pass.Fset.PositionFor(f.Pos(), false)
-		fileNames = append(fileNames, pos.Filename)
-	}
+	fileNames := getFileNames(pass)
 
 	var diffs []string
 	err := diffFormattedFilesToArray(fileNames, *cfg, &diffs, lock)
diff --git a/pkg/golinters/gofmt.go b/pkg/golinters/gofmt.go
index 1d50bfc5..e8c02411 100644
--- a/pkg/golinters/gofmt.go
+++ b/pkg/golinters/gofmt.go
@@ -53,11 +53,7 @@ func NewGofmt(settings *config.GoFmtSettings) *goanalysis.Linter {
 }
 
 func runGofmt(lintCtx *linter.Context, pass *analysis.Pass, settings *config.GoFmtSettings) ([]goanalysis.Issue, error) {
-	var fileNames []string
-	for _, f := range pass.Files {
-		pos := pass.Fset.PositionFor(f.Pos(), false)
-		fileNames = append(fileNames, pos.Filename)
-	}
+	fileNames := getFileNames(pass)
 
 	var issues []goanalysis.Issue
 
diff --git a/pkg/golinters/gofumpt.go b/pkg/golinters/gofumpt.go
index 60d97b94..312dfd6d 100644
--- a/pkg/golinters/gofumpt.go
+++ b/pkg/golinters/gofumpt.go
@@ -73,11 +73,7 @@ func NewGofumpt(settings *config.GofumptSettings) *goanalysis.Linter {
 }
 
 func runGofumpt(lintCtx *linter.Context, pass *analysis.Pass, diff differ, options format.Options) ([]goanalysis.Issue, error) {
-	var fileNames []string
-	for _, f := range pass.Files {
-		pos := pass.Fset.PositionFor(f.Pos(), false)
-		fileNames = append(fileNames, pos.Filename)
-	}
+	fileNames := getFileNames(pass)
 
 	var issues []goanalysis.Issue
 
diff --git a/pkg/golinters/goimports.go b/pkg/golinters/goimports.go
index e59ee3dd..42aa69b4 100644
--- a/pkg/golinters/goimports.go
+++ b/pkg/golinters/goimports.go
@@ -55,11 +55,7 @@ func NewGoimports(settings *config.GoImportsSettings) *goanalysis.Linter {
 }
 
 func runGoiImports(lintCtx *linter.Context, pass *analysis.Pass) ([]goanalysis.Issue, error) {
-	var fileNames []string
-	for _, f := range pass.Files {
-		pos := pass.Fset.PositionFor(f.Pos(), false)
-		fileNames = append(fileNames, pos.Filename)
-	}
+	fileNames := getFileNames(pass)
 
 	var issues []goanalysis.Issue
 
diff --git a/pkg/golinters/gomodguard.go b/pkg/golinters/gomodguard.go
index 76dd6701..e21658d5 100644
--- a/pkg/golinters/gomodguard.go
+++ b/pkg/golinters/gomodguard.go
@@ -73,12 +73,7 @@ func NewGomodguard(settings *config.GoModGuardSettings) *goanalysis.Linter {
 		}
 
 		analyzer.Run = func(pass *analysis.Pass) (interface{}, error) {
-			var files []string
-			for _, file := range pass.Files {
-				files = append(files, pass.Fset.PositionFor(file.Pos(), false).Filename)
-			}
-
-			gomodguardIssues := processor.ProcessFiles(files)
+			gomodguardIssues := processor.ProcessFiles(getFileNames(pass))
 
 			mu.Lock()
 			defer mu.Unlock()
diff --git a/pkg/golinters/lll.go b/pkg/golinters/lll.go
index 65d4c15a..25b767a0 100644
--- a/pkg/golinters/lll.go
+++ b/pkg/golinters/lll.go
@@ -56,11 +56,7 @@ func NewLLL(settings *config.LllSettings) *goanalysis.Linter {
 }
 
 func runLll(pass *analysis.Pass, settings *config.LllSettings) ([]goanalysis.Issue, error) {
-	var fileNames []string
-	for _, f := range pass.Files {
-		pos := pass.Fset.PositionFor(f.Pos(), false)
-		fileNames = append(fileNames, pos.Filename)
-	}
+	fileNames := getFileNames(pass)
 
 	spaces := strings.Repeat(" ", settings.TabWidth)
 
diff --git a/pkg/golinters/misspell.go b/pkg/golinters/misspell.go
index 47eb7a7b..b5cc5c8a 100644
--- a/pkg/golinters/misspell.go
+++ b/pkg/golinters/misspell.go
@@ -61,12 +61,7 @@ func NewMisspell(settings *config.MisspellSettings) *goanalysis.Linter {
 }
 
 func runMisspell(lintCtx *linter.Context, pass *analysis.Pass, replacer *misspell.Replacer) ([]goanalysis.Issue, error) {
-	var fileNames []string
-
-	for _, f := range pass.Files {
-		pos := pass.Fset.PositionFor(f.Pos(), false)
-		fileNames = append(fileNames, pos.Filename)
-	}
+	fileNames := getFileNames(pass)
 
 	var issues []goanalysis.Issue
 	for _, filename := range fileNames {
diff --git a/pkg/golinters/revive.go b/pkg/golinters/revive.go
index 0e150720..906e1c3e 100644
--- a/pkg/golinters/revive.go
+++ b/pkg/golinters/revive.go
@@ -75,11 +75,7 @@ func NewRevive(settings *config.ReviveSettings) *goanalysis.Linter {
 }
 
 func runRevive(lintCtx *linter.Context, pass *analysis.Pass, settings *config.ReviveSettings) ([]goanalysis.Issue, error) {
-	var files []string
-	for _, file := range pass.Files {
-		files = append(files, pass.Fset.PositionFor(file.Pos(), false).Filename)
-	}
-	packages := [][]string{files}
+	packages := [][]string{getFileNames(pass)}
 
 	conf, err := getReviveConfig(settings)
 	if err != nil {
diff --git a/pkg/golinters/util.go b/pkg/golinters/util.go
index 1940f30e..1044567a 100644
--- a/pkg/golinters/util.go
+++ b/pkg/golinters/util.go
@@ -2,8 +2,11 @@ package golinters
 
 import (
 	"fmt"
+	"path/filepath"
 	"strings"
 
+	"golang.org/x/tools/go/analysis"
+
 	"github.com/golangci/golangci-lint/pkg/config"
 )
 
@@ -22,3 +25,17 @@ func formatCodeBlock(code string, _ *config.Config) string {
 
 	return fmt.Sprintf("```\n%s\n```", code)
 }
+
+func getFileNames(pass *analysis.Pass) []string {
+	var fileNames []string
+	for _, f := range pass.Files {
+		fileName := pass.Fset.PositionFor(f.Pos(), true).Filename
+		ext := filepath.Ext(fileName)
+		if ext != "" && ext != ".go" {
+			// position has been adjusted to a non-go file, revert to original file
+			fileName = pass.Fset.PositionFor(f.Pos(), false).Filename
+		}
+		fileNames = append(fileNames, fileName)
+	}
+	return fileNames
+}
diff --git a/pkg/golinters/wsl.go b/pkg/golinters/wsl.go
index 0b10798e..9d7060b0 100644
--- a/pkg/golinters/wsl.go
+++ b/pkg/golinters/wsl.go
@@ -67,15 +67,11 @@ func NewWSL(settings *config.WSLSettings) *goanalysis.Linter {
 }
 
 func runWSL(pass *analysis.Pass, conf *wsl.Configuration) []goanalysis.Issue {
-	var files = make([]string, 0, len(pass.Files))
-	for _, file := range pass.Files {
-		files = append(files, pass.Fset.PositionFor(file.Pos(), false).Filename)
-	}
-
 	if conf == nil {
 		return nil
 	}
 
+	files := getFileNames(pass)
 	wslErrors, _ := wsl.NewProcessorWithConfig(*conf).ProcessFiles(files)
 	if len(wslErrors) == 0 {
 		return nil
diff --git a/test/run_test.go b/test/run_test.go
index 254f6597..cf1f5549 100644
--- a/test/run_test.go
+++ b/test/run_test.go
@@ -95,7 +95,7 @@ func TestTestsAreLintedByDefault(t *testing.T) {
 }
 
 func TestCgoOk(t *testing.T) {
-	testshared.NewLintRunner(t).Run("--no-config", "--enable-all", "-D", "nosnakecase", getTestDataDir("cgo")).ExpectNoIssues()
+	testshared.NewLintRunner(t).Run("--no-config", "--enable-all", "-D", "nosnakecase,gci", getTestDataDir("cgo")).ExpectNoIssues()
 }
 
 func TestCgoWithIssues(t *testing.T) {
@@ -104,6 +104,10 @@ func TestCgoWithIssues(t *testing.T) {
 		ExpectHasIssue("Printf format %t has arg cs of wrong type")
 	r.Run("--no-config", "--disable-all", "-Estaticcheck", getTestDataDir("cgo_with_issues")).
 		ExpectHasIssue("SA5009: Printf format %t has arg #1 of wrong type")
+	r.Run("--no-config", "--disable-all", "-Egofmt", getTestDataDir("cgo_with_issues")).
+		ExpectHasIssue("File is not `gofmt`-ed with `-s` (gofmt)")
+	r.Run("--no-config", "--disable-all", "-Erevive", getTestDataDir("cgo_with_issues")).
+		ExpectHasIssue("indent-error-flow: if block ends with a return statement")
 }
 
 func TestUnsafeOk(t *testing.T) {
@@ -127,7 +131,7 @@ func TestLineDirectiveProcessedFilesLiteLoading(t *testing.T) {
 }
 
 func TestSortedResults(t *testing.T) {
-	var testCases = []struct {
+	testCases := []struct {
 		opt  string
 		want string
 	}{
diff --git a/test/testdata/cgo_with_issues/main.go b/test/testdata/cgo_with_issues/main.go
index 6eab19a2..3e880bf5 100644
--- a/test/testdata/cgo_with_issues/main.go
+++ b/test/testdata/cgo_with_issues/main.go
@@ -21,3 +21,15 @@ func Example() {
 	fmt.Printf("bad format %t", cs)
 	C.free(unsafe.Pointer(cs))
 }
+
+func notFormattedForGofmt()  {
+}
+
+func errorForRevive(p *int) error {
+	if p == nil {
+		return nil
+	} else {
+		return nil
+	}
+}
+