[DowngradePhp72] Add DowngradePregUnmatchedAsNullConstantRector (#6021)

Co-authored-by: kaizen-ci <info@kaizen-ci.org>
This commit is contained in:
Abdul Malik Ikhsan 2021-04-04 18:40:55 +07:00 committed by GitHub
parent b2412ad62a
commit 6fe05c462c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 894 additions and 0 deletions

View File

@ -6,6 +6,7 @@ use Rector\Core\Configuration\Option;
use Rector\Core\ValueObject\PhpVersion;
use Rector\DowngradePhp72\Rector\ClassMethod\DowngradeParameterTypeWideningRector;
use Rector\DowngradePhp72\Rector\FunctionLike\DowngradeObjectTypeDeclarationRector;
use Rector\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
@ -15,4 +16,5 @@ return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(DowngradeObjectTypeDeclarationRector::class);
$services->set(DowngradeParameterTypeWideningRector::class);
$services->set(DowngradePregUnmatchedAsNullConstantRector::class);
};

View File

@ -114,6 +114,7 @@ parameters:
- rules/CodeQualityStrict/Rector/Variable/MoveVariableDeclarationNearReferenceRector.php
- rules/Php80/Rector/If_/NullsafeOperatorRector.php
- rules/Renaming/NodeManipulator/ClassRenamer.php
- rules/DowngradePhp72/Rector/FuncCall/DowngradePregUnmatchedAsNullConstantRector.php
- "#^Cognitive complexity for \"Rector\\\\Php70\\\\EregToPcreTransformer\\:\\:(.*?)\" is (.*?), keep it under 9$#"
- '#Cognitive complexity for "Rector\\CodeQuality\\Rector\\If_\\SimplifyIfIssetToNullCoalescingRector\:\:shouldSkip\(\)" is 10, keep it under 9#'

View File

