Skip to content

Commit

Permalink
[DX] Decouple PropertyTypeDecorator (#1055)
Browse files Browse the repository at this point in the history
  • Loading branch information
TomasVotruba committed Oct 25, 2021
1 parent 8e2908c commit b305c4e
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 38 deletions.
22 changes: 14 additions & 8 deletions rules/DowngradePhp74/Rector/Array_/DowngradeArraySpreadRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -189,17 +189,23 @@ private function createArrayItems(Array_ $array): array
*/
private function createArrayMerge(Array_ $array, array $items): FuncCall
{
/** @var Scope $nodeScope */
$nodeScope = $array->getAttribute(AttributeKey::SCOPE);
return new FuncCall(new Name('array_merge'), array_map(function (ArrayItem $item) use ($nodeScope): Arg {
if ($item !== null && $item->unpack) {
/** @var Scope $scope */
$scope = $array->getAttribute(AttributeKey::SCOPE);

$args = array_map(function (ArrayItem|null $arrayItem) use ($scope): Arg {
if ($arrayItem === null) {
throw new ShouldNotHappenException();
}

if ($arrayItem->unpack) {
// Do not unpack anymore
$item->unpack = false;
return $this->createArgFromSpreadArrayItem($nodeScope, $item);
$arrayItem->unpack = false;
return $this->createArgFromSpreadArrayItem($scope, $arrayItem);
}

return new Arg($item);
}, $items));
return new Arg($arrayItem);
}, $items);
return new FuncCall(new Name('array_merge'), $args);
}

/**
Expand Down
6 changes: 5 additions & 1 deletion rules/Naming/Naming/PropertyNaming.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use PHPStan\Type\StaticType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeWithClassName;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Naming\RectorNamingInflector;
use Rector\Naming\ValueObject\ExpectedName;
use Rector\NodeTypeResolver\NodeTypeResolver;
Expand Down Expand Up @@ -204,8 +205,11 @@ private function fqnToShortName(string $fqn): string
return $fqn;
}

/** @var string $lastNamePart */
$lastNamePart = Strings::after($fqn, '\\', - 1);
if (! is_string($lastNamePart)) {
throw new ShouldNotHappenException();
}

if (\str_ends_with($lastNamePart, self::INTERFACE)) {
return Strings::substring($lastNamePart, 0, - strlen(self::INTERFACE));
}
Expand Down
7 changes: 6 additions & 1 deletion rules/Naming/PhpArray/ArrayFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace Rector\Naming\PhpArray;

use Rector\Core\Exception\ShouldNotHappenException;

final class ArrayFilter
{
/**
Expand All @@ -23,7 +25,10 @@ public function filterWithAtLeastTwoOccurences(array $values): array
continue;
}

/** @var string $value */
if (! is_string($value)) {
throw new ShouldNotHappenException();
}

$duplicatedValues[] = $value;
}

Expand Down
51 changes: 51 additions & 0 deletions src/NodeDecorator/PropertyTypeDecorator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

namespace Rector\Core\NodeDecorator;

use PhpParser\Node\Stmt\Property;
use PHPStan\Type\Generic\GenericObjectType;
use PHPStan\Type\Type;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger;
use Rector\Core\Php\PhpVersionProvider;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\PHPStanStaticTypeMapper\ValueObject\TypeKind;
use Rector\StaticTypeMapper\StaticTypeMapper;

final class PropertyTypeDecorator
{
public function __construct(
private PhpDocInfoFactory $phpDocInfoFactory,
private PhpVersionProvider $phpVersionProvider,
private StaticTypeMapper $staticTypeMapper,
private PhpDocTypeChanger $phpDocTypeChanger,
) {
}

public function decorate(Property $property, ?Type $type): void
{
if ($type === null) {
return;
}

$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);

if ($this->phpVersionProvider->isAtLeastPhpVersion(PhpVersionFeature::TYPED_PROPERTIES)) {
$phpParserType = $this->staticTypeMapper->mapPHPStanTypeToPhpParserNode($type, TypeKind::PROPERTY());

if ($phpParserType !== null) {
$property->type = $phpParserType;

if ($type instanceof GenericObjectType) {
$this->phpDocTypeChanger->changeVarType($phpDocInfo, $type);
}

return;
}
}

$this->phpDocTypeChanger->changeVarType($phpDocInfo, $type);
}
}
32 changes: 4 additions & 28 deletions src/PhpParser/Node/NodeFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@
use PHPStan\PhpDocParser\Ast\PhpDoc\GenericTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Type\Generic\GenericObjectType;
use PHPStan\Type\MixedType;
use PHPStan\Type\Type;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger;
use Rector\Core\Configuration\CurrentNodeProvider;
use Rector\Core\Exception\NotImplementedYetException;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\NodeDecorator\PropertyTypeDecorator;
use Rector\Core\Php\PhpVersionProvider;
use Rector\Core\PhpParser\AstResolver;
use Rector\Core\ValueObject\MethodName;
Expand Down Expand Up @@ -103,6 +103,7 @@ public function __construct(
private PhpDocTypeChanger $phpDocTypeChanger,
private CurrentNodeProvider $currentNodeProvider,
private AstResolver $reflectionAstResolver,
private PropertyTypeDecorator $propertyTypeDecorator
) {
}

Expand Down Expand Up @@ -223,7 +224,7 @@ public function createPublicInjectPropertyFromNameAndType(string $name, ?Type $t

$property = $propertyBuilder->getNode();

$this->addPropertyType($property, $type);
$this->propertyTypeDecorator->decorate($property, $type);

// add @inject
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
Expand All @@ -238,7 +239,7 @@ public function createPrivatePropertyFromNameAndType(string $name, ?Type $type):
$propertyBuilder->makePrivate();

$property = $propertyBuilder->getNode();
$this->addPropertyType($property, $type);
$this->propertyTypeDecorator->decorate($property, $type);

return $property;
}
Expand Down Expand Up @@ -630,31 +631,6 @@ private function normalizeArgValue($value)
return $value;
}

private function addPropertyType(Property $property, ?Type $type): void
{
if ($type === null) {
return;
}

$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);

if ($this->phpVersionProvider->isAtLeastPhpVersion(PhpVersionFeature::TYPED_PROPERTIES)) {
$phpParserType = $this->staticTypeMapper->mapPHPStanTypeToPhpParserNode($type, TypeKind::PROPERTY());

if ($phpParserType !== null) {
$property->type = $phpParserType;

if ($type instanceof GenericObjectType) {
$this->phpDocTypeChanger->changeVarType($phpDocInfo, $type);
}

return;
}
}

$this->phpDocTypeChanger->changeVarType($phpDocInfo, $type);
}

private function createClassPart(string $class): Name | FullyQualified
{
if (in_array($class, self::REFERENCES, true)) {
Expand Down

0 comments on commit b305c4e

Please sign in to comment.