mirror of
https://github.com/danog/psalm.git
synced 2024-12-02 09:37:59 +01:00
Merge pull request #10344 from robchett/seal_method_seal_properties_without_prefix
Support @(no-)seal-(properties|methods) annotations without prefix
This commit is contained in:
commit
d041b652cd
@ -202,7 +202,7 @@ takesFoo(getFoo());
|
||||
|
||||
This provides the same, but for `false`. Psalm uses this internally for functions like `preg_replace`, which can return false if the given input has encoding errors, but where 99.9% of the time the function operates as expected.
|
||||
|
||||
### `@psalm-seal-properties`, `@psalm-no-seal-properties`
|
||||
### `@psalm-seal-properties`, `@psalm-no-seal-properties`, `@seal-properties`, `@no-seal-properties`
|
||||
|
||||
If you have a magic property getter/setter, you can use `@psalm-seal-properties` to instruct Psalm to disallow getting and setting any properties not contained in a list of `@property` (or `@property-read`/`@property-write`) annotations.
|
||||
This is automatically enabled with the configuration option `sealAllProperties` and can be disabled for a class with `@psalm-no-seal-properties`
|
||||
@ -211,7 +211,7 @@ This is automatically enabled with the configuration option `sealAllProperties`
|
||||
<?php
|
||||
/**
|
||||
* @property string $foo
|
||||
* @psalm-seal-properties
|
||||
* @seal-properties
|
||||
*/
|
||||
class A {
|
||||
public function __get(string $name): ?string {
|
||||
@ -227,7 +227,7 @@ $a = new A();
|
||||
$a->bar = 5; // this call fails
|
||||
```
|
||||
|
||||
### `@psalm-seal-methods`, `@psalm-no-seal-methods`
|
||||
### `@psalm-seal-methods`, `@psalm-no-seal-methods`, `@seal-methods`, `@no-seal-methods`
|
||||
|
||||
If you have a magic method caller, you can use `@psalm-seal-methods` to instruct Psalm to disallow calling any methods not contained in a list of `@method` annotations.
|
||||
This is automatically enabled with the configuration option `sealAllMethods` and can be disabled for a class with `@psalm-no-seal-methods`
|
||||
@ -236,7 +236,7 @@ This is automatically enabled with the configuration option `sealAllMethods` and
|
||||
<?php
|
||||
/**
|
||||
* @method foo(): string
|
||||
* @psalm-seal-methods
|
||||
* @seal-methods
|
||||
*/
|
||||
class A {
|
||||
public function __call(string $name, array $args) {
|
||||
|
@ -236,18 +236,20 @@ final class ClassLikeDocblockParser
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($parsed_docblock->tags['psalm-seal-properties'])) {
|
||||
$info->sealed_properties = true;
|
||||
}
|
||||
if (isset($parsed_docblock->tags['psalm-no-seal-properties'])) {
|
||||
$info->sealed_properties = false;
|
||||
}
|
||||
foreach (['', 'psalm-'] as $prefix) {
|
||||
if (isset($parsed_docblock->tags[$prefix . 'seal-properties'])) {
|
||||
$info->sealed_properties = true;
|
||||
}
|
||||
if (isset($parsed_docblock->tags[$prefix . 'no-seal-properties'])) {
|
||||
$info->sealed_properties = false;
|
||||
}
|
||||
|
||||
if (isset($parsed_docblock->tags['psalm-seal-methods'])) {
|
||||
$info->sealed_methods = true;
|
||||
}
|
||||
if (isset($parsed_docblock->tags['psalm-no-seal-methods'])) {
|
||||
$info->sealed_methods = false;
|
||||
if (isset($parsed_docblock->tags[$prefix . 'seal-methods'])) {
|
||||
$info->sealed_methods = true;
|
||||
}
|
||||
if (isset($parsed_docblock->tags[$prefix . 'no-seal-methods'])) {
|
||||
$info->sealed_methods = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($parsed_docblock->tags['psalm-inheritors'])) {
|
||||
|
@ -1118,6 +1118,21 @@ class MagicMethodAnnotationTest extends TestCase
|
||||
$b->foo();',
|
||||
'error_message' => 'UndefinedMagicMethod',
|
||||
],
|
||||
'inheritSealedMethodsWithoutPrefix' => [
|
||||
'code' => '<?php
|
||||
/**
|
||||
* @seal-methods
|
||||
*/
|
||||
class A {
|
||||
public function __call(string $method, array $args) {}
|
||||
}
|
||||
|
||||
class B extends A {}
|
||||
|
||||
$b = new B();
|
||||
$b->foo();',
|
||||
'error_message' => 'UndefinedMagicMethod',
|
||||
],
|
||||
'lonelyMethod' => [
|
||||
'code' => '<?php
|
||||
/**
|
||||
|
@ -1189,6 +1189,38 @@ class MagicPropertyTest extends TestCase
|
||||
}',
|
||||
'error_message' => 'InvalidDocblock',
|
||||
],
|
||||
'sealedWithNoProperties' => [
|
||||
'code' => '<?php
|
||||
/**
|
||||
* @psalm-seal-properties
|
||||
*/
|
||||
final class OrganizationObject {
|
||||
|
||||
public function __get(string $key)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
||||
echo (new OrganizationObject)->errors;',
|
||||
'error_message' => 'UndefinedMagicPropertyFetch',
|
||||
],
|
||||
'sealedWithNoPropertiesNoPrefix' => [
|
||||
'code' => '<?php
|
||||
/**
|
||||
* @seal-properties
|
||||
*/
|
||||
final class OrganizationObject {
|
||||
|
||||
public function __get(string $key)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
echo (new OrganizationObject)->errors;',
|
||||
'error_message' => 'UndefinedMagicPropertyFetch',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user