@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector;
use Iterator;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
use Symplify\SmartFileSystem\SmartFileInfo;
final class DowngradePregUnmatchedAsNullConstantRectorTest extends AbstractRectorTestCase
{
/**
* @requires PHP 7.2
* @dataProvider provideData()
*/
public function test(SmartFileInfo $fileInfo): void
{
$this->doTestFileInfo($fileInfo);
}
/**
* @return Iterator<SmartFileInfo>
*/
public function provideData(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
}
public function provideConfigFilePath(): string
{
return __DIR__ . '/config/configured_rule.php';
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace Rector\Tests\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector\Fixture;
class ClassConstant
{
public const PREG_UNMATCHED_AS_NULL = \PREG_UNMATCHED_AS_NULL;
}
?>
-----
<?php
namespace Rector\Tests\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector\Fixture;
class ClassConstant
{
public const PREG_UNMATCHED_AS_NULL = 512;
}
?>

View File

@ -0,0 +1,44 @@
<?php
namespace Rector\Tests\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector\Fixture;
class ComplexInIf
{
public function run()
{
$match = (\PREG_PATTERN_ORDER | \PREG_SET_ORDER) & $flags ? 'preg_match_all' : 'preg_match';
try {
if (\false === $match($regexp, $this->string, $matches, $flags | \PREG_UNMATCHED_AS_NULL, $offset)) {
}
} catch (\Exception $e) {
}
}
}
?>
-----
<?php
namespace Rector\Tests\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector\Fixture;
class ComplexInIf
{
public function run()
{
$match = (\PREG_PATTERN_ORDER | \PREG_SET_ORDER) & $flags ? 'preg_match_all' : 'preg_match';
try {
if (\false === $match($regexp, $this->string, $matches, $flags, $offset)) {
}
array_walk_recursive($matches, function (&$value) {
if ($value === '') {
$value = null;
}
});
} catch (\Exception $e) {
}
}
}
?>

View File

@ -0,0 +1,46 @@
<?php
namespace Rector\Tests\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector\Fixture;
class ComplexInIf3
{
public function run()
{
$match = (\PREG_PATTERN_ORDER | \PREG_SET_ORDER) & $flags ? 'preg_match_all' : 'preg_match';
try {
if (\false === $match($regexp, $this->string, $matches, $flags | \PREG_UNMATCHED_AS_NULL, $offset)) {
echo 'statement';
}
} catch (\Exception $e) {
}
}
}
?>
-----
<?php
namespace Rector\Tests\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector\Fixture;
class ComplexInIf3
{
public function run()
{
$match = (\PREG_PATTERN_ORDER | \PREG_SET_ORDER) & $flags ? 'preg_match_all' : 'preg_match';
try {
if (\false === $match($regexp, $this->string, $matches, $flags, $offset)) {
echo 'statement';
}
array_walk_recursive($matches, function (&$value) {
if ($value === '') {
$value = null;
}
});
} catch (\Exception $e) {
}
}
}
?>

View File

@ -0,0 +1,46 @@
<?php
namespace Rector\Tests\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector\Fixture;
class ComplexInIf3
{
public function run()
{
$match = (\PREG_PATTERN_ORDER | \PREG_SET_ORDER) & $flags ? 'preg_match_all' : 'preg_match';
try {
if ($match($regexp, $this->string, $matches, $flags | \PREG_UNMATCHED_AS_NULL, $offset)) {
echo 'statement';
}
} catch (\Exception $e) {
}
}
}
?>
-----
<?php
namespace Rector\Tests\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector\Fixture;
class ComplexInIf3
{
public function run()
{
$match = (\PREG_PATTERN_ORDER | \PREG_SET_ORDER) & $flags ? 'preg_match_all' : 'preg_match';
try {
if ($match($regexp, $this->string, $matches, $flags, $offset)) {
array_walk_recursive($matches, function (&$value) {
if ($value === '') {
$value = null;
}
});
echo 'statement';
}
} catch (\Exception $e) {
}
}
}
?>

View File

@ -0,0 +1,42 @@
<?php
namespace Rector\Tests\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector\Fixture;
class ComplexInIfDirectCall
{
public function run()
{
try {
if (preg_match_all($regexp, $this->string, $matches, $flags | \PREG_UNMATCHED_AS_NULL, $offset)) {
}
} catch (\Exception $e) {
}
}
}
?>
-----
<?php
namespace Rector\Tests\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector\Fixture;
class ComplexInIfDirectCall
{
public function run()
{
try {
if (preg_match_all($regexp, $this->string, $matches, $flags, $offset)) {
array_walk_recursive($matches, function (&$value) {
if ($value === '') {
$value = null;
}
});
}
} catch (\Exception $e) {
}
}
}
?>

View File

@ -0,0 +1,42 @@
<?php
namespace Rector\Tests\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector\Fixture;
class ComplexInIfNegation
{
public function run()
{
try {
if (!preg_match_all($regexp, $this->string, $matches, $flags | \PREG_UNMATCHED_AS_NULL, $offset)) {
}
} catch (\Exception $e) {
}
}
}
?>
-----
<?php
namespace Rector\Tests\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector\Fixture;
class ComplexInIfNegation
{
public function run()
{
try {
if (!preg_match_all($regexp, $this->string, $matches, $flags, $offset)) {
}
array_walk_recursive($matches, function (&$value) {
if ($value === '') {
$value = null;
}
});
} catch (\Exception $e) {
}
}
}
?>

View File

@ -0,0 +1,32 @@
<?php
namespace Rector\Tests\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector\Fixture;
class Fixture
{
public function run()
{
preg_match('/(a)(b)*(c)/', 'ac', $matches, PREG_UNMATCHED_AS_NULL);
}
}
?>
-----
<?php
namespace Rector\Tests\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector\Fixture;
class Fixture
{
public function run()
{
preg_match('/(a)(b)*(c)/', 'ac', $matches);
array_walk_recursive($matches, function (&$value) {
if ($value === '') {
$value = null;
}
});
}
}
?>

View File

@ -0,0 +1,32 @@
<?php
namespace Rector\Tests\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector\Fixture;
class FqnConstant
{
public function run()
{
preg_match('/(a)(b)*(c)/', 'ac', $matches, $flags | \PREG_OFFSET_CAPTURE | \PREG_UNMATCHED_AS_NULL);
}
}
?>
-----
<?php
namespace Rector\Tests\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector\Fixture;
class FqnConstant
{
public function run()
{
preg_match('/(a)(b)*(c)/', 'ac', $matches, $flags | \PREG_OFFSET_CAPTURE);
array_walk_recursive($matches, function (&$value) {
if ($value === '') {
$value = null;
}
});
}
}
?>

View File

@ -0,0 +1,32 @@
<?php
namespace Rector\Tests\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector\Fixture;
class PregMatchAll
{
public function run()
{
preg_match_all('/(a)(b)*(c)/', 'ac', $matches, PREG_UNMATCHED_AS_NULL);
}
}
?>
-----
<?php
namespace Rector\Tests\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector\Fixture;
class PregMatchAll
{
public function run()
{
preg_match_all('/(a)(b)*(c)/', 'ac', $matches);
array_walk_recursive($matches, function (&$value) {
if ($value === '') {
$value = null;
}
});
}
}
?>

View File

@ -0,0 +1,14 @@
<?php
namespace Rector\Tests\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector\Fixture;
class SkipDifferentFlag
{
public function run()
{
preg_match('/(a)(b)*(c)/', 'ac', $matches, PREG_OFFSET_CAPTURE);
}
}
?>

View File

@ -0,0 +1,14 @@
<?php
namespace Rector\Tests\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector\Fixture;
class SkipNoFlag
{
public function run()
{
preg_match('/(a)(b)*(c)/', 'ac', $matches);
}
}
?>

View File

@ -0,0 +1,14 @@
<?php
namespace Rector\Tests\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector\Fixture;
class SkipNotRegexFunctions
{
public function run()
{
strlen('test');
}
}
?>

View File

@ -0,0 +1,32 @@
<?php
namespace Rector\Tests\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector\Fixture;
class WithFlags2
{
public function run()
{
preg_match('/(a)(b)*(c)/', 'ac', $matches, $flags | PREG_OFFSET_CAPTURE | PREG_UNMATCHED_AS_NULL);
}
}
?>
-----
<?php
namespace Rector\Tests\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector\Fixture;
class WithFlags2
{
public function run()
{
preg_match('/(a)(b)*(c)/', 'ac', $matches, $flags | PREG_OFFSET_CAPTURE);
array_walk_recursive($matches, function (&$value) {
if ($value === '') {
$value = null;
}
});
}
}
?>

View File

@ -0,0 +1,32 @@
<?php
namespace Rector\Tests\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector\Fixture;
class WithFlags2
{
public function run()
{
preg_match('/(a)(b)*(c)/', 'ac', $matches, $flags | PREG_UNMATCHED_AS_NULL | PREG_OFFSET_CAPTURE);
}
}
?>
-----
<?php
namespace Rector\Tests\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector\Fixture;
class WithFlags2
{
public function run()
{
preg_match('/(a)(b)*(c)/', 'ac', $matches, $flags | PREG_OFFSET_CAPTURE);
array_walk_recursive($matches, function (&$value) {
if ($value === '') {
$value = null;
}
});
}
}
?>

View File

@ -0,0 +1,32 @@
<?php
namespace Rector\Tests\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector\Fixture;
class WithFlags3
{
public function run()
{
preg_match('/(a)(b)*(c)/', 'ac', $matches, PREG_OFFSET_CAPTURE | PREG_UNMATCHED_AS_NULL);
}
}
?>
-----
<?php
namespace Rector\Tests\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector\Fixture;
class WithFlags3
{
public function run()
{
preg_match('/(a)(b)*(c)/', 'ac', $matches, PREG_OFFSET_CAPTURE);
array_walk_recursive($matches, function (&$value) {
if ($value === '') {
$value = null;
}
});
}
}
?>

View File

@ -0,0 +1,32 @@
<?php
namespace Rector\Tests\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector\Fixture;
class WithFlags4
{
public function run()
{
preg_match('/(a)(b)*(c)/', 'ac', $matches, PREG_OFFSET_CAPTURE | PREG_UNMATCHED_AS_NULL | $flag | $anotherFlag);
}
}
?>
-----
<?php
namespace Rector\Tests\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector\Fixture;
class WithFlags4
{
public function run()
{
preg_match('/(a)(b)*(c)/', 'ac', $matches, PREG_OFFSET_CAPTURE | $flag | $anotherFlag);
array_walk_recursive($matches, function (&$value) {
if ($value === '') {
$value = null;
}
});
}
}
?>

View File

@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
use Rector\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(DowngradePregUnmatchedAsNullConstantRector::class);
};

View File

@ -0,0 +1,338 @@
<?php
declare(strict_types=1);
namespace Rector\DowngradePhp72\Rector\FuncCall;
use Nette\NotImplementedException;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\BinaryOp\BitwiseOr;
use PhpParser\Node\Expr\BinaryOp\Identical;
use PhpParser\Node\Expr\BooleanNot;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\ConstFetch;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\Ternary;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Param;
use PhpParser\Node\Scalar\LNumber;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt\ClassConst;
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\If_;
use Rector\Core\Exception\NotImplementedYetException;
use Rector\Core\NodeManipulator\IfManipulator;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Tests\DowngradePhp72\Rector\FuncCall\DowngradePregUnmatchedAsNullConstantRector\DowngradePregUnmatchedAsNullConstantRectorTest
*/
final class DowngradePregUnmatchedAsNullConstantRector extends AbstractRector
{
/**
* @var string[]
*/
private const REGEX_FUNCTION_NAMES = ['preg_match', 'preg_match_all'];
/**
* @var string
*/
private const FLAG = 'PREG_UNMATCHED_AS_NULL';
/**
* @var IfManipulator
*/
private $ifManipulator;
public function __construct(IfManipulator $ifManipulator)
{
$this->ifManipulator = $ifManipulator;
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [FuncCall::class, ClassConst::class];
}
/**
* @param FuncCall|ClassConst $node
*/
public function refactor(Node $node): ?Node
{
if ($node instanceof ClassConst) {
return $this->processsClassConst($node);
}
if (! $this->isRegexFunctionNames($node)) {
return null;
}
$args = $node->args;
if (! isset($args[3])) {
return null;
}
$flags = $args[3]->value;
/** @var Variable $variable */
$variable = $args[2]->value;
if ($flags instanceof BitwiseOr) {
$this->cleanBitWiseOrFlags($node, $flags);
return $this->handleEmptyStringToNullMatch($node, $variable);
}
if (! $flags instanceof ConstFetch) {
return null;
}
if (! $this->isName($flags, self::FLAG)) {
return null;
}
$node = $this->handleEmptyStringToNullMatch($node, $variable);
unset($node->args[3]);
return $node;
}
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition(
'Remove PREG_UNMATCHED_AS_NULL from preg_match and set null value on empty string matched on each match',
[
new CodeSample(
<<<'CODE_SAMPLE'
class SomeClass
{
public function run()
{
preg_match('/(a)(b)*(c)/', 'ac', $matches, PREG_UNMATCHED_AS_NULL);
}
}
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
class SomeClass
{
public function run()
{
preg_match('/(a)(b)*(c)/', 'ac', $matches);
array_walk_recursive($matches, function (&$value) {
if ($value === '') {
$value = null;
}
});
}
}
CODE_SAMPLE
),
]
);
}
private function processsClassConst(ClassConst $classConst): ClassConst
{
foreach ($classConst->consts as $key => $singleClassConst) {
if (! $singleClassConst->value instanceof ConstFetch) {
continue;
}
if (! $this->isName($singleClassConst->value, self::FLAG)) {
continue;
}
$classConst->consts[$key]->value = new LNumber(512);
return $classConst;
}
return $classConst;
}
private function isRegexFunctionNames(FuncCall $funcCall): bool
{
if ($this->isNames($funcCall, self::REGEX_FUNCTION_NAMES)) {
return true;
}
$variable = $funcCall->name;
if (! $variable instanceof Variable) {
return false;
}
/** @var Assign|null $assignExprVariable */
$assignExprVariable = $this->betterNodeFinder->findFirstPreviousOfNode($funcCall, function (Node $node) use (
$variable
): bool {
if (! $node instanceof Assign) {
return false;
}
return $this->nodeComparator->areNodesEqual($node->var, $variable);
});
if (! $assignExprVariable instanceof Assign) {
return false;
}
$expr = $assignExprVariable->expr;
if (! $expr instanceof Ternary) {
return false;
}
if (! $expr->if instanceof String_) {
return false;
}
if (! $expr->else instanceof String_) {
return false;
}
return in_array($expr->if->value, self::REGEX_FUNCTION_NAMES, true) && in_array(
$expr->else->value,
self::REGEX_FUNCTION_NAMES,
true
);
}
private function cleanBitWiseOrFlags(FuncCall $funcCall, BitwiseOr $bitwiseOr, ?Expr $expr = null): void
{
if ($bitwiseOr->left instanceof BitwiseOr) {
/** @var BitwiseOr $leftLeft */
$leftLeft = $bitwiseOr->left;
if ($leftLeft->left instanceof ConstFetch && $this->isName($leftLeft->left, self::FLAG)) {
$bitwiseOr = new BitwiseOr($leftLeft->right, $bitwiseOr->right);
}
/** @var BitwiseOr $leftRight */
$leftRight = $bitwiseOr->left;
if ($leftRight->right instanceof ConstFetch && $this->isName($leftRight->right, self::FLAG)) {
$bitwiseOr = new BitwiseOr($leftRight->left, $bitwiseOr->right);
}
if ($bitwiseOr->left instanceof BitwiseOr) {
$this->cleanBitWiseOrFlags($funcCall, $bitwiseOr->left, $bitwiseOr->right);
return;
}
}
if ($expr instanceof Expr) {
$bitwiseOr = new BitwiseOr($bitwiseOr, $expr);
}
$this->assignThirdArgsValue($funcCall, $bitwiseOr);
}
private function assignThirdArgsValue(FuncCall $funcCall, BitwiseOr $bitwiseOr): void
{
if ($bitwiseOr instanceof BitWiseOr && $bitwiseOr->right instanceof ConstFetch && $this->isName(
$bitwiseOr->right,
self::FLAG
)) {
$bitwiseOr = $bitwiseOr->left;
}
if ($bitwiseOr instanceof BitWiseOr && $bitwiseOr->left instanceof ConstFetch && $this->isName(
$bitwiseOr->left,
self::FLAG
)) {
$bitwiseOr = $bitwiseOr->right;
}
$funcCall->args[3]->value = $bitwiseOr;
}
private function handleEmptyStringToNullMatch(FuncCall $funcCall, Variable $variable): FuncCall
{
$closure = new Closure();
$variablePass = new Variable('value');
$param = new Param($variablePass);
$param->byRef = true;
$closure->params = [$param];
$assign = new Assign($variablePass, $this->nodeFactory->createNull());
$if = $this->ifManipulator->createIfExpr(
new Identical($variablePass, new String_('')),
new Expression($assign)
);
$closure->stmts[0] = $if;
$arguments = $this->nodeFactory->createArgs([$variable, $closure]);
$replaceEmptystringToNull = $this->nodeFactory->createFuncCall('array_walk_recursive', $arguments);
return $this->processReplace($funcCall, $replaceEmptystringToNull);
}
private function processReplace(FuncCall $funcCall, FuncCall $replaceEmptystringToNull): FuncCall
{
$parent = $funcCall->getAttribute(AttributeKey::PARENT_NODE);
if ($parent instanceof Expression) {
$this->addNodeAfterNode($replaceEmptystringToNull, $funcCall);
return $funcCall;
}
if ($parent instanceof If_ && $parent->cond === $funcCall) {
return $this->processInIf($parent, $funcCall, $replaceEmptystringToNull);
}
if (! $parent instanceof Node) {
throw new NotImplementedException();
}
$if = $parent->getAttribute(AttributeKey::PARENT_NODE);
if ($parent instanceof BooleanNot) {
return $this->processInIf($if, $funcCall, $replaceEmptystringToNull);
}
if (! $parent instanceof Identical) {
throw new NotImplementedYetException();
}
if (! $if instanceof If_) {
throw new NotImplementedYetException();
}
return $this->processInIf($if, $funcCall, $replaceEmptystringToNull);
}
private function processInIf(If_ $if, FuncCall $funcCall, FuncCall $replaceEmptystringToNull): FuncCall
{
$cond = $if->cond;
if (! $cond instanceof Identical && ! $cond instanceof BooleanNot) {
$this->handleNotInIdenticalAndBooleanNot($if, $replaceEmptystringToNull);
}
if ($cond instanceof Identical) {
$valueCompare = $cond->left === $funcCall
? $cond->right
: $cond->left;
if ($this->valueResolver->isFalse($valueCompare)) {
$this->addNodeAfterNode($replaceEmptystringToNull, $if);
}
}
if ($cond instanceof BooleanNot) {
$this->addNodeAfterNode($replaceEmptystringToNull, $if);
}
return $funcCall;
}
private function handleNotInIdenticalAndBooleanNot(If_ $if, FuncCall $funcCall): void
{
if ($if->stmts !== []) {
$firstStmt = $if->stmts[0];
$this->addNodeBeforeNode($funcCall, $firstStmt);
} else {
$if->stmts[0] = new Expression($funcCall);
}
}
}