Updated Rector to commit ed80bec474

ed80bec474 [Strict] Add parameter to require non-empty values opt-in (#956)
This commit is contained in:
Tomas Votruba 2021-10-05 15:59:39 +00:00
parent e2239d52a1
commit 8203945744
14 changed files with 278 additions and 124 deletions

View File

@ -9782,15 +9782,34 @@ Rename file to respect class name
Fixer for PHPStan reports by strict type rule - "PHPStan\Rules\BooleansInConditions\BooleanInBooleanNotRule"
:wrench: **configure it!**
- class: [`Rector\Strict\Rector\BooleanNot\BooleanInBooleanNotRuleFixerRector`](../rules/Strict/Rector/BooleanNot/BooleanInBooleanNotRuleFixerRector.php)
```php
use Rector\Strict\Rector\BooleanNot\BooleanInBooleanNotRuleFixerRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(BooleanInBooleanNotRuleFixerRector::class)
->call('configure', [[
BooleanInBooleanNotRuleFixerRector::TREAT_AS_NON_EMPTY => true,
]]);
};
```
```diff
class SomeClass
{
public function run(string $name)
- public function run(string|null $name)
+ public function run(string $name)
{
- if (! $name) {
+ if ($name === '') {
+ if ($name === null) {
return 'no name';
}
@ -9805,8 +9824,26 @@ Fixer for PHPStan reports by strict type rule - "PHPStan\Rules\BooleansInConditi
Fixer for PHPStan reports by strict type rule - "PHPStan\Rules\BooleansInConditions\BooleanInIfConditionRule"
:wrench: **configure it!**
- class: [`Rector\Strict\Rector\If_\BooleanInIfConditionRuleFixerRector`](../rules/Strict/Rector/If_/BooleanInIfConditionRuleFixerRector.php)
```php
use Rector\Strict\Rector\If_\BooleanInIfConditionRuleFixerRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(BooleanInIfConditionRuleFixerRector::class)
->call('configure', [[
BooleanInIfConditionRuleFixerRector::TREAT_AS_NON_EMPTY => false,
]]);
};
```
```diff
final class NegatedString
{
@ -9828,8 +9865,26 @@ Fixer for PHPStan reports by strict type rule - "PHPStan\Rules\BooleansInConditi
Fixer for PHPStan reports by strict type rule - "PHPStan\Rules\BooleansInConditions\BooleanInTernaryOperatorRule"
:wrench: **configure it!**
- class: [`Rector\Strict\Rector\Ternary\BooleanInTernaryOperatorRuleFixerRector`](../rules/Strict/Rector/Ternary/BooleanInTernaryOperatorRuleFixerRector.php)
```php
use Rector\Strict\Rector\Ternary\BooleanInTernaryOperatorRuleFixerRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(BooleanInTernaryOperatorRuleFixerRector::class)
->call('configure', [[
BooleanInTernaryOperatorRuleFixerRector::TREAT_AS_NON_EMPTY => false,
]]);
};
```
```diff
final class ArrayCompare
{
@ -9847,8 +9902,26 @@ Fixer for PHPStan reports by strict type rule - "PHPStan\Rules\BooleansInConditi
Fixer for PHPStan reports by strict type rule - "PHPStan\Rules\DisallowedConstructs\DisallowedEmptyRule"
:wrench: **configure it!**
- class: [`Rector\Strict\Rector\Empty_\DisallowedEmptyRuleFixerRector`](../rules/Strict/Rector/Empty_/DisallowedEmptyRuleFixerRector.php)
```php
use Rector\Strict\Rector\Empty_\DisallowedEmptyRuleFixerRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(DisallowedEmptyRuleFixerRector::class)
->call('configure', [[
DisallowedEmptyRuleFixerRector::TREAT_AS_NON_EMPTY => false,
]]);
};
```
```diff
final class SomeEmptyArray
{
@ -9866,8 +9939,26 @@ Fixer for PHPStan reports by strict type rule - "PHPStan\Rules\DisallowedConstru
Fixer for PHPStan reports by strict type rule - "PHPStan\Rules\DisallowedConstructs\DisallowedShortTernaryRule"
:wrench: **configure it!**
- class: [`Rector\Strict\Rector\Ternary\DisallowedShortTernaryRuleFixerRector`](../rules/Strict/Rector/Ternary/DisallowedShortTernaryRuleFixerRector.php)
```php
use Rector\Strict\Rector\Ternary\DisallowedShortTernaryRuleFixerRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(DisallowedShortTernaryRuleFixerRector::class)
->call('configure', [[
DisallowedShortTernaryRuleFixerRector::TREAT_AS_NON_EMPTY => false,
]]);
};
```
```diff
final class ShortTernaryArray
{

View File

@ -5,26 +5,38 @@ namespace Rector\Strict\NodeFactory;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\BinaryOp\BooleanAnd;
use PhpParser\Node\Expr\BinaryOp\BooleanOr;
use PhpParser\Node\Expr\BinaryOp\Identical;
use PhpParser\Node\Expr\BinaryOp\NotIdentical;
use PhpParser\Node\Expr\ConstFetch;
use PhpParser\Node\Expr\BooleanNot;
use PhpParser\Node\Expr\Instanceof_;
use PhpParser\Node\Name;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Scalar\LNumber;
use PhpParser\Node\Scalar\String_;
use PHPStan\Type\ArrayType;
use PHPStan\Type\BooleanType;
use PHPStan\Type\FloatType;
use PHPStan\Type\IntegerType;
use PHPStan\Type\StringType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeCombinator;
use PHPStan\Type\TypeWithClassName;
use PHPStan\Type\UnionType;
use Rector\Core\PhpParser\Node\NodeFactory;
final class ExactCompareFactory
{
public function createIdenticalFalsyCompare(\PHPStan\Type\Type $exprType, \PhpParser\Node\Expr $expr) : ?\PhpParser\Node\Expr\BinaryOp\Identical
/**
* @var \Rector\Core\PhpParser\Node\NodeFactory
*/
private $nodeFactory;
public function __construct(\Rector\Core\PhpParser\Node\NodeFactory $nodeFactory)
{
$this->nodeFactory = $nodeFactory;
}
/**
* @return \PhpParser\Node\Expr|null
*/
public function createIdenticalFalsyCompare(\PHPStan\Type\Type $exprType, \PhpParser\Node\Expr $expr, bool $treatAsNonEmpty)
{
if ($exprType instanceof \PHPStan\Type\StringType) {
return new \PhpParser\Node\Expr\BinaryOp\Identical($expr, new \PhpParser\Node\Scalar\String_(''));
@ -32,21 +44,21 @@ final class ExactCompareFactory
if ($exprType instanceof \PHPStan\Type\IntegerType) {
return new \PhpParser\Node\Expr\BinaryOp\Identical($expr, new \PhpParser\Node\Scalar\LNumber(0));
}
if ($exprType instanceof \PHPStan\Type\BooleanType) {
return new \PhpParser\Node\Expr\BinaryOp\Identical($expr, $this->nodeFactory->createFalse());
}
if ($exprType instanceof \PHPStan\Type\ArrayType) {
return new \PhpParser\Node\Expr\BinaryOp\Identical($expr, new \PhpParser\Node\Expr\Array_([]));
}
if (!$exprType instanceof \PHPStan\Type\UnionType) {
return null;
}
if (!\PHPStan\Type\TypeCombinator::containsNull($exprType)) {
return null;
}
return $this->createTruthyFromUnionType($exprType, $expr);
return $this->createTruthyFromUnionType($exprType, $expr, $treatAsNonEmpty);
}
/**
* @return \PhpParser\Node\Expr\BinaryOp\NotIdentical|\PhpParser\Node\Expr\BinaryOp\Identical|\PhpParser\Node\Expr\Instanceof_|null
* @return \PhpParser\Node\Expr|null
*/
public function createNotIdenticalFalsyCompare(\PHPStan\Type\Type $exprType, \PhpParser\Node\Expr $expr)
public function createNotIdenticalFalsyCompare(\PHPStan\Type\Type $exprType, \PhpParser\Node\Expr $expr, bool $treatAsNotEmpty)
{
if ($exprType instanceof \PHPStan\Type\StringType) {
return new \PhpParser\Node\Expr\BinaryOp\NotIdentical($expr, new \PhpParser\Node\Scalar\String_(''));
@ -60,62 +72,76 @@ final class ExactCompareFactory
if (!$exprType instanceof \PHPStan\Type\UnionType) {
return null;
}
if (!\PHPStan\Type\TypeCombinator::containsNull($exprType)) {
return null;
}
return $this->createFromUnionType($exprType, $expr);
return $this->createFromUnionType($exprType, $expr, $treatAsNotEmpty);
}
/**
* @param \PHPStan\Type\Type|\PHPStan\Type\UnionType $exprType
* @return \PhpParser\Node\Expr\BinaryOp\Identical|\PhpParser\Node\Expr\Instanceof_|\PhpParser\Node\Expr\BinaryOp\NotIdentical
* @return \PhpParser\Node\Expr|null
*/
private function createFromUnionType($exprType, \PhpParser\Node\Expr $expr)
{
$exprType = \PHPStan\Type\TypeCombinator::removeNull($exprType);
if ($exprType instanceof \PHPStan\Type\BooleanType) {
$trueConstFetch = new \PhpParser\Node\Expr\ConstFetch(new \PhpParser\Node\Name('true'));
return new \PhpParser\Node\Expr\BinaryOp\Identical($expr, $trueConstFetch);
}
if ($exprType instanceof \PHPStan\Type\TypeWithClassName) {
return new \PhpParser\Node\Expr\Instanceof_($expr, new \PhpParser\Node\Name\FullyQualified($exprType->getClassName()));
}
$nullConstFetch = new \PhpParser\Node\Expr\ConstFetch(new \PhpParser\Node\Name('null'));
return new \PhpParser\Node\Expr\BinaryOp\NotIdentical($expr, $nullConstFetch);
}
private function resolveFalsyTypesCount(\PHPStan\Type\UnionType $unionType) : int
{
$falsyTypesCount = 0;
foreach ($unionType->getTypes() as $unionedType) {
if ($unionedType instanceof \PHPStan\Type\StringType) {
++$falsyTypesCount;
}
if ($unionedType instanceof \PHPStan\Type\IntegerType) {
++$falsyTypesCount;
}
if ($unionedType instanceof \PHPStan\Type\FloatType) {
++$falsyTypesCount;
}
if ($unionedType instanceof \PHPStan\Type\ArrayType) {
++$falsyTypesCount;
}
}
return $falsyTypesCount;
}
private function createTruthyFromUnionType(\PHPStan\Type\UnionType $unionType, \PhpParser\Node\Expr $expr) : ?\PhpParser\Node\Expr\BinaryOp\Identical
private function createFromUnionType(\PHPStan\Type\UnionType $unionType, \PhpParser\Node\Expr $expr, bool $treatAsNotEmpty)
{
$unionType = \PHPStan\Type\TypeCombinator::removeNull($unionType);
if ($unionType instanceof \PHPStan\Type\BooleanType) {
$trueConstFetch = new \PhpParser\Node\Expr\ConstFetch(new \PhpParser\Node\Name('true'));
return new \PhpParser\Node\Expr\BinaryOp\Identical($expr, $trueConstFetch);
return new \PhpParser\Node\Expr\BinaryOp\Identical($expr, $this->nodeFactory->createTrue());
}
if ($unionType instanceof \PHPStan\Type\TypeWithClassName) {
return new \PhpParser\Node\Expr\Instanceof_($expr, new \PhpParser\Node\Name\FullyQualified($unionType->getClassName()));
}
$nullConstFetch = $this->nodeFactory->createNull();
$toNullNotIdentical = new \PhpParser\Node\Expr\BinaryOp\NotIdentical($expr, $nullConstFetch);
if ($unionType instanceof \PHPStan\Type\UnionType) {
$falsyTypesCount = $this->resolveFalsyTypesCount($unionType);
// impossible to refactor to string value compare, as many falsy values can be provided
if ($falsyTypesCount > 1) {
$compareExprs = [];
foreach ($unionType->getTypes() as $unionedType) {
$compareExprs[] = $this->createNotIdenticalFalsyCompare($unionedType, $expr, $treatAsNotEmpty);
}
/** @var Expr $truthyExpr */
$truthyExpr = \array_shift($compareExprs);
foreach ($compareExprs as $compareExpr) {
/** @var Expr $compareExpr */
$truthyExpr = new \PhpParser\Node\Expr\BinaryOp\BooleanOr($truthyExpr, $compareExpr);
}
return $truthyExpr;
}
$compareExpr = $this->createNotIdenticalFalsyCompare($unionType, $expr, $treatAsNotEmpty);
if (!$compareExpr instanceof \PhpParser\Node\Expr) {
return null;
}
return new \PhpParser\Node\Expr\BinaryOp\BooleanAnd($toNullNotIdentical, $compareExpr);
}
/**
* @return \PhpParser\Node\Expr|null
*/
private function createTruthyFromUnionType(\PHPStan\Type\UnionType $unionType, \PhpParser\Node\Expr $expr, bool $treatAsNonEmpty)
{
$unionType = \PHPStan\Type\TypeCombinator::removeNull($unionType);
if ($unionType instanceof \PHPStan\Type\UnionType) {
$compareExprs = [];
foreach ($unionType->getTypes() as $unionedType) {
$compareExprs[] = $this->createIdenticalFalsyCompare($unionedType, $expr, $treatAsNonEmpty);
}
/** @var Expr $truthyExpr */
$truthyExpr = \array_shift($compareExprs);
foreach ($compareExprs as $compareExpr) {
/** @var Expr $compareExpr */
$truthyExpr = new \PhpParser\Node\Expr\BinaryOp\BooleanOr($truthyExpr, $compareExpr);
}
return $truthyExpr;
}
if ($unionType instanceof \PHPStan\Type\BooleanType) {
return new \PhpParser\Node\Expr\BinaryOp\Identical($expr, $this->nodeFactory->createTrue());
}
if ($unionType instanceof \PHPStan\Type\TypeWithClassName) {
$instanceOf = new \PhpParser\Node\Expr\Instanceof_($expr, new \PhpParser\Node\Name\FullyQualified($unionType->getClassName()));
return new \PhpParser\Node\Expr\BooleanNot($instanceOf);
}
$toNullIdentical = new \PhpParser\Node\Expr\BinaryOp\Identical($expr, $this->nodeFactory->createNull());
// assume we have to check empty string, integer and bools
if (!$treatAsNonEmpty) {
$scalarFalsyIdentical = $this->createIdenticalFalsyCompare($unionType, $expr, $treatAsNonEmpty);
if (!$scalarFalsyIdentical instanceof \PhpParser\Node\Expr) {
return null;
}
return new \PhpParser\Node\Expr\BinaryOp\BooleanOr($toNullIdentical, $scalarFalsyIdentical);
}
$nullConstFetch = new \PhpParser\Node\Expr\ConstFetch(new \PhpParser\Node\Name('null'));
return new \PhpParser\Node\Expr\BinaryOp\Identical($expr, $nullConstFetch);
return $toNullIdentical;
}
}

View File

@ -0,0 +1,31 @@
<?php
declare (strict_types=1);
namespace Rector\Strict\Rector;
use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
use Rector\Core\Rector\AbstractRector;
use RectorPrefix20211005\Webmozart\Assert\Assert;
/**
* @see \Rector\Tests\Strict\Rector\BooleanNot\BooleanInBooleanNotRuleFixerRector\BooleanInBooleanNotRuleFixerRectorTest
*/
abstract class AbstractFalsyScalarRuleFixerRector extends \Rector\Core\Rector\AbstractRector implements \Rector\Core\Contract\Rector\ConfigurableRectorInterface
{
/**
* @var string
*/
public const TREAT_AS_NON_EMPTY = 'treat_as_non_empty';
/**
* @var bool
*/
protected $treatAsNonEmpty = \false;
/**
* @param array<string, mixed> $configuration
*/
public function configure(array $configuration) : void
{
$treatAsNonEmpty = $configuration[self::TREAT_AS_NON_EMPTY] ?? \false;
\RectorPrefix20211005\Webmozart\Assert\Assert::boolean($treatAsNonEmpty);
$this->treatAsNonEmpty = $treatAsNonEmpty;
}
}

View File

@ -4,13 +4,13 @@ declare (strict_types=1);
namespace Rector\Strict\Rector\BooleanNot;
use PhpParser\Node;
use PhpParser\Node\Expr\BinaryOp\Identical;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\BooleanNot;
use PHPStan\Analyser\Scope;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\Strict\NodeFactory\ExactCompareFactory;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Rector\Strict\Rector\AbstractFalsyScalarRuleFixerRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* Fixer Rector for PHPStan rule:
@ -18,7 +18,7 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
*
* @see \Rector\Tests\Strict\Rector\BooleanNot\BooleanInBooleanNotRuleFixerRector\BooleanInBooleanNotRuleFixerRectorTest
*/
final class BooleanInBooleanNotRuleFixerRector extends \Rector\Core\Rector\AbstractRector
final class BooleanInBooleanNotRuleFixerRector extends \Rector\Strict\Rector\AbstractFalsyScalarRuleFixerRector
{
/**
* @var \Rector\Strict\NodeFactory\ExactCompareFactory
@ -31,10 +31,10 @@ final class BooleanInBooleanNotRuleFixerRector extends \Rector\Core\Rector\Abstr
public function getRuleDefinition() : \Symplify\RuleDocGenerator\ValueObject\RuleDefinition
{
$errorMessage = \sprintf('Fixer for PHPStan reports by strict type rule - "%s"', 'PHPStan\\Rules\\BooleansInConditions\\BooleanInBooleanNotRule');
return new \Symplify\RuleDocGenerator\ValueObject\RuleDefinition($errorMessage, [new \Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample(<<<'CODE_SAMPLE'
return new \Symplify\RuleDocGenerator\ValueObject\RuleDefinition($errorMessage, [new \Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample(<<<'CODE_SAMPLE'
class SomeClass
{
public function run(string $name)
public function run(string|null $name)
{
if (! $name) {
return 'no name';
@ -49,7 +49,7 @@ class SomeClass
{
public function run(string $name)
{
if ($name === '') {
if ($name === null) {
return 'no name';
}
@ -57,7 +57,7 @@ class SomeClass
}
}
CODE_SAMPLE
)]);
, [self::TREAT_AS_NON_EMPTY => \true])]);
}
/**
* @return array<class-string<Node>>
@ -69,13 +69,13 @@ CODE_SAMPLE
/**
* @param BooleanNot $node
*/
public function refactor(\PhpParser\Node $node) : ?\PhpParser\Node\Expr\BinaryOp\Identical
public function refactor(\PhpParser\Node $node) : ?\PhpParser\Node\Expr
{
$scope = $node->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::SCOPE);
if (!$scope instanceof \PHPStan\Analyser\Scope) {
return null;
}
$exprType = $scope->getType($node->expr);
return $this->exactCompareFactory->createIdenticalFalsyCompare($exprType, $node->expr);
return $this->exactCompareFactory->createIdenticalFalsyCompare($exprType, $node->expr, $this->treatAsNonEmpty);
}
}

View File

@ -4,21 +4,19 @@ declare (strict_types=1);
namespace Rector\Strict\Rector\Empty_;
use PhpParser\Node;
use PhpParser\Node\Expr\BinaryOp\Identical;
use PhpParser\Node\Expr\BinaryOp\NotIdentical;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\BooleanNot;
use PhpParser\Node\Expr\Empty_;
use PhpParser\Node\Expr\Instanceof_;
use PHPStan\Analyser\Scope;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\Strict\NodeFactory\ExactCompareFactory;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Rector\Strict\Rector\AbstractFalsyScalarRuleFixerRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Tests\Strict\Rector\Empty_\DisallowedEmptyRuleFixerRector\DisallowedEmptyRuleFixerRectorTest
*/
final class DisallowedEmptyRuleFixerRector extends \Rector\Core\Rector\AbstractRector
final class DisallowedEmptyRuleFixerRector extends \Rector\Strict\Rector\AbstractFalsyScalarRuleFixerRector
{
/**
* @var \Rector\Strict\NodeFactory\ExactCompareFactory
@ -31,7 +29,7 @@ final class DisallowedEmptyRuleFixerRector extends \Rector\Core\Rector\AbstractR
public function getRuleDefinition() : \Symplify\RuleDocGenerator\ValueObject\RuleDefinition
{
$errorMessage = \sprintf('Fixer for PHPStan reports by strict type rule - "%s"', 'PHPStan\\Rules\\DisallowedConstructs\\DisallowedEmptyRule');
return new \Symplify\RuleDocGenerator\ValueObject\RuleDefinition($errorMessage, [new \Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample(<<<'CODE_SAMPLE'
return new \Symplify\RuleDocGenerator\ValueObject\RuleDefinition($errorMessage, [new \Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample(<<<'CODE_SAMPLE'
final class SomeEmptyArray
{
public function run(array $items)
@ -49,7 +47,7 @@ final class SomeEmptyArray
}
}
CODE_SAMPLE
)]);
, [self::TREAT_AS_NON_EMPTY => \false])]);
}
/**
* @return array<class-string<Node>>
@ -60,6 +58,7 @@ CODE_SAMPLE
}
/**
* @param Empty_|BooleanNot $node
* @return \PhpParser\Node\Expr|null
*/
public function refactor(\PhpParser\Node $node)
{
@ -70,10 +69,10 @@ CODE_SAMPLE
if ($node instanceof \PhpParser\Node\Expr\BooleanNot) {
return $this->refactorBooleanNot($node, $scope);
}
return $this->refactorEmpty($node, $scope);
return $this->refactorEmpty($node, $scope, $this->treatAsNonEmpty);
}
/**
* @return \PhpParser\Node\Expr\BinaryOp\NotIdentical|\PhpParser\Node\Expr\BinaryOp\Identical|\PhpParser\Node\Expr\Instanceof_|null
* @return \PhpParser\Node\Expr|null
*/
private function refactorBooleanNot(\PhpParser\Node\Expr\BooleanNot $booleanNot, \PHPStan\Analyser\Scope $scope)
{
@ -82,11 +81,14 @@ CODE_SAMPLE
}
$empty = $booleanNot->expr;
$emptyExprType = $scope->getType($empty->expr);
return $this->exactCompareFactory->createNotIdenticalFalsyCompare($emptyExprType, $empty->expr);
return $this->exactCompareFactory->createNotIdenticalFalsyCompare($emptyExprType, $empty->expr, $this->treatAsNonEmpty);
}
private function refactorEmpty(\PhpParser\Node\Expr\Empty_ $empty, \PHPStan\Analyser\Scope $scope) : ?\PhpParser\Node\Expr\BinaryOp\Identical
/**
* @return \PhpParser\Node\Expr|null
*/
private function refactorEmpty(\PhpParser\Node\Expr\Empty_ $empty, \PHPStan\Analyser\Scope $scope, bool $treatAsNonEmpty)
{
$exprType = $scope->getType($empty->expr);
return $this->exactCompareFactory->createIdenticalFalsyCompare($exprType, $empty->expr);
return $this->exactCompareFactory->createIdenticalFalsyCompare($exprType, $empty->expr, $treatAsNonEmpty);
}
}

View File

@ -4,12 +4,13 @@ declare (strict_types=1);
namespace Rector\Strict\Rector\If_;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Stmt\If_;
use PHPStan\Analyser\Scope;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\Strict\NodeFactory\ExactCompareFactory;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Rector\Strict\Rector\AbstractFalsyScalarRuleFixerRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* Fixer Rector for PHPStan rules:
@ -18,7 +19,7 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
*
* @see \Rector\Tests\Strict\Rector\If_\BooleanInIfConditionRuleFixerRector\BooleanInIfConditionRuleFixerRectorTest
*/
final class BooleanInIfConditionRuleFixerRector extends \Rector\Core\Rector\AbstractRector
final class BooleanInIfConditionRuleFixerRector extends \Rector\Strict\Rector\AbstractFalsyScalarRuleFixerRector
{
/**
* @var \Rector\Strict\NodeFactory\ExactCompareFactory
@ -31,7 +32,7 @@ final class BooleanInIfConditionRuleFixerRector extends \Rector\Core\Rector\Abst
public function getRuleDefinition() : \Symplify\RuleDocGenerator\ValueObject\RuleDefinition
{
$errorMessage = \sprintf('Fixer for PHPStan reports by strict type rule - "%s"', 'PHPStan\\Rules\\BooleansInConditions\\BooleanInIfConditionRule');
return new \Symplify\RuleDocGenerator\ValueObject\RuleDefinition($errorMessage, [new \Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample(<<<'CODE_SAMPLE'
return new \Symplify\RuleDocGenerator\ValueObject\RuleDefinition($errorMessage, [new \Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample(<<<'CODE_SAMPLE'
final class NegatedString
{
public function run(string $name)
@ -57,7 +58,7 @@ final class NegatedString
}
}
CODE_SAMPLE
)]);
, [self::TREAT_AS_NON_EMPTY => \false])]);
}
/**
* @return array<class-string<Node>>
@ -77,15 +78,15 @@ CODE_SAMPLE
}
// 1. if
$ifCondExprType = $scope->getType($node->cond);
$notIdentical = $this->exactCompareFactory->createNotIdenticalFalsyCompare($ifCondExprType, $node->cond);
$notIdentical = $this->exactCompareFactory->createNotIdenticalFalsyCompare($ifCondExprType, $node->cond, $this->treatAsNonEmpty);
if ($notIdentical !== null) {
$node->cond = $notIdentical;
}
// 2. elseifs
foreach ($node->elseifs as $elseif) {
$elseifCondExprType = $scope->getType($elseif->cond);
$notIdentical = $this->exactCompareFactory->createNotIdenticalFalsyCompare($elseifCondExprType, $elseif->cond);
if ($notIdentical === null) {
$notIdentical = $this->exactCompareFactory->createNotIdenticalFalsyCompare($elseifCondExprType, $elseif->cond, $this->treatAsNonEmpty);
if (!$notIdentical instanceof \PhpParser\Node\Expr) {
continue;
}
$elseif->cond = $notIdentical;

View File

@ -7,10 +7,10 @@ use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Ternary;
use PHPStan\Analyser\Scope;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\Strict\NodeFactory\ExactCompareFactory;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Rector\Strict\Rector\AbstractFalsyScalarRuleFixerRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* Fixer Rector for PHPStan rule:
@ -18,7 +18,7 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
*
* @see \Rector\Tests\Strict\Rector\Ternary\BooleanInTernaryOperatorRuleFixerRector\BooleanInTernaryOperatorRuleFixerRectorTest
*/
final class BooleanInTernaryOperatorRuleFixerRector extends \Rector\Core\Rector\AbstractRector
final class BooleanInTernaryOperatorRuleFixerRector extends \Rector\Strict\Rector\AbstractFalsyScalarRuleFixerRector
{
/**
* @var \Rector\Strict\NodeFactory\ExactCompareFactory
@ -31,7 +31,7 @@ final class BooleanInTernaryOperatorRuleFixerRector extends \Rector\Core\Rector\
public function getRuleDefinition() : \Symplify\RuleDocGenerator\ValueObject\RuleDefinition
{
$errorMessage = \sprintf('Fixer for PHPStan reports by strict type rule - "%s"', 'PHPStan\\Rules\\BooleansInConditions\\BooleanInTernaryOperatorRule');
return new \Symplify\RuleDocGenerator\ValueObject\RuleDefinition($errorMessage, [new \Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample(<<<'CODE_SAMPLE'
return new \Symplify\RuleDocGenerator\ValueObject\RuleDefinition($errorMessage, [new \Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample(<<<'CODE_SAMPLE'
final class ArrayCompare
{
public function run(array $data)
@ -49,7 +49,7 @@ final class ArrayCompare
}
}
CODE_SAMPLE
)]);
, [self::TREAT_AS_NON_EMPTY => \false])]);
}
/**
* @return array<class-string<Node>>
@ -72,7 +72,7 @@ CODE_SAMPLE
return null;
}
$exprType = $scope->getType($node->cond);
$falsyIdentical = $this->exactCompareFactory->createNotIdenticalFalsyCompare($exprType, $node->cond);
$falsyIdentical = $this->exactCompareFactory->createNotIdenticalFalsyCompare($exprType, $node->cond, $this->treatAsNonEmpty);
if (!$falsyIdentical instanceof \PhpParser\Node\Expr) {
return null;
}

View File

@ -4,13 +4,14 @@ declare (strict_types=1);
namespace Rector\Strict\Rector\Ternary;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\Ternary;
use PHPStan\Analyser\Scope;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\Strict\NodeFactory\ExactCompareFactory;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Rector\Strict\Rector\AbstractFalsyScalarRuleFixerRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* Fixer Rector for PHPStan rule:
@ -18,7 +19,7 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
*
* @see \Rector\Tests\Strict\Rector\Ternary\DisallowedShortTernaryRuleFixerRector\DisallowedShortTernaryRuleFixerRectorTest
*/
final class DisallowedShortTernaryRuleFixerRector extends \Rector\Core\Rector\AbstractRector
final class DisallowedShortTernaryRuleFixerRector extends \Rector\Strict\Rector\AbstractFalsyScalarRuleFixerRector
{
/**
* @var \Rector\Strict\NodeFactory\ExactCompareFactory
@ -31,7 +32,7 @@ final class DisallowedShortTernaryRuleFixerRector extends \Rector\Core\Rector\Ab
public function getRuleDefinition() : \Symplify\RuleDocGenerator\ValueObject\RuleDefinition
{
$errorMessage = \sprintf('Fixer for PHPStan reports by strict type rule - "%s"', 'PHPStan\\Rules\\DisallowedConstructs\\DisallowedShortTernaryRule');
return new \Symplify\RuleDocGenerator\ValueObject\RuleDefinition($errorMessage, [new \Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample(<<<'CODE_SAMPLE'
return new \Symplify\RuleDocGenerator\ValueObject\RuleDefinition($errorMessage, [new \Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample(<<<'CODE_SAMPLE'
final class ShortTernaryArray
{
public function run(array $array)
@ -49,7 +50,7 @@ final class ShortTernaryArray
}
}
CODE_SAMPLE
)]);
, [self::TREAT_AS_NON_EMPTY => \false])]);
}
/**
* @return array<class-string<Node>>
@ -77,12 +78,12 @@ CODE_SAMPLE
return $node;
}
$exprType = $scope->getType($node->cond);
$falsyIdentical = $this->exactCompareFactory->createNotIdenticalFalsyCompare($exprType, $node->cond);
if ($falsyIdentical === null) {
$compareExpr = $this->exactCompareFactory->createNotIdenticalFalsyCompare($exprType, $node->cond, $this->treatAsNonEmpty);
if (!$compareExpr instanceof \PhpParser\Node\Expr) {
return null;
}
$node->if = $node->cond;
$node->cond = $falsyIdentical;
$node->cond = $compareExpr;
return $node;
}
private function refactorResetFuncCall(\PhpParser\Node\Expr\Ternary $ternary, \PhpParser\Node\Expr\FuncCall $resetFuncCall, \PHPStan\Analyser\Scope $scope) : void
@ -90,8 +91,8 @@ CODE_SAMPLE
$ternary->if = $ternary->cond;
$firstArgValue = $resetFuncCall->args[0]->value;
$firstArgType = $scope->getType($firstArgValue);
$falsyCompareExpr = $this->exactCompareFactory->createNotIdenticalFalsyCompare($firstArgType, $firstArgValue);
if ($falsyCompareExpr === null) {
$falsyCompareExpr = $this->exactCompareFactory->createNotIdenticalFalsyCompare($firstArgType, $firstArgValue, $this->treatAsNonEmpty);
if (!$falsyCompareExpr instanceof \PhpParser\Node\Expr) {
return;
}
$ternary->cond = $falsyCompareExpr;

View File

@ -16,11 +16,11 @@ final class VersionResolver
/**
* @var string
*/
public const PACKAGE_VERSION = 'd4cb2395dc729e4c77e9b0e4a99677d9acb6d1b8';
public const PACKAGE_VERSION = 'ed80bec474110d2e50f71c6dd1cad0c9a9b10491';
/**
* @var string
*/
public const RELEASE_DATE = '2021-10-05 13:00:07';
public const RELEASE_DATE = '2021-10-05 15:37:14';
public static function resolvePackageVersion() : string
{
$process = new \RectorPrefix20211005\Symfony\Component\Process\Process(['git', 'log', '--pretty="%H"', '-n1', 'HEAD'], __DIR__);

2
vendor/autoload.php vendored
View File

@ -4,4 +4,4 @@
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInitd87bb4d6b2429001a11f93df21ff7afc::getLoader();
return ComposerAutoloaderInitb8a825bcc5a32aba1955fc41da5cfa8e::getLoader();

View File

@ -2961,6 +2961,7 @@ return array(
'Rector\\StaticTypeMapper\\ValueObject\\Type\\SelfObjectType' => $baseDir . '/packages/StaticTypeMapper/ValueObject/Type/SelfObjectType.php',
'Rector\\StaticTypeMapper\\ValueObject\\Type\\ShortenedObjectType' => $baseDir . '/packages/StaticTypeMapper/ValueObject/Type/ShortenedObjectType.php',
'Rector\\Strict\\NodeFactory\\ExactCompareFactory' => $baseDir . '/rules/Strict/NodeFactory/ExactCompareFactory.php',
'Rector\\Strict\\Rector\\AbstractFalsyScalarRuleFixerRector' => $baseDir . '/rules/Strict/Rector/AbstractFalsyScalarRuleFixerRector.php',
'Rector\\Strict\\Rector\\BooleanNot\\BooleanInBooleanNotRuleFixerRector' => $baseDir . '/rules/Strict/Rector/BooleanNot/BooleanInBooleanNotRuleFixerRector.php',
'Rector\\Strict\\Rector\\Empty_\\DisallowedEmptyRuleFixerRector' => $baseDir . '/rules/Strict/Rector/Empty_/DisallowedEmptyRuleFixerRector.php',
'Rector\\Strict\\Rector\\If_\\BooleanInIfConditionRuleFixerRector' => $baseDir . '/rules/Strict/Rector/If_/BooleanInIfConditionRuleFixerRector.php',

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInitd87bb4d6b2429001a11f93df21ff7afc
class ComposerAutoloaderInitb8a825bcc5a32aba1955fc41da5cfa8e
{
private static $loader;
@ -22,15 +22,15 @@ class ComposerAutoloaderInitd87bb4d6b2429001a11f93df21ff7afc
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInitd87bb4d6b2429001a11f93df21ff7afc', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInitb8a825bcc5a32aba1955fc41da5cfa8e', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
spl_autoload_unregister(array('ComposerAutoloaderInitd87bb4d6b2429001a11f93df21ff7afc', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInitb8a825bcc5a32aba1955fc41da5cfa8e', 'loadClassLoader'));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
if ($useStaticLoader) {
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInitd87bb4d6b2429001a11f93df21ff7afc::getInitializer($loader));
call_user_func(\Composer\Autoload\ComposerStaticInitb8a825bcc5a32aba1955fc41da5cfa8e::getInitializer($loader));
} else {
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
@ -42,19 +42,19 @@ class ComposerAutoloaderInitd87bb4d6b2429001a11f93df21ff7afc
$loader->register(true);
if ($useStaticLoader) {
$includeFiles = Composer\Autoload\ComposerStaticInitd87bb4d6b2429001a11f93df21ff7afc::$files;
$includeFiles = Composer\Autoload\ComposerStaticInitb8a825bcc5a32aba1955fc41da5cfa8e::$files;
} else {
$includeFiles = require __DIR__ . '/autoload_files.php';
}
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequired87bb4d6b2429001a11f93df21ff7afc($fileIdentifier, $file);
composerRequireb8a825bcc5a32aba1955fc41da5cfa8e($fileIdentifier, $file);
}
return $loader;
}
}
function composerRequired87bb4d6b2429001a11f93df21ff7afc($fileIdentifier, $file)
function composerRequireb8a825bcc5a32aba1955fc41da5cfa8e($fileIdentifier, $file)
{
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
require $file;

View File

@ -4,7 +4,7 @@
namespace Composer\Autoload;
class ComposerStaticInitd87bb4d6b2429001a11f93df21ff7afc
class ComposerStaticInitb8a825bcc5a32aba1955fc41da5cfa8e
{
public static $files = array (
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
@ -3321,6 +3321,7 @@ class ComposerStaticInitd87bb4d6b2429001a11f93df21ff7afc
'Rector\\StaticTypeMapper\\ValueObject\\Type\\SelfObjectType' => __DIR__ . '/../..' . '/packages/StaticTypeMapper/ValueObject/Type/SelfObjectType.php',
'Rector\\StaticTypeMapper\\ValueObject\\Type\\ShortenedObjectType' => __DIR__ . '/../..' . '/packages/StaticTypeMapper/ValueObject/Type/ShortenedObjectType.php',
'Rector\\Strict\\NodeFactory\\ExactCompareFactory' => __DIR__ . '/../..' . '/rules/Strict/NodeFactory/ExactCompareFactory.php',
'Rector\\Strict\\Rector\\AbstractFalsyScalarRuleFixerRector' => __DIR__ . '/../..' . '/rules/Strict/Rector/AbstractFalsyScalarRuleFixerRector.php',
'Rector\\Strict\\Rector\\BooleanNot\\BooleanInBooleanNotRuleFixerRector' => __DIR__ . '/../..' . '/rules/Strict/Rector/BooleanNot/BooleanInBooleanNotRuleFixerRector.php',
'Rector\\Strict\\Rector\\Empty_\\DisallowedEmptyRuleFixerRector' => __DIR__ . '/../..' . '/rules/Strict/Rector/Empty_/DisallowedEmptyRuleFixerRector.php',
'Rector\\Strict\\Rector\\If_\\BooleanInIfConditionRuleFixerRector' => __DIR__ . '/../..' . '/rules/Strict/Rector/If_/BooleanInIfConditionRuleFixerRector.php',
@ -3892,9 +3893,9 @@ class ComposerStaticInitd87bb4d6b2429001a11f93df21ff7afc
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInitd87bb4d6b2429001a11f93df21ff7afc::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitd87bb4d6b2429001a11f93df21ff7afc::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInitd87bb4d6b2429001a11f93df21ff7afc::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInitb8a825bcc5a32aba1955fc41da5cfa8e::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitb8a825bcc5a32aba1955fc41da5cfa8e::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInitb8a825bcc5a32aba1955fc41da5cfa8e::$classMap;
}, null, ClassLoader::class);
}

View File

@ -9,8 +9,8 @@ $loader = require_once __DIR__.'/autoload.php';
if (!class_exists('AutoloadIncluder', false) && !interface_exists('AutoloadIncluder', false) && !trait_exists('AutoloadIncluder', false)) {
spl_autoload_call('RectorPrefix20211005\AutoloadIncluder');
}
if (!class_exists('ComposerAutoloaderInitd87bb4d6b2429001a11f93df21ff7afc', false) && !interface_exists('ComposerAutoloaderInitd87bb4d6b2429001a11f93df21ff7afc', false) && !trait_exists('ComposerAutoloaderInitd87bb4d6b2429001a11f93df21ff7afc', false)) {
spl_autoload_call('RectorPrefix20211005\ComposerAutoloaderInitd87bb4d6b2429001a11f93df21ff7afc');
if (!class_exists('ComposerAutoloaderInitb8a825bcc5a32aba1955fc41da5cfa8e', false) && !interface_exists('ComposerAutoloaderInitb8a825bcc5a32aba1955fc41da5cfa8e', false) && !trait_exists('ComposerAutoloaderInitb8a825bcc5a32aba1955fc41da5cfa8e', false)) {
spl_autoload_call('RectorPrefix20211005\ComposerAutoloaderInitb8a825bcc5a32aba1955fc41da5cfa8e');
}
if (!class_exists('Helmich\TypoScriptParser\Parser\AST\Statement', false) && !interface_exists('Helmich\TypoScriptParser\Parser\AST\Statement', false) && !trait_exists('Helmich\TypoScriptParser\Parser\AST\Statement', false)) {
spl_autoload_call('RectorPrefix20211005\Helmich\TypoScriptParser\Parser\AST\Statement');
@ -3306,9 +3306,9 @@ if (!function_exists('print_node')) {
return \RectorPrefix20211005\print_node(...func_get_args());
}
}
if (!function_exists('composerRequired87bb4d6b2429001a11f93df21ff7afc')) {
function composerRequired87bb4d6b2429001a11f93df21ff7afc() {
return \RectorPrefix20211005\composerRequired87bb4d6b2429001a11f93df21ff7afc(...func_get_args());
if (!function_exists('composerRequireb8a825bcc5a32aba1955fc41da5cfa8e')) {
function composerRequireb8a825bcc5a32aba1955fc41da5cfa8e() {
return \RectorPrefix20211005\composerRequireb8a825bcc5a32aba1955fc41da5cfa8e(...func_get_args());
}
}
if (!function_exists('parseArgs')) {