diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..0cc9fab --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,4 @@ +linters: + disable-all: true + enable: + - explicitreturn \ No newline at end of file diff --git a/main.go b/cmd/explicitreturn/main.go similarity index 71% rename from main.go rename to cmd/explicitreturn/main.go index fcea876..58b6450 100644 --- a/main.go +++ b/cmd/explicitreturn/main.go @@ -2,7 +2,7 @@ package main import ( "golang.org/x/tools/go/analysis/singlechecker" - "tildegit.org/indigo/explicitreturn/analyzer" + "tildegit.org/indigo/explicitreturn/pkg/analyzer" ) func main() { diff --git a/example.go b/example.go deleted file mode 100644 index 44560dc..0000000 --- a/example.go +++ /dev/null @@ -1,22 +0,0 @@ -package main - -func DoConfusingStuff() (x int, y string) { - return -} - -func DoProceduralStuff() { - return -} - -func DoSensibleStuff() (x int, y string) { - return x, y -} - -func DoSillyStuff() (x int, y string) { - if true { - return x, y - } - return -} - -var x = func() (x int, y string) { return } diff --git a/analyzer/analyzer.go b/pkg/analyzer/analyzer.go similarity index 87% rename from analyzer/analyzer.go rename to pkg/analyzer/analyzer.go index 7e6650e..c4eeb53 100644 --- a/analyzer/analyzer.go +++ b/pkg/analyzer/analyzer.go @@ -35,7 +35,7 @@ func run(pass *analysis.Pass) (interface{}, error) { for _, statement := range funcBody.List { returnStmt, ok := statement.(*ast.ReturnStmt) if ok && returnStmt.Results == nil && function.Type.Results != nil { - pass.Reportf(returnStmt.Pos(), "implicit return found for anonymous function") + pass.ReportRangef(returnStmt, "implicit return found in anonymous function") } } case *ast.FuncDecl: @@ -43,7 +43,7 @@ func run(pass *analysis.Pass) (interface{}, error) { for _, statement := range funcBody.List { returnStmt, ok := statement.(*ast.ReturnStmt) if ok && returnStmt.Results == nil && function.Type.Results != nil { - pass.Reportf(returnStmt.Return, "implicit return found in function %s", function.Name) + pass.ReportRangef(returnStmt, "implicit return found in function %s", function.Name) } } default: diff --git a/pkg/analyzer/analyzer_test.go b/pkg/analyzer/analyzer_test.go new file mode 100644 index 0000000..e2ee662 --- /dev/null +++ b/pkg/analyzer/analyzer_test.go @@ -0,0 +1,11 @@ +package analyzer + +import ( + "testing" + + "golang.org/x/tools/go/analysis/analysistest" +) + +func TestAll(t *testing.T) { + analysistest.Run(t, analysistest.TestData(), Analyzer) +} diff --git a/pkg/analyzer/testdata/example.go b/pkg/analyzer/testdata/example.go new file mode 100644 index 0000000..3bb9cfd --- /dev/null +++ b/pkg/analyzer/testdata/example.go @@ -0,0 +1,23 @@ +package main + +func SimpleNakedReturn() (x int, y string) { + return // want `implicit return found in function SimpleNakedReturn` +} + +func IgnorableProcedure() { + return // No return values expected, all good here! +} + +func SimpleFunction() (x int, y string) { + return x, y // Return values are as foretold in the function signature +} + +func MultipleReturnPaths() (x int, y string) { + if true { + return x, y // All good here, but... + } + return // want `implicit return found in function MultipleReturnPaths` +} + +// Also works on anonymous functions! +var x = func() (x int, y string) { return } // want `implicit return found in anonymous function`