Skip to content

Commit

Permalink
Regression tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Mar 15, 2021
1 parent adacab8 commit d01431c
Show file tree
Hide file tree
Showing 20 changed files with 427 additions and 31 deletions.
12 changes: 10 additions & 2 deletions src/Analyser/MutatingScope.php
Original file line number Diff line number Diff line change
Expand Up @@ -854,8 +854,16 @@ private function resolveType(Expr $node): Type
$uncertainty = false;

if ($node->class instanceof Node\Name) {
$className = $this->resolveName($node->class);
$classType = new ObjectType($className);
$unresolvedClassName = $node->class->toString();
if (
strtolower($unresolvedClassName) === 'static'
&& $this->isInClass()
) {
$classType = new StaticType($this->getClassReflection());
} else {
$className = $this->resolveName($node->class);
$classType = new ObjectType($className);
}
} else {
$classType = $this->getType($node->class);
$classType = TypeTraverser::map($classType, static function (Type $type, callable $traverse) use (&$uncertainty): Type {
Expand Down
8 changes: 7 additions & 1 deletion src/Type/StaticType.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,13 @@ public function isSuperTypeOf(Type $type): TrinaryLogic
}

if ($type instanceof ObjectType) {
return TrinaryLogic::createMaybe()->and($this->getStaticObjectType()->isSuperTypeOf($type));
$result = $this->getStaticObjectType()->isSuperTypeOf($type);
$classReflection = $type->getClassReflection();
if ($result->yes() && $classReflection !== null && $classReflection->isFinal()) {
return $result;
}

return TrinaryLogic::createMaybe()->and($result);
}

if ($type instanceof CompoundType) {
Expand Down
6 changes: 6 additions & 0 deletions tests/PHPStan/Analyser/AnalyserIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,12 @@ public function testBug3922(): void
$this->assertCount(0, $errors);
}

public function testBug1843(): void
{
$errors = $this->runAnalyse(__DIR__ . '/data/bug-1843.php');
$this->assertCount(0, $errors);
}

/**
* @param string $file
* @return \PHPStan\Analyser\Error[]
Expand Down
24 changes: 24 additions & 0 deletions tests/PHPStan/Analyser/NodeScopeResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5666,6 +5666,26 @@ public function dataBug4267(): array
return $this->gatherAssertTypes(__DIR__ . '/data/bug-4267.php');
}

public function dataBug2231(): array
{
return $this->gatherAssertTypes(__DIR__ . '/data/bug-2231.php');
}

public function dataBug3558(): array
{
return $this->gatherAssertTypes(__DIR__ . '/data/bug-3558.php');
}

public function dataBug3351(): array
{
return $this->gatherAssertTypes(__DIR__ . '/data/bug-3351.php');
}

public function dataBug4213(): array
{
return $this->gatherAssertTypes(__DIR__ . '/data/bug-4213.php');
}

/**
* @dataProvider dataArrayFunctions
* @param string $description
Expand Down Expand Up @@ -11282,6 +11302,10 @@ private function gatherAssertTypes(string $file): array
* @dataProvider dataGenericParent
* @dataProvider dataBug4247
* @dataProvider dataBug4267
* @dataProvider dataBug2231
* @dataProvider dataBug3558
* @dataProvider dataBug3351
* @dataProvider dataBug4213
* @param string $assertType
* @param string $file
* @param mixed ...$args
Expand Down
24 changes: 24 additions & 0 deletions tests/PHPStan/Analyser/data/bug-1843.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace Bug1843;

class HelloWorld
{
const W = '1';

const P = [
self::W => [
'A' => '2',
'B' => '3',
'C' => '4',
'D' => '5',
'E' => '6',
'F' => '7',
],
];

public function sayHello(): void
{
echo self::P[self::W]['A'];
}
}
39 changes: 39 additions & 0 deletions tests/PHPStan/Analyser/data/bug-2231.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

namespace Bug2231;

use function PHPStan\Analyser\assertType;

class Foo
{

public function doFoo(?Foo $x): void
{
if ($x !== null && !($x instanceof static)) {
throw new \TypeError('custom error');
}

assertType('static(Bug2231\Foo)|null', $x);
}

public function doBar(?Foo $x): void
{
if ($x !== null && !($x instanceof self)) {
throw new \TypeError('custom error');
}

assertType('Bug2231\Foo|null', $x);
}

public function doBaz($x): void
{
if ($x instanceof self) {
assertType('Bug2231\Foo', $x);
}

if ($x instanceof static) {
assertType('static(Bug2231\Foo)', $x);
}
}

}
30 changes: 30 additions & 0 deletions tests/PHPStan/Analyser/data/bug-3351.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php declare(strict_types = 1);

use function PHPStan\Analyser\assertType;

class HelloWorld
{
public function sayHello(): void
{
$a = ['a', 'b', 'c'];
$b = [1, 2, 3];

$c = $this->combine($a, $b);
assertType('array<string, int>|false', $c);

assertType('array(\'a\' => 1, \'b\' => 2, \'c\' => 3)', array_combine($a, $b));
}

/**
* @template TKey
* @template TValue
* @param array<TKey> $keys
* @param array<TValue> $values
*
* @return array<TKey, TValue>|false
*/
private function combine(array $keys, array $values)
{
return array_combine($keys, $values);
}
}
33 changes: 33 additions & 0 deletions tests/PHPStan/Analyser/data/bug-3558.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace Bug3558;

use function PHPStan\Analyser\assertType;

function (): void {
$idGroups = [];

if(time() > 3){
$idGroups[] = [1,2];
$idGroups[] = [1,2];
$idGroups[] = [1,2];
}

if(count($idGroups) > 0){
assertType('array(array(1, 2), array(1, 2), array(1, 2))', $idGroups);
}
};

function (): void {
$idGroups = [1];

if(time() > 3){
$idGroups[] = [1,2];
$idGroups[] = [1,2];
$idGroups[] = [1,2];
}

if(count($idGroups) > 1){
assertType('array(0 => 1, ?1 => array(1, 2), ?2 => array(1, 2), ?3 => array(1, 2))', $idGroups);
}
};
64 changes: 64 additions & 0 deletions tests/PHPStan/Analyser/data/bug-4213.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

namespace Bug4213;

use function PHPStan\Analyser\assertType;

abstract class BaseEnum
{
private string $value;

final private function __construct(string $value)
{
$this->value = $value;
}
/**
* @return static
*/
public static function get(string $value): self {
return new static($value);
}
}

final class Enum extends BaseEnum
{
}

final class Entity {
public function setEnums(Enum ...$enums): void {
}
/**
* @param Enum[] $enums
*/
public function setEnumsWithoutSplat(array $enums): void {
}
}

function (): void {
assertType('Bug4213\Enum', Enum::get('test'));
assertType('array(Bug4213\Enum)', array_map([Enum::class, 'get'], ['test']));
};


class Foo
{
/**
* @return static
*/
public static function create() : Foo
{
return new static();
}
}


class Bar extends Foo
{
}

function (): void {
$cbFoo = [Foo::class, 'create'];
$cbBar = [Bar::class, 'create'];
assertType('Bug4213\Foo', $cbFoo());
assertType('Bug4213\Bar', $cbBar());
};
28 changes: 0 additions & 28 deletions tests/PHPStan/Reflection/StaticTypeTest.php

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -190,4 +190,15 @@ public function testBugComposerDependentVariables(): void
$this->analyse([__DIR__ . '/data/bug-composer-dependent-variables.php'], []);
}

