Ruleguard by example: Type patterns

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: