Fix nullsafe transpile (#6101)

Co-authored-by: Tomas Votruba <tomas.vot@gmail.com>
This commit is contained in:
Rob Landers 2021-04-15 21:16:27 +02:00 committed by GitHub
parent b8071fb7bc
commit 27f3544e8e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 13 deletions

View File

@ -4930,8 +4930,8 @@ Change nullsafe operator to ternary operator rector
```diff
-$dateAsString = $booking->getStartDate()?->asDateTimeString();
-$dateAsString = $booking->startDate?->dateTimeString;
+$dateAsString = $booking->getStartDate() ? $booking->getStartDate()->asDateTimeString() : null;
+$dateAsString = $booking->startDate ? $booking->startDate->dateTimeString : null;
+$dateAsString = ($_ = $booking->getStartDate()) ? $_->asDateTimeString() : null;
+$dateAsString = ($_ = $booking->startDate) ? $_->dateTimeString : null;
```
<br>

View File

@ -17,6 +17,12 @@ class Fixture
// all are property fetch
$dateAsString = $booking->getStartDate?->asDateTimeString;
$getStartDate = true;
$bookingGetStartDate = true;
// previously named vars aren't reused
$dateAsString = $booking->getStartDate?->asDateTimeString;
}
}
@ -31,16 +37,22 @@ class Fixture
public function run($booking)
{
// with argument
$dateAsString = $booking->getStartDate($args1) ? $booking->getStartDate($args1)->asDateTimeString($arg2) : null;
$dateAsString = ($getStartDate = $booking->getStartDate($args1)) ? $getStartDate->asDateTimeString($arg2) : null;
// without argument, one is method call, next property fetch
$dateAsString = $booking->getStartDate() ? $booking->getStartDate()->asDateTimeString : null;
$dateAsString = ($getStartDate = $booking->getStartDate()) ? $getStartDate->asDateTimeString : null;
// without argument, one is property call, next method fetch
$dateAsString = $booking->getStartDate ? $booking->getStartDate->asDateTimeString() : null;
$dateAsString = ($bookingGetStartDate = $booking->getStartDate) ? $bookingGetStartDate->asDateTimeString() : null;
// all are property fetch
$dateAsString = $booking->getStartDate ? $booking->getStartDate->asDateTimeString : null;
$dateAsString = ($bookingGetStartDate = $booking->getStartDate) ? $bookingGetStartDate->asDateTimeString : null;
$getStartDate = true;
$bookingGetStartDate = true;
// previously named vars aren't reused
$dateAsString = ($bookingGetStartDate2 = $booking->getStartDate) ? $bookingGetStartDate2->asDateTimeString : null;
}
}

View File

@ -21,8 +21,8 @@ class MultipleCall
{
public function run($object)
{
$result = ($object->multiple($args1) ? $object->multiple($args1)->call($args2) : null) ? ($object->multiple($args1) ? $object->multiple($args1)->call($args2) : null)->otherCall($args3) : null;
$result = (($object->multiple($args1) ? $object->multiple($args1)->call($args2) : null) ? ($object->multiple($args1) ? $object->multiple($args1)->call($args2) : null)->otherCall($args3) : null) ? (($object->multiple($args1) ? $object->multiple($args1)->call($args2) : null) ? ($object->multiple($args1) ? $object->multiple($args1)->call($args2) : null)->otherCall($args3) : null)->anotherCall($args4) : null;
$result = ($call = ($multiple = $object->multiple($args1)) ? $multiple->call($args2) : null) ? $call->otherCall($args3) : null;
$result = ($otherCall = ($call = ($multiple = $object->multiple($args1)) ? $multiple->call($args2) : null) ? $call->otherCall($args3) : null) ? $otherCall->anotherCall($args4) : null;
}
}

View File

@ -5,12 +5,15 @@ declare(strict_types=1);
namespace Rector\DowngradePhp80\Rector\NullsafeMethodCall;
use PhpParser\Node;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\NullsafeMethodCall;
use PhpParser\Node\Expr\NullsafePropertyFetch;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\Ternary;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\Php70\NodeAnalyzer\VariableNaming;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -19,6 +22,16 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
*/
final class DowngradeNullsafeToTernaryOperatorRector extends AbstractRector
{
/**
* @var VariableNaming
*/
public $variableNaming;
public function __construct(VariableNaming $variableNaming)
{
$this->variableNaming = $variableNaming;
}
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition('Change nullsafe operator to ternary operator rector', [
@ -29,8 +42,8 @@ $dateAsString = $booking->startDate?->dateTimeString;
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
$dateAsString = $booking->getStartDate() ? $booking->getStartDate()->asDateTimeString() : null;
$dateAsString = $booking->startDate ? $booking->startDate->dateTimeString : null;
$dateAsString = ($bookingGetStartDate = $booking->getStartDate()) ? $bookingGetStartDate->asDateTimeString() : null;
$dateAsString = ($bookingGetStartDate = $booking->startDate) ? $bookingGetStartDate->dateTimeString : null;
CODE_SAMPLE
),
]);
@ -49,10 +62,12 @@ CODE_SAMPLE
*/
public function refactor(Node $node): ?Node
{
$tempVarName = $this->variableNaming->resolveFromNodeWithScopeCountAndFallbackName($node->var, $node->getAttribute(AttributeKey::SCOPE), '_');
$tempVar = new Node\Expr\Variable($tempVarName);
$called = $node instanceof NullsafeMethodCall
? new MethodCall($node->var, $node->name, $node->args)
: new PropertyFetch($node->var, $node->name);
? new MethodCall($tempVar, $node->name, $node->args)
: new PropertyFetch($tempVar, $node->name);
return new Ternary($node->var, $called, $this->nodeFactory->createNull());
return new Ternary(new Assign($tempVar, $node->var), $called, $this->nodeFactory->createNull());
}
}