Skip to content
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

General type inference improvements #98

Merged
merged 1 commit into from
Sep 5, 2023
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
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@
"require-dev": {
"laminas/laminas-coding-standard": "^2.5",
"phpbench/phpbench": "^1.2.14",
"phpunit/phpunit": "^10.2.6",
"phpunit/phpunit": "^10.3.3",
"psalm/plugin-phpunit": "^0.18.4",
"vimeo/psalm": "^5.13.1"
"vimeo/psalm": "^5.15.0"
},
"autoload": {
"psr-4": {
Expand Down
247 changes: 127 additions & 120 deletions composer.lock

Large diffs are not rendered by default.

130 changes: 8 additions & 122 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="5.13.1@086b94371304750d1c673315321a55d15fc59015">
<files psalm-version="5.15.0@5c774aca4746caf3d239d9c8cadb9f882ca29352">
<file src="src/AbstractOptions.php">
<DocblockTypeContradiction>
<code><![CDATA[! is_array($options) && ! $options instanceof Traversable]]></code>
</DocblockTypeContradiction>
<MixedArgument>
<code>$key</code>
<code>$key</code>
<code>$letter</code>
<code>$value</code>
</MixedArgument>
<MixedAssignment>
<code>$array[$normalizedKey]</code>
<code>$key</code>
<code>$key</code>
<code>$letter</code>
<code>$value</code>
<code>$value</code>
</MixedAssignment>
<RawObjectIteration>
<code>$this</code>
</RawObjectIteration>
<MixedInferredReturnType>
<code>TValue</code>
</MixedInferredReturnType>
<MixedReturnStatement>
<code><![CDATA[$this->{$getter}()]]></code>
</MixedReturnStatement>
</file>
<file src="src/ArrayObject.php">
<ArgumentTypeCoercion>
Expand Down Expand Up @@ -308,14 +304,8 @@
</InvalidArgument>
<MissingClosureParamType>
<code>$a</code>
<code>$a</code>
<code>$b</code>
<code>$b</code>
</MissingClosureParamType>
<MixedArgument>
<code>$a</code>
<code>$b</code>
</MixedArgument>
<MixedAssignment>
<code>$unserialized</code>
</MixedAssignment>
Expand Down Expand Up @@ -374,37 +364,15 @@
</UndefinedInterfaceMethod>
</file>
<file src="test/FastPriorityQueueTest.php">
<InvalidArgument>
<code><![CDATA['foo']]></code>
</InvalidArgument>
<MissingClosureParamType>
<code>$e</code>
<code>$e</code>
</MissingClosureParamType>
<MixedArgument>
<code>$unserialized</code>
<code>$unserialized</code>
</MixedArgument>
<MixedAssignment>
<code>$datum</code>
<code>$expected[]</code>
<code>$item</code>
<code>$item</code>
<code>$item</code>
<code>$item</code>
<code>$item</code>
<code>$test[]</code>
<code>$test[]</code>
<code>$test[]</code>
<code>$test[]</code>
<code>$test[]</code>
<code>$test[]</code>
<code>$test[]</code>
<code>$test[]</code>
<code>$test[]</code>
<code>$unserialized</code>
<code>$value</code>
<code>$value</code>
<code>$value</code>
<code>$value</code>
<code>$value</code>
Expand All @@ -413,33 +381,13 @@
</file>
<file src="test/GlobTest.php">
<MixedArgument>
<code>$expectedFileName</code>
<code>$result[$i]</code>
</MixedArgument>
<MixedAssignment>
<code>$expectedFileName</code>
</MixedAssignment>
<RedundantConditionGivenDocblockType>
<code>assertIsArray</code>
</RedundantConditionGivenDocblockType>
</file>
<file src="test/OptionsTest.php">
<InternalMethod>
<code>addToAssertionCount</code>
</InternalMethod>
<InvalidArgument>
<code><![CDATA['asd']]></code>
<code><![CDATA[new TestOptions(['test_field' => 1])]]></code>
</InvalidArgument>
</file>
<file src="test/ParametersTest.php">
<ArgumentTypeCoercion>
<code><![CDATA['ArrayAccess']]></code>
<code><![CDATA['ArrayObject']]></code>
<code><![CDATA['Countable']]></code>
<code><![CDATA['Serializable']]></code>
<code><![CDATA['Traversable']]></code>
</ArgumentTypeCoercion>
<UndefinedPropertyFetch>
<code><![CDATA[$parameters->bar]]></code>
<code><![CDATA[$parameters->baz]]></code>
Expand All @@ -449,66 +397,4 @@
<code><![CDATA[$parameters->foof]]></code>
</UndefinedPropertyFetch>
</file>
<file src="test/PriorityListTest.php">
<NullArgument>
<code>null</code>
<code>null</code>
<code>null</code>
<code>null</code>
<code>null</code>
</NullArgument>
<TypeDoesNotContainType>
<code>assertEmpty</code>
</TypeDoesNotContainType>
</file>
<file src="test/PriorityQueueTest.php">
<MixedArgument>
<code>$unserialized</code>
<code>$unserialized</code>
<code>$unserialized</code>
</MixedArgument>
<MixedAssignment>
<code>$item</code>
<code>$test[]</code>
<code>$unserialized</code>
</MixedAssignment>
</file>
<file src="test/SplQueueTest.php">
<MixedArgument>
<code>$unserialized</code>
<code>$unserialized</code>
</MixedArgument>
<MixedAssignment>
<code>$unserialized</code>
</MixedAssignment>
</file>
<file src="test/SplStackTest.php">
<MixedArgument>
<code>$unserialized</code>
<code>$unserialized</code>
</MixedArgument>
<MixedAssignment>
<code>$unserialized</code>
</MixedAssignment>
</file>
<file src="test/StringUtilsTest.php">
<MixedArgument>
<code>$str</code>
</MixedArgument>
</file>
<file src="test/StringWrapper/IconvTest.php">
<TooManyArguments>
<code><![CDATA[new Iconv('utf-8')]]></code>
</TooManyArguments>
</file>
<file src="test/StringWrapper/IntlTest.php">
<TooManyArguments>
<code><![CDATA[new Intl('utf-8')]]></code>
</TooManyArguments>
</file>
<file src="test/StringWrapper/MbStringTest.php">
<TooManyArguments>
<code><![CDATA[new MbString('utf-8')]]></code>
</TooManyArguments>
</file>
</files>
20 changes: 13 additions & 7 deletions src/AbstractOptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Traversable;

use function array_shift;
use function get_object_vars;
use function is_array;
use function is_callable;
use function method_exists;
Expand All @@ -16,6 +17,10 @@
use function strtolower;
use function ucwords;

/**
* @template TValue
* @implements ParameterObjectInterface<string, TValue>
*/
abstract class AbstractOptions implements ParameterObjectInterface
{
// phpcs:disable PSR2.Classes.PropertyDeclaration.Underscore,WebimpressCodingStandard.NamingConventions.ValidVariableName.NotCamelCapsProperty
Expand All @@ -33,7 +38,7 @@ abstract class AbstractOptions implements ParameterObjectInterface
/**
* Constructor
*
* @param array|Traversable|null $options
* @param iterable<string, TValue>|AbstractOptions<TValue>|null $options
Ocramius marked this conversation as resolved.
Show resolved Hide resolved
*/
public function __construct($options = null)
{
Expand All @@ -45,7 +50,7 @@ public function __construct($options = null)
/**
* Set one or more configuration properties
*
* @param array|Traversable|AbstractOptions $options
* @param iterable<string, TValue>|AbstractOptions<TValue> $options
* @throws Exception\InvalidArgumentException
* @return AbstractOptions Provides fluent interface
*/
Expand Down Expand Up @@ -77,19 +82,20 @@ public function setFromArray($options)
/**
* Cast to array
*
* @return array
* @return array<string, TValue>
*/
public function toArray()
{
$array = [];

/** @param string[] $letters */
$transform = static function (array $letters): string {
/** @var list<string> $letters */
$letter = array_shift($letters);
return '_' . strtolower($letter);
};

foreach ($this as $key => $value) {
/** @psalm-var TValue $value */
foreach (get_object_vars($this) as $key => $value) {
if ($key === '__strictMode__') {
continue;
}
Expand All @@ -106,7 +112,7 @@ public function toArray()
* @see ParameterObject::__set()
*
* @param string $key
* @param mixed $value
* @param TValue|null $value
* @throws Exception\BadMethodCallException
* @return void
*/
Expand Down Expand Up @@ -137,7 +143,7 @@ public function __set($key, $value)
*
* @param string $key
* @throws Exception\BadMethodCallException
* @return mixed
* @return TValue
*/
public function __get($key)
{
Expand Down
15 changes: 10 additions & 5 deletions src/ParameterObjectInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,33 @@

namespace Laminas\Stdlib;

/**
* @template TKey of string
* @template TValue
*/
interface ParameterObjectInterface
{
/**
* @param string $key
* @param TKey $key
* @param TValue|null $value
* @return void
*/
public function __set($key, mixed $value);

/**
* @param string $key
* @return mixed
* @param TKey $key
* @return TValue
*/
public function __get($key);

/**
* @param string $key
* @param TKey $key
* @return bool
*/
public function __isset($key);

/**
* @param string $key
* @param TKey $key
* @return void
*/
public function __unset($key);
Expand Down
2 changes: 1 addition & 1 deletion test/ArrayObjectTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ public function testUasort(): void

public function testUksort(): void
{
$function = static function ($a, $b): int {
$function = static function (string $a, string $b): int {
$a = preg_replace('@^(a|an|the) @', '', $a);
$b = preg_replace('@^(a|an|the) @', '', $b);
self::assertNotNull($a);
Expand Down
19 changes: 11 additions & 8 deletions test/FastPriorityQueueTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,15 @@
#[Group('Laminas_Stdlib')]
class FastPriorityQueueTest extends TestCase
{
/** @var FastPriorityQueue */
protected $queue;
/** @var FastPriorityQueue<string> */
private FastPriorityQueue $queue;

/** @var string[] */
protected $expected;
private array $expected;

protected function setUp(): void
{
/** @psalm-var FastPriorityQueue<string> $this->queue */
$this->queue = new FastPriorityQueue();
$this->insertDataQueue($this->queue);
$this->expected = [
Expand Down Expand Up @@ -107,7 +108,8 @@ public function testSerializationAndDeserializationShouldMaintainState(): void
{
$s = serialize($this->queue);
$unserialized = unserialize($s);
$count = count($this->queue);
self::assertInstanceOf(FastPriorityQueue::class, $unserialized);
$count = count($this->queue);
self::assertSame(
$count,
count($unserialized),
Expand Down Expand Up @@ -168,6 +170,7 @@ public function testSetInvalidExtractFlag(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('The extract flag specified is not valid');
/** @psalm-suppress InvalidArgument */
$this->queue->setExtractFlags('foo');
}

Expand All @@ -191,7 +194,7 @@ public function testContains(): void

public function testHasPriority(): void
{
foreach ($this->getDataPriorityQueue() as $value => $priority) {
foreach ($this->getDataPriorityQueue() as $priority) {
self::assertTrue($this->queue->hasPriority($priority));
}
self::assertFalse($this->queue->hasPriority(10000));
Expand All @@ -211,7 +214,7 @@ public function testCanRemoveItemFromQueue(): void
self::assertEquals($expected, $test);
}

public function testRemoveOnlyTheFirstOccurenceFromQueue(): void
public function testRemoveOnlyTheFirstOccurrenceFromQueue(): void
{
$data = $this->getDataPriorityQueue();
$this->queue->insert('test2', $data['test2']);
Expand Down Expand Up @@ -246,7 +249,7 @@ public function testRewindShouldNotRaiseErrorWhenQueueIsEmpty(): void

public function testRemoveShouldFindItemEvenIfMultipleItemsAreInQueue(): void
{
$prototype = static function ($e): void {
$prototype = static function (): void {
};

$queue = new FastPriorityQueue();
Expand All @@ -268,7 +271,7 @@ public function testRemoveShouldFindItemEvenIfMultipleItemsAreInQueue(): void

public function testIterativelyRemovingItemsShouldRemoveAllItems(): void
{
$prototype = static function ($e): void {
$prototype = static function (): void {
};

$queue = new FastPriorityQueue();
Expand Down
Loading