Skip to content

Commit

Permalink
[Downgrade] [PHP 7.3] Downgrade trailing commas in function calls (#4796
Browse files Browse the repository at this point in the history
)

Co-authored-by: Tommy Quissens <tommy.quissens@storefront.be>
Co-authored-by: rector-bot <tomas@getrector.org>
  • Loading branch information
3 people committed Dec 5, 2020
1 parent c85ee2d commit 8bfb36d
Show file tree
Hide file tree
Showing 11 changed files with 203 additions and 36 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"jean85/pretty-package-versions": "^1.5.1",
"nette/robot-loader": "^3.2",
"nette/utils": "^3.1",
"nikic/php-parser": "4.10.2",
"nikic/php-parser": "4.10.3",
"phpstan/phpdoc-parser": "^0.4.9",
"phpstan/phpstan": "^0.12.52",
"phpstan/phpstan-phpunit": "^0.12.16",
Expand Down
2 changes: 2 additions & 0 deletions config/set/downgrade-php73.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
declare(strict_types=1);

use Rector\Downgrade\Rector\LNumber\ChangePhpVersionInPlatformCheckRector;
use Rector\DowngradePhp73\Rector\FuncCall\DowngradeTrailingCommasInFunctionCallsRector;
use Rector\DowngradePhp73\Rector\List_\DowngradeListReferenceAssignmentRector;
use Rector\DowngradePhp73\Rector\String_\DowngradeFlexibleHeredocSyntaxRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
Expand All @@ -15,4 +16,5 @@
->call('configure', [[
ChangePhpVersionInPlatformCheckRector::TARGET_PHP_VERSION => 70300,
]]);
$services->set(DowngradeTrailingCommasInFunctionCallsRector::class);
};
5 changes: 5 additions & 0 deletions packages/node-type-resolver/src/Node/AttributeKey.php
Original file line number Diff line number Diff line change
Expand Up @@ -227,4 +227,9 @@ final class AttributeKey
* @var string
*/
public const IS_FRESH_NODE = 'is_fresh_node';

/**
* @var string
*/
public const FUNC_ARGS_TRAILING_COMMA = 'trailing_comma';
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
use PhpParser\Node\NullableType;
use PhpParser\Node\Param;
use PhpParser\Node\Stmt\ClassMethod;
use PHPStan\Type\NullType as PHPStanNullType;
use PHPStan\Type\ObjectType as PHPStanObjectType;
use PHPStan\Type\UnionType as PHPStanUnionType;
use PHPStan\Type\NullType;
use PHPStan\Type\ObjectType;
use PHPStan\Type\UnionType;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\Rector\AbstractRector;
Expand Down Expand Up @@ -112,15 +112,20 @@ public function refactor(Node $node): ?Node
return $node;
}

private function isDateTimeParam(Param $param): bool
{
return $this->nodeTypeResolver->isObjectTypeOrNullableObjectType($param, DateTime::class);
}

private function refactorParamTypeHint(Param $param): void
{
$dateTimeInterfaceType = new FullyQualified(DateTimeInterface::class);
$fullyQualified = new FullyQualified(DateTimeInterface::class);
if ($param->type instanceof NullableType) {
$param->type = new NullableType($dateTimeInterfaceType);
$param->type = new NullableType($fullyQualified);
return;
}

$param->type = $dateTimeInterfaceType;
$param->type = $fullyQualified;
}

private function refactorParamDocBlock(Param $param, ClassMethod $classMethod): void
Expand All @@ -131,16 +136,16 @@ private function refactorParamDocBlock(Param $param, ClassMethod $classMethod):
$phpDocInfo = $this->phpDocInfoFactory->createEmpty($classMethod);
}

$types = [new PHPStanObjectType(DateTime::class), new PHPStanObjectType(DateTimeImmutable::class)];
$types = [new ObjectType(DateTime::class), new ObjectType(DateTimeImmutable::class)];
if ($param->type instanceof NullableType) {
$types[] = new PHPStanNullType();
$types[] = new NullType();
}

$paramName = $this->getName($param->var);
if ($paramName === null) {
throw new ShouldNotHappenException();
}
$phpDocInfo->changeParamType(new PHPStanUnionType($types), $param, $paramName);
$phpDocInfo->changeParamType(new UnionType($types), $param, $paramName);
}

private function refactorMethodCalls(Param $param, ClassMethod $classMethod): void
Expand All @@ -165,16 +170,16 @@ private function refactorMethodCall(Param $param, MethodCall $methodCall): void
return;
}

$newAssignNode = new Assign(new Variable($paramName), $methodCall);
$assign = new Assign(new Variable($paramName), $methodCall);

/** @var Node $parentNode */
$parentNode = $methodCall->getAttribute(AttributeKey::PARENT_NODE);
if ($parentNode instanceof Arg) {
$parentNode->value = $newAssignNode;
$parentNode->value = $assign;
return;
}

$parentNode->expr = $newAssignNode;
$parentNode->expr = $assign;
}

private function shouldSkipMethodCallRefactor(string $paramName, MethodCall $methodCall): bool
Expand All @@ -194,9 +199,4 @@ private function shouldSkipMethodCallRefactor(string $paramName, MethodCall $met

return $parentNode instanceof Assign;
}

