Ruleguard by example: Filters

package gorules

import "github.com/quasilyte/go-ruleguard/dsl"

// Suppose that we want to report the duplicated left and right operands of binary operations.
//
// But if the operand has some side effects, this rule can cause false positives:
// `f() && f()` can make sense (although it's not the best piece of code).
//
// This is where *filters* come to the rescue.

func dupSubExpr(m dsl.Matcher) {
	// All filters are written as a Where() argument.
	// In our case, we need to assert that $x is "pure".
	// It can be achieved by checking the m["x"] member Pure field.
	m.Match(`$x || $x`,
		`$x && $x`,
		`$x | $x`,
		`$x & $x`).
		Where(m["x"].Pure).
		Report(`suspicious identical LHS and RHS`)
}
$ ruleguard -c 0 -rules rules.go main.go
main.go:9:5: suspicious identical LHS and RHS
9		if cond && cond {
main.go:12:5: suspicious identical LHS and RHS
12		if obj.conditions[2] && obj.conditions[2] {
main.go
package main

func main() {
	var cond bool
	var obj struct {
		conditions []bool
	}

	if cond && cond {
	}

	if obj.conditions[2] && obj.conditions[2] {
	}

	if f() && f() { // $x is not pure
	}
}

func f() bool { return false }

Notes:

To index Next: Type filters Edit this page