Skip to content

Commit d422850

Browse files
authored
add: ReadWritePropertiesExtension (#2)
1 parent 4b25e4e commit d422850

File tree

2 files changed

+87
-0
lines changed

2 files changed

+87
-0
lines changed

phpstan.neon

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,8 @@ services:
8686
class: Symbiote\SilverstripePHPStan\Type\HasMethodTypeSpecifyingExtension
8787
tags:
8888
- phpstan.typeSpecifier.methodTypeSpecifyingExtension
89+
# Special handling for configuration properties
90+
-
91+
class: Symbiote\SilverstripePHPStan\Reflection\ReadWritePropertiesExtension
92+
tags:
93+
- phpstan.properties.readWriteExtension
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<?php
2+
3+
namespace Symbiote\SilverstripePHPStan\Reflection;
4+
5+
use PHPStan\Reflection\PropertyReflection;
6+
use SilverStripe\Core\Config\Configurable;
7+
8+
/**
9+
* Adds information about configuration properties, which are always read,
10+
* written and initialized. We check for the presence of the '@config'
11+
* docblock as described in the official silverstripe docs
12+
* (https://docs.silverstripe.org/en/4/developer_guides/configuration/configuration/#configuration-properties)
13+
* and wether or not the class defining the property uses the 'Configurable' trait.
14+
*/
15+
class ReadWritePropertiesExtension implements \PHPStan\Rules\Properties\ReadWritePropertiesExtension
16+
{
17+
18+
/**
19+
* isAlwaysRead - see https://phpstan.org/developing-extensions/always-read-written-properties
20+
*
21+
* @param PropertyReflection $property the reflection from the static analysis
22+
* @param string $propertyName the name of the property
23+
* @return bool
24+
*/
25+
public function isAlwaysRead(PropertyReflection $property, string $propertyName): bool
26+
{
27+
return
28+
$this->containsConfigBlock($property) &&
29+
$this->classUsesConfigTrait($property);
30+
}
31+
32+
/**
33+
* isAlwaysWritten - see https://phpstan.org/developing-extensions/always-read-written-properties
34+
*
35+
* @param PropertyReflection $property the reflection from the static analysis
36+
* @param string $propertyName the name of the property
37+
* @return bool
38+
*/
39+
public function isAlwaysWritten(PropertyReflection $property, string $propertyName): bool
40+
{
41+
return
42+
$this->containsConfigBlock($property) &&
43+
$this->classUsesConfigTrait($property);
44+
}
45+
46+
/**
47+
* isInitialized - see https://phpstan.org/developing-extensions/always-read-written-properties
48+
*
49+
* @param PropertyReflection $property the reflection from the static analysis
50+
* @param string $propertyName the name of the property
51+
* @return bool
52+
*/
53+
public function isInitialized(PropertyReflection $property, string $propertyName): bool
54+
{
55+
return
56+
$this->containsConfigBlock($property) &&
57+
$this->classUsesConfigTrait($property);
58+
}
59+
60+
/**
61+
* containsConfigBlock - check if the @config docblock is present
62+
*
63+
* @param PropertyReflection $property the property to check
64+
* @return bool
65+
*/
66+
public function containsConfigBlock(PropertyReflection $property): bool
67+
{
68+
return !!strpos($property->getDocComment(), '@config');
69+
}
70+
71+
/**
72+
* classUsesConfigTrait - check if the class defining the property is using
73+
* the configurable trait
74+
*
75+
* @param PropertyReflection $property the property to check
76+
* @return bool
77+
*/
78+
public function classUsesConfigTrait(PropertyReflection $property): bool
79+
{
80+
return $property->getDeclaringClass()->hasTraitUse(Configurable::class);
81+
}
82+
}

0 commit comments

Comments
 (0)