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
7 changes: 7 additions & 0 deletions src/Rules/TooWideTypehints/TooWideTypeCheck.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@ public function checkFunction(

$returnType = TypeCombinator::union(...$returnTypes);

if (
$returnType->isConstantScalarValue()->yes()
&& $functionReturnType->isConstantScalarValue()->yes()
) {
return [];
}

// Do not require to have @return null/true/false in descendant classes
if (
$checkDescendantClass
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ protected function getRule(): Rule
);
}

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

public function testRule(): void
{
$this->analyse([__DIR__ . '/data/tooWideClosureReturnType.php'], [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,9 @@ public function testBug11980(): void
]);
}

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

}
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,7 @@ public function testPublicProtectedWithInheritance(): void

public function testBug5095(): void
{
$this->analyse([__DIR__ . '/data/bug-5095.php'], [
[
'Method Bug5095\Parser::unaryOperatorFor() never returns \'not\' so it can be removed from the return type.',
21,
],
]);
$this->analyse([__DIR__ . '/data/bug-5095.php'], []);
}

#[RequiresPhp('>= 8.0')]
Expand Down Expand Up @@ -199,4 +194,28 @@ public function testBug11980(): void
]);
}

public function testBug10312(): void
{
$this->checkProtectedAndPublicMethods = true;
$this->analyse([__DIR__ . '/data/bug-10312.php'], []);
}

public function testBug10312b(): void
{
$this->checkProtectedAndPublicMethods = true;
$this->analyse([__DIR__ . '/data/bug-10312b.php'], []);
}

public function testBug10312c(): void
{
$this->checkProtectedAndPublicMethods = true;
$this->analyse([__DIR__ . '/data/bug-10312c.php'], []);
}

public function testBug10312d(): void
{
$this->checkProtectedAndPublicMethods = true;
$this->analyse([__DIR__ . '/data/bug-10312d.php'], []);
}

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

namespace Bug10312;

class Cmsissue
{
public const LANE_BACKLOG = 'Backlog';

public const LANE_READY_FOR_IMPL = 'Bereit zur Entwicklung';

public const LANE_IN_IMPL = 'In Entwicklung';

public const LANE_READY_FOR_UAT = 'Bereit zur Abnahme';

public const LANE_READY_FOR_UAT_KANBAN = 'Test';

public const LANE_PROJECT_BACKLOG = 'Backlog';

public const LANE_PROJECT_IN_IMPL = 'Projekt in Umsetzung';

public const LANE_SKIP = '';
}


final class Mapper
{

/**
* @return Cmsissue::LANE_*
*/
public function mapIssueStatus(): string
{
if (rand(0,1) === 0) {
return Cmsissue::LANE_BACKLOG;
}
if (rand(0,1) === 0) {
return Cmsissue::LANE_READY_FOR_IMPL;
}
if (rand(0,1) === 0) {
return Cmsissue::LANE_IN_IMPL;
}
if (rand(0,1) === 0) {
return Cmsissue::LANE_READY_FOR_UAT;
}

return Cmsissue::LANE_SKIP;
}
}
45 changes: 45 additions & 0 deletions tests/PHPStan/Rules/TooWideTypehints/data/bug-10312a.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

namespace Bug10312a;

class Cmsissue
{
public const LANE_BACKLOG = 'Backlog';

public const LANE_READY_FOR_IMPL = 'Bereit zur Entwicklung';

public const LANE_IN_IMPL = 'In Entwicklung';

public const LANE_READY_FOR_UAT = 'Bereit zur Abnahme';

public const LANE_READY_FOR_UAT_KANBAN = 'Test';

public const LANE_PROJECT_BACKLOG = 'Backlog';

public const LANE_PROJECT_IN_IMPL = 'Projekt in Umsetzung';

public const LANE_SKIP = '';
}


