Closed ktomk closed 4 years ago
I found these snippets:
To sum up, IteratorIterator forwards unknown methods to the object it wraps, and Psalm should know it (but doesn't). Reproduced more succinctly and prominently: https://3v4l.org/vCAfm & https://psalm.dev/r/4146a0fcf0
I found these snippets:
@weirdan Yes, this is exactly it. And good correction on the examples index()
and true
were perhaps not making it immediately visible, sorry.
From what I know this is a special property of IteratorIterator and it makes sense (at least to humble me) having an iterator as a decorator (but I know it can inherit surprises [next to Traverable being a PHP internal interface], referencing Anthony Ferrara in Nov 2011 about IteratorIterator, IMHO wrongfully he was coining it as inconsistent, but I can understand the moment of realization as a WTF moment).
Probably decorators are easy to handle for psalm and the case of IteratorIterator was never brought up, as these are annotated in code most often (e.g. Subject|Decorator
), for a native decorator, this most certainly is not the case (there is no PHP code to add annotations to that psalm could infer from).
This (I think) calls for templated @mixin
. I'll try to work on that today.
@muglug: I updated my case against the \@dev version (currently at a701163f0aecdc1db24cd3a334c85d4b918c4ff2) and get the same result. Do I need to make use of @mixin as well in my own codebase?
/E: Found it, @mixin
works, counter-test with previous revision does also work. I guess b/c the FilterIterator in my concrete case passes the real subject to parent::__construct()
within the FilterIterator::__construct()
which has as first parameter not the subject (in terms of decoration).
PHP IteratorIterator (and a couple of sub-types based on it, e.g. FilterIreator) are decorating the Traversable (the one constructor parameter).
However psalm detects an UndefinedMethod (see https://psalm.dev/022) albeit it is defined in the Traversable:
What I would like to ask for (decorating support is maybe not so wrong as there might be something coming up with PHP 8), is that I can use
@method
to denoteindex()
existing without relying on the psalm configuration it should be acceptable without__call
but instead that the psalm utility is aware of the fact that the Traversable Subject is decorated by IteratorIterator.I can work-around this by setting
<psalm usePhpDocMethodsWithoutMagicCall="true">
as the concrete code already has the@method
annotation (not part of the example above) but no__call
implementation.However if the
@method
annotation would not be in my (extend to the example given) case, the work-around would not work with psalm leaving the existing method detected as nonexistent (false-positive).First of all I think it's ok to report the issue.
Additionally I'd like to ask if there is some (psalm) specific annotation I could make use of to alleviate next to
@method
and changing psalms' configuration.(this is also something Phpstorm can't manage [yet], it just takes
@method
for granted but can somewhat deduce the concrete implementation as well. Scrutinizer needs an additional@scrutinizer ignore-call
annotation at invocation-point)