mirror of
https://github.com/rectorphp/rector.git
synced 2025-01-17 21:38:22 +01:00
[Naming] Make bool property respect is/has/was naming (#4215)
This commit is contained in:
parent
d9dd72cd6c
commit
52f02d8c91
@ -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);
|
||||
};
|
||||
|
@ -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()
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
@ -2440,27 +2461,6 @@ $someObject->methodName('yes', 'maybe')
|
||||
|
||||
<br>
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
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()
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
### 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()
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Param;
|
||||
@ -3625,30 +3649,6 @@ private function methodName($paramName): string
|
||||
|
||||
<br>
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
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()
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
### Public Properties
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
+
|
||||
}
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
### `MakeGetterClassMethodNameStartWithGetRector`
|
||||
|
||||
- class: [`Rector\Naming\Rector\ClassMethod\MakeGetterClassMethodNameStartWithGetRector`](/rules/naming/src/Rector/ClassMethod/MakeGetterClassMethodNameStartWithGetRector.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) {
|
||||
|
@ -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()
|
||||
);
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Naming\Rector\Property;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
use Rector\Naming\PropertyRenamer;
|
||||
use Rector\Naming\ValueObjectFactory\PropertyRenameFactory;
|
||||
|
||||
/**
|
||||
* @see \Rector\Naming\Tests\Rector\Property\MakeBoolPropertyRespectIsHasWasMethodNamingRector\MakeBoolPropertyRespectIsHasWasMethodNamingRectorTest
|
||||
* @see \Rector\Naming\Tests\Rector\Property\MakeBoolPropertyRespectIsHasWasMethodNamingRector\Php74Test
|
||||
*/
|
||||
final class MakeBoolPropertyRespectIsHasWasMethodNamingRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var PropertyRenamer
|
||||
*/
|
||||
private $propertyRenamer;
|
||||
|
||||
/**
|
||||
* @var PropertyRenameFactory
|
||||
*/
|
||||
private $propertyRenameFactory;
|
||||
|
||||
public function __construct(PropertyRenamer $propertyRenamer, PropertyRenameFactory $propertyRenameFactory)
|
||||
{
|
||||
$this->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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Naming\Tests\Rector\Property\MakeBoolPropertyRespectIsHasWasMethodNamingRector\Fixture;
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $full = false;
|
||||
|
||||
public function isFull()
|
||||
{
|
||||
return $this->full;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Naming\Tests\Rector\Property\MakeBoolPropertyRespectIsHasWasMethodNamingRector\Fixture;
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $isFull = false;
|
||||
|
||||
public function isFull()
|
||||
{
|
||||
return $this->isFull;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Naming\Tests\Rector\Property\MakeBoolPropertyRespectIsHasWasMethodNamingRector\Fixture;
|
||||
|
||||
class SomeClassHas
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $full = false;
|
||||
|
||||
public function hasFull()
|
||||
{
|
||||
return $this->full;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Naming\Tests\Rector\Property\MakeBoolPropertyRespectIsHasWasMethodNamingRector\Fixture;
|
||||
|
||||
class SomeClassHas
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $hasFull = false;
|
||||
|
||||
public function hasFull()
|
||||
{
|
||||
return $this->hasFull;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Naming\Tests\Rector\Property\MakeBoolPropertyRespectIsHasWasMethodNamingRector\Fixture;
|
||||
|
||||
class SomeClassWas
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $full = false;
|
||||
|
||||
public function wasFull()
|
||||
{
|
||||
return $this->full;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Naming\Tests\Rector\Property\MakeBoolPropertyRespectIsHasWasMethodNamingRector\Fixture;
|
||||
|
||||
class SomeClassWas
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $wasFull = false;
|
||||
|
||||
public function wasFull()
|
||||
{
|
||||
return $this->wasFull;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Naming\Tests\Rector\Property\MakeBoolPropertyRespectIsHasWasMethodNamingRector\Fixture;
|
||||
|
||||
class MethodNameAfterPrefixNotMatchesPropertyName
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $full = false;
|
||||
|
||||
public function isSomething()
|
||||
{
|
||||
return $this->full;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Naming\Tests\Rector\Property\MakeBoolPropertyRespectIsHasWasMethodNamingRector\Fixture;
|
||||
|
||||
class MethodNameAfterPrefixNotMatchesPropertyName
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $isSomething = false;
|
||||
|
||||
public function isSomething()
|
||||
{
|
||||
return $this->isSomething;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Naming\Tests\Rector\Property\MakeBoolPropertyRespectIsHasWasMethodNamingRector\Fixture;
|
||||
|
||||
class NoDefaultValue
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $full;
|
||||
|
||||
public function isFull()
|
||||
{
|
||||
return $this->full;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Naming\Tests\Rector\Property\MakeBoolPropertyRespectIsHasWasMethodNamingRector\Fixture;
|
||||
|
||||
class NoDefaultValue
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $isFull;
|
||||
|
||||
public function isFull()
|
||||
{
|
||||
return $this->isFull;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Naming\Tests\Rector\Property\MakeBoolPropertyRespectIsHasWasMethodNamingRector\Fixture;
|
||||
|
||||
class NoDocblock
|
||||
{
|
||||
private $full = false;
|
||||
|
||||
public function isFull()
|
||||
{
|
||||
return $this->full;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Naming\Tests\Rector\Property\MakeBoolPropertyRespectIsHasWasMethodNamingRector\Fixture;
|
||||
|
||||
class NoDocblock
|
||||
{
|
||||
private $isFull = false;
|
||||
|
||||
public function isFull()
|
||||
{
|
||||
return $this->isFull;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Naming\Tests\Rector\Property\MakeBoolPropertyRespectIsHasWasMethodNamingRector\Fixture;
|
||||
|
||||
class SkipAlreadyPrefixed
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $isFull = false;
|
||||
|
||||
public function isFull()
|
||||
{
|
||||
return $this->isFull;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Naming\Tests\Rector\Property\MakeBoolPropertyRespectIsHasWasMethodNamingRector\Fixture;
|
||||
|
||||
class SkipConflict
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $isFull;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $full = false;
|
||||
|
||||
public function isFull()
|
||||
{
|
||||
return $this->full;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Naming\Tests\Rector\Property\MakeBoolPropertyRespectIsHasWasMethodNamingRector\Fixture;
|
||||
|
||||
|
||||
class SkipMethodsWithMoreThanJustReturn
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $full = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $property = true;
|
||||
|
||||
public function isFull()
|
||||
{
|
||||
if ($this->property === true) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->full;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Naming\Tests\Rector\Property\MakeBoolPropertyRespectIsHasWasMethodNamingRector\Fixture;
|
||||
|
||||
class SkipMultiplePrefixedMethods
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $full = false;
|
||||
|
||||
public function isFull()
|
||||
{
|
||||
return $this->full;
|
||||
}
|
||||
|
||||
public function wasFull()
|
||||
{
|
||||
return $this->full;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Naming\Tests\Rector\Property\MakeBoolPropertyRespectIsHasWasMethodNamingRector\Fixture;
|
||||
|
||||
class SkipNoDocblockAndDefaultValue
|
||||
{
|
||||
private $full;
|
||||
|
||||
public function isFull()
|
||||
{
|
||||
return $this->full;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Naming\Tests\Rector\Property\MakeBoolPropertyRespectIsHasWasMethodNamingRector\Fixture;
|
||||
|
||||
class SkipNonBooleanProperty
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $full = 'string';
|
||||
|
||||
public function isFull()
|
||||
{
|
||||
return $this->full;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Naming\Tests\Rector\Property\MakeBoolPropertyRespectIsHasWasMethodNamingRector\Fixture;
|
||||
|
||||
class SkipPropertyUnusedInPrefixedMethod
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $full = false;
|
||||
|
||||
public function isFull()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function something()
|
||||
{
|
||||
return $this->full;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Naming\Tests\Rector\Property\MakeBoolPropertyRespectIsHasWasMethodNamingRector\Fixture;
|
||||
|
||||
class SkipProtectedProperty
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $full = false;
|
||||
|
||||
public function isFull()
|
||||
{
|
||||
return $this->full;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Naming\Tests\Rector\Property\MakeBoolPropertyRespectIsHasWasMethodNamingRector\Fixture;
|
||||
|
||||
class SkipPublicProperty
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $full = false;
|
||||
|
||||
public function isFull()
|
||||
{
|
||||
return $this->full;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Naming\Tests\Rector\Property\MakeBoolPropertyRespectIsHasWasMethodNamingRector\Fixture;
|
||||
|
||||
class SkipUnknownPrefix
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $full = false;
|
||||
|
||||
public function unknownFull()
|
||||
{
|
||||
return $this->full;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Naming\Tests\Rector\Property\MakeBoolPropertyRespectIsHasWasMethodNamingRector\FixturePhp74;
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
private bool $full;
|
||||
|
||||
public function isFull()
|
||||
{
|
||||
return $this->full;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Naming\Tests\Rector\Property\MakeBoolPropertyRespectIsHasWasMethodNamingRector\FixturePhp74;
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
private bool $isFull;
|
||||
|
||||
public function isFull()
|
||||
{
|
||||
return $this->isFull;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Naming\Tests\Rector\Property\MakeBoolPropertyRespectIsHasWasMethodNamingRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Core\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Rector\Naming\Rector\Property\MakeBoolPropertyRespectIsHasWasMethodNamingRector;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
final class MakeBoolPropertyRespectIsHasWasMethodNamingRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData()
|
||||
*/
|
||||
public function test(SmartFileInfo $fileInfo): void
|
||||
{
|
||||
$this->doTestFileInfo($fileInfo);
|
||||
}
|
||||
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
|
||||
}
|
||||
|
||||
protected function getRectorClass(): string
|
||||
{
|
||||
return MakeBoolPropertyRespectIsHasWasMethodNamingRector::class;
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Naming\Tests\Rector\Property\MakeBoolPropertyRespectIsHasWasMethodNamingRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Core\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Rector\Core\ValueObject\PhpVersionFeature;
|
||||
use Rector\Naming\Rector\Property\MakeBoolPropertyRespectIsHasWasMethodNamingRector;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
/**
|
||||
* @requires PHP >= 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;
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user