1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-30 04:39:00 +01:00

Inherit throws docblock from parent class by default (#1947)

This commit is contained in:
Sergey Melesh 2019-07-15 00:29:04 +03:00 committed by Matthew Brown
parent 96429ff94f
commit af875439e7
2 changed files with 118 additions and 10 deletions

View File

@ -303,11 +303,10 @@ class Populator
$declaring_method_storage->overridden_downstream = true;
$declaring_method_storage->overridden_somewhere = true;
if (!$method_storage->throws
&& $method_storage->inheritdoc
&& $declaring_method_storage->throws
if ($declaring_method_storage->throws
&& (!$method_storage->throws || $method_storage->inheritdoc)
) {
$method_storage->throws = $declaring_method_storage->throws;
$method_storage->throws += $declaring_method_storage->throws;
}
if (count($storage->overridden_method_ids[$method_name]) === 1
@ -774,11 +773,10 @@ class Populator
if (isset($interface_storage->methods[$method_name])) {
$interface_method_storage = $interface_storage->methods[$method_name];
if (!$method_storage->throws
&& $method_storage->inheritdoc
&& $interface_method_storage->throws
if ($interface_method_storage->throws
&& (!$method_storage->throws || $method_storage->inheritdoc)
) {
$method_storage->throws = $interface_method_storage->throws;
$method_storage->throws += $interface_method_storage->throws;
}
if ($interface_method_storage->return_type

View File

@ -449,8 +449,6 @@ class ThrowsAnnotationTest extends TestCase
*/
public function testDocumentedThrowInInterfaceWithoutInheritDocblock()
{
$this->expectExceptionMessage('MissingThrowsDocblock');
$this->expectException(\Psalm\Exception\CodeException::class);
Config::getInstance()->check_for_throws_docblock = true;
$this->addFile(
@ -478,4 +476,116 @@ class ThrowsAnnotationTest extends TestCase
$this->analyzeFile('somefile.php', $context);
}
/**
* @return void
*/
public function testDocumentedThrowInSubclassWithExtendedInheritDocblock()
{
Config::getInstance()->check_for_throws_docblock = true;
$this->addFile(
'somefile.php',
'<?php
interface Foo
{
/**
* @throws \InvalidArgumentException
*/
public function test(): void;
}
class Bar implements Foo
{
/**
* {@inheritdoc}
* @throws \OutOfBoundsException
*/
public function test(): void
{
throw new \OutOfBoundsException();
}
}
'
);
$context = new Context();
$this->analyzeFile('somefile.php', $context);
}
/**
* @return void
*/
public function testDocumentedThrowInInterfaceWithExtendedInheritDocblock()
{
Config::getInstance()->check_for_throws_docblock = true;
$this->addFile(
'somefile.php',
'<?php
interface Foo
{
/**
* @throws \InvalidArgumentException
*/
public function test(): void;
}
class Bar implements Foo
{
/**
* {@inheritdoc}
* @throws \OutOfBoundsException
*/
public function test(): void
{
throw new \InvalidArgumentException();
}
}
'
);
$context = new Context();
$this->analyzeFile('somefile.php', $context);
}
/**
* @return void
*/
public function testDocumentedThrowInInterfaceWithOverriddenDocblock()
{
$this->expectExceptionMessage('MissingThrowsDocblock');
$this->expectException(\Psalm\Exception\CodeException::class);
Config::getInstance()->check_for_throws_docblock = true;
$this->addFile(
'somefile.php',
'<?php
interface Foo
{
/**
* @throws \InvalidArgumentException
*/
public function test(): void;
}
class Bar implements Foo
{
/**
* @throws \OutOfBoundsException
*/
public function test(): void
{
throw new \InvalidArgumentException();
}
}
'
);
$context = new Context();
$this->analyzeFile('somefile.php', $context);
}
}