Fix the plural form checker false positives for good

Used the real MediaWiki "here be dragons" parser to get the actual
parameters given to the plural function. Yet again I was amazed
how versatile parser hooks are and dismayed that there is no good
documentation how to use SFH_OBJECT_ARGS. Normal parser function
would not do it, because I need raw text.

It was pretty easy to figure out how to use PPFrame->expand as it is
pretty much the only function available, and it only takes a handful of
constants as parameter. Of course the constants are undocumented as well,
but PPFrame::RECOVER_ORIG sounded like it would return the raw text and
that seems to be the case as well.

The trickiest part was how to have my own callback called when parser
finds the plural magic word. Simply creating a new parser and attaching
my callback with setFunctionHook would not do it, as it would get
overridden by the core plural handler. I found a workaround by
explicitly calling firstCallInit on the parser before setting my
callback.

Calling PPFrame::expand without parameters nicely triggers my callbacks
again when there are plurals embedded inside plurals. The unit tests
are currently hard coding the order in which the plural calls are
processed (left to right, inner before outer). This seems okay a price
to pay to not have to sort them in tests.

The final problem was to figure out why I didn't get any plural forms
after calling Parser::preprocess. It turned out to be a simple
mistake with the anonymous function declaration. It references the
$plurals variable with 'use', but of course modifications to that
inside the anonymous function are not visible outside, unless
you pass it by reference.

Constructing a new parser for every check is going to be much
slower, but on the other hand it is likely not going to matter
unless one is mass-checking translations. We can cache the parser
later if performance turns out to be a problem.

Bug: 59241
Change-Id: Id5c3f40b801c5186f5cb2341e21eea7f0f694958
Merge "Fix the plural form checker false positives for good"