mirror of
https://github.com/danog/psalm.git
synced 2024-11-30 04:39:00 +01:00
Merge pull request #10828 from jack-worman/MissingClassConstType
This commit is contained in:
commit
3a1b10f211
@ -313,6 +313,7 @@
|
||||
<xs:element name="MismatchingDocblockParamType" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="MismatchingDocblockPropertyType" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="MismatchingDocblockReturnType" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="MissingClassConstType" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="MissingClosureParamType" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="MissingClosureReturnType" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="MissingConstructor" type="IssueHandlerType" minOccurs="0" />
|
||||
|
@ -232,6 +232,7 @@ Level 5 and above allows a more non-verifiable code, and higher levels are even
|
||||
- [InvalidDocblockParamName](issues/InvalidDocblockParamName.md)
|
||||
- [InvalidFalsableReturnType](issues/InvalidFalsableReturnType.md)
|
||||
- [InvalidStringClass](issues/InvalidStringClass.md)
|
||||
- [MissingClassConstType](issues/MissingClassConstType.md)
|
||||
- [MissingClosureParamType](issues/MissingClosureParamType.md)
|
||||
- [MissingClosureReturnType](issues/MissingClosureReturnType.md)
|
||||
- [MissingConstructor](issues/MissingConstructor.md)
|
||||
|
@ -113,6 +113,7 @@
|
||||
- [MismatchingDocblockParamType](issues/MismatchingDocblockParamType.md)
|
||||
- [MismatchingDocblockPropertyType](issues/MismatchingDocblockPropertyType.md)
|
||||
- [MismatchingDocblockReturnType](issues/MismatchingDocblockReturnType.md)
|
||||
- [MissingClassConstType](issues/MissingClassConstType.md)
|
||||
- [MissingClosureParamType](issues/MissingClosureParamType.md)
|
||||
- [MissingClosureReturnType](issues/MissingClosureReturnType.md)
|
||||
- [MissingConstructor](issues/MissingConstructor.md)
|
||||
|
21
docs/running_psalm/issues/MissingClassConstType.md
Normal file
21
docs/running_psalm/issues/MissingClassConstType.md
Normal file
@ -0,0 +1,21 @@
|
||||
# MissingClassConstType
|
||||
|
||||
Emitted when a class constant doesn't have a declared type.
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
class A {
|
||||
public const B = 0;
|
||||
}
|
||||
```
|
||||
|
||||
Correct with:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
class A {
|
||||
public const int B = 0;
|
||||
}
|
||||
```
|
@ -48,6 +48,7 @@ use Psalm\Issue\InvalidDocblock;
|
||||
use Psalm\Issue\InvalidEnumBackingType;
|
||||
use Psalm\Issue\InvalidEnumCaseValue;
|
||||
use Psalm\Issue\InvalidTypeImport;
|
||||
use Psalm\Issue\MissingClassConstType;
|
||||
use Psalm\Issue\MissingDocblockType;
|
||||
use Psalm\Issue\MissingPropertyType;
|
||||
use Psalm\Issue\ParseError;
|
||||
@ -82,6 +83,7 @@ use function ltrim;
|
||||
use function preg_match;
|
||||
use function preg_replace;
|
||||
use function preg_split;
|
||||
use function sprintf;
|
||||
use function strtolower;
|
||||
use function trim;
|
||||
use function usort;
|
||||
@ -1418,6 +1420,23 @@ final class ClassLikeNodeScanner
|
||||
$description,
|
||||
);
|
||||
|
||||
|
||||
if ($this->codebase->analysis_php_version_id >= 8_03_00
|
||||
&& $stmt->type === null
|
||||
) {
|
||||
IssueBuffer::maybeAdd(
|
||||
new MissingClassConstType(
|
||||
sprintf(
|
||||
'Class constant "%s::%s" should have a declared type.',
|
||||
$storage->name,
|
||||
$const->name->name,
|
||||
),
|
||||
new CodeLocation($this->file_scanner, $const),
|
||||
),
|
||||
$suppressed_issues,
|
||||
);
|
||||
}
|
||||
|
||||
if ($exists) {
|
||||
$existing_constants[$const->name->name] = $constant_storage;
|
||||
}
|
||||
|
11
src/Psalm/Issue/MissingClassConstType.php
Normal file
11
src/Psalm/Issue/MissingClassConstType.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psalm\Issue;
|
||||
|
||||
final class MissingClassConstType extends CodeIssue
|
||||
{
|
||||
public const ERROR_LEVEL = 2;
|
||||
public const SHORTCODE = 359;
|
||||
}
|
@ -133,14 +133,20 @@ class PluginTest extends TestCase
|
||||
|
||||
$file_path = getcwd() . '/src/somefile.php';
|
||||
|
||||
|
||||
$this->addFile(
|
||||
$file_path,
|
||||
'<?php
|
||||
class A {
|
||||
const C = [
|
||||
"foo" => "Psalm\Internal\Analyzer\ProjectAnalyzer",
|
||||
];
|
||||
}',
|
||||
sprintf(
|
||||
<<<'PHP'
|
||||
<?php
|
||||
class A {
|
||||
const %s C = [
|
||||
"foo" => "Psalm\Internal\Analyzer\ProjectAnalyzer",
|
||||
];
|
||||
}
|
||||
PHP,
|
||||
$this->project_analyzer->getCodebase()->analysis_php_version_id >= 8_03_00 ? 'array' : '',
|
||||
),
|
||||
);
|
||||
|
||||
$this->analyzeFile($file_path, new Context());
|
||||
@ -173,14 +179,18 @@ class PluginTest extends TestCase
|
||||
|
||||
$this->addFile(
|
||||
$file_path,
|
||||
'<?php
|
||||
namespace Psalm;
|
||||
|
||||
class A {
|
||||
const C = [
|
||||
"foo" => \Psalm\Internal\Analyzer\ProjectAnalyzer::class . "::foo",
|
||||
];
|
||||
}',
|
||||
sprintf(
|
||||
<<<'PHP'
|
||||
<?php
|
||||
namespace Psalm;
|
||||
class A {
|
||||
const %s C = [
|
||||
"foo" => \Psalm\Internal\Analyzer\ProjectAnalyzer::class . "::foo",
|
||||
];
|
||||
}
|
||||
PHP,
|
||||
$this->project_analyzer->getCodebase()->analysis_php_version_id >= 8_03_00 ? 'array' : '',
|
||||
),
|
||||
);
|
||||
|
||||
$this->analyzeFile($file_path, new Context());
|
||||
|
@ -316,6 +316,7 @@ class DocumentationTest extends TestCase
|
||||
|
||||
case 'InvalidOverride':
|
||||
case 'MissingOverrideAttribute':
|
||||
case 'MissingClassConstType':
|
||||
$php_version = '8.3';
|
||||
break;
|
||||
}
|
||||
|
60
tests/MissingClassConstTypeTest.php
Normal file
60
tests/MissingClassConstTypeTest.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psalm\Tests;
|
||||
|
||||
use Psalm\Issue\MissingClassConstType;
|
||||
use Psalm\Tests\Traits\InvalidCodeAnalysisTestTrait;
|
||||
use Psalm\Tests\Traits\ValidCodeAnalysisTestTrait;
|
||||
|
||||
class MissingClassConstTypeTest extends TestCase
|
||||
{
|
||||
use ValidCodeAnalysisTestTrait;
|
||||
use InvalidCodeAnalysisTestTrait;
|
||||
|
||||
public function providerValidCodeParse(): iterable
|
||||
{
|
||||
return [
|
||||
'has type; >= PHP 8.3' => [
|
||||
'code' => <<<'PHP'
|
||||
<?php
|
||||
class A {
|
||||
public const int B = 0;
|
||||
}
|
||||
PHP,
|
||||
'assertions' => [],
|
||||
'ignored_issues' => [],
|
||||
'php_version' => '8.3',
|
||||
],
|
||||
'no type; < PHP 8.3' => [
|
||||
'code' => <<<'PHP'
|
||||
<?php
|
||||
class A {
|
||||
public const B = 0;
|
||||
}
|
||||
PHP,
|
||||
'assertions' => [],
|
||||
'ignored_issues' => [],
|
||||
'php_version' => '8.2',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function providerInvalidCodeParse(): iterable
|
||||
{
|
||||
return [
|
||||
'no type; >= PHP 8.3' => [
|
||||
'code' => <<<'PHP'
|
||||
<?php
|
||||
class A {
|
||||
public const B = 0;
|
||||
}
|
||||
PHP,
|
||||
'error_message' => MissingClassConstType::getIssueType(),
|
||||
'error_levels' => [],
|
||||
'php_version' => '8.3',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user