/**
* @return Cmsissue::LANE_*
*/
function mapIssueStatus(): string
{
if (rand(0,1) === 0) {
return Cmsissue::LANE_BACKLOG;
}
if (rand(0,1) === 0) {
return Cmsissue::LANE_READY_FOR_IMPL;
}
if (rand(0,1) === 0) {
return Cmsissue::LANE_IN_IMPL;
}
if (rand(0,1) === 0) {
return Cmsissue::LANE_READY_FOR_UAT;
}

return Cmsissue::LANE_SKIP;
}

40 changes: 40 additions & 0 deletions tests/PHPStan/Rules/TooWideTypehints/data/bug-10312b.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace Bug10312b;

interface MinPhpVersionInterface
{
/**
* @return PhpVersion::*
*/
public function provideMinPhpVersion() : int;
}

final class PhpVersion
{
/**
* @var int
*/
public const PHP_52 = 50200;
/**
* @var int
*/
public const PHP_53 = 50300;
/**
* @var int
*/
public const PHP_54 = 50400;
/**
* @var int
*/
public const PHP_55 = 50500;
}

final class TypedPropertyFromStrictConstructorReadonlyClassRector implements MinPhpVersionInterface
{
public function provideMinPhpVersion(): int
{
return PhpVersion::PHP_55;
}

}
44 changes: 44 additions & 0 deletions tests/PHPStan/Rules/TooWideTypehints/data/bug-10312c.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php // lint >= 8.1

declare(strict_types = 1);

namespace Bug10312c;

enum Foo: int
{
case BAR = 1;
case BAZ = 2;
}

interface ReturnsFoo
{
/** @return value-of<Foo> */
public function returnsFooValue(): int;
}

class ReturnsBar implements ReturnsFoo
{
#[\Override]
public function returnsFooValue(): int
{
return Foo::BAR->value;
}
}

class ReturnsBarWithFinalMethod implements ReturnsFoo
{
#[\Override]
final public function returnsFooValue(): int
{
return Foo::BAR->value;
}
}

final class ReturnsBaz implements ReturnsFoo
{
#[\Override]
public function returnsFooValue(): int
{
return Foo::BAZ->value;
}
}
41 changes: 41 additions & 0 deletions tests/PHPStan/Rules/TooWideTypehints/data/bug-10312d.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php // lint >= 8.1

declare(strict_types = 1);

namespace Bug10312d;

enum Foo: int
{
case BAR = 1;
case BAZ = 2;
}

class FooBar {
public ?Foo $foo = null;
}

interface ReturnsFoo
{
/** @return value-of<Foo> */
public function returnsFooValue(): int;

/** @return value-of<Foo>|null */
public function returnsFooOrNullValue(): ?int;
}

final class ReturnsNullsafeBaz implements ReturnsFoo
{
#[\Override]
public function returnsFooValue(): int
{
$f = new FooBar();
return $f->foo?->value;
}

#[\Override]
public function returnsFooOrNullValue(): ?int
{
$f = new FooBar();
return $f->foo?->value;
}
}
44 changes: 44 additions & 0 deletions tests/PHPStan/Rules/TooWideTypehints/data/bug-10312e.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace Bug10312e;

class Cmsissue
{
public const LANE_BACKLOG = 'Backlog';

public const LANE_READY_FOR_IMPL = 'Bereit zur Entwicklung';

public const LANE_IN_IMPL = 'In Entwicklung';

public const LANE_READY_FOR_UAT = 'Bereit zur Abnahme';

public const LANE_READY_FOR_UAT_KANBAN = 'Test';

public const LANE_PROJECT_BACKLOG = 'Backlog';

public const LANE_PROJECT_IN_IMPL = 'Projekt in Umsetzung';

public const LANE_SKIP = '';
}


/**
* @return Cmsissue::LANE_*
*/
$x = function(): string
{
if (rand(0,1) === 0) {
return Cmsissue::LANE_BACKLOG;
}
if (rand(0,1) === 0) {
return Cmsissue::LANE_READY_FOR_IMPL;
}
if (rand(0,1) === 0) {
return Cmsissue::LANE_IN_IMPL;
}
if (rand(0,1) === 0) {
return Cmsissue::LANE_READY_FOR_UAT;
}

return Cmsissue::LANE_SKIP;
};
Loading