diff --git a/config/set/naming.php b/config/set/naming.php
index 5e2bf666b5f..e35ad5ac7e0 100644
--- a/config/set/naming.php
+++ b/config/set/naming.php
@@ -9,6 +9,7 @@ use Rector\Naming\Rector\ClassMethod\MakeIsserClassMethodNameStartWithIsRector;
use Rector\Naming\Rector\ClassMethod\RenameParamToMatchTypeRector;
use Rector\Naming\Rector\ClassMethod\RenameVariableToMatchNewTypeRector;
use Rector\Naming\Rector\Foreach_\RenameForeachValueVariableToMatchMethodCallReturnTypeRector;
+use Rector\Naming\Rector\Property\MakeBoolPropertyRespectIsHasWasMethodNamingRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
@@ -20,4 +21,5 @@ return static function (ContainerConfigurator $containerConfigurator): void {
$services->set(MakeGetterClassMethodNameStartWithGetRector::class);
$services->set(MakeIsserClassMethodNameStartWithIsRector::class);
$services->set(RenameForeachValueVariableToMatchMethodCallReturnTypeRector::class);
+ $services->set(MakeBoolPropertyRespectIsHasWasMethodNamingRector::class);
};
diff --git a/docs/nodes_overview.md b/docs/nodes_overview.md
index 556049970cf..c7c984629fb 100644
--- a/docs/nodes_overview.md
+++ b/docs/nodes_overview.md
@@ -2131,9 +2131,9 @@ declare(strict_types=1);
use PhpParser\Node\Expr\Eval_;
use PhpParser\Node\Scalar\String_;
-$phpCode = new String_('Some php code');
+$string = new String_('Some php code');
-return new Eval_($phpCode);
+return new Eval_(new String_('Some php code'));
```
↓
@@ -2152,9 +2152,9 @@ declare(strict_types=1);
use PhpParser\Node\Expr\Eval_;
use PhpParser\Node\Scalar\String_;
-$string = new String_('Some php code');
+$phpCode = new String_('Some php code');
-return new Eval_(new String_('Some php code'));
+return new Eval_($phpCode);
```
↓
@@ -2418,6 +2418,27 @@ match ($variableName) {
declare(strict_types=1);
+use PhpParser\Node\Expr\MethodCall;
+use PhpParser\Node\Expr\Variable;
+
+$variable = new Variable('someObject');
+
+return new MethodCall($variable, 'methodName');
+```
+
+↓
+
+```php
+$someObject->methodName()
+```
+
+
+
+```php
+methodName('yes', 'maybe')
-```php
-methodName()
-```
-
-
-
### Public Properties
@@ -3599,6 +3599,30 @@ public const SOME_CLASS_CONSTANT = 'default value';
declare(strict_types=1);
+use PhpParser\Node\Stmt\Class_;
+use PhpParser\Node\Stmt\ClassMethod;
+
+$classMethod = new ClassMethod('methodName');
+$classMethod->flags = Class_::MODIFIER_PUBLIC;
+
+return $classMethod;
+```
+
+↓
+
+```php
+public function methodName()
+{
+}
+```
+
+
+
+```php
+
-```php
-flags = Class_::MODIFIER_PUBLIC;
-
-return $classMethod;
-```
-
-↓
-
-```php
-public function methodName()
-{
-}
-```
-
-
-
### Public Properties
diff --git a/docs/rector_rules_overview.md b/docs/rector_rules_overview.md
index eede9dcc500..5f944e1c463 100644
--- a/docs/rector_rules_overview.md
+++ b/docs/rector_rules_overview.md
@@ -1,4 +1,4 @@
-# All 580 Rectors Overview
+# All 581 Rectors Overview
- [Projects](#projects)
---
@@ -29,7 +29,7 @@
- [MockeryToProphecy](#mockerytoprophecy) (2)
- [MockistaToMockery](#mockistatomockery) (2)
- [MysqlToMysqli](#mysqltomysqli) (4)
-- [Naming](#naming) (7)
+- [Naming](#naming) (8)
- [Nette](#nette) (16)
- [NetteCodeQuality](#nettecodequality) (6)
- [NetteKdyby](#nettekdyby) (4)
@@ -7282,6 +7282,30 @@ Add mysql_query and mysql_error with connection
## Naming
+### `MakeBoolPropertyRespectIsHasWasMethodNamingRector`
+
+- class: [`Rector\Naming\Rector\Property\MakeBoolPropertyRespectIsHasWasMethodNamingRector`](/rules/naming/src/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector.php)
+- [test fixtures](/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture)
+
+Renames property to respect is/has/was method naming
+
+```diff
+ class SomeClass
+ {
+- private $full = false;
++ private $isFull = false;
+
+ public function isFull()
+ {
+- return $this->full;
++ return $this->isFull;
+ }
++
+ }
+```
+
+
+
### `MakeGetterClassMethodNameStartWithGetRector`
- class: [`Rector\Naming\Rector\ClassMethod\MakeGetterClassMethodNameStartWithGetRector`](/rules/naming/src/Rector/ClassMethod/MakeGetterClassMethodNameStartWithGetRector.php)
diff --git a/packages/node-type-resolver/src/NodeTypeResolver.php b/packages/node-type-resolver/src/NodeTypeResolver.php
index 8387d5a8b10..09a78a2b48e 100644
--- a/packages/node-type-resolver/src/NodeTypeResolver.php
+++ b/packages/node-type-resolver/src/NodeTypeResolver.php
@@ -13,9 +13,11 @@ use PhpParser\Node\Expr\New_;
use PhpParser\Node\Param;
use PhpParser\Node\Scalar;
use PhpParser\Node\Stmt\Class_;
+use PhpParser\Node\Stmt\Property;
use PHPStan\Analyser\Scope;
use PHPStan\Type\Accessory\NonEmptyArrayType;
use PHPStan\Type\ArrayType;
+use PHPStan\Type\BooleanType;
use PHPStan\Type\FloatType;
use PHPStan\Type\IntegerType;
use PHPStan\Type\IntersectionType;
@@ -256,6 +258,25 @@ final class NodeTypeResolver
return false;
}
+ public function isBooleanType(Node $node): bool
+ {
+ return $this->isStaticType($node, BooleanType::class);
+ }
+
+ public function isPropertyBoolean(Property $property): bool
+ {
+ if ($this->isBooleanType($property)) {
+ return true;
+ }
+
+ $defaultNodeValue = $property->props[0]->default;
+ if ($defaultNodeValue === null) {
+ return false;
+ }
+
+ return $this->isBooleanType($defaultNodeValue);
+ }
+
private function addNodeTypeResolver(NodeTypeResolverInterface $nodeTypeResolver): void
{
foreach ($nodeTypeResolver->getNodeClasses() as $nodeClass) {
diff --git a/rules/naming/src/Guard/BreakingVariableRenameGuard.php b/rules/naming/src/Guard/BreakingVariableRenameGuard.php
index 0ef1d2cc183..8beb7b1ba45 100644
--- a/rules/naming/src/Guard/BreakingVariableRenameGuard.php
+++ b/rules/naming/src/Guard/BreakingVariableRenameGuard.php
@@ -122,6 +122,10 @@ final class BreakingVariableRenameGuard
public function shouldSkipProperty(PropertyRename $propertyRename): bool
{
+ if (! $propertyRename->getProperty()->isPrivate()) {
+ return true;
+ }
+
$conflictingPropertyNames = $this->conflictingNameResolver->resolveConflictingPropertyNames(
$propertyRename->getClassLike()
);
diff --git a/rules/naming/src/Naming/ExpectedNameResolver.php b/rules/naming/src/Naming/ExpectedNameResolver.php
index 6184c09c903..8b645c15653 100644
--- a/rules/naming/src/Naming/ExpectedNameResolver.php
+++ b/rules/naming/src/Naming/ExpectedNameResolver.php
@@ -125,6 +125,10 @@ final class ExpectedNameResolver
return null;
}
+ if ($this->nodeTypeResolver->isPropertyBoolean($property)) {
+ return $this->propertyNaming->getExpectedNameFromBooleanPropertyType($property);
+ }
+
$expectedName = $this->propertyNaming->getExpectedNameFromType($phpDocInfo->getVarType());
if ($expectedName === null) {
return null;
diff --git a/rules/naming/src/Naming/PropertyNaming.php b/rules/naming/src/Naming/PropertyNaming.php
index ccce55f02b9..72ec35e00f4 100644
--- a/rules/naming/src/Naming/PropertyNaming.php
+++ b/rules/naming/src/Naming/PropertyNaming.php
@@ -5,14 +5,20 @@ declare(strict_types=1);
namespace Rector\Naming\Naming;
use Nette\Utils\Strings;
+use PhpParser\Node\Stmt\ClassMethod;
+use PhpParser\Node\Stmt\Property;
+use PhpParser\Node\Stmt\Return_;
use PHPStan\Type\ObjectType;
use PHPStan\Type\StaticType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeWithClassName;
use PHPStan\Type\UnionType;
+use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\Naming\RectorNamingInflector;
use Rector\Naming\ValueObject\ExpectedName;
use Rector\NetteKdyby\Naming\VariableNaming;
+use Rector\NodeNameResolver\NodeNameResolver;
+use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\PHPStan\Type\SelfObjectType;
use Rector\PHPStan\Type\ShortenedObjectType;
use Rector\PHPStanStaticTypeMapper\Utils\TypeUnwrapper;
@@ -35,6 +41,12 @@ final class PropertyNaming
*/
private const INTERFACE = 'Interface';
+ /**
+ * @see https://regex101.com/r/RDhBNR/1
+ * @var string
+ */
+ private const PREFIXED_CLASS_METHODS_REGEX = '#^(is|are|was|were|has|have|had|can)[A-Z].+#';
+
/**
* @var TypeUnwrapper
*/
@@ -45,10 +57,26 @@ final class PropertyNaming
*/
private $rectorNamingInflector;
- public function __construct(TypeUnwrapper $typeUnwrapper, RectorNamingInflector $rectorNamingInflector)
- {
+ /**
+ * @var BetterNodeFinder
+ */
+ private $betterNodeFinder;
+
+ /**
+ * @var NodeNameResolver
+ */
+ private $nodeNameResolver;
+
+ public function __construct(
+ TypeUnwrapper $typeUnwrapper,
+ RectorNamingInflector $rectorNamingInflector,
+ BetterNodeFinder $betterNodeFinder,
+ NodeNameResolver $nodeNameResolver
+ ) {
$this->typeUnwrapper = $typeUnwrapper;
$this->rectorNamingInflector = $rectorNamingInflector;
+ $this->betterNodeFinder = $betterNodeFinder;
+ $this->nodeNameResolver = $nodeNameResolver;
}
public function getExpectedNameFromMethodName(string $methodName): ?ExpectedName
@@ -131,6 +159,23 @@ final class PropertyNaming
return lcfirst($pascalCaseName);
}
+ public function getExpectedNameFromBooleanPropertyType(Property $property): ?string
+ {
+ $prefixedClassMethods = $this->getPrefixedClassMethods($property);
+ if ($prefixedClassMethods === []) {
+ return null;
+ }
+
+ $classMethods = $this->filterClassMethodsWithPropertyFetchReturnOnly($prefixedClassMethods, $property);
+
+ if (count($classMethods) !== 1) {
+ return null;
+ }
+
+ $classMethod = reset($classMethods);
+ return $this->nodeNameResolver->getName($classMethod);
+ }
+
private function getClassName(TypeWithClassName $typeWithClassName): string
{
if ($typeWithClassName instanceof ShortenedObjectType) {
@@ -243,6 +288,65 @@ final class PropertyNaming
return $shortName;
}
+ /**
+ * @return ClassMethod[]
+ */
+ private function getPrefixedClassMethods(Property $property): array
+ {
+ $name = $this->nodeNameResolver->getName($property);
+ if ($name === null) {
+ return [];
+ }
+
+ $classLike = $property->getAttribute(AttributeKey::CLASS_NODE);
+ if ($classLike === null) {
+ return [];
+ }
+
+ $classMethods = $this->betterNodeFinder->findInstanceOf($classLike, ClassMethod::class);
+ return array_filter($classMethods, function (ClassMethod $classMethod): bool {
+ $classMethodName = $this->nodeNameResolver->getName($classMethod);
+ return Strings::match($classMethodName, self::PREFIXED_CLASS_METHODS_REGEX) !== null;
+ });
+ }
+
+ /**
+ * @param ClassMethod[] $prefixedClassMethods
+ * @return ClassMethod[]
+ */
+ private function filterClassMethodsWithPropertyFetchReturnOnly(
+ array $prefixedClassMethods,
+ Property $property
+ ): array {
+ $currentName = $this->nodeNameResolver->getName($property);
+ if ($currentName === null) {
+ return [];
+ }
+
+ return array_filter($prefixedClassMethods, function (ClassMethod $classMethod) use ($currentName): bool {
+ $stmts = $classMethod->stmts;
+ if ($stmts === null) {
+ return false;
+ }
+
+ if (! array_key_exists(0, $stmts)) {
+ return false;
+ }
+
+ $return = $stmts[0];
+ if (! $return instanceof Return_) {
+ return false;
+ }
+
+ $node = $return->expr;
+ if ($node === null) {
+ return false;
+ }
+
+ return $this->nodeNameResolver->isName($node, $currentName);
+ });
+ }
+
private function isPrefixedInterface(string $shortClassName): bool
{
if (strlen($shortClassName) <= 3) {
diff --git a/rules/naming/src/PropertyRenamer.php b/rules/naming/src/PropertyRenamer.php
index d0f8e830be1..f86b4574694 100644
--- a/rules/naming/src/PropertyRenamer.php
+++ b/rules/naming/src/PropertyRenamer.php
@@ -47,6 +47,10 @@ final class PropertyRenamer
return null;
}
+ if ($this->areNamesDifferent($propertyRename)) {
+ return null;
+ }
+
$onlyPropertyProperty = $propertyRename->getPropertyProperty();
$onlyPropertyProperty->name = new VarLikeIdentifier($propertyRename->getExpectedName());
$this->renamePropertyFetchesInClass($propertyRename);
@@ -54,6 +58,11 @@ final class PropertyRenamer
return $propertyRename->getProperty();
}
+ private function areNamesDifferent(PropertyRename $propertyRename): bool
+ {
+ return $propertyRename->getCurrentName() === $propertyRename->getExpectedName();
+ }
+
private function renamePropertyFetchesInClass(PropertyRename $propertyRename): void
{
// 1. replace property fetch rename in whole class
diff --git a/rules/naming/src/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector.php b/rules/naming/src/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector.php
new file mode 100644
index 00000000000..1c99ed104eb
--- /dev/null
+++ b/rules/naming/src/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector.php
@@ -0,0 +1,99 @@
+propertyRenamer = $propertyRenamer;
+ $this->propertyRenameFactory = $propertyRenameFactory;
+ }
+
+ public function getDefinition(): RectorDefinition
+ {
+ return new RectorDefinition('Renames property to respect is/has/was method naming', [
+ new CodeSample(
+ <<<'CODE_SAMPLE'
+class SomeClass
+{
+ private $full = false;
+
+ public function isFull()
+ {
+ return $this->full;
+ }
+}
+CODE_SAMPLE
+
+ ,
+ <<<'CODE_SAMPLE'
+class SomeClass
+{
+ private $isFull = false;
+
+ public function isFull()
+ {
+ return $this->isFull;
+ }
+
+}
+CODE_SAMPLE
+
+ ),
+ ]);
+ }
+
+ /**
+ * @return string[]
+ */
+ public function getNodeTypes(): array
+ {
+ return [Property::class];
+ }
+
+ /**
+ * @param Property $node
+ */
+ public function refactor(Node $node): ?Node
+ {
+ if (! $this->isPropertyBoolean($node)) {
+ return null;
+ }
+
+ $propertyRename = $this->propertyRenameFactory->create($node);
+ if ($propertyRename === null) {
+ return null;
+ }
+
+ if ($this->propertyRenamer->rename($propertyRename) === null) {
+ return null;
+ }
+
+ return $node;
+ }
+}
diff --git a/rules/naming/tests/Naming/PropertyNamingTest.php b/rules/naming/tests/Naming/PropertyNamingTest.php
index b5da2c03413..08aacf8fd58 100644
--- a/rules/naming/tests/Naming/PropertyNamingTest.php
+++ b/rules/naming/tests/Naming/PropertyNamingTest.php
@@ -4,26 +4,33 @@ declare(strict_types=1);
namespace Rector\Naming\Tests\Naming;
-use Doctrine\Inflector\InflectorFactory;
use Iterator;
+use Rector\Core\HttpKernel\RectorKernel;
use Rector\Naming\Naming\PropertyNaming;
-use Rector\Naming\RectorNamingInflector;
use Rector\Naming\ValueObject\ExpectedName;
-use Rector\PHPStanStaticTypeMapper\Utils\TypeUnwrapper;
use Symplify\PackageBuilder\Tests\AbstractKernelTestCase;
final class PropertyNamingTest extends AbstractKernelTestCase
{
+ /**
+ * @var PropertyNaming
+ */
+ private $propertyNaming;
+
+ protected function setUp(): void
+ {
+ $this->bootKernel(RectorKernel::class);
+
+ $this->propertyNaming = self::$container->get(PropertyNaming::class);
+ }
+
/**
* @dataProvider getExpectedNameFromMethodNameDataProvider
*/
public function testGetExpectedNameFromMethodName(string $methodName, ?string $expectedPropertyName): void
{
- $propertyNaming = new PropertyNaming(new TypeUnwrapper(), new RectorNamingInflector(
- InflectorFactory::create()->build()
- ));
/** @var ExpectedName $actualPropertyName */
- $actualPropertyName = $propertyNaming->getExpectedNameFromMethodName($methodName);
+ $actualPropertyName = $this->propertyNaming->getExpectedNameFromMethodName($methodName);
if ($expectedPropertyName === null) {
$this->assertNull($actualPropertyName);
diff --git a/rules/naming/tests/Rector/Class_/RenamePropertyToMatchTypeRector/Fixture/git_wrapper.php.inc b/rules/naming/tests/Rector/Class_/RenamePropertyToMatchTypeRector/Fixture/git_wrapper.php.inc
index 7bc30b34daf..45acb398cd1 100644
--- a/rules/naming/tests/Rector/Class_/RenamePropertyToMatchTypeRector/Fixture/git_wrapper.php.inc
+++ b/rules/naming/tests/Rector/Class_/RenamePropertyToMatchTypeRector/Fixture/git_wrapper.php.inc
@@ -9,7 +9,7 @@ class GitWrapperChange
/**
* @var \Rector\Naming\Tests\Rector\Class_\RenamePropertyToMatchTypeRector\Source\GitWrapper
*/
- protected $wrapper;
+ private $wrapper;
public function __construct(GitWrapper $wrapper)
{
@@ -30,7 +30,7 @@ class GitWrapperChange
/**
* @var \Rector\Naming\Tests\Rector\Class_\RenamePropertyToMatchTypeRector\Source\GitWrapper
*/
- protected $gitWrapper;
+ private $gitWrapper;
public function __construct(GitWrapper $wrapper)
{
diff --git a/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/fixture.php.inc b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/fixture.php.inc
new file mode 100644
index 00000000000..ddf07f9b54f
--- /dev/null
+++ b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/fixture.php.inc
@@ -0,0 +1,37 @@
+full;
+ }
+}
+
+?>
+-----
+isFull;
+ }
+}
+
+?>
diff --git a/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/fixture_has.php.inc b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/fixture_has.php.inc
new file mode 100644
index 00000000000..3306cffeeb4
--- /dev/null
+++ b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/fixture_has.php.inc
@@ -0,0 +1,37 @@
+full;
+ }
+}
+
+?>
+-----
+hasFull;
+ }
+}
+
+?>
diff --git a/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/fixture_was.php.inc b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/fixture_was.php.inc
new file mode 100644
index 00000000000..f3c02fa216c
--- /dev/null
+++ b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/fixture_was.php.inc
@@ -0,0 +1,37 @@
+full;
+ }
+}
+
+?>
+-----
+wasFull;
+ }
+}
+
+?>
diff --git a/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/method_name_after_prefix_not_matches_property_name.php.inc b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/method_name_after_prefix_not_matches_property_name.php.inc
new file mode 100644
index 00000000000..481af2f65cd
--- /dev/null
+++ b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/method_name_after_prefix_not_matches_property_name.php.inc
@@ -0,0 +1,39 @@
+full;
+ }
+
+}
+
+?>
+-----
+isSomething;
+ }
+
+}
+
+?>
diff --git a/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/no_default_value.php.inc b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/no_default_value.php.inc
new file mode 100644
index 00000000000..ded71fb95e5
--- /dev/null
+++ b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/no_default_value.php.inc
@@ -0,0 +1,37 @@
+full;
+ }
+}
+
+?>
+-----
+isFull;
+ }
+}
+
+?>
diff --git a/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/no_docblock.php.inc b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/no_docblock.php.inc
new file mode 100644
index 00000000000..dcd99e8164c
--- /dev/null
+++ b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/no_docblock.php.inc
@@ -0,0 +1,31 @@
+full;
+ }
+}
+
+?>
+-----
+isFull;
+ }
+}
+
+?>
diff --git a/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/skip_already_prefixed.php.inc b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/skip_already_prefixed.php.inc
new file mode 100644
index 00000000000..b40c4732bc1
--- /dev/null
+++ b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/skip_already_prefixed.php.inc
@@ -0,0 +1,18 @@
+isFull;
+ }
+}
+
+?>
diff --git a/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/skip_conflict.php.inc b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/skip_conflict.php.inc
new file mode 100644
index 00000000000..844ee35a690
--- /dev/null
+++ b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/skip_conflict.php.inc
@@ -0,0 +1,23 @@
+full;
+ }
+}
+
+?>
diff --git a/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/skip_methods_with_more_than_just_return.php.inc b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/skip_methods_with_more_than_just_return.php.inc
new file mode 100644
index 00000000000..44fb6b21faa
--- /dev/null
+++ b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/skip_methods_with_more_than_just_return.php.inc
@@ -0,0 +1,28 @@
+property === true) {
+ return true;
+ }
+
+ return $this->full;
+ }
+}
+
+?>
diff --git a/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/skip_multiple_prefixed_methods.php.inc b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/skip_multiple_prefixed_methods.php.inc
new file mode 100644
index 00000000000..e4bde745bc4
--- /dev/null
+++ b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/skip_multiple_prefixed_methods.php.inc
@@ -0,0 +1,23 @@
+full;
+ }
+
+ public function wasFull()
+ {
+ return $this->full;
+ }
+}
+
+?>
diff --git a/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/skip_no_docblock_and_default_value.php.inc b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/skip_no_docblock_and_default_value.php.inc
new file mode 100644
index 00000000000..2a14b46c9f3
--- /dev/null
+++ b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/skip_no_docblock_and_default_value.php.inc
@@ -0,0 +1,15 @@
+full;
+ }
+}
+
+?>
diff --git a/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/skip_non_boolean_property.php.inc b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/skip_non_boolean_property.php.inc
new file mode 100644
index 00000000000..3987d99d455
--- /dev/null
+++ b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/skip_non_boolean_property.php.inc
@@ -0,0 +1,18 @@
+full;
+ }
+}
+
+?>
diff --git a/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/skip_property_unused_in_prefixed_method.php.inc b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/skip_property_unused_in_prefixed_method.php.inc
new file mode 100644
index 00000000000..3ef981343c9
--- /dev/null
+++ b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/skip_property_unused_in_prefixed_method.php.inc
@@ -0,0 +1,23 @@
+full;
+ }
+}
+
+?>
diff --git a/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/skip_protected_property.php.inc b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/skip_protected_property.php.inc
new file mode 100644
index 00000000000..7161aca834d
--- /dev/null
+++ b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/skip_protected_property.php.inc
@@ -0,0 +1,18 @@
+full;
+ }
+}
+
+?>
diff --git a/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/skip_public_property.php.inc b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/skip_public_property.php.inc
new file mode 100644
index 00000000000..952169d85c8
--- /dev/null
+++ b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/skip_public_property.php.inc
@@ -0,0 +1,18 @@
+full;
+ }
+}
+
+?>
diff --git a/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/skip_unknown_prefix.php.inc b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/skip_unknown_prefix.php.inc
new file mode 100644
index 00000000000..04ded5eaf1a
--- /dev/null
+++ b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Fixture/skip_unknown_prefix.php.inc
@@ -0,0 +1,18 @@
+full;
+ }
+}
+
+?>
diff --git a/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/FixturePhp74/fixture.php.inc b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/FixturePhp74/fixture.php.inc
new file mode 100644
index 00000000000..6488f350b1c
--- /dev/null
+++ b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/FixturePhp74/fixture.php.inc
@@ -0,0 +1,31 @@
+full;
+ }
+}
+
+?>
+-----
+isFull;
+ }
+}
+
+?>
diff --git a/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/MakeBoolPropertyRespectIsHasWasMethodNamingRectorTest.php b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/MakeBoolPropertyRespectIsHasWasMethodNamingRectorTest.php
new file mode 100644
index 00000000000..d0062463fbf
--- /dev/null
+++ b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/MakeBoolPropertyRespectIsHasWasMethodNamingRectorTest.php
@@ -0,0 +1,31 @@
+doTestFileInfo($fileInfo);
+ }
+
+ public function provideData(): Iterator
+ {
+ return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
+ }
+
+ protected function getRectorClass(): string
+ {
+ return MakeBoolPropertyRespectIsHasWasMethodNamingRector::class;
+ }
+}
diff --git a/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Php74Test.php b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Php74Test.php
new file mode 100644
index 00000000000..f48915cce40
--- /dev/null
+++ b/rules/naming/tests/Rector/Property/MakeBoolPropertyRespectIsHasWasMethodNamingRector/Php74Test.php
@@ -0,0 +1,40 @@
+= 7.4
+ */
+final class Php74Test extends AbstractRectorTestCase
+{
+ /**
+ * @dataProvider provideData()
+ */
+ public function test(SmartFileInfo $fileInfo): void
+ {
+ $this->doTestFileInfo($fileInfo);
+ }
+
+ public function provideData(): Iterator
+ {
+ return $this->yieldFilesFromDirectory(__DIR__ . '/FixturePhp74');
+ }
+
+ protected function getPhpVersion(): string
+ {
+ return PhpVersionFeature::TYPED_PROPERTIES;
+ }
+
+ protected function getRectorClass(): string
+ {
+ return MakeBoolPropertyRespectIsHasWasMethodNamingRector::class;
+ }
+}
diff --git a/rules/symfony/src/ValueObject/ServiceDefinition.php b/rules/symfony/src/ValueObject/ServiceDefinition.php
index 68af2331a63..0bf344133a5 100644
--- a/rules/symfony/src/ValueObject/ServiceDefinition.php
+++ b/rules/symfony/src/ValueObject/ServiceDefinition.php
@@ -16,12 +16,12 @@ final class ServiceDefinition
/**
* @var bool
*/
- private $public = false;
+ private $isPublic = false;
/**
* @var bool
*/
- private $synthetic = false;
+ private $isSynthetic = false;
/**
* @var TagInterface[]
@@ -45,8 +45,8 @@ final class ServiceDefinition
{
$this->id = $id;
$this->class = $class;
- $this->public = $public;
- $this->synthetic = $synthetic;
+ $this->isPublic = $public;
+ $this->isSynthetic = $synthetic;
$this->alias = $alias;
$this->tags = $tags;
}
@@ -63,12 +63,12 @@ final class ServiceDefinition
public function isPublic(): bool
{
- return $this->public;
+ return $this->isPublic;
}
public function isSynthetic(): bool
{
- return $this->synthetic;
+ return $this->isSynthetic;
}
public function getAlias(): ?string
diff --git a/src/Rector/AbstractRector/NodeTypeResolverTrait.php b/src/Rector/AbstractRector/NodeTypeResolverTrait.php
index b61188f918d..3baceb49fd3 100644
--- a/src/Rector/AbstractRector/NodeTypeResolverTrait.php
+++ b/src/Rector/AbstractRector/NodeTypeResolverTrait.php
@@ -10,6 +10,7 @@ use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
+use PhpParser\Node\Stmt\Property;
use PhpParser\Node\Stmt\Return_;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;
@@ -81,6 +82,16 @@ trait NodeTypeResolverTrait
return $objectType->equals($desiredObjectType);
}
+ public function isBooleanType(Node $node): bool
+ {
+ return $this->nodeTypeResolver->isBooleanType($node);
+ }
+
+ public function isPropertyBoolean(Property $property): bool
+ {
+ return $this->nodeTypeResolver->isPropertyBoolean($property);
+ }
+
/**
* @param ObjectType|string $type
*/