-
Notifications
You must be signed in to change notification settings - Fork 523
Introduce Type->getConstantArrayKeys()
#4171
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At first, when looking at the method getConstantArrayKeys
, I thought it would have return the array keys of the ConstantArray.
ie array{'foo': 1, 'bar': 2}
::getConstantArrayKeys returns 'foo'|'bar'
So I dunno if a better naming should be found.
Also, do we need this method:
- Isn't the same than
$type->toArrayKey()->getConstantScalarTypes()
? - Or it might be better to introduce
getConstantIntegers
(which can be reused for some other situation like DynamicReturnType extension with constantIntegers) and to say thatgetConstantArrayKeys = array_merge(getConstantIntegers, getConstantStrings)
I took inspiration from other existing I agree it could be misleading, but I did not thought about a better name yet.
your example call returns all types of constant scalars (which would again need filtering at all call-sites, as a array key is only interessted in we are not interessted in
the benefit of the new Type method is, that it encapsulates knowledge about which types a array-key can have into the Type-system. Calling my goal is to get rid of |
hmm I just see my resulting types are wrong after the PR. I need to think more about the semantics $c = [false, false, false];
/** @var 0|1|2 $offset */
$offset = doFoo();
$c[$offset] = true;
- assertType('array{bool, bool, bool}', $c);
+ assertType('array{true, true, true}', $c); Back to the drawing board ;-) |
Technically with
Yes I understand the purpose, I just thought the getConstantIntegers would have been more useful since it would also have solve checks like
And calling array_merge($type->getConstantStrings(), $type->getConstantIntegers()) wasn't that much complicate than type->getConstantArrayKeys() but both method getConstantArrayKeys and getConstantIntegers can exists.
I just don't like the naming (which I find misleading) but it's definitety similar to existing methods and I don't have a better naming yet too. I stay with your method, I think I'll try to introduce |
@@ -4229,29 +4229,43 @@ public function specifyExpressionType(Expr $expr, Type $type, Type $nativeType, | |||
|
|||
$scope = $this; | |||
if ($expr instanceof Expr\ArrayDimFetch && $expr->dim !== null) { | |||
$dimType = $scope->getType($expr->dim)->toArrayKey(); | |||
if ($dimType instanceof ConstantIntegerType || $dimType instanceof ConstantStringType) { | |||
$dimTypes = $scope->getType($expr->dim)->getConstantArrayKeys(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw @staabm this change is wrong
toArrayKey does the cast
getConstantArrayKeys only return the constants.
So NullType->toArrayKey was ConstantString('')
And NullType::getConstantArrayKeys returns []
You will need
$scope->getType($expr->dim)->toArrayKey->getConstantArrayKeys();
Which make the method less useful. (it becomes the same than ->toArrayKey->getConstantScalarValues()
, unless for static analysis).
Or maybe the method you need is toConstantArrayKeys
...
I've always avoided adding getConstantIntegers because of IntegerRangeType. It'd consume a lot of memory, it would not be efficient. I don't know about array keys, but I feel like for math we need methods like |
How would you do for code like this then
? It should be changed to
|
I'd add something like |
@VincentLanglet for inspiration: we did similar things here https://github.com/phpstan/phpstan-src/blob/2.1.x/src/Type/BitwiseFlagHelper.php |
Maybe it should be |
As discussed in #4161 (review)
Todo
ConstantArrayType->unsetOffset()
ArrayType->setOffsetValueType()
ArrayType->unsetOffset()
ConstantArrayTypeBuilder
TypeCombinator
?