Skip to content

Commit

Permalink
Fix array and iterable type action methods on NeverType
Browse files Browse the repository at this point in the history
  • Loading branch information
herndlm authored and ondrejmirtes committed Nov 5, 2022
1 parent d91411b commit 7a7b386
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 4 deletions.
104 changes: 100 additions & 4 deletions src/Type/NeverType.php
Expand Up @@ -12,10 +12,8 @@
use PHPStan\Reflection\Type\UnresolvedPropertyPrototypeReflection;
use PHPStan\ShouldNotHappenException;
use PHPStan\TrinaryLogic;
use PHPStan\Type\Traits\NonArrayTypeTrait;
use PHPStan\Type\Traits\NonGeneralizableTypeTrait;
use PHPStan\Type\Traits\NonGenericTypeTrait;
use PHPStan\Type\Traits\NonIterableTypeTrait;
use PHPStan\Type\Traits\NonRemoveableTypeTrait;
use PHPStan\Type\Traits\UndecidedBooleanTypeTrait;
use PHPStan\Type\Traits\UndecidedComparisonCompoundTypeTrait;
Expand All @@ -25,9 +23,7 @@ class NeverType implements CompoundType
{

use UndecidedBooleanTypeTrait;
use NonArrayTypeTrait;
use NonGenericTypeTrait;
use NonIterableTypeTrait;
use UndecidedComparisonCompoundTypeTrait;
use NonRemoveableTypeTrait;
use NonGeneralizableTypeTrait;
Expand All @@ -50,6 +46,16 @@ public function getReferencedClasses(): array
return [];
}

public function getArrays(): array
{
return [];
}

public function getConstantArrays(): array
{
return [];
}

public function accepts(Type $type, bool $strictTypes): TrinaryLogic
{
return TrinaryLogic::createYes();
Expand Down Expand Up @@ -149,16 +155,61 @@ public function isIterableAtLeastOnce(): TrinaryLogic
return TrinaryLogic::createMaybe();
}

public function getArraySize(): Type
{
return new NeverType();
}

public function getIterableKeyType(): Type
{
return new NeverType();
}

public function getFirstIterableKeyType(): Type
{
return new NeverType();
}

public function getLastIterableKeyType(): Type
{
return new NeverType();
}

public function getIterableValueType(): Type
{
return new NeverType();
}

public function getFirstIterableValueType(): Type
{
return new NeverType();
}

public function getLastIterableValueType(): Type
{
return new NeverType();
}

public function isArray(): TrinaryLogic
{
return TrinaryLogic::createNo();
}

public function isConstantArray(): TrinaryLogic
{
return TrinaryLogic::createNo();
}

public function isOversizedArray(): TrinaryLogic
{
return TrinaryLogic::createNo();
}

public function isList(): TrinaryLogic
{
return TrinaryLogic::createNo();
}

public function isOffsetAccessible(): TrinaryLogic
{
return TrinaryLogic::createYes();
Expand All @@ -184,6 +235,51 @@ public function unsetOffset(Type $offsetType): Type
return new NeverType();
}

public function getKeysArray(): Type
{
return new NeverType();
}

public function getValuesArray(): Type
{
return new NeverType();
}

public function fillKeysArray(Type $valueType): Type
{
return new NeverType();
}

public function flipArray(): Type
{
return new NeverType();
}

public function intersectKeyArray(Type $otherArraysType): Type
{
return new NeverType();
}

public function popArray(): Type
{
return new NeverType();
}

public function searchArray(Type $needleType): Type
{
return new NeverType();
}

public function shiftArray(): Type
{
return new NeverType();
}

public function shuffleArray(): Type
{
return new NeverType();
}

public function isCallable(): TrinaryLogic
{
return TrinaryLogic::createYes();
Expand Down
1 change: 1 addition & 0 deletions tests/PHPStan/Analyser/NodeScopeResolverTest.php
Expand Up @@ -1122,6 +1122,7 @@ public function dataFileAsserts(): iterable
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-7913.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Functions/data/bug-8280.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-8272.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Comparison/data/bug-8277.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/strtr.php');
}

Expand Down
Expand Up @@ -17,6 +17,11 @@ protected function getRule(): Rule
return new NumberComparisonOperatorsConstantConditionRule();
}

public function testBug8277(): void
{
$this->analyse([__DIR__ . '/data/bug-8277.php'], []);
}

public function testRule(): void
{
$this->analyse([__DIR__ . '/data/number-comparison-operators.php'], [
Expand Down
36 changes: 36 additions & 0 deletions tests/PHPStan/Rules/Comparison/data/bug-8277.php
@@ -0,0 +1,36 @@
<?php declare(strict_types = 1);

namespace Bug8277;

use Generator;
use function PHPStan\Testing\assertType;

/**
* {@see FunctionalStreamTest::testWindow()}
*
* @template K
* @template T
*
* @param iterable<K, T> $stream
* @param positive-int $width
*
* @return Generator<int, T[]>
*/
function swindow(iterable $stream, int $width): Generator
{
$window = [];
foreach ($stream as $value) {
$window[] = $value;
$count = count($window);

assertType('int<1, max>', $count);

switch (true) {
case $count > $width:
array_shift($window);
// no break
case $count === $width:
yield $window;
}
}
}

0 comments on commit 7a7b386

Please sign in to comment.