package gorules
import "github.com/quasilyte/go-ruleguard/dsl"
// Normally, all matching is done on the AST and types level.
// But sometimes it's necessary (or just easier) to treat the
// submatches as text.
func printFmt(m dsl.Matcher) {
// Here we scan a $s string for %s, %d and %v.
m.Match(`fmt.Println($s, $*_)`,
`fmt.Print($s, $*_)`).
Where(m["s"].Text.Matches(`%[sdv]`)).
Report("found formatting directive in non-formatting call")
}
func wrongErrChecked(m dsl.Matcher) {
// Here we check for both types and names.
// Note that we can use `==` and `!=` with Text.
m.Match("if $*_, $err0 := $*_; $err1 != nil { $*_ }").
Where(m["err0"].Text == "err" && m["err0"].Type.Is("error") &&
m["err1"].Text != "err" && m["err1"].Type.Is("error")).
Report("maybe wrong err in error check")
}
package main
import "fmt"
func main() {
var msg string
fmt.Println("error: %s", msg)
fmt.Print("Hello, %s!", "ruleguard")
fmt.Println("no formatting directives")
var err2 error
if v, err := f(); err2 != nil {
fmt.Println(v, err)
}
if v, err2 := f(); err2 != nil {
fmt.Println(v, err2)
}
if v, err := f(); err != nil {
fmt.Println(v, err)
}
}
func f() (int, error) { return 0, nil }
Notes:
Text
on a right-hand-side (e.g. m["x"].Text != m["y"].Text
)