package gorules
import "github.com/quasilyte/go-ruleguard/dsl"
// Sometimes you can't describe the exact type using the normal syntax.
//
// Suppose that you're trying to find array-typed value dereferencing.
// There can be unlimited ways to write array type: not only you need to spell
// its element type, it should also have a size specified as a part of the type.
//
// Fear not, we have a solution!
func unslice(m dsl.Matcher) {
// We can safely omit the [:] for strings and slices (but not arrays!).
// The `[]$_` type pattern accepts any slice types: []int, []T, [][]string and so on.
m.Match(`$s[:]`).
Where(m["s"].Type.Is(`[]$_`)).
Suggest(`$s`).
Report(`$s[:] is a no-op, can be written as $s`)
}
func underef(m dsl.Matcher) {
// Arrays are automatically dereferenced during the indexing, so explicit * is not needed.
// The `*[$_]$_` type pattern accepts any pointer-to-array types: *[5]int, [16][]T and so on.
m.Match(`(*$arr)[$i]`).
Where(m["arr"].Type.Is(`*[$_]$_`)).
Suggest(`$arr[$i]`).
Report(`explicit dereference is redundant, can be written as $arr[$i]`)
}
package main
type myStringer struct{}
func (myStringer) String() string { return "example" }
func main() {
var b []byte
println(b[:])
var intArr5 [5]int
intArr5ptr := &intArr5
stringArr2Ptr := new([2]string)
println((*intArr5ptr)[0])
println((*stringArr2Ptr)[0])
}
Notes:
map[$k]$v
matches any mapmap[$t]$t
matches a map where a key and value types are the samestruct{$*_}
matches any structstruct{$x; $*_}
matches a struct that has $x-typed first fieldstruct{$*_; $x; $*_}
matches a struct that contains $x-typed fieldstruct{$*_; $x}
matches a struct that has $x-typed last field