Skip to content

Commit cb19258

Browse files
authored
ruleguard: implement Var.Object.IsGlobal() predicate (#370)
1 parent 0e209b8 commit cb19258

File tree

9 files changed

+86
-32
lines changed

9 files changed

+86
-32
lines changed

analyzer/testdata/src/filtertest/f1.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -872,3 +872,23 @@ func detectNode() {
872872
nodeTest(rows[0][5], "IndexExpr") // want `true`
873873
nodeTest("42", "IndexExpr")
874874
}
875+
876+
var globalVar string
877+
var globalVar2 string = time.Now().String() // want `\Qglobal var`
878+
var globalVar3 = time.Now().String() // want `\Qglobal var`
879+
var (
880+
globalVar4 string
881+
)
882+
883+
func detectGlobal() {
884+
globalVar = time.Now().String() // want `\Qglobal var`
885+
globalVar4 = time.Now().String() // want `\Qglobal var`
886+
{
887+
globalVar := time.Now().String() // shadowed global var
888+
print(globalVar)
889+
}
890+
{
891+
var globalVar = time.Now().String() // shadowed global var
892+
print(globalVar)
893+
}
894+
}

analyzer/testdata/src/filtertest/rules.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,4 +263,11 @@ func testRules(m dsl.Matcher) {
263263
m.Match(`typeTest($x, $y, "identical types")`).
264264
Where(m["x"].Type.IdenticalTo(m["y"])).
265265
Report(`true`)
266+
267+
m.Match(`$x = time.Now().String()`,
268+
`var $x = time.Now().String()`,
269+
`var $x $_ = time.Now().String()`,
270+
`$x := time.Now().String()`).
271+
Where(m["x"].Object.IsGlobal()).
272+
Report(`global var`)
266273
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ go 1.17
55
require (
66
github.com/go-toolsmith/astcopy v1.0.0
77
github.com/google/go-cmp v0.5.6
8-
github.com/quasilyte/go-ruleguard/dsl v0.3.15
8+
github.com/quasilyte/go-ruleguard/dsl v0.3.16
99
github.com/quasilyte/go-ruleguard/rules v0.0.0-20211022131956-028d6511ab71
1010
github.com/quasilyte/gogrep v0.0.0-20220120141003-628d8b3623b5
1111
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
1010
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
1111
github.com/quasilyte/go-ruleguard v0.3.1-0.20210203134552-1b5a410e1cc8/go.mod h1:KsAh3x0e7Fkpgs+Q9pNLS5XpFSvYCEVl5gP9Pp1xp30=
1212
github.com/quasilyte/go-ruleguard/dsl v0.3.0/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
13-
github.com/quasilyte/go-ruleguard/dsl v0.3.15 h1:rClYn6lk8wUV5kXnQG4JVsRQjZhSetaNtwml5wkFp5g=
14-
github.com/quasilyte/go-ruleguard/dsl v0.3.15/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
13+
github.com/quasilyte/go-ruleguard/dsl v0.3.16 h1:yJtIpd4oyNS+/c/gKqxNwoGO9+lPOsy1A4BzKjJRcrI=
14+
github.com/quasilyte/go-ruleguard/dsl v0.3.16/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
1515
github.com/quasilyte/go-ruleguard/rules v0.0.0-20201231183845-9e62ed36efe1/go.mod h1:7JTjp89EGyU1d6XfBiXihJNG37wB2VRkd125Q1u7Plc=
1616
github.com/quasilyte/go-ruleguard/rules v0.0.0-20211022131956-028d6511ab71 h1:CNooiryw5aisadVfzneSZPswRWvnVW8hF1bS/vo8ReI=
1717
github.com/quasilyte/go-ruleguard/rules v0.0.0-20211022131956-028d6511ab71/go.mod h1:4cgAphtvu7Ftv7vOT2ZOYhC6CvBxZixcasr8qIOTA50=

ruleguard/filters.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@ import (
77
"go/types"
88
"path/filepath"
99

10+
"github.com/quasilyte/gogrep"
11+
"github.com/quasilyte/gogrep/nodetag"
12+
1013
"github.com/quasilyte/go-ruleguard/internal/xtypes"
1114
"github.com/quasilyte/go-ruleguard/ruleguard/quasigo"
1215
"github.com/quasilyte/go-ruleguard/ruleguard/textmatch"
1316
"github.com/quasilyte/go-ruleguard/ruleguard/typematch"
14-
"github.com/quasilyte/gogrep"
15-
"github.com/quasilyte/gogrep/nodetag"
1617
)
1718

1819
const filterSuccess = matchFilterResult("")
@@ -363,6 +364,18 @@ func makeLineFilter(src, varname string, op token.Token, rhsVarname string) filt
363364
}
364365
}
365366

367+
func makeObjectIsGlobalFilter(src, varname string) filterFunc {
368+
return func(params *filterParams) matchFilterResult {
369+
obj := params.ctx.Types.ObjectOf(identOf(params.subExpr(varname)))
370+
globalScope := params.ctx.Pkg.Scope()
371+
if obj.Parent() == globalScope {
372+
return filterSuccess
373+
}
374+
375+
return filterFailure(src)
376+
}
377+
}
378+
366379
func makeGoVersionFilter(src string, op token.Token, version GoVersion) filterFunc {
367380
return func(params *filterParams) matchFilterResult {
368381
if params.ctx.GoVersion.IsAny() {

ruleguard/ir/filter_op.gen.go

Lines changed: 30 additions & 24 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ruleguard/ir/gen_filter_op.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//go:build generate
12
// +build generate
23

34
package main
@@ -52,6 +53,7 @@ func main() {
5253
{name: "VarFilter", comment: "m[$Value].Filter($Args[0])", valueType: "string", flags: flagHasVar},
5354
{name: "VarNodeIs", comment: "m[$Value].Node.Is($Args[0])", valueType: "string", flags: flagHasVar},
5455
{name: "VarObjectIs", comment: "m[$Value].Object.Is($Args[0])", valueType: "string", flags: flagHasVar},
56+
{name: "VarObjectIsGlobal", comment: "m[$Value].Object.IsGlobal()", valueType: "string", flags: flagHasVar},
5557
{name: "VarTypeIs", comment: "m[$Value].Type.Is($Args[0])", valueType: "string", flags: flagHasVar},
5658
{name: "VarTypeIdenticalTo", comment: "m[$Value].Type.IdenticalTo($Args[0])", valueType: "string", flags: flagHasVar},
5759
{name: "VarTypeUnderlyingIs", comment: "m[$Value].Type.Underlying().Is($Args[0])", valueType: "string", flags: flagHasVar},

ruleguard/ir_loader.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@ import (
1111
"io/ioutil"
1212
"regexp"
1313

14+
"github.com/quasilyte/gogrep"
15+
"github.com/quasilyte/gogrep/nodetag"
16+
1417
"github.com/quasilyte/go-ruleguard/ruleguard/goutil"
1518
"github.com/quasilyte/go-ruleguard/ruleguard/ir"
1619
"github.com/quasilyte/go-ruleguard/ruleguard/quasigo"
1720
"github.com/quasilyte/go-ruleguard/ruleguard/textmatch"
1821
"github.com/quasilyte/go-ruleguard/ruleguard/typematch"
19-
"github.com/quasilyte/gogrep"
20-
"github.com/quasilyte/gogrep/nodetag"
2122
)
2223

2324
type irLoaderConfig struct {
@@ -675,6 +676,8 @@ func (l *irLoader) newFilter(filter ir.FilterExpr, info *filterInfo) (matchFilte
675676
result.fn = makePureFilter(result.src, filter.Value.(string))
676677
case ir.FilterVarConstOp:
677678
result.fn = makeConstFilter(result.src, filter.Value.(string))
679+
case ir.FilterVarObjectIsGlobalOp:
680+
result.fn = makeObjectIsGlobalFilter(result.src, filter.Value.(string))
678681
case ir.FilterVarConstSliceOp:
679682
result.fn = makeConstSliceFilter(result.src, filter.Value.(string))
680683
case ir.FilterVarAddressableOp:

ruleguard/irconv/irconv.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ import (
1111
"strings"
1212

1313
"github.com/go-toolsmith/astcopy"
14+
"golang.org/x/tools/go/ast/astutil"
15+
1416
"github.com/quasilyte/go-ruleguard/ruleguard/goutil"
1517
"github.com/quasilyte/go-ruleguard/ruleguard/ir"
16-
"golang.org/x/tools/go/ast/astutil"
1718
)
1819

1920
type Context struct {
@@ -714,6 +715,8 @@ func (conv *converter) convertFilterExprImpl(e ast.Expr) ir.FilterExpr {
714715
return ir.FilterExpr{Op: ir.FilterRootNodeParentIsOp, Args: args}
715716
case "Object.Is":
716717
return ir.FilterExpr{Op: ir.FilterVarObjectIsOp, Value: op.varName, Args: args}
718+
case "Object.IsGlobal":
719+
return ir.FilterExpr{Op: ir.FilterVarObjectIsGlobalOp, Value: op.varName}
717720
case "Type.HasPointers":
718721
return ir.FilterExpr{Op: ir.FilterVarTypeHasPointersOp, Value: op.varName}
719722
case "Type.Is":

0 commit comments

Comments
 (0)