Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove getDoctrine*() methods from PhpDocInfo, use getByType() instead #1935

Merged
merged 1 commit into from
Aug 31, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .phpstorm.meta.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
// $container->get(Type::class) → instance of "Type"
override(\Psr\Container\ContainerInterface::get(0), type(0));

// $propertyPhpDocInfo->getByType(Type::class) → instance of "Type"|null - @todo how to make this nullable?
override(\Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo::getByType(0), type(0));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nikic Do you have any tip how to teach PHPStorm nullable type?

I tried variations of ↓... but no success

-type(0)
+type(0)|null

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately this isn't supported right now. PhpStorm itself doesn't do much in terms of nullability analysis, so the missing null type probably won't result in false positive warnings at least.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, feature then, thank you 👍

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


// PhpStorm 2019.1 - add argument autocomplete
// https://blog.jetbrains.com/phpstorm/2019/02/new-phpstorm-meta-php-features/
expectedArguments(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use PhpParser\Node;
use PhpParser\Node\Stmt\Class_;
use Rector\Architecture\Tests\Rector\Class_\RemoveRepositoryFromEntityAnnotationRector\RemoveRepositoryFromEntityAnnotationRectorTest;
use Rector\DoctrinePhpDocParser\Ast\PhpDoc\Class_\EntityTagValueNode;
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockManipulator;
use Rector\Rector\AbstractRector;
use Rector\RectorDefinition\CodeSample;
Expand Down Expand Up @@ -73,7 +74,7 @@ public function refactor(Node $node): ?Node

$phpDocInfo = $this->docBlockManipulator->createPhpDocInfoFromNode($node);

$doctrineEntityTag = $phpDocInfo->getDoctrineEntity();
$doctrineEntityTag = $phpDocInfo->getByType(EntityTagValueNode::class);
if ($doctrineEntityTag === null) {
return null;
}
Expand Down
53 changes: 1 addition & 52 deletions packages/BetterPhpDocParser/src/PhpDocInfo/PhpDocInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,6 @@
use Rector\BetterPhpDocParser\Attributes\Ast\PhpDoc\AttributeAwareVarTagValueNode;
use Rector\BetterPhpDocParser\Attributes\Attribute\Attribute;
use Rector\BetterPhpDocParser\Attributes\Contract\Ast\AttributeAwareNodeInterface;
use Rector\DoctrinePhpDocParser\Ast\PhpDoc\Class_\EntityTagValueNode;
use Rector\DoctrinePhpDocParser\Ast\PhpDoc\Property_\IdTagValueNode;
use Rector\DoctrinePhpDocParser\Ast\PhpDoc\Property_\JoinColumnTagValueNode;
use Rector\DoctrinePhpDocParser\Ast\PhpDoc\Property_\ManyToManyTagValueNode;
use Rector\DoctrinePhpDocParser\Ast\PhpDoc\Property_\ManyToOneTagValueNode;
use Rector\DoctrinePhpDocParser\Ast\PhpDoc\Property_\OneToManyTagValueNode;
use Rector\DoctrinePhpDocParser\Ast\PhpDoc\Property_\OneToOneTagValueNode;
use Rector\DoctrinePhpDocParser\Ast\PhpDoc\Property_\TableTagValueNode;
use Rector\DoctrinePhpDocParser\Contract\Ast\PhpDoc\DoctrineRelationTagValueNodeInterface;

final class PhpDocInfo
Expand Down Expand Up @@ -176,46 +168,6 @@ public function getVarTypes(): array
return $this->getResolvedTypesAttribute($varTagValue);
}

public function getDoctrineId(): ?IdTagValueNode
{
return $this->getByType(IdTagValueNode::class);
}

public function getDoctrineTable(): ?TableTagValueNode
{
return $this->getByType(TableTagValueNode::class);
}

public function getDoctrineManyToMany(): ?ManyToManyTagValueNode
{
return $this->getByType(ManyToManyTagValueNode::class);
}

public function getDoctrineManyToOne(): ?ManyToOneTagValueNode
{
return $this->getByType(ManyToOneTagValueNode::class);
}

public function getDoctrineOneToOne(): ?OneToOneTagValueNode
{
return $this->getByType(OneToOneTagValueNode::class);
}

public function getDoctrineOneToMany(): ?OneToManyTagValueNode
{
return $this->getByType(OneToManyTagValueNode::class);
}

public function getDoctrineEntity(): ?EntityTagValueNode
{
return $this->getByType(EntityTagValueNode::class);
}

public function getDoctrineJoinColumnTagValueNode(): ?JoinColumnTagValueNode
{
return $this->getByType(JoinColumnTagValueNode::class);
}

/**
* @return string[]
*/
Expand Down Expand Up @@ -257,10 +209,7 @@ public function getReturnTypes(): array

