Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 34 additions & 1 deletion stubs/Utils/ArrayHash.stub
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Nette\Utils;
* @implements \IteratorAggregate<array-key, T>
* @implements \ArrayAccess<array-key, T>
*/
class ArrayHash extends \stdClass implements \ArrayAccess, \IteratorAggregate
class ArrayHash extends \stdClass implements \ArrayAccess, \Countable, \IteratorAggregate
{

/**
Expand All @@ -18,4 +18,37 @@ class ArrayHash extends \stdClass implements \ArrayAccess, \IteratorAggregate
// nothing
}

/**
* @param T $value
*/
public function offsetSet($key, $value): void
{
// nothing
}

/**
* @param array-key $key
* @return T
*/
public function offsetGet($key): mixed
{
// nothing
}

/**
* @param array-key $key
*/
public function offsetExists($key): bool
{
// nothing
}

/**
* @param array-key $key
*/
public function offsetUnset($key): void
{
// nothing
}

}
19 changes: 6 additions & 13 deletions tests/Type/Nette/ArrayHashStubTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

namespace PHPStan\Type\Nette;

use Composer\InstalledVersions;
use OutOfBoundsException;
use Iterator;
use Nette\Utils\ArrayHash;
use PHPStan\Testing\TypeInferenceTestCase;
use function class_exists;
use function version_compare;
use ReflectionMethod;
use ReflectionNamedType;

final class ArrayHashStubTest extends TypeInferenceTestCase
{
Expand All @@ -15,16 +15,9 @@ public static function dataFileAsserts(): iterable
{
yield from self::gatherAssertTypes(__DIR__ . '/data/array-hash.php');

try {
$utilsVersion = class_exists(InstalledVersions::class)
? InstalledVersions::getVersion('nette/utils')
: null;
} catch (OutOfBoundsException $e) {
$utilsVersion = null;
}

// nette/utils 4.0+ declares getIterator(): \Iterator, older versions \RecursiveArrayIterator
if ($utilsVersion === null || version_compare($utilsVersion, '4.0.0', '<')) {
$iteratorReturnType = (new ReflectionMethod(ArrayHash::class, 'getIterator'))->getReturnType();
if (!$iteratorReturnType instanceof ReflectionNamedType || $iteratorReturnType->getName() !== Iterator::class) {
return;
}

Expand Down
3 changes: 2 additions & 1 deletion tests/Type/Nette/data/array-hash.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
function test(ArrayHash $hash): void
{
assertType('Nette\\Utils\\ArrayHash<int>', $hash);
assertType('int|null', $hash['foo']);
assertType('int', $hash['foo']);
assertType('int', $hash->offsetGet('foo'));
assertType('mixed', $hash->foo);
}
Loading