Skip to content

Commit 4cdf42f

Browse files
authored
Merge pull request #66 from cschleiden/analyzer/fix-func-literals
Ensure linter only analyzes statements in top-level workflow functions
2 parents 17a95ef + 4f08d4d commit 4cdf42f

File tree

2 files changed

+45
-8
lines changed

2 files changed

+45
-8
lines changed

analyzer/analyzer.go

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package analyzer
22

33
import (
4-
"fmt"
54
"go/ast"
65
"go/types"
76

@@ -20,9 +19,28 @@ var Analyzer = &analysis.Analyzer{
2019
func run(pass *analysis.Pass) (interface{}, error) {
2120
inspector := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
2221

22+
// Expect workflows to be top level functions in a file. Therefore it should be enough to just keep track if the current
23+
// AST node is a descendant of a workflow FuncDecl.
24+
inWorkflow := true
25+
2326
inspector.Nodes(nil, func(node ast.Node, push bool) bool {
24-
if !push {
25-
return false
27+
28+
if _, ok := node.(*ast.FuncDecl); ok {
29+
if !push {
30+
// Finished with the current workflow
31+
inWorkflow = false
32+
return false
33+
}
34+
} else {
35+
if !push {
36+
// Only check nodes while descending
37+
return false
38+
}
39+
40+
if !inWorkflow {
41+
// Only check nodes while in a top-level workflow func
42+
return false
43+
}
2644
}
2745

2846
switch n := node.(type) {
@@ -32,6 +50,8 @@ func run(pass *analysis.Pass) (interface{}, error) {
3250
return false
3351
}
3452

53+
inWorkflow = true
54+
3555
// Check return types
3656
if n.Type.Results == nil || len(n.Type.Results.List) == 0 {
3757
pass.Reportf(n.Pos(), "workflow `%v` doesn't return anything. needs to return at least `error`", n.Name.Name)
@@ -69,8 +89,6 @@ func run(pass *analysis.Pass) (interface{}, error) {
6989
case *types.Chan:
7090
pass.Reportf(n.Pos(), "using native channels is not allowed in workflows, use `workflow.Channel` instead")
7191
}
72-
73-
// checkStatements(pass, n.Body.List)
7492
}
7593

7694
case *ast.SelectStmt:
@@ -141,8 +159,6 @@ func checkVarsInScope(pass *analysis.Pass, scope *types.Scope) {
141159
func checkNamed(pass *analysis.Pass, ref types.Object, named *types.Named) {
142160
if obj := named.Obj(); obj != nil {
143161
if pkg := obj.Pkg(); pkg != nil {
144-
fmt.Println(pkg.Path(), obj.Name(), obj.Id())
145-
146162
switch pkg.Path() {
147163
case "sync":
148164
if obj.Name() == "WaitGroup" {

analyzer/testdata/src/p/p.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func wfVarUsage(ctx workflow.Context) error {
8787
return nil
8888
}
8989

90-
func wfChanFuncDecl(ctx workflow.Context) error {
90+
func wfChanNestedFunc(ctx workflow.Context) error {
9191
x := func() {
9292
select {} // want "`select` statements are not allowed in workflows, use `workflow.Select` instead"
9393
}
@@ -111,3 +111,24 @@ func activity(ctx context.Context) error {
111111

112112
return nil
113113
}
114+
115+
type SomeField struct {
116+
f func() error
117+
}
118+
119+
var sf SomeField = SomeField{
120+
f: func() error {
121+
go fmt.Println("24")
122+
123+
c := make(chan int)
124+
select {
125+
case <-c:
126+
}
127+
128+
for x := range c {
129+
fmt.Println(x)
130+
}
131+
132+
return nil
133+
},
134+
}

0 commit comments

Comments
 (0)