public function getDoctrineRelationTagValueNode(): ?DoctrineRelationTagValueNodeInterface
{
return $this->getDoctrineManyToMany() ??
$this->getDoctrineOneToMany() ??
$this->getDoctrineOneToOne() ??
$this->getDoctrineManyToOne() ?? null;
return $this->getByType(DoctrineRelationTagValueNodeInterface::class);
}

public function removeTagValueNodeFromNode(PhpDocTagValueNode $phpDocTagValueNode): void
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Property;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\DoctrinePhpDocParser\Ast\PhpDoc\Class_\EntityTagValueNode;
use Rector\DoctrinePhpDocParser\Ast\PhpDoc\Property_\ColumnTagValueNode;
use Rector\DoctrinePhpDocParser\Ast\PhpDoc\Property_\IdTagValueNode;
use Rector\DoctrinePhpDocParser\Ast\PhpDoc\Property_\TableTagValueNode;
use Rector\DoctrinePhpDocParser\Contract\Ast\PhpDoc\DoctrineRelationTagValueNodeInterface;
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockManipulator;
Expand All @@ -30,7 +32,7 @@ public function isDoctrineEntityClass(Class_ $class): bool
return false;
}

return (bool) $classPhpDocInfo->getDoctrineEntity();
return (bool) $classPhpDocInfo->getByType(EntityTagValueNode::class);
}

public function isDoctrineEntityClassWithIdProperty(Class_ $class): bool
Expand Down Expand Up @@ -69,7 +71,7 @@ public function hasPropertyDoctrineIdTag(Property $property): bool
return false;
}

return (bool) $propertyPhpDocInfo->getDoctrineId();
return (bool) $propertyPhpDocInfo->getByType(IdTagValueNode::class);
}

public function getDoctrineRelationTagValueNode(Property $property): ?DoctrineRelationTagValueNodeInterface
Expand All @@ -89,7 +91,7 @@ public function getDoctrineTableTagValueNode(Class_ $class): ?TableTagValueNode
return null;
}

return $classPhpDocInfo->getDoctrineTable();
return $classPhpDocInfo->getByType(TableTagValueNode::class);
}

