Improve/fix type StringOrArray extension#167
Conversation
| } | ||
|
|
||
| if (count($type->getConstantArrays()) > 0) { | ||
| return TypeCombinator::union( |
There was a problem hiding this comment.
those wouldn't even be needed anymore I guess because this function is wrapped in a TypeTraverser already that deals with union types. the alternative would be to explicitly handle only the first constant array and array below instead of all of them. not sure what is simpler / reads better, in the end it might not matter much..
There was a problem hiding this comment.
@herndlm I also think that if (count($type->getConstantArrays()) > 0) {...} is no longer needed.
There was a problem hiding this comment.
The question is how to do it differently. A condition like that has to stay to access only the first ConstantArray and get rid of the union for example. Or any other ideas?
There was a problem hiding this comment.
Had a closer look. What about this?
$maybeEmptyArray = [];
if (count($type->getConstantArrays()) > 0) {
$constantArray = $type->getConstantArrays()[0];
if (
$constantArray->isOptionalKey(0) &&
$constantArray->getArraySize()->equals(IntegerRangeType::fromInterval(0, 1))
) {
$maybeEmptyArray[] = $constantArray;
}
}
return TypeCombinator::union(
...array_merge(
$maybeEmptyArray,
array_map(
function (ArrayType $arrayType): Type {
return $arrayType->setOffsetValueType(
$arrayType->getIterableKeyType(),
$this->getType($arrayType->getIterableValueType())
);
},
$type->getArrays()
)
)
);I don't think that it matters whether we use $type->getConstantArrays()[0] or foreach ($type->getConstantArrays() as $constantArray) {}
There was a problem hiding this comment.
No, this fails for
/** @var 'foo'|array{foo?: true, bar: int} $union */
$union = null;
assertType('array{foo?: string, bar: string}|string', esc_sql($union));with
-'array{foo?: string, bar: string}|string'
+'array{foo?: string|true, bar: int|string}|string'
There was a problem hiding this comment.
got rid of the array_map and union
|
Does PHP allow |
sure, there's no reason against it. without such code (and also e.g. with the weird Neutron CS rule that forbids to have a callable assigned to a var) PHPStan wouldn't be able to efficiently parse and handle the AST to figure out types |
|
@IanDelMar let me/us know please what you think of this. I did briefly confirm the test cases with a real WordPress, but I don't know the internals of the escaping function well enough. Maybe @johnbillion can quickly check too :) |
|
@herndlm Looks good to me! |
Co-authored-by: IanDelMar <[email protected]>
|
Is it ready to merge? |
| return new StringType(); | ||
| } | ||
|
|
||
| if (!$type->isArray()->yes()) { |
There was a problem hiding this comment.
| if (!$type->isArray()->yes()) { | |
| if ($type->isArray()->no()) { |
There was a problem hiding this comment.
If it is a maybe type !yes means maybe or no,
no means no only.
There was a problem hiding this comment.
Both are not a 100% correct I suppose, the maybe case might need another extra handling instead of just returning the input below. I'll check it later.
There was a problem hiding this comment.
dealing with the maybe here is highly annoying, e.g. your proposed change would lead to a *NEVER* (mine to a '') when a maybe array like mixed or iterable is passed. both are wrong. and in both cases PHPStan should be complaining because esc_sql does not support those types via PHPDoc. Natively it does of course, I know..
And I can't even say what we would return with a mixed, I guess we could just bail out early and not handle and return the default type or smth like that
There was a problem hiding this comment.
adapted, what do you think? should at least be simpler and less wrong now :)
There was a problem hiding this comment.
Thought the same, but can't return null here because this is wrapped with the TypeTraverser:map() which doesn't allow returning null AFAIK
There was a problem hiding this comment.
BTW just curious, your profile says Vienna but you seem yo be active very late until into the night. Are you still in Vienna? I'm from Austria and lived there too, missing it a bit from time to time..
There was a problem hiding this comment.
I still live in Vienna. My activity time mainly depends on my day job and after work napping :-D. Vienna is a nice place to live. I would miss it too at least in late spring and summer.
There was a problem hiding this comment.
And good old boss Viktor is in Budapest, the twin cities, right? :)
Anyway, shall we merge? :P
Also: sorry for calling you old Viktor
d8ab289 to
3f1821e
Compare
Closes #154
Successor of #163
instanceof''in case of an invalid type input