package gorules
import "github.com/quasilyte/go-ruleguard/dsl"
// Sometimes you want to match a statement that is **followed** or **preceded** by another statement.
// For this case we'll need a multi-statement patterns that gogrep does recognize.
func useParallelAssignment(m dsl.Matcher) {
// If we want to specify $x statement that is followed by $y, we use `$x; $y` notation.
// Here we match three statements:
// 1. $x assigned to a temporary $tmp
// 2. $x is re-assigned to $y
// 3. $y is re-assigned to $tmp
m.Match(`$tmp := $x; $x = $y; $y = $tmp`).
Report(`use parallel assignent: $x, $y = $y, $x`)
}
package main
func main() {
var obj1, obj2 struct {
value int
}
// Bad swapping choice:
tmp := obj1.value
obj1.value = obj2.value
obj2.value = tmp
// This is the right way to do it:
obj1.value, obj2.value = obj2.value, obj1.value
}
Notes:
$*_
can be used to describe "any number of statements before this node": $*_; $x
$*_
can be used to describe "any number of statements after this node": $x; $*_
{$*_; $x; $*_}