1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-22 22:01:48 +01:00

Merge pull request #9280 from weirdan/forbid-overriding-built-in-enum-methods

This commit is contained in:
Bruce Weirdan 2023-02-13 00:48:46 -04:00 committed by GitHub
commit 67b1e3fcea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 75 additions and 2 deletions

View File

@ -2000,7 +2000,7 @@ abstract class FunctionLikeAnalyzer extends SourceAnalyzer
MethodAnalyzer::checkMethodSignatureMustOmitReturnType($storage, $codeLocation);
if ($appearing_class_storage->is_enum) {
MethodAnalyzer::checkForbiddenEnumMethod($storage);
MethodAnalyzer::checkForbiddenEnumMethod($storage, $appearing_class_storage);
}
if (!$context->calling_method_id || !$context->collect_initializations) {

View File

@ -16,6 +16,7 @@ use Psalm\Issue\NonStaticSelfCall;
use Psalm\Issue\UndefinedMethod;
use Psalm\IssueBuffer;
use Psalm\StatementsSource;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Storage\MethodStorage;
use UnexpectedValueException;
@ -310,7 +311,7 @@ class MethodAnalyzer extends FunctionLikeAnalyzer
);
}
public static function checkForbiddenEnumMethod(MethodStorage $method_storage): void
public static function checkForbiddenEnumMethod(MethodStorage $method_storage, ClassLikeStorage $enum_storage): void
{
if ($method_storage->cased_name === null || $method_storage->location === null) {
return;
@ -324,5 +325,21 @@ class MethodAnalyzer extends FunctionLikeAnalyzer
$method_storage->defining_fqcln . '::' . $method_storage->cased_name,
));
}
if ($method_name_lc === 'cases') {
IssueBuffer::maybeAdd(new InvalidEnumMethod(
'Enums cannot define ' . $method_storage->cased_name,
$method_storage->location,
$method_storage->defining_fqcln . '::' . $method_storage->cased_name,
));
}
if ($enum_storage->enum_type && ($method_name_lc === 'from' || $method_name_lc === 'tryfrom')) {
IssueBuffer::maybeAdd(new InvalidEnumMethod(
'Enums cannot define ' . $method_storage->cased_name,
$method_storage->location,
$method_storage->defining_fqcln . '::' . $method_storage->cased_name,
));
}
}
}

View File

@ -805,6 +805,62 @@ class EnumTest extends TestCase
'ignored_issues' => [],
'php_version' => '8.1',
],
'forbiddenUnitEnumCasesMethod' => [
'code' => '<?php
enum Foo {
case A;
public static function cases(): array
{
return [];
}
}
',
'error_message' => 'InvalidEnumMethod',
'ignored_issues' => [],
'php_version' => '8.1',
],
'forbiddenBackedEnumCasesMethod' => [
'code' => '<?php
enum Status: string {
case Open = "open";
public static function cases(): array
{
return [];
}
}
',
'error_message' => 'InvalidEnumMethod',
'ignored_issues' => [],
'php_version' => '8.1',
],
'forbiddenBackedEnumFromMethod' => [
'code' => '<?php
enum Status: string {
case Open = "open";
public static function from(string $value): self
{
throw new Exception;
}
}
',
'error_message' => 'InvalidEnumMethod',
'ignored_issues' => [],
'php_version' => '8.1',
],
'forbiddenBackedEnumTryFromMethod' => [
'code' => '<?php
enum Status: string {
case Open = "open";
public static function tryFrom(string $value): ?self
{
return null;
}
}
',
'error_message' => 'InvalidEnumMethod',
'ignored_issues' => [],
'php_version' => '8.1',
],
];
}
}