mirror of
https://github.com/danog/psalm.git
synced 2024-11-30 04:39:00 +01:00
MissingClassConstType
This commit is contained in:
parent
4ea41cb69a
commit
c7fc76ec57
@ -313,6 +313,7 @@
|
|||||||
<xs:element name="MismatchingDocblockParamType" type="IssueHandlerType" minOccurs="0" />
|
<xs:element name="MismatchingDocblockParamType" type="IssueHandlerType" minOccurs="0" />
|
||||||
<xs:element name="MismatchingDocblockPropertyType" type="IssueHandlerType" minOccurs="0" />
|
<xs:element name="MismatchingDocblockPropertyType" type="IssueHandlerType" minOccurs="0" />
|
||||||
<xs:element name="MismatchingDocblockReturnType" 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="MissingClosureParamType" type="IssueHandlerType" minOccurs="0" />
|
||||||
<xs:element name="MissingClosureReturnType" type="IssueHandlerType" minOccurs="0" />
|
<xs:element name="MissingClosureReturnType" type="IssueHandlerType" minOccurs="0" />
|
||||||
<xs:element name="MissingConstructor" 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)
|
- [InvalidDocblockParamName](issues/InvalidDocblockParamName.md)
|
||||||
- [InvalidFalsableReturnType](issues/InvalidFalsableReturnType.md)
|
- [InvalidFalsableReturnType](issues/InvalidFalsableReturnType.md)
|
||||||
- [InvalidStringClass](issues/InvalidStringClass.md)
|
- [InvalidStringClass](issues/InvalidStringClass.md)
|
||||||
|
- [MissingClassConstType](issues/MissingClassConstType.md)
|
||||||
- [MissingClosureParamType](issues/MissingClosureParamType.md)
|
- [MissingClosureParamType](issues/MissingClosureParamType.md)
|
||||||
- [MissingClosureReturnType](issues/MissingClosureReturnType.md)
|
- [MissingClosureReturnType](issues/MissingClosureReturnType.md)
|
||||||
- [MissingConstructor](issues/MissingConstructor.md)
|
- [MissingConstructor](issues/MissingConstructor.md)
|
||||||
|
@ -113,6 +113,7 @@
|
|||||||
- [MismatchingDocblockParamType](issues/MismatchingDocblockParamType.md)
|
- [MismatchingDocblockParamType](issues/MismatchingDocblockParamType.md)
|
||||||
- [MismatchingDocblockPropertyType](issues/MismatchingDocblockPropertyType.md)
|
- [MismatchingDocblockPropertyType](issues/MismatchingDocblockPropertyType.md)
|
||||||
- [MismatchingDocblockReturnType](issues/MismatchingDocblockReturnType.md)
|
- [MismatchingDocblockReturnType](issues/MismatchingDocblockReturnType.md)
|
||||||
|
- [MissingClassConstType](issues/MissingClassConstType.md)
|
||||||
- [MissingClosureParamType](issues/MissingClosureParamType.md)
|
- [MissingClosureParamType](issues/MissingClosureParamType.md)
|
||||||
- [MissingClosureReturnType](issues/MissingClosureReturnType.md)
|
- [MissingClosureReturnType](issues/MissingClosureReturnType.md)
|
||||||
- [MissingConstructor](issues/MissingConstructor.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\InvalidEnumBackingType;
|
||||||
use Psalm\Issue\InvalidEnumCaseValue;
|
use Psalm\Issue\InvalidEnumCaseValue;
|
||||||
use Psalm\Issue\InvalidTypeImport;
|
use Psalm\Issue\InvalidTypeImport;
|
||||||
|
use Psalm\Issue\MissingClassConstType;
|
||||||
use Psalm\Issue\MissingDocblockType;
|
use Psalm\Issue\MissingDocblockType;
|
||||||
use Psalm\Issue\MissingPropertyType;
|
use Psalm\Issue\MissingPropertyType;
|
||||||
use Psalm\Issue\ParseError;
|
use Psalm\Issue\ParseError;
|
||||||
@ -82,6 +83,7 @@ use function ltrim;
|
|||||||
use function preg_match;
|
use function preg_match;
|
||||||
use function preg_replace;
|
use function preg_replace;
|
||||||
use function preg_split;
|
use function preg_split;
|
||||||
|
use function sprintf;
|
||||||
use function strtolower;
|
use function strtolower;
|
||||||
use function trim;
|
use function trim;
|
||||||
use function usort;
|
use function usort;
|
||||||
@ -1418,6 +1420,23 @@ final class ClassLikeNodeScanner
|
|||||||
$description,
|
$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) {
|
if ($exists) {
|
||||||
$existing_constants[$const->name->name] = $constant_storage;
|
$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';
|
$file_path = getcwd() . '/src/somefile.php';
|
||||||
|
|
||||||
|
|
||||||
$this->addFile(
|
$this->addFile(
|
||||||
$file_path,
|
$file_path,
|
||||||
'<?php
|
sprintf(
|
||||||
class A {
|
<<<'PHP'
|
||||||
const C = [
|
<?php
|
||||||
"foo" => "Psalm\Internal\Analyzer\ProjectAnalyzer",
|
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());
|
$this->analyzeFile($file_path, new Context());
|
||||||
@ -173,14 +179,18 @@ class PluginTest extends TestCase
|
|||||||
|
|
||||||
$this->addFile(
|
$this->addFile(
|
||||||
$file_path,
|
$file_path,
|
||||||
'<?php
|
sprintf(
|
||||||
namespace Psalm;
|
<<<'PHP'
|
||||||
|
<?php
|
||||||
class A {
|
namespace Psalm;
|
||||||
const C = [
|
class A {
|
||||||
"foo" => \Psalm\Internal\Analyzer\ProjectAnalyzer::class . "::foo",
|
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());
|
$this->analyzeFile($file_path, new Context());
|
||||||
|
@ -316,6 +316,7 @@ class DocumentationTest extends TestCase
|
|||||||
|
|
||||||
case 'InvalidOverride':
|
case 'InvalidOverride':
|
||||||
case 'MissingOverrideAttribute':
|
case 'MissingOverrideAttribute':
|
||||||
|
case 'MissingClassConstType':
|
||||||
$php_version = '8.3';
|
$php_version = '8.3';
|
||||||
break;
|
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