mirror of
https://github.com/rectorphp/rector.git
synced 2024-05-31 00:10:51 +00:00
[Strict] Add parameter to require non-empty values opt-in (#956)
This commit is contained in:
parent
d4cb2395dc
commit
ed80bec474
2
.github/workflows/rector.yaml
vendored
2
.github/workflows/rector.yaml
vendored
|
@ -59,7 +59,7 @@ jobs:
|
|||
## First run Rector - here can't be --dry-run !!! it would stop the job with it and not commit anything in the future
|
||||
- run: bin/rector process ${{ matrix.paths }} --ansi --no-progress-bar
|
||||
|
||||
- run: vendor/bin/ecs check --match-git-diff --fix --ansi
|
||||
- run: vendor/bin/ecs check --fix --ansi
|
||||
|
||||
# see https://github.com/EndBug/add-and-commit
|
||||
-
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
10
phpstan.neon
10
phpstan.neon
|
@ -501,3 +501,13 @@ parameters:
|
|||
|
||||
# scope & mutating scope mish-mash
|
||||
- '#Parameter \#4 \$nodeCallback of method PHPStan\\Analyser\\NodeScopeResolver\:\:processStmtNodes\(\) expects callable\(PhpParser\\Node, PHPStan\\Analyser\\Scope\)\: void, Closure\(PhpParser\\Node, PHPStan\\Analyser\\MutatingScope\)\: void given#'
|
||||
|
||||
# share configuration to avoid duplication in 5 rules
|
||||
-
|
||||
message: '#Instead of abstract class, use specific service with composition#'
|
||||
path: rules/Strict/Rector/AbstractFalsyScalarRuleFixerRector.php
|
||||
|
||||
# false positive - configured parmaeter
|
||||
-
|
||||
message: '#Property with protected modifier is not allowed\. Use interface contract method instead#'
|
||||
path: rules/Strict/Rector/AbstractFalsyScalarRuleFixerRector.php
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Rector\Tests\CodeQuality\Rector\Expression\InlineIfToExplicitIfRector\Fixture;
|
||||
|
||||
class BooleanOr
|
||||
class SomeBooleanOr
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
|
@ -17,7 +17,7 @@ class BooleanOr
|
|||
|
||||
namespace Rector\Tests\CodeQuality\Rector\Expression\InlineIfToExplicitIfRector\Fixture;
|
||||
|
||||
class BooleanOr
|
||||
class SomeBooleanOr
|
||||
{
|
||||
public function run()
|
||||
{
|
|
@ -4,7 +4,7 @@ namespace Rector\Tests\EarlyReturn\Rector\If_\ChangeNestedIfsToEarlyReturnRector
|
|||
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
||||
class BooleanAnd
|
||||
class AnotherBooleanAnd
|
||||
{
|
||||
private function isPreviousExpressionVisuallySimilar(Expression $previousExpression, Node $previousNode): bool
|
||||
{
|
||||
|
@ -27,7 +27,7 @@ namespace Rector\Tests\EarlyReturn\Rector\If_\ChangeNestedIfsToEarlyReturnRector
|
|||
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
||||
class BooleanAnd
|
||||
class AnotherBooleanAnd
|
||||
{
|
||||
private function isPreviousExpressionVisuallySimilar(Expression $previousExpression, Node $previousNode): bool
|
||||
{
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\Strict\Rector\BooleanNot\BooleanInBooleanNotRuleFixerRector\Fixture;
|
||||
|
||||
final class StringUnionInteger
|
||||
{
|
||||
public function run(string|int $maye)
|
||||
{
|
||||
if (! $maye) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\Strict\Rector\BooleanNot\BooleanInBooleanNotRuleFixerRector\Fixture;
|
||||
|
||||
final class StringUnionInteger
|
||||
{
|
||||
public function run(string|int $maye)
|
||||
{
|
||||
if ($maye === 0 || $maye === '') {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -38,7 +38,7 @@ final class UnionWithNull
|
|||
|
||||
public function run()
|
||||
{
|
||||
if ($this->value === null) {
|
||||
if ($this->value === null || $this->value === '') {
|
||||
return 'empty';
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\Strict\Rector\BooleanNot\BooleanInBooleanNotRuleFixerRector\Fixture;
|
||||
|
||||
final class UnionWithStringNull
|
||||
{
|
||||
public function run(string|null $value)
|
||||
{
|
||||
if (!$value) {
|
||||
return 'empty';
|
||||
}
|
||||
|
||||
return 'full';
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\Strict\Rector\BooleanNot\BooleanInBooleanNotRuleFixerRector\Fixture;
|
||||
|
||||
final class UnionWithStringNull
|
||||
{
|
||||
public function run(string|null $value)
|
||||
{
|
||||
if ($value === null || $value === '') {
|
||||
return 'empty';
|
||||
}
|
||||
|
||||
return 'full';
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\Strict\Rector\BooleanNot\BooleanInBooleanNotRuleFixerRector\FixtureTreatAsNonEmpty;
|
||||
|
||||
final class UnionWithNull
|
||||
{
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $value;
|
||||
|
||||
public function run()
|
||||
{
|
||||
if (! $this->value) {
|
||||
return 'empty';
|
||||
}
|
||||
|
||||
return 'set';
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\Strict\Rector\BooleanNot\BooleanInBooleanNotRuleFixerRector\FixtureTreatAsNonEmpty;
|
||||
|
||||
final class UnionWithNull
|
||||
{
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $value;
|
||||
|
||||
public function run()
|
||||
{
|
||||
if ($this->value === null) {
|
||||
return 'empty';
|
||||
}
|
||||
|
||||
return 'set';
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\Strict\Rector\BooleanNot\BooleanInBooleanNotRuleFixerRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
final class TreatAsNonEmptyRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData()
|
||||
*/
|
||||
public function test(SmartFileInfo $fileInfo): void
|
||||
{
|
||||
$this->doTestFileInfo($fileInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Iterator<SmartFileInfo>
|
||||
*/
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
return $this->yieldFilesFromDirectory(__DIR__ . '/FixtureTreatAsNonEmpty');
|
||||
}
|
||||
|
||||
public function provideConfigFilePath(): string
|
||||
{
|
||||
return __DIR__ . '/config/treat_as_non_empty.php';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
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,
|
||||
]]);
|
||||
};
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\Strict\Rector\Empty_\DisallowedEmptyRuleFixerRector\Fixture;
|
||||
|
||||
final class EmptyStringNullable
|
||||
{
|
||||
public function run(string|null $value)
|
||||
{
|
||||
return empty($value);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\Strict\Rector\Empty_\DisallowedEmptyRuleFixerRector\Fixture;
|
||||
|
||||
final class EmptyStringNullable
|
||||
{
|
||||
public function run(string|null $value)
|
||||
{
|
||||
return $value === null || $value === '';
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Rector\Tests\Strict\Rector\Empty_\DisallowedEmptyRuleFixerRector\Fixture;
|
||||
|
||||
final class SkipMultiUnionTypes
|
||||
final class MultiUnionTypes
|
||||
{
|
||||
/**
|
||||
* @param int|int[]|null|string $id
|
||||
|
@ -12,3 +12,22 @@ final class SkipMultiUnionTypes
|
|||
return empty($id);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\Strict\Rector\Empty_\DisallowedEmptyRuleFixerRector\Fixture;
|
||||
|
||||
final class MultiUnionTypes
|
||||
{
|
||||
/**
|
||||
* @param int|int[]|null|string $id
|
||||
*/
|
||||
public function get($id)
|
||||
{
|
||||
return $id === [] || $id === 0 || $id === '';
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
|
@ -20,7 +20,7 @@ final class UnionObjectNullable
|
|||
{
|
||||
public function run(null|\DateTime $dateTime)
|
||||
{
|
||||
return $dateTime === null;
|
||||
return !$dateTime instanceof \DateTime;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\Strict\Rector\If_\BooleanInIfConditionRuleFixerRector\Fixture;
|
||||
|
||||
final class IntegerUnionString
|
||||
{
|
||||
public function run(int|string $value)
|
||||
{
|
||||
if ($value) {
|
||||
return 'name';
|
||||
}
|
||||
|
||||
return 'no name';
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\Strict\Rector\If_\BooleanInIfConditionRuleFixerRector\Fixture;
|
||||
|
||||
final class IntegerUnionString
|
||||
{
|
||||
public function run(int|string $value)
|
||||
{
|
||||
if ($value !== 0 || $value !== '') {
|
||||
return 'name';
|
||||
}
|
||||
|
||||
return 'no name';
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\Strict\Rector\Ternary\BooleanInTernaryOperatorRuleFixerRector\Fixture;
|
||||
|
||||
final class NullableString
|
||||
{
|
||||
public function run(string|null $value)
|
||||
{
|
||||
return $value ? 1 : 2;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\Strict\Rector\Ternary\BooleanInTernaryOperatorRuleFixerRector\Fixture;
|
||||
|
||||
final class NullableString
|
||||
{
|
||||
public function run(string|null $value)
|
||||
{
|
||||
return $value !== null && $value !== '' ? 1 : 2;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -6,27 +6,33 @@ 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(Type $exprType, Expr $expr): ?Identical
|
||||
public function __construct(
|
||||
private NodeFactory $nodeFactory
|
||||
) {
|
||||
}
|
||||
|
||||
public function createIdenticalFalsyCompare(Type $exprType, Expr $expr, bool $treatAsNonEmpty): Expr|null
|
||||
{
|
||||
if ($exprType instanceof StringType) {
|
||||
return new Identical($expr, new String_(''));
|
||||
|
@ -36,6 +42,10 @@ final class ExactCompareFactory
|
|||
return new Identical($expr, new LNumber(0));
|
||||
}
|
||||
|
||||
if ($exprType instanceof BooleanType) {
|
||||
return new Identical($expr, $this->nodeFactory->createFalse());
|
||||
}
|
||||
|
||||
if ($exprType instanceof ArrayType) {
|
||||
return new Identical($expr, new Array_([]));
|
||||
}
|
||||
|
@ -44,14 +54,10 @@ final class ExactCompareFactory
|
|||
return null;
|
||||
}
|
||||
|
||||
if (! TypeCombinator::containsNull($exprType)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->createTruthyFromUnionType($exprType, $expr);
|
||||
return $this->createTruthyFromUnionType($exprType, $expr, $treatAsNonEmpty);
|
||||
}
|
||||
|
||||
public function createNotIdenticalFalsyCompare(Type $exprType, Expr $expr): NotIdentical|Identical|Instanceof_|null
|
||||
public function createNotIdenticalFalsyCompare(Type $exprType, Expr $expr, bool $treatAsNotEmpty): Expr|null
|
||||
{
|
||||
if ($exprType instanceof StringType) {
|
||||
return new NotIdentical($expr, new String_(''));
|
||||
|
@ -69,74 +75,90 @@ final class ExactCompareFactory
|
|||
return null;
|
||||
}
|
||||
|
||||
if (! TypeCombinator::containsNull($exprType)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->createFromUnionType($exprType, $expr);
|
||||
return $this->createFromUnionType($exprType, $expr, $treatAsNotEmpty);
|
||||
}
|
||||
|
||||
private function createFromUnionType(Type|UnionType $exprType, Expr $expr): Identical|Instanceof_|NotIdentical
|
||||
{
|
||||
$exprType = TypeCombinator::removeNull($exprType);
|
||||
|
||||
if ($exprType instanceof BooleanType) {
|
||||
$trueConstFetch = new ConstFetch(new Name('true'));
|
||||
return new Identical($expr, $trueConstFetch);
|
||||
}
|
||||
|
||||
if ($exprType instanceof TypeWithClassName) {
|
||||
return new Instanceof_($expr, new FullyQualified($exprType->getClassName()));
|
||||
}
|
||||
|
||||
$nullConstFetch = new ConstFetch(new Name('null'));
|
||||
return new NotIdentical($expr, $nullConstFetch);
|
||||
}
|
||||
|
||||
private function resolveFalsyTypesCount(UnionType $unionType): int
|
||||
{
|
||||
$falsyTypesCount = 0;
|
||||
|
||||
foreach ($unionType->getTypes() as $unionedType) {
|
||||
if ($unionedType instanceof StringType) {
|
||||
++$falsyTypesCount;
|
||||
}
|
||||
|
||||
if ($unionedType instanceof IntegerType) {
|
||||
++$falsyTypesCount;
|
||||
}
|
||||
|
||||
if ($unionedType instanceof FloatType) {
|
||||
++$falsyTypesCount;
|
||||
}
|
||||
|
||||
if ($unionedType instanceof ArrayType) {
|
||||
++$falsyTypesCount;
|
||||
}
|
||||
}
|
||||
|
||||
return $falsyTypesCount;
|
||||
}
|
||||
|
||||
private function createTruthyFromUnionType(UnionType $unionType, Expr $expr): ?Identical
|
||||
private function createFromUnionType(UnionType $unionType, Expr $expr, bool $treatAsNotEmpty): Expr|null
|
||||
{
|
||||
$unionType = TypeCombinator::removeNull($unionType);
|
||||
|
||||
if ($unionType instanceof BooleanType) {
|
||||
$trueConstFetch = new ConstFetch(new Name('true'));
|
||||
return new Identical($expr, $trueConstFetch);
|
||||
return new Identical($expr, $this->nodeFactory->createTrue());
|
||||
}
|
||||
|
||||
if ($unionType instanceof TypeWithClassName) {
|
||||
return new Instanceof_($expr, new FullyQualified($unionType->getClassName()));
|
||||
}
|
||||
|
||||
$nullConstFetch = $this->nodeFactory->createNull();
|
||||
$toNullNotIdentical = new NotIdentical($expr, $nullConstFetch);
|
||||
|
||||
if ($unionType instanceof UnionType) {
|
||||
$falsyTypesCount = $this->resolveFalsyTypesCount($unionType);
|
||||
$compareExprs = [];
|
||||
|
||||
// impossible to refactor to string value compare, as many falsy values can be provided
|
||||
if ($falsyTypesCount > 1) {
|
||||
return null;
|
||||
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 BooleanOr($truthyExpr, $compareExpr);
|
||||
}
|
||||
|
||||
return $truthyExpr;
|
||||
}
|
||||
|
||||
$nullConstFetch = new ConstFetch(new Name('null'));
|
||||
return new Identical($expr, $nullConstFetch);
|
||||
$compareExpr = $this->createNotIdenticalFalsyCompare($unionType, $expr, $treatAsNotEmpty);
|
||||
if (! $compareExpr instanceof Expr) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new BooleanAnd($toNullNotIdentical, $compareExpr);
|
||||
}
|
||||
|
||||
private function createTruthyFromUnionType(UnionType $unionType, Expr $expr, bool $treatAsNonEmpty): Expr|null
|
||||
{
|
||||
$unionType = TypeCombinator::removeNull($unionType);
|
||||
|
||||
if ($unionType instanceof 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 BooleanOr($truthyExpr, $compareExpr);
|
||||
}
|
||||
|
||||
return $truthyExpr;
|
||||
}
|
||||
|
||||
if ($unionType instanceof BooleanType) {
|
||||
return new Identical($expr, $this->nodeFactory->createTrue());
|
||||
}
|
||||
|
||||
if ($unionType instanceof TypeWithClassName) {
|
||||
$instanceOf = new Instanceof_($expr, new FullyQualified($unionType->getClassName()));
|
||||
return new BooleanNot($instanceOf);
|
||||
}
|
||||
|
||||
$toNullIdentical = new 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 Expr) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new BooleanOr($toNullIdentical, $scalarFalsyIdentical);
|
||||
}
|
||||
|
||||
return $toNullIdentical;
|
||||
}
|
||||
}
|
||||
|
|
33
rules/Strict/Rector/AbstractFalsyScalarRuleFixerRector.php
Normal file
33
rules/Strict/Rector/AbstractFalsyScalarRuleFixerRector.php
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Strict\Rector;
|
||||
|
||||
use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Webmozart\Assert\Assert;
|
||||
|
||||
/**
|
||||
* @see \Rector\Tests\Strict\Rector\BooleanNot\BooleanInBooleanNotRuleFixerRector\BooleanInBooleanNotRuleFixerRectorTest
|
||||
*/
|
||||
abstract class AbstractFalsyScalarRuleFixerRector extends AbstractRector implements ConfigurableRectorInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public const TREAT_AS_NON_EMPTY = 'treat_as_non_empty';
|
||||
|
||||
protected bool $treatAsNonEmpty = false;
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $configuration
|
||||
*/
|
||||
public function configure(array $configuration): void
|
||||
{
|
||||
$treatAsNonEmpty = $configuration[self::TREAT_AS_NON_EMPTY] ?? false;
|
||||
Assert::boolean($treatAsNonEmpty);
|
||||
|
||||
$this->treatAsNonEmpty = $treatAsNonEmpty;
|
||||
}
|
||||
}
|
|
@ -5,13 +5,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;
|
||||
|
||||
/**
|
||||
|
@ -20,7 +20,7 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
|||
*
|
||||
* @see \Rector\Tests\Strict\Rector\BooleanNot\BooleanInBooleanNotRuleFixerRector\BooleanInBooleanNotRuleFixerRectorTest
|
||||
*/
|
||||
final class BooleanInBooleanNotRuleFixerRector extends AbstractRector
|
||||
final class BooleanInBooleanNotRuleFixerRector extends AbstractFalsyScalarRuleFixerRector
|
||||
{
|
||||
public function __construct(
|
||||
private ExactCompareFactory $exactCompareFactory
|
||||
|
@ -34,11 +34,11 @@ final class BooleanInBooleanNotRuleFixerRector extends AbstractRector
|
|||
'PHPStan\Rules\BooleansInConditions\BooleanInBooleanNotRule'
|
||||
);
|
||||
return new RuleDefinition($errorMessage, [
|
||||
new CodeSample(
|
||||
new ConfiguredCodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
class SomeClass
|
||||
{
|
||||
public function run(string $name)
|
||||
public function run(string|null $name)
|
||||
{
|
||||
if (! $name) {
|
||||
return 'no name';
|
||||
|
@ -54,7 +54,7 @@ class SomeClass
|
|||
{
|
||||
public function run(string $name)
|
||||
{
|
||||
if ($name === '') {
|
||||
if ($name === null) {
|
||||
return 'no name';
|
||||
}
|
||||
|
||||
|
@ -62,6 +62,10 @@ class SomeClass
|
|||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
[
|
||||
self::TREAT_AS_NON_EMPTY => true,
|
||||
]
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
@ -77,7 +81,7 @@ CODE_SAMPLE
|
|||
/**
|
||||
* @param BooleanNot $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Identical
|
||||
public function refactor(Node $node): ?Expr
|
||||
{
|
||||
$scope = $node->getAttribute(AttributeKey::SCOPE);
|
||||
if (! $scope instanceof Scope) {
|
||||
|
@ -86,6 +90,6 @@ CODE_SAMPLE
|
|||
|
||||
$exprType = $scope->getType($node->expr);
|
||||
|
||||
return $this->exactCompareFactory->createIdenticalFalsyCompare($exprType, $node->expr);
|
||||
return $this->exactCompareFactory->createIdenticalFalsyCompare($exprType, $node->expr, $this->treatAsNonEmpty);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,22 +5,20 @@ 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 AbstractRector
|
||||
final class DisallowedEmptyRuleFixerRector extends AbstractFalsyScalarRuleFixerRector
|
||||
{
|
||||
public function __construct(
|
||||
private ExactCompareFactory $exactCompareFactory,
|
||||
|
@ -34,7 +32,7 @@ final class DisallowedEmptyRuleFixerRector extends AbstractRector
|
|||
'PHPStan\Rules\DisallowedConstructs\DisallowedEmptyRule'
|
||||
);
|
||||
return new RuleDefinition($errorMessage, [
|
||||
new CodeSample(
|
||||
new ConfiguredCodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
final class SomeEmptyArray
|
||||
{
|
||||
|
@ -54,6 +52,10 @@ final class SomeEmptyArray
|
|||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
[
|
||||
self::TREAT_AS_NON_EMPTY => false,
|
||||
]
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
@ -69,7 +71,7 @@ CODE_SAMPLE
|
|||
/**
|
||||
* @param Empty_|BooleanNot $node
|
||||
*/
|
||||
public function refactor(Node $node)
|
||||
public function refactor(Node $node): Expr|null
|
||||
{
|
||||
$scope = $node->getAttribute(AttributeKey::SCOPE);
|
||||
if (! $scope instanceof Scope) {
|
||||
|
@ -80,10 +82,10 @@ CODE_SAMPLE
|
|||
return $this->refactorBooleanNot($node, $scope);
|
||||
}
|
||||
|
||||
return $this->refactorEmpty($node, $scope);
|
||||
return $this->refactorEmpty($node, $scope, $this->treatAsNonEmpty);
|
||||
}
|
||||
|
||||
private function refactorBooleanNot(BooleanNot $booleanNot, Scope $scope): NotIdentical|Identical|Instanceof_|null
|
||||
private function refactorBooleanNot(BooleanNot $booleanNot, Scope $scope): Expr|null
|
||||
{
|
||||
if (! $booleanNot->expr instanceof Empty_) {
|
||||
return null;
|
||||
|
@ -92,12 +94,16 @@ 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(Empty_ $empty, Scope $scope): ?Identical
|
||||
private function refactorEmpty(Empty_ $empty, Scope $scope, bool $treatAsNonEmpty): Expr|null
|
||||
{
|
||||
$exprType = $scope->getType($empty->expr);
|
||||
return $this->exactCompareFactory->createIdenticalFalsyCompare($exprType, $empty->expr);
|
||||
return $this->exactCompareFactory->createIdenticalFalsyCompare($exprType, $empty->expr, $treatAsNonEmpty);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,12 +5,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;
|
||||
|
||||
/**
|
||||
|
@ -20,7 +21,7 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
|||
*
|
||||
* @see \Rector\Tests\Strict\Rector\If_\BooleanInIfConditionRuleFixerRector\BooleanInIfConditionRuleFixerRectorTest
|
||||
*/
|
||||
final class BooleanInIfConditionRuleFixerRector extends AbstractRector
|
||||
final class BooleanInIfConditionRuleFixerRector extends AbstractFalsyScalarRuleFixerRector
|
||||
{
|
||||
public function __construct(
|
||||
private ExactCompareFactory $exactCompareFactory
|
||||
|
@ -34,7 +35,7 @@ final class BooleanInIfConditionRuleFixerRector extends AbstractRector
|
|||
'PHPStan\Rules\BooleansInConditions\BooleanInIfConditionRule'
|
||||
);
|
||||
return new RuleDefinition($errorMessage, [
|
||||
new CodeSample(
|
||||
new ConfiguredCodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
final class NegatedString
|
||||
{
|
||||
|
@ -62,6 +63,10 @@ final class NegatedString
|
|||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
[
|
||||
self::TREAT_AS_NON_EMPTY => false,
|
||||
]
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
@ -86,7 +91,11 @@ 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;
|
||||
}
|
||||
|
@ -96,9 +105,11 @@ CODE_SAMPLE
|
|||
$elseifCondExprType = $scope->getType($elseif->cond);
|
||||
$notIdentical = $this->exactCompareFactory->createNotIdenticalFalsyCompare(
|
||||
$elseifCondExprType,
|
||||
$elseif->cond
|
||||
$elseif->cond,
|
||||
$this->treatAsNonEmpty
|
||||
);
|
||||
if ($notIdentical === null) {
|
||||
|
||||
if (! $notIdentical instanceof Expr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,10 +8,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;
|
||||
|
||||
/**
|
||||
|
@ -20,7 +20,7 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
|||
*
|
||||
* @see \Rector\Tests\Strict\Rector\Ternary\BooleanInTernaryOperatorRuleFixerRector\BooleanInTernaryOperatorRuleFixerRectorTest
|
||||
*/
|
||||
final class BooleanInTernaryOperatorRuleFixerRector extends AbstractRector
|
||||
final class BooleanInTernaryOperatorRuleFixerRector extends AbstractFalsyScalarRuleFixerRector
|
||||
{
|
||||
public function __construct(
|
||||
private ExactCompareFactory $exactCompareFactory
|
||||
|
@ -34,7 +34,7 @@ final class BooleanInTernaryOperatorRuleFixerRector extends AbstractRector
|
|||
'PHPStan\Rules\BooleansInConditions\BooleanInTernaryOperatorRule'
|
||||
);
|
||||
return new RuleDefinition($errorMessage, [
|
||||
new CodeSample(
|
||||
new ConfiguredCodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
final class ArrayCompare
|
||||
{
|
||||
|
@ -54,6 +54,10 @@ final class ArrayCompare
|
|||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
[
|
||||
self::TREAT_AS_NON_EMPTY => false,
|
||||
]
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
@ -83,7 +87,11 @@ CODE_SAMPLE
|
|||
|
||||
$exprType = $scope->getType($node->cond);
|
||||
|
||||
$falsyIdentical = $this->exactCompareFactory->createNotIdenticalFalsyCompare($exprType, $node->cond);
|
||||
$falsyIdentical = $this->exactCompareFactory->createNotIdenticalFalsyCompare(
|
||||
$exprType,
|
||||
$node->cond,
|
||||
$this->treatAsNonEmpty
|
||||
);
|
||||
if (! $falsyIdentical instanceof Expr) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -5,13 +5,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;
|
||||
|
||||
/**
|
||||
|
@ -20,7 +21,7 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
|||
*
|
||||
* @see \Rector\Tests\Strict\Rector\Ternary\DisallowedShortTernaryRuleFixerRector\DisallowedShortTernaryRuleFixerRectorTest
|
||||
*/
|
||||
final class DisallowedShortTernaryRuleFixerRector extends AbstractRector
|
||||
final class DisallowedShortTernaryRuleFixerRector extends AbstractFalsyScalarRuleFixerRector
|
||||
{
|
||||
public function __construct(
|
||||
private ExactCompareFactory $exactCompareFactory,
|
||||
|
@ -34,7 +35,7 @@ final class DisallowedShortTernaryRuleFixerRector extends AbstractRector
|
|||
'PHPStan\Rules\DisallowedConstructs\DisallowedShortTernaryRule'
|
||||
);
|
||||
return new RuleDefinition($errorMessage, [
|
||||
new CodeSample(
|
||||
new ConfiguredCodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
final class ShortTernaryArray
|
||||
{
|
||||
|
@ -54,6 +55,10 @@ final class ShortTernaryArray
|
|||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
[
|
||||
self::TREAT_AS_NON_EMPTY => false,
|
||||
]
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
@ -88,13 +93,17 @@ CODE_SAMPLE
|
|||
}
|
||||
|
||||
$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 Expr) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$node->if = $node->cond;
|
||||
$node->cond = $falsyIdentical;
|
||||
$node->cond = $compareExpr;
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
@ -108,10 +117,11 @@ CODE_SAMPLE
|
|||
|
||||
$falsyCompareExpr = $this->exactCompareFactory->createNotIdenticalFalsyCompare(
|
||||
$firstArgType,
|
||||
$firstArgValue
|
||||
$firstArgValue,
|
||||
$this->treatAsNonEmpty
|
||||
);
|
||||
|
||||
if ($falsyCompareExpr === null) {
|
||||
if (! $falsyCompareExpr instanceof Expr) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user