public function isDoctrineProperty(Property $property): bool
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\Doctrine\PhpDocParser\DoctrineDocBlockResolver;
use Rector\DoctrinePhpDocParser\Ast\PhpDoc\Property_\ColumnTagValueNode;
use Rector\DoctrinePhpDocParser\Ast\PhpDoc\Property_\IdTagValueNode;
use Rector\NodeContainer\ParsedNodesByType;
use Rector\PhpParser\Node\Manipulator\ClassManipulator;
use Rector\PhpParser\Node\Resolver\NameResolver;
Expand Down Expand Up @@ -111,12 +112,11 @@ private function isPropertyClassIdWithUuidType(Property $property): bool
{
$propertyPhpDocInfo = $this->phpDocInfoFactory->createFromNode($property);

$idTagValueNode = $propertyPhpDocInfo->getDoctrineId();
$idTagValueNode = $propertyPhpDocInfo->getByType(IdTagValueNode::class);
if ($idTagValueNode === null) {
return false;
}

/** @var ColumnTagValueNode|null $columnTagValueNode */
$columnTagValueNode = $propertyPhpDocInfo->getByType(ColumnTagValueNode::class);
if ($columnTagValueNode === null) {
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Rector\Doctrine\PhpDocParser\Ast\PhpDoc\PhpDocTagNodeFactory;
use Rector\Doctrine\Provider\EntityWithMissingUuidProvider;
use Rector\Doctrine\Uuid\JoinTableNameResolver;
use Rector\DoctrinePhpDocParser\Ast\PhpDoc\Property_\JoinColumnTagValueNode;
use Rector\DoctrinePhpDocParser\Contract\Ast\PhpDoc\DoctrineRelationTagValueNodeInterface;
use Rector\DoctrinePhpDocParser\Contract\Ast\PhpDoc\ToManyTagNodeInterface;
use Rector\DoctrinePhpDocParser\Contract\Ast\PhpDoc\ToOneTagNodeInterface;
Expand Down Expand Up @@ -148,8 +149,7 @@ private function updateDocComment(Property $property): void

private function refactorToManyPropertyPhpDocInfo(PhpDocInfo $propertyPhpDocInfo, Property $property): void
{
$doctrineJoinColumnTagValueNode = $propertyPhpDocInfo->getDoctrineJoinColumnTagValueNode();

$doctrineJoinColumnTagValueNode = $propertyPhpDocInfo->getByType(JoinColumnTagValueNode::class);
if ($doctrineJoinColumnTagValueNode) {
// replace @ORM\JoinColumn with @ORM\JoinTable
$propertyPhpDocInfo->removeTagValueNodeFromNode($doctrineJoinColumnTagValueNode);
Expand All @@ -161,7 +161,7 @@ private function refactorToManyPropertyPhpDocInfo(PhpDocInfo $propertyPhpDocInfo

private function refactorToOnePropertyPhpDocInfo(PhpDocInfo $propertyPhpDocInfo): void
{
$joinColumnTagValueNode = $propertyPhpDocInfo->getDoctrineJoinColumnTagValueNode();
$joinColumnTagValueNode = $propertyPhpDocInfo->getByType(JoinColumnTagValueNode::class);

if ($joinColumnTagValueNode) {
$joinColumnTagValueNode->changeNullable(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ private function resolveTemplateName(ClassMethod $classMethod): string
/** @var PhpDocInfo $classMethodPhpDocInfo */
$classMethodPhpDocInfo = $this->getPhpDocInfo($classMethod);

/** @var TemplateTagValueNode|null $templateTagValueNode */
$templateTagValueNode = $classMethodPhpDocInfo->getByType(TemplateTagValueNode::class);
if ($templateTagValueNode === null) {
throw new ShouldNotHappenException(__METHOD__);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,17 @@ public function inferProperty(Property $property): array

$phpDocInfo = $this->docBlockManipulator->createPhpDocInfoFromNode($property);

/** @var ColumnTagValueNode|null $doctrineColumnTagValueNode */
$doctrineColumnTagValueNode = $phpDocInfo->getByType(ColumnTagValueNode::class);
if ($doctrineColumnTagValueNode === null) {
return [];
}

$scalarType = $this->doctrineTypeToScalarType[$doctrineColumnTagValueNode->getType()] ?? null;
$type = $doctrineColumnTagValueNode->getType();
if ($type === null) {
return [];
}

$scalarType = $this->doctrineTypeToScalarType[$type] ?? null;
if ($scalarType === null) {
return [];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public function inferProperty(Property $property): array
if ($relationTagValueNode instanceof ToManyTagNodeInterface) {
return $this->processToManyRelation($relationTagValueNode);
} elseif ($relationTagValueNode instanceof ToOneTagNodeInterface) {
$joinColumnTagValueNode = $phpDocInfo->getDoctrineJoinColumnTagValueNode();
$joinColumnTagValueNode = $phpDocInfo->getByType(JoinColumnTagValueNode::class);
return $this->processToOneRelation($relationTagValueNode, $joinColumnTagValueNode);
}

Expand Down
5 changes: 4 additions & 1 deletion utils/PHPStanExtensions/config/phpstan-extensions.neon
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
services:
- Rector\PHPStanExtensions\Utils\PHPStanValueResolver

# $node->geAttribute($1) => Type|null by $1
# $node->getAttribute($1) => Type|null by $1
- { class: Rector\PHPStanExtensions\Rector\Type\GetAttributeReturnTypeExtension, tags: [phpstan.broker.dynamicMethodReturnTypeExtension] }

# $nameResolver->getName() => in some cases always string
Expand All @@ -11,3 +11,6 @@ services:

# $betterNodeFinder->findByInstance(..., $1) => $1[]
- { class: Rector\PHPStanExtensions\Rector\Type\BetterNodeFinderReturnTypeExtension, tags: [phpstan.broker.dynamicMethodReturnTypeExtension] }

# $phpDocInfo->getByType($1) => Type|null by $1
- { class: Rector\PHPStanExtensions\Rector\Type\PhpDocInfoGetByTypeReturnTypeExtension, tags: [phpstan.broker.dynamicMethodReturnTypeExtension] }
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php declare(strict_types=1);

namespace Rector\PHPStanExtensions\Rector\Type;

use PhpParser\Node\Expr;
use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Expr\MethodCall;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Type\DynamicMethodReturnTypeExtension;
use PHPStan\Type\NullType;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;
use PHPStan\Type\UnionType;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;

final class PhpDocInfoGetByTypeReturnTypeExtension implements DynamicMethodReturnTypeExtension
{
public function getClass(): string
{
return PhpDocInfo::class;
}

public function isMethodSupported(MethodReflection $methodReflection): bool
{
return $methodReflection->getName() === 'getByType';
}

public function getTypeFromMethodCall(
MethodReflection $methodReflection,
MethodCall $methodCall,
Scope $scope
): Type {
$returnType = $this->resolveArgumentValue($methodCall->args[0]->value);

return new UnionType([new ObjectType($returnType), new NullType()]);
}

private function resolveArgumentValue(Expr $expr): ?string
{
if ($expr instanceof ClassConstFetch) {
if ((string) $expr->name !== 'class') {
return null;
}

return $expr->class->toString();
}

return null;
}
}