private function isDateTimeParam(Param $param): bool
{
return $this->nodeTypeResolver->isObjectTypeOrNullableObjectType($param, DateTime::class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

declare(strict_types=1);

namespace Rector\DowngradePhp73\Rector\FuncCall;

use PhpParser\Node;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\StaticCall;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

/**
* @see \Rector\DowngradePhp73\Tests\Rector\FuncCall\DowngradeTrailingCommasInFunctionCallsRector\DowngradeTrailingCommasInFunctionCallsRectorTest
*/
final class DowngradeTrailingCommasInFunctionCallsRector extends AbstractRector
{
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition(
'Remove trailing commas in function calls', [
new CodeSample(
<<<'CODE_SAMPLE'
class SomeClass
{
public function __construct(string $value)
{
$compacted = compact(
'posts',
'units',
);
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
class SomeClass
{
public function __construct(string $value)
{
$compacted = compact(
'posts',
'units'
);
}
}
CODE_SAMPLE
),
]
);
}

/**
* @return string[]
*/
public function getNodeTypes(): array
{
return [FuncCall::class, MethodCall::class, StaticCall::class];
}

/**
* @param FuncCall|MethodCall|StaticCall $node
*/
public function refactor(Node $node): ?Node
{
if ($node->args) {
$node->setAttribute(AttributeKey::ORIGINAL_NODE, null);
$last = $node->args[array_key_last($node->args)];
$last->setAttribute(AttributeKey::FUNC_ARGS_TRAILING_COMMA, false);
}

return $node;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace Rector\DowngradePhp73\Tests\Rector\FuncCall\DowngradeTrailingCommasInFunctionCallsRector;

use Iterator;
use Rector\DowngradePhp73\Rector\FuncCall\DowngradeTrailingCommasInFunctionCallsRector;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
use Symplify\SmartFileSystem\SmartFileInfo;

final class DowngradeTrailingCommasInFunctionCallsRectorTest extends AbstractRectorTestCase
{
/**
* @requires PHP >= 7.3
* @dataProvider provideData()
*/
public function test(SmartFileInfo $fileInfo): void
{
$this->doTestFileInfo($fileInfo);
}

public function provideData(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
}

protected function getRectorClass(): string
{
return DowngradeTrailingCommasInFunctionCallsRector::class;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace Rector\DowngradePhp73\Tests\Rector\FuncCall\DowngradeTrailingCommasInFunctionCallsRector\Fixture;

class FixtureClass
{
public function run()
{
compact('posts','units',);
$this->setData('posts','units',);
self::run('posts','units',);
self::run('posts',
'units',);

$this->setOnClick("[Zip ID: {$modelid}] {$e->getMessage($modelId,)}",);
}
}

?>
-----
<?php

namespace Rector\DowngradePhp73\Tests\Rector\FuncCall\DowngradeTrailingCommasInFunctionCallsRector\Fixture;

class FixtureClass
{
public function run()
{
compact('posts', 'units');
$this->setData('posts', 'units');
self::run('posts', 'units');
self::run('posts', 'units');

$this->setOnClick("[Zip ID: {$modelid}] {{$e->getMessage($modelId)}}");
}
}

?>
Original file line number Diff line number Diff line change
Expand Up @@ -154,18 +154,6 @@ public function refactor(Node $node): ?Node
return null;
}

private function removeExistingConnectionParameter(FuncCall $funcCall): void
{
/** @var string $functionName */
$functionName = $this->getName($funcCall);
if (! isset(self::FUNCTION_CONNECTION_PARAMETER_POSITION_MAP[$functionName])) {
return;
}

$connectionPosition = self::FUNCTION_CONNECTION_PARAMETER_POSITION_MAP[$functionName];
unset($funcCall->args[$connectionPosition]);
}

private function isProbablyMysql(Node $node): bool
{
if ($this->isObjectType($node, 'mysqli')) {
Expand Down Expand Up @@ -199,6 +187,18 @@ private function findConnectionVariable(FuncCall $funcCall): ?Expr
return $connectionAssign !== null ? $connectionAssign->var : null;
}

private function removeExistingConnectionParameter(FuncCall $funcCall): void
{
/** @var string $functionName */
$functionName = $this->getName($funcCall);
if (! isset(self::FUNCTION_CONNECTION_PARAMETER_POSITION_MAP[$functionName])) {
return;
}

$connectionPosition = self::FUNCTION_CONNECTION_PARAMETER_POSITION_MAP[$functionName];
unset($funcCall->args[$connectionPosition]);
}

private function isUnionTypeWithResourceSubType(Type $staticType, ResourceType $resourceType): bool
{
if ($staticType instanceof UnionType) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,6 @@ private function shouldSkip(ClassMethod $classMethod): bool
if (! $this->isName($classMethod, MethodName::SET_STATE)) {
return true;
}

if ($classMethod->isStatic()) {
return true;
}

return false;
return $classMethod->isStatic();
}
}
16 changes: 16 additions & 0 deletions src/PhpParser/Printer/BetterStandardPrinter.php
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,22 @@ protected function pScalar_EncapsedStringPart(EncapsedStringPart $encapsedString
return '`' . $encapsedStringPart->value . '`';
}

protected function pCommaSeparated(array $nodes): string
{
$result = parent::pCommaSeparated($nodes);

$last = end($nodes);

if ($last instanceof Node) {
$trailingComma = $last->getAttribute(AttributeKey::FUNC_ARGS_TRAILING_COMMA);
if ($trailingComma === false) {
$result = rtrim($result, ',');
}
}

return $result;
}

/**
* @param Node[] $stmts
* @return Node[]|mixed[]
Expand Down
3 changes: 3 additions & 0 deletions src/ValueObject/PhpVersionFeature.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ final class PhpVersionFeature
*/
public const ELVIS_OPERATOR = 50300;

/**
* @var int
*/
public const DATE_TIME_INTERFACE = 50500;

/**
Expand Down

0 comments on commit 8bfb36d

Please sign in to comment.