1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-26 20:34:47 +01:00

Add DuplicateFunction issue

Fixes #49
This commit is contained in:
Matthew Brown 2019-01-06 16:40:44 -05:00
parent 58b71e56b1
commit 214fd7d461
8 changed files with 73 additions and 9 deletions

View File

@ -143,6 +143,7 @@
<xs:element name="DocblockTypeContradiction" type="IssueHandlerType" minOccurs="0" />
<xs:element name="DuplicateArrayKey" type="IssueHandlerType" minOccurs="0" />
<xs:element name="DuplicateParam" type="IssueHandlerType" minOccurs="0" />
<xs:element name="DuplicateFunction" type="IssueHandlerType" minOccurs="0" />
<xs:element name="DuplicateClass" type="IssueHandlerType" minOccurs="0" />
<xs:element name="DuplicateMethod" type="IssueHandlerType" minOccurs="0" />
<xs:element name="EmptyArrayAccess" type="IssueHandlerType" minOccurs="0" />

View File

@ -180,6 +180,16 @@ class A {}
class A {}
```
### DuplicateFunction
Emitted when a function is defined twice
```php
function foo() : void {}
function bar() : void {}
function foo() : void {}
```
### DuplicateMethod
Emitted when a method is defined twice

View File

@ -21,6 +21,7 @@ use Psalm\Exception\IncorrectDocblockException;
use Psalm\Exception\TypeParseTreeException;
use Psalm\FileSource;
use Psalm\Issue\DuplicateClass;
use Psalm\Issue\DuplicateFunction;
use Psalm\Issue\DuplicateMethod;
use Psalm\Issue\DuplicateParam;
use Psalm\Issue\InvalidDocblock;
@ -851,15 +852,46 @@ class ReflectorVisitor extends PhpParser\NodeVisitorAbstract implements PhpParse
($this->aliases->namespace ? $this->aliases->namespace . '\\' : '') . $stmt->name->name;
$function_id = strtolower($cased_function_id);
if (isset($this->file_storage->functions[$function_id])) {
if ($this->codebase->register_stub_files || $this->codebase->register_autoload_files) {
if ($this->codebase->register_stub_files || $this->codebase->register_autoload_files) {
if (isset($this->file_storage->functions[$function_id])) {
$this->codebase->functions->addGlobalFunction(
$function_id,
$this->file_storage->functions[$function_id]
);
}
return $this->file_storage->functions[$function_id];
return $this->file_storage->functions[$function_id];
}
} else {
if (isset($this->file_storage->functions[$function_id])) {
$duplicate_function_storage = $this->file_storage->functions[$function_id];
if (IssueBuffer::accepts(
new DuplicateFunction(
'Method ' . $function_id . ' has already been defined'
. ($duplicate_function_storage->location
? ' in ' . $duplicate_function_storage->location->file_path
: ''),
new CodeLocation($this->file_scanner, $stmt, null, true)
)
)) {
// fall through
}
$this->file_storage->has_visitor_issues = true;
$duplicate_function_storage->has_visitor_issues = true;
return $this->file_storage->functions[$function_id];
} elseif (isset($this->config->getPredefinedFunctions()[$function_id])) {
if (IssueBuffer::accepts(
new DuplicateFunction(
'Method ' . $function_id . ' has already been defined as a core function',
new CodeLocation($this->file_scanner, $stmt, null, true)
)
)) {
// fall through
}
}
}
$storage = new FunctionLikeStorage();

View File

@ -0,0 +1,6 @@
<?php
namespace Psalm\Issue;
class DuplicateFunction extends CodeIssue
{
}

View File

@ -1328,6 +1328,12 @@ class FunctionCallTest extends TestCase
foo($x);
}',
],
'duplicateNamespacedFunction' => [
'<?php
namespace Bar;
function sort() : void {}',
],
];
}
@ -1728,6 +1734,17 @@ class FunctionCallTest extends TestCase
}',
'error_message' => 'InvalidScalarArgument',
],
'duplicateFunction' => [
'<?php
function f() : void {}
function f() : void {}',
'error_message' => 'DuplicateFunction',
],
'duplicateCoreFunction' => [
'<?php
function sort() : void {}',
'error_message' => 'DuplicateFunction',
],
];
}
}

View File

@ -77,7 +77,6 @@ class SymbolLookupTest extends \Psalm\Tests\TestCase
$codebase = $this->project_analyzer->getCodebase();
$codebase->scanFiles();
$this->analyzeFile('somefile.php', new Context());
$this->assertSame('<?php public function foo() : void', $codebase->getSymbolInformation('somefile.php', 'B\A::foo()'));
@ -114,7 +113,6 @@ class SymbolLookupTest extends \Psalm\Tests\TestCase
$codebase = $this->project_analyzer->getCodebase();
$codebase->scanFiles();
$this->analyzeFile('somefile.php', new Context());

View File

@ -236,7 +236,7 @@ class Php56Test extends TestCase
return intval(...$args);
}
function foo(ArrayIterator $args): int {
function bar(ArrayIterator $args): int {
return intval(...$args);
}',
],

View File

@ -872,7 +872,7 @@ class TypeReconciliationTest extends TestCase
if ($i == 0.0) {}
if (0.0 == $i) {}
}
function foo(float $i) : void {
function bar(float $i) : void {
$i = $i / 100.0;
if ($i == "5") {}
if ("5" == $i) {}
@ -883,7 +883,7 @@ class TypeReconciliationTest extends TestCase
if ($i == 0) {}
if (0 == $i) {}
}
function foo(string $i) : void {
function bat(string $i) : void {
if ($i == 5) {}
if (5 == $i) {}
if ($i == 5.0) {}