Skip to content

Commit

Permalink
[Php81] Handle non-dynamic + dynamic args (non-array, non-scalar) pas…
Browse files Browse the repository at this point in the history
…sed to New_ on NewInInitializerRector (#1737)
  • Loading branch information
samsonasik committed Jan 28, 2022
1 parent 79dd9bb commit 73f5fc1
Show file tree
Hide file tree
Showing 14 changed files with 414 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace Rector\Tests\Php81\Rector\ClassMethod\NewInInitializerRector\Fixture;

use DateTime;
use DateTimeZone;

class PassNonDynamicArg
{
private DateTime $dateTime;

public function __construct(
?DateTime $dateTime = null
) {
$this->dateTime = $dateTime ?? new DateTime('now', new DateTimeZone('Asia/Jakarta'));
}
}

?>
-----
<?php

namespace Rector\Tests\Php81\Rector\ClassMethod\NewInInitializerRector\Fixture;

use DateTime;
use DateTimeZone;

class PassNonDynamicArg
{
public function __construct(private DateTime $dateTime = new DateTime('now', new DateTimeZone('Asia/Jakarta')))
{
}
}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace Rector\Tests\Php81\Rector\ClassMethod\NewInInitializerRector\Fixture;

class SomeClass
{
private Logger $logger;

public function __construct(
?Logger $logger = null,
) {
$this->logger = $logger ?? new NullLogger(['a' => 'b']);
}
}

?>
-----
<?php

namespace Rector\Tests\Php81\Rector\ClassMethod\NewInInitializerRector\Fixture;

class SomeClass
{
public function __construct(private Logger $logger = new NullLogger(['a' => 'b']))
{
}
}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace Rector\Tests\Php81\Rector\ClassMethod\NewInInitializerRector\Fixture;

class SomeClass
{
private Logger $logger;

public function __construct(
?Logger $logger = null,
) {
$this->logger = $logger ?? new NullLogger(['b']);
}
}

?>
-----
<?php

namespace Rector\Tests\Php81\Rector\ClassMethod\NewInInitializerRector\Fixture;

class SomeClass
{
public function __construct(private Logger $logger = new NullLogger(['b']))
{
}
}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace Rector\Tests\Php81\Rector\ClassMethod\NewInInitializerRector\Fixture;

use stdClass;

class SomeClass
{
private Logger $logger;

public function __construct(
?Logger $logger = null,
) {
$this->logger = $logger ?? new NullLogger([new stdClass]);
}
}

?>
-----
<?php

namespace Rector\Tests\Php81\Rector\ClassMethod\NewInInitializerRector\Fixture;

use stdClass;

class SomeClass
{
public function __construct(private Logger $logger = new NullLogger([new stdClass]))
{
}
}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace Rector\Tests\Php81\Rector\ClassMethod\NewInInitializerRector\Fixture;

class SomeClass
{
private Logger $logger;

public function __construct(
?Logger $logger = null,
) {
$this->logger = $logger ?? new NullLogger([]);
}
}

?>
-----
<?php

namespace Rector\Tests\Php81\Rector\ClassMethod\NewInInitializerRector\Fixture;

class SomeClass
{
public function __construct(private Logger $logger = new NullLogger([]))
{
}
}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace Rector\Tests\Php81\Rector\ClassMethod\NewInInitializerRector\Fixture;

class SomeClass
{
private Logger $logger;

public function __construct(
?Logger $logger = null,
) {
$this->logger = $logger ?? new NullLogger(new Db());
}
}

?>
-----
<?php

namespace Rector\Tests\Php81\Rector\ClassMethod\NewInInitializerRector\Fixture;

class SomeClass
{
public function __construct(private Logger $logger = new NullLogger(new Db()))
{
}
}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Rector\Tests\Php81\Rector\ClassMethod\NewInInitializerRector\Fixture;

class SkipNoParamConstruct
{
public function __construct()
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace Rector\Tests\Php81\Rector\ClassMethod\NewInInitializerRector\Fixture;

use DateTime;

class SkipPassDynamicArg
{
private DateTime $dateTime;

public function __construct(
?DateTime $dateTime = null
) {
$variable = 'now';
$this->dateTime = $dateTime ?? new DateTime($variable);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace Rector\Tests\Php81\Rector\ClassMethod\NewInInitializerRector\Fixture;

use DateTime;

class SkipPassDynamicArg2
{
private DateTime $dateTime;

public function __construct(
?DateTime $dateTime = null
) {
$timezone = 'Asia/Jakarta';
$this->dateTime = $dateTime ?? new DateTime('now', new DateTimeZone($timezone));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Rector\Tests\Php81\Rector\ClassMethod\NewInInitializerRector\Fixture;

class SkipPassDynamicArg3
{
private Logger $logger;

public function __construct(
?Logger $logger = null,
) {
$x = 'b';
$this->logger = $logger ?? new NullLogger(['a' => $x]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Rector\Tests\Php81\Rector\ClassMethod\NewInInitializerRector\Fixture;

class SkipPassDynamicArg4
{
private Logger $logger;

public function __construct(
?Logger $logger = null,
) {
$x = 'b';
$this->logger = $logger ?? new NullLogger([$x => 'a']);
}
}
83 changes: 83 additions & 0 deletions rules/Php81/NodeAnalyzer/ComplexNewAnalyzer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php

declare(strict_types=1);

namespace Rector\Php81\NodeAnalyzer;

use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Expr\New_;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Scalar;
use Rector\Core\NodeAnalyzer\ExprAnalyzer;

final class ComplexNewAnalyzer
{
public function __construct(
private readonly ExprAnalyzer $exprAnalyzer
) {
}

public function isDynamic(New_ $new): bool
{
if (! $new->class instanceof FullyQualified) {
return true;
}

$args = $new->getArgs();

foreach ($args as $arg) {
$value = $arg->value;

if ($this->isAllowedNew($value)) {
continue;
}

if ($value instanceof Array_ && $this->isAllowedArray($value)) {
continue;
}

if ($value instanceof Scalar) {
continue;
}

return true;
}

return false;
}

private function isAllowedNew(Expr $expr): bool
{
if ($expr instanceof New_) {
return ! $this->isDynamic($expr);
}

return false;
}

private function isAllowedArray(Array_ $array): bool
{
if (! $this->exprAnalyzer->isDynamicArray($array)) {
return true;
}

$arrayItems = $array->items;
foreach ($arrayItems as $arrayItem) {
if (! $arrayItem instanceof ArrayItem) {
continue;
}

if (! $arrayItem->value instanceof New_) {
return false;
}

if ($this->isDynamic($arrayItem->value)) {
return false;
}
}

return true;
}
}
Loading

0 comments on commit 73f5fc1

Please sign in to comment.