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 */