Skip to content

Commit

Permalink
Support assertions on class constants
Browse files Browse the repository at this point in the history
  • Loading branch information
muglug committed May 28, 2019
1 parent 0e6d07c commit 81b6a6f
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 6 deletions.
22 changes: 19 additions & 3 deletions src/Psalm/Type/Reconciler.php
Original file line number Diff line number Diff line change
Expand Up @@ -339,8 +339,9 @@ public static function reconcileTypes(
$is_equality = true;
}

if ($existing_var_type === null && is_string($key) &&
$statements_analyzer->isSuperGlobal($key)
if ($existing_var_type === null
&& is_string($key)
&& $statements_analyzer->isSuperGlobal($key)
) {
$existing_var_type = $statements_analyzer->getGlobalType($key);
}
Expand Down Expand Up @@ -2655,7 +2656,22 @@ private static function getValueForKey(
$base_key = array_shift($key_parts);

if (!isset($existing_keys[$base_key])) {
return null;
if (strpos($base_key, '::')) {
list($fq_class_name, $const_name) = explode('::', $base_key);

$all_class_constants = $codebase->classlikes->getConstantsForClass(
$fq_class_name,
\ReflectionProperty::IS_PRIVATE
);

if (isset($all_class_constants[$const_name])) {
$existing_keys[$base_key] = clone $all_class_constants[$const_name];
} else {
return null;
}
} else {
return null;
}
}

while ($key_parts) {
Expand Down
29 changes: 26 additions & 3 deletions tests/ArrayAccessTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -460,17 +460,40 @@ public function bar(string $key): bool {
[],
['MixedReturnStatement', 'MixedInferredReturnType']
],
'assertConstantOffsetsInFunction' => [
'assertSelfClassConstantOffsetsInFunction' => [
'<?php
namespace Ns;
class C {
public const ARR = [
"a" => ["foo" => true],
"b" => []
];
public function bar(?string $key): bool {
if ($key === null || !array_key_exists($key, self::ARR) || !array_key_exists("foo", self::ARR[$key])) {
return false;
}
return self::ARR[$key]["foo"];
}
}',
[],
['MixedReturnStatement', 'MixedInferredReturnType']
],
'assertNamedClassConstantOffsetsInFunction' => [
'<?php
namespace Ns;
class C {
public const ARR = [
"a" => ["foo" => true],
"b" => [],
];
}
function bar(string $key): bool {
if (!array_key_exists($key, C::ARR) || !array_key_exists("foo", C::ARR[$key])) {
function bar(?string $key): bool {
if ($key === null || !array_key_exists($key, C::ARR) || !array_key_exists("foo", C::ARR[$key])) {
return false;
}
Expand Down

0 comments on commit 81b6a6f

Please sign in to comment.