Skip to content
Permalink
Browse files

Fix #2015 - complain about invalid @throws classes

  • Loading branch information...
muglug committed Aug 13, 2019
1 parent d5b0268 commit ef3771d643ce5a92e0d3bfa6fd744dda29e0fd17
@@ -1019,6 +1019,35 @@ function (FunctionLikeParameter $p) {
}
}
foreach ($storage->throws as $expected_exception => $_) {
if ($storage->location
&& ClassLikeAnalyzer::checkFullyQualifiedClassLikeName(
$statements_analyzer,
$expected_exception,
$storage->location,
$statements_analyzer->getSuppressedIssues(),
false
)
) {
$input_type = new Type\Union([new TNamedObject($expected_exception)]);
$container_type = new Type\Union([new TNamedObject('Exception'), new TNamedObject('Throwable')]);
if (!TypeAnalyzer::isContainedBy($codebase, $input_type, $container_type)) {
if (IssueBuffer::accepts(
new \Psalm\Issue\InvalidThrow(
'Cannot throw ' . $expected_exception
. ' as it does not implement Throwable',
$storage->location,
$expected_exception
),
$statements_analyzer->getSuppressedIssues()
)) {
// fall through
}
}
}
}
foreach ($statements_analyzer->getUncaughtThrows($context) as $possibly_thrown_exception => $codelocations) {
$is_expected = false;
@@ -2034,20 +2034,16 @@ private function registerFunctionLike(PhpParser\Node\FunctionLike $stmt, $fake_m
$storage->suppressed_issues = $docblock_info->suppress;
if ($this->config->check_for_throws_docblock ||
$this->config->check_for_throws_in_global_scope
) {
foreach ($docblock_info->throws as $throw_class) {
$exception_fqcln = Type::getFQCLNFromString(
$throw_class,
$this->aliases
);
foreach ($docblock_info->throws as $throw_class) {
$exception_fqcln = Type::getFQCLNFromString(
$throw_class,
$this->aliases
);
$this->codebase->scanner->queueClassLikeForScanning($exception_fqcln, $this->file_path);
$this->file_storage->referenced_classlikes[strtolower($exception_fqcln)] = $exception_fqcln;
$this->codebase->scanner->queueClassLikeForScanning($exception_fqcln, $this->file_path);
$this->file_storage->referenced_classlikes[strtolower($exception_fqcln)] = $exception_fqcln;
$storage->throws[$exception_fqcln] = true;
}
$storage->throws[$exception_fqcln] = true;
}
if (!$this->config->use_docblock_types) {
@@ -6,6 +6,46 @@
class ThrowsAnnotationTest extends TestCase
{
public function testUndefinedClassAsThrows() : void
{
$this->expectExceptionMessage('UndefinedClass');
$this->expectException(\Psalm\Exception\CodeException::class);
$this->addFile(
'somefile.php',
'<?php
/**
* @throws Foo
*/
function bar() : void {}'
);
$context = new Context();
$this->analyzeFile('somefile.php', $context);
}
public function testNonThrowableClassAsThrows() : void
{
$this->expectExceptionMessage('InvalidThrow');
$this->expectException(\Psalm\Exception\CodeException::class);
$this->addFile(
'somefile.php',
'<?php
class Foo {}
/**
* @throws Foo
*/
function bar() : void {}'
);
$context = new Context();
$this->analyzeFile('somefile.php', $context);
}
/**
* @return void
*/
@@ -123,8 +123,8 @@ public function testUncaughtDocumentedThrowCallInNamespace()
'<?php
namespace ns;
/**
* @throws RangeException
* @throws InvalidArgumentException
* @throws \RangeException
* @throws \InvalidArgumentException
*/
function foo(int $x, int $y) : int {
if ($y === 0) {
@@ -273,8 +273,8 @@ public function testUncaughtDocumentedThrowCallInNamespaceWhenSuppressing()
'<?php
namespace ns;
/**
* @throws RangeException
* @throws InvalidArgumentException
* @throws \RangeException
* @throws \InvalidArgumentException
*/
function foo(int $x, int $y) : int {
if ($y === 0) {

0 comments on commit ef3771d

Please sign in to comment.
You can’t perform that action at this time.