mirror of
https://github.com/danog/psalm.git
synced 2024-11-26 20:34:47 +01:00
parent
58b71e56b1
commit
214fd7d461
@ -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" />
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
6
src/Psalm/Issue/DuplicateFunction.php
Normal file
6
src/Psalm/Issue/DuplicateFunction.php
Normal file
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
namespace Psalm\Issue;
|
||||
|
||||
class DuplicateFunction extends CodeIssue
|
||||
{
|
||||
}
|
@ -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',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
|
||||
|
||||
|
@ -236,7 +236,7 @@ class Php56Test extends TestCase
|
||||
return intval(...$args);
|
||||
}
|
||||
|
||||
function foo(ArrayIterator $args): int {
|
||||
function bar(ArrayIterator $args): int {
|
||||
return intval(...$args);
|
||||
}',
|
||||
],
|
||||
|
@ -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) {}
|
||||
|
Loading…
Reference in New Issue
Block a user