Open gmazzap opened 2 years ago
I found these snippets:
You can do this which almost gets you there, but it doesn't handle ints how you'd want. This pattern is actually not safe though, so I'm not sure the cast issue should be considered a false positive: https://3v4l.org/mKN4o
We can't guarantee that there aren't other references to an object, so changing the template type isn't possible to do safely. I think we need to spend some time thinking through how this feature should work and what guarantees we want to provide, and make clear to the user what their responsibilities are to ensure the code is correct. I'm not sure @psalm-this-out
is actually a good idea in general.
I found these snippets:
We can't guarantee that there aren't other references to an object
Sure thing.
I'm not sure @psalm-this-out is actually a good idea in general.
Me neither :) Mutable design is bad, because of the issue you described: that is a runtime issue, which you can't find using a static analysis, and that is why many people (inlcuding me) advocates for immutability. In my company code-styling we've banned setters for a reason :)
I used psalm-this-out
in my example because I realized that was the smallest code I could use to describe the feature request.
If you want to implement conditional assertions only for @psalm-assert
, I would be happy anyway.
Still, I think @psalm-assert-if
would be very useful, as it could save writing code, after all it is a combination of two assertions, which could be merged in one.
Take:
/** @psalm-assert-if($param is Foo) <something> */
function ifParamIsFooAssertSomething($param) {}
it would be equivalent to:
/** @psalm-assert-if-true Foo $param */
function assertParamIsFoo($param): bool {}
/** @psalm-assert <something> */
function assertSomething(): bool {}
function ifParamIsFooAssertSomething($param) {
if (assertParamIsFoo($param)) {
assertSomething();
}
}
So we can already obtain what I'm asking, but what I'm asking would make it easier/less verbose.
Conditional assertions is something that is somehow partially implemented via
psalm-assert-if-true
/psalm-assert-if-false
, however that regards the methods' return type, not parameters.Imagine a code like this:
After last line,
$stringOrNull
isStringOrNull<string>
, but Psalm still sees it asStringOrNull<null>
. See https://psalm.dev/r/17f5693767To solve this, we could have something like:
(I mean, there could be different syntaxes, I tried to imagine the one similar to existing Psalm syntax)
Something very similar could be implemented for
psalm-assert
.