mvdan/gogrep

cannot search for switch statement with arbitrary body

rogpeppe opened this issue · 3 comments

I was interested to find out how many instances of the idiom:

 switch $x := $x.(type) { .... }

there were in the Go source tree. This seems like a reasonable thing to search for to me,
but you can't use $*_ inside the braces because gogrep_any_ is not a valid thing to
find inside a switch body.

gogrep 'switch $x { $*_ }' ./...
cannot parse expr: 1:20: expected '}', found 'IDENT' _gogrep_any__ (and 1 more errors)

This would be true of select statements too - it would be nice to be able to search for all select statements that include a given communication operator, for example.

mvdan commented

I've encountered the same when trying to match other kinds of nodes where a single ident will not do.

Perhaps we could make the tokenizer understand the language well enough to be able to construct valid programs from wildcards. So for example, given:

switch $x { $y* }

it would produce

switch $x { case _gogrep_any_y: }

and then the matcher would be taught to see if a CaseClause follows that pattern, and if it does, treat it like a wildcard (which we only do for Ident now) and stop recursion.

mvdan commented

I ended up with a hack that's basically what I commented above, but slightly more complex to be more robust and support selects. Please try it out.