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

Flag duplicate constants

Fixes vimeo/psalm#6882
Addresses p1 from vimeo/psalm#6471
This commit is contained in:
Bruce Weirdan 2021-11-11 00:44:17 +02:00
parent 8c761dd6d9
commit 85f2083acb
No known key found for this signature in database
GPG Key ID: CFC3AAB181751B0D
6 changed files with 85 additions and 0 deletions

View File

@ -240,6 +240,7 @@
<xs:element name="DocblockTypeContradiction" type="IssueHandlerType" minOccurs="0" />
<xs:element name="DuplicateArrayKey" type="IssueHandlerType" minOccurs="0" />
<xs:element name="DuplicateClass" type="IssueHandlerType" minOccurs="0" />
<xs:element name="DuplicateConstant" type="ClassIssueHandlerType" minOccurs="0" />
<xs:element name="DuplicateEnumCase" type="ClassIssueHandlerType" minOccurs="0" />
<xs:element name="DuplicateEnumCaseValue" type="ClassIssueHandlerType" minOccurs="0" />
<xs:element name="DuplicateFunction" type="IssueHandlerType" minOccurs="0" />

View File

@ -20,6 +20,7 @@
- [DocblockTypeContradiction](issues/DocblockTypeContradiction.md)
- [DuplicateArrayKey](issues/DuplicateArrayKey.md)
- [DuplicateClass](issues/DuplicateClass.md)
- [DuplicateConstant](issues/DuplicateConstant.md)
- [DuplicateFunction](issues/DuplicateFunction.md)
- [DuplicateMethod](issues/DuplicateMethod.md)
- [DuplicateParam](issues/DuplicateParam.md)

View File

@ -0,0 +1,16 @@
# DuplicateConstant
Emitted when a constant is defined twice in a single class or when there's a
clash between a constant and an enum case.
```php
<?php
class C {
public const A = 1;
public const A = 2;
}
```
## Why this is bad
The above code wont compile.

View File

@ -28,6 +28,7 @@ use Psalm\Internal\Type\TypeAlias;
use Psalm\Internal\Type\TypeParser;
use Psalm\Internal\Type\TypeTokenizer;
use Psalm\Issue\DuplicateClass;
use Psalm\Issue\DuplicateConstant;
use Psalm\Issue\DuplicateEnumCase;
use Psalm\Issue\InvalidDocblock;
use Psalm\Issue\InvalidEnumBackingType;
@ -1193,6 +1194,19 @@ class ClassLikeNodeScanner
$fq_classlike_name
);
if (isset($storage->constants[$const->name->name])
|| isset($storage->enum_cases[$const->name->name])
) {
if (IssueBuffer::accepts(new DuplicateConstant(
'Constant names should be unique',
new CodeLocation($this->file_scanner, $const),
$fq_classlike_name
))) {
// fall through
}
continue;
}
$storage->constants[$const->name->name] = $constant_storage = new \Psalm\Storage\ClassConstantStorage(
$const_type,
$stmt->isProtected()
@ -1271,6 +1285,17 @@ class ClassLikeNodeScanner
ClassLikeStorage $storage,
string $fq_classlike_name
): void {
if (isset($storage->constants[$stmt->name->name])) {
if (IssueBuffer::accepts(new DuplicateConstant(
'Constant names should be unique',
new CodeLocation($this->file_scanner, $stmt),
$fq_classlike_name
))) {
// fall through
}
return;
}
$enum_value = null;
if ($stmt->expr !== null) {

View File

@ -0,0 +1,9 @@
<?php
namespace Psalm\Issue;
class DuplicateConstant extends ClassIssue
{
public const ERROR_LEVEL = -1;
public const SHORTCODE = 302;
}

View File

@ -1430,6 +1430,39 @@ class ConstantTest extends TestCase
}',
'error_message' => 'UndefinedClass',
],
'duplicateConstants' => [
'<?php
class A {
public const B = 1;
public const B = 2;
}
',
'error_message' => 'DuplicateConstant',
],
'constantDuplicatesEnumCase' => [
'<?php
enum State {
case Open;
public const Open = 1;
}
',
'error_message' => 'DuplicateConstant',
[],
false,
'8.1',
],
'enumCaseDuplicatesConstant' => [
'<?php
enum State {
public const Open = 1;
case Open;
}
',
'error_message' => 'DuplicateConstant',
[],
false,
'8.1',
],
];
}
}