Why does IntelliJ Structural Search find some of `(int) ($expr$ + 0.5f)`, but not all?

81 Views Asked by At

I'm trying to use Structural Search to replace a rounding anti-pattern with the correct pattern. I'm searching for:

(int) ($expr$ + 0.5f)

in order to replace it with:

Math.round($expr$)

Strangely, that search pattern finds most of the instances of the anti-pattern, but not all, and I can't see any relevant difference. Here are two it doesn't find:

return (int) (lowestHeight / 256f + minHeight + 0.5f);

and

return (int) ((lowestHeight & 0xFFFF) / 256f + minHeight + 0.5f);

But just a few lines above, it had no problem with this expression:

return (int) (getHeight(x, y) + 0.5f);

or a few lines below with this expression:

if (((tallWaterLevel[xx + yy * TILE_SIZE]) > ((int) (tallHeightMap[xx + yy * TILE_SIZE] / 256f + 0.5f)))

nor with dozens of other similar instances in the codebase. I don't see the difference.

What's going on? Why doesn't it find the first two expressions? What's the difference, and how do I make it find them?

I've already asked this question on the Jetbrains Community site, and I got a response that seems to be implying it is a bug. I am hoping to get more views here and that it yet might turn out it is based on a lack of understanding on my part.

I have not set any filters or changed any Structural Search settings from the default. As I said, it actually finds most instances of the pattern.

1

There are 1 best solutions below

1
On

I am going to surmise - I have no concrete evidence for this - but there could be some issue with the way intellij handles associativity of the + operator - it should be left associative, but perhaps it is considering it right associative, so it reads your expression

lowestHeight / 256f + minHeight + 0.5f

as

lowestHeight / 256f + (minHeight + 0.5f)  // right associative, doesn't match

rather than

(lowestHeight / 256f + minHeight) + 0.5f  // left associative, does match

I don't have a clever workaround for this: all I can suggest is to try searching for:

(int) ($expr1$ + $expr2$ + 0.5f)