Skip to content

Resolve Static throw points #4128

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

Open
wants to merge 5 commits into
base: 2.1.x
Choose a base branch
from
Open
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 src/Analyser/MutatingScope.php
Original file line number Diff line number Diff line change
Expand Up @@ -3125,7 +3125,7 @@ public function enterClassMethod(
$this->getParameterAttributes($classMethod),
$this->transformStaticType($this->getFunctionType($classMethod->returnType, false, false)),
$phpDocReturnType !== null ? $this->transformStaticType(TemplateTypeHelper::toArgument($phpDocReturnType)) : null,
$throwType,
$throwType !== null ? $this->transformStaticType(TemplateTypeHelper::toArgument($throwType)) : null,
$deprecatedDescription,
$isDeprecated,
$isInternal,
Expand Down Expand Up @@ -3212,7 +3212,7 @@ public function enterPropertyHook(
$this->getParameterAttributes($hook),
$realReturnType,
$phpDocReturnType,
$throwType,
$throwType !== null ? $this->transformStaticType(TemplateTypeHelper::toArgument($throwType)) : null,
$deprecatedDescription,
$isDeprecated,
false,
Expand Down
3 changes: 2 additions & 1 deletion src/Reflection/Dummy/ChangedTypeMethodReflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public function __construct(
private array $variants,
private ?array $namedArgumentsVariants,
private ?Type $selfOutType,
private ?Type $throwType,
)
{
}
Expand Down Expand Up @@ -122,7 +123,7 @@ public function isBuiltin(): TrinaryLogic

public function getThrowType(): ?Type
{
return $this->reflection->getThrowType();
return $this->throwType;
}

public function hasSideEffects(): TrinaryLogic
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,18 @@ private function transformMethodWithStaticType(ClassReflection $declaringClass,
$namedArgumentVariants = $namedArgumentVariants !== null
? array_map($variantFn, $namedArgumentVariants)
: null;
$throwType = $method->getThrowType();
$throwType = $throwType !== null
? $this->transformStaticType($throwType)
: null;

return new ChangedTypeMethodReflection(
$declaringClass,
$method,
$variants,
$namedArgumentVariants,
$selfOutType,
$throwType,
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,18 @@ private function transformMethodWithStaticType(ClassReflection $declaringClass,
$namedArgumentsVariants = $namedArgumentsVariants !== null
? array_map($variantFn, $namedArgumentsVariants)
: null;
$throwType = $method->getThrowType();
$throwType = $throwType !== null
? $this->transformStaticType($throwType)
: null;

return new ChangedTypeMethodReflection(
$declaringClass,
$method,
$variants,
$namedArgumentsVariants,
$selfOutType,
$throwType,
);
}

Expand Down
41 changes: 41 additions & 0 deletions tests/PHPStan/Rules/Exceptions/Bug11900Test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php declare(strict_types = 1);

namespace PHPStan\Rules\Exceptions;

use PHPStan\Rules\Rule;
use PHPStan\Testing\RuleTestCase;
use PHPUnit\Framework\Attributes\RequiresPhp;

/**
* @extends RuleTestCase<MissingCheckedExceptionInMethodThrowsRule>
*/
class Bug11900Test extends RuleTestCase
{

protected function getRule(): Rule
{
return new MissingCheckedExceptionInMethodThrowsRule(
new MissingCheckedExceptionInThrowsCheck(new DefaultExceptionTypeResolver(
self::createReflectionProvider(),
[],
[],
[],
[],
)),
);
}

#[RequiresPhp('>= 8.4')]
public function testRule(): void
{
$this->analyse([__DIR__ . '/data/bug-11900.php'], []);
}

public static function getAdditionalConfigFiles(): array
{
return [
__DIR__ . '/bug-11900.neon',
];
}

}
6 changes: 6 additions & 0 deletions tests/PHPStan/Rules/Exceptions/bug-11900.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
parameters:
exceptions:
implicitThrows: false
check:
missingCheckedExceptionInThrows: true
tooWideThrowType: true
50 changes: 50 additions & 0 deletions tests/PHPStan/Rules/Exceptions/data/bug-11900.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php // lint >= 8.4

namespace Bug11900;

use Exception;
use Throwable;

abstract class ADataException extends Exception
{
/**
* @return void
* @throws static
*/
public function throw1(): void
{
throw $this;
}

/**
* @return void
* @throws static
*/
public static function throw2(): void
{
throw new static();
}
}

final class TestDataException extends ADataException
{
}

class TestPhpStan
{
/**
* @throws TestDataException
*/
public function validate(TestDataException $e): void
{
$e->throw1();
}

/**
* @throws TestDataException
*/
public function validate2(): void
{
TestDataException::throw2();
}
}
Loading