public function testBug2231(): void
{
$this->treatPhpDocTypesAsCertain = true;
$this->analyse([__DIR__ . '/../../Analyser/data/bug-2231.php'], [
[
'Result of && is always false.',
21,
],
]);
}

}
7 changes: 7 additions & 0 deletions tests/PHPStan/Rules/Methods/MethodSignatureRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -290,4 +290,11 @@ public function testBug4084(): void
$this->analyse([__DIR__ . '/data/bug-4084.php'], []);
}

public function testBug3523(): void
{
$this->reportMaybes = true;
$this->reportStatic = true;
$this->analyse([__DIR__ . '/data/bug-3523.php'], []);
}

}
15 changes: 15 additions & 0 deletions tests/PHPStan/Rules/Methods/ReturnTypeRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -459,4 +459,19 @@ public function testReturnStatic(): void
$this->analyse([__DIR__ . '/data/return-static.php'], []);
}

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

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

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

}
42 changes: 42 additions & 0 deletions tests/PHPStan/Rules/Methods/data/bug-3120.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

namespace Bug3120;

class A {
/** @return static */
public static function getInstance() {
$class = static::class;
return new $class();
}
}

final class AChild extends A {
public static function getInstance() {
return new AChild();
}
}

class Test
{
final public function __construct()
{}

/**
* @return static
*/
public function foo(): self
{
return self::bar(new static());
}

/**
* @phpstan-template T of Test
* @phpstan-param T $object
* @phpstan-return T
*/
public function bar(Test $object): self
{
return $object;
}

}

0 comments on commit d01431c

Please sign in to comment.