Skip to content

Commit

Permalink
Remove dynamic type checks #3 (#5942)
Browse files Browse the repository at this point in the history
  • Loading branch information
TomasVotruba authored Mar 21, 2021
1 parent ae1c6b9 commit 4f27f39
Show file tree
Hide file tree
Showing 54 changed files with 232 additions and 170 deletions.
15 changes: 10 additions & 5 deletions packages/BetterPhpDocParser/PhpDocInfo/PhpDocInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
use Rector\Core\Configuration\CurrentNodeProvider;
use Rector\Core\Exception\NotImplementedYetException;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\Util\StaticInstanceOf;
use Rector\StaticTypeMapper\StaticTypeMapper;

/**
Expand Down Expand Up @@ -486,16 +485,21 @@ private function getTypeOrMixed(?PhpDocTagValueNode $phpDocTagValueNode): Type
return $this->staticTypeMapper->mapPHPStanPhpDocTypeToPHPStanType($phpDocTagValueNode, $this->node);
}

/**
* @param class-string $type
*/
private function ensureTypeIsTagValueNode(string $type, string $location): void
{
/** @var array<class-string> $desiredTypes */
/** @var array<class-string<\PhpParser\Node>> $desiredTypes */
$desiredTypes = array_merge([
PhpDocTagValueNode::class,
PhpDocTagNode::class,
], NodeTypes::TYPE_AWARE_NODES);

if (StaticInstanceOf::isOneOf($type, $desiredTypes)) {
return;
foreach ($desiredTypes as $desiredType) {
if (is_a($type, $desiredType, true)) {
return;
}
}

throw new ShouldNotHappenException(sprintf(
Expand All @@ -509,7 +513,8 @@ private function ensureTypeIsTagValueNode(string $type, string $location): void
private function resolveNameForPhpDocTagValueNode(PhpDocTagValueNode $phpDocTagValueNode): string
{
foreach (self::TAGS_TYPES_TO_NAMES as $tagValueNodeType => $name) {
if ($phpDocTagValueNode instanceof $tagValueNodeType) {
/** @var class-string<PhpDocTagNode> $tagValueNodeType */
if (is_a($phpDocTagValueNode, $tagValueNodeType, true)) {
return $name;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ public function findClassConstant(string $className, string $constantName): ?Cla
public function isCollectableNode(Node $node): bool
{
foreach (self::COLLECTABLE_NODE_TYPES as $collectableNodeType) {
/** @var class-string<Node> $collectableNodeType */
if (is_a($node, $collectableNodeType, true)) {
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
use PHPStan\Type\Type;
use PHPStan\Type\TypeWithClassName;
use PHPStan\Type\UnionType;
use Rector\Core\Util\StaticInstanceOf;
use Rector\Core\Util\StaticNodeInstanceOf;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\NodeTypeResolver;

Expand Down Expand Up @@ -55,7 +55,7 @@ public function collect(Node $node): void
}

// make sure name is valid
if (StaticInstanceOf::isOneOf($node->name, [StaticCall::class, MethodCall::class])) {
if (StaticNodeInstanceOf::isOneOf($node->name, [StaticCall::class, MethodCall::class])) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

interface NodeNameResolverInterface
{
/**
* @return class-string<Node>
*/
public function getNode(): string;

public function resolve(Node $node): ?string;
Expand Down
4 changes: 2 additions & 2 deletions packages/NodeNameResolver/NodeNameResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
use Rector\Core\Contract\Rector\RectorInterface;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\PhpParser\Printer\BetterStandardPrinter;
use Rector\Core\Util\StaticInstanceOf;
use Rector\Core\Util\StaticNodeInstanceOf;
use Rector\NodeNameResolver\Contract\NodeNameResolverInterface;
use Rector\NodeNameResolver\Regex\RegexPatternDetector;
use Rector\NodeTypeResolver\FileSystem\CurrentFileInfoProvider;
Expand Down Expand Up @@ -220,7 +220,7 @@ public function matchNameFromMap(Node $node, array $renameMap): ?string

private function isCallOrIdentifier(Node $node): bool
{
return StaticInstanceOf::isOneOf($node, [MethodCall::class, StaticCall::class, Identifier::class]);
return StaticNodeInstanceOf::isOneOf($node, [MethodCall::class, StaticCall::class, Identifier::class]);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ public function autowireClassConstFetchNameResolver(NodeNameResolver $nodeNameRe
$this->nodeNameResolver = $nodeNameResolver;
}

/**
* @return class-string<Node>
*/
public function getNode(): string
{
return ClassConstFetch::class;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ public function autowireClassConstNameResolver(NodeNameResolver $nodeNameResolve
$this->nodeNameResolver = $nodeNameResolver;
}

/**
* @return class-string<Node>
*/
public function getNode(): string
{
return ClassConst::class;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ public function autowireClassNameResolver(NodeNameResolver $nodeNameResolver): v
$this->nodeNameResolver = $nodeNameResolver;
}

/**
* @return class-string<Node>
*/
public function getNode(): string
{
return ClassLike::class;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@

final class EmptyNameResolver implements NodeNameResolverInterface
{
/**
* @return class-string<Node>
*/
public function getNode(): string
{
return Empty_::class;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ public function __construct(ReflectionProvider $reflectionProvider)
$this->reflectionProvider = $reflectionProvider;
}

/**
* @return class-string<Node>
*/
public function getNode(): string
{
return FuncCall::class;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@

final class FunctionNameResolver implements NodeNameResolverInterface
{
/**
* @return class-string<Node>
*/
public function getNode(): string
{
return Function_::class;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ public function __construct(FuncCallNameResolver $funcCallNameResolver)
$this->funcCallNameResolver = $funcCallNameResolver;
}

/**
* @return class-string<Node>
*/
public function getNode(): string
{
return Name::class;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ public function autowireParamNameResolver(NodeNameResolver $nodeNameResolver): v
$this->nodeNameResolver = $nodeNameResolver;
}

/**
* @return class-string<Node>
*/
public function getNode(): string
{
return Param::class;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ public function autowirePropertyNameResolver(NodeNameResolver $nodeNameResolver)
$this->nodeNameResolver = $nodeNameResolver;
}

/**
* @return class-string<Node>
*/
public function getNode(): string
{
return Property::class;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ public function autowireUseNameResolver(NodeNameResolver $nodeNameResolver): voi
$this->nodeNameResolver = $nodeNameResolver;
}

/**
* @return class-string<Node>
*/
public function getNode(): string
{
return Use_::class;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@

final class VariableNameResolver implements NodeNameResolverInterface
{
/**
* @return class-string<Node>
*/
public function getNode(): string
{
return Variable::class;
Expand Down
4 changes: 2 additions & 2 deletions packages/NodeNestingScope/ContextAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
use PhpParser\Node\Stmt\Switch_;
use PhpParser\Node\Stmt\While_;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\Core\Util\StaticInstanceOf;
use Rector\Core\Util\StaticNodeInstanceOf;

final class ContextAnalyzer
{
Expand Down Expand Up @@ -49,7 +49,7 @@ public function isInLoop(Node $node): bool
return false;
}

return StaticInstanceOf::isOneOf($firstParent, self::LOOP_NODES);
return StaticNodeInstanceOf::isOneOf($firstParent, self::LOOP_NODES);
}

public function isInIf(Node $node): bool
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,11 @@ public function findParentType(Node $node, array $allowedTypes): ?Node

/**
* Find node based on $callable or null, when the nesting scope is broken
* @param class-string[] $allowedTypes
* @param array<class-string<Node>> $allowedTypes
*/
public function findParent(Node $node, callable $callable, array $allowedTypes): ?Node
{
/** @var array<class-string<Node>> $parentNestingBreakTypes */
$parentNestingBreakTypes = array_diff(ControlStructure::BREAKING_SCOPE_NODE_TYPES, $allowedTypes);

$this->isBreakingNodeFoundFirst = false;
Expand Down
4 changes: 2 additions & 2 deletions packages/PostRector/Collector/NodesToAddCollector.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
use Rector\ChangesReporting\Collector\RectorChangeCollector;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\Core\Util\StaticInstanceOf;
use Rector\Core\Util\StaticNodeInstanceOf;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\PostRector\Contract\Collector\NodeCollectorInterface;

Expand Down Expand Up @@ -128,7 +128,7 @@ public function addNodesBeforeNode(array $newNodes, Node $positionNode): void

private function resolveNearestExpressionPosition(Node $node): string
{
if (StaticInstanceOf::isOneOf($node, [Expression::class, Stmt::class])) {
if (StaticNodeInstanceOf::isOneOf($node, [Expression::class, Stmt::class])) {
return spl_object_hash($node);
}

Expand Down
16 changes: 10 additions & 6 deletions packages/StaticTypeMapper/StaticTypeMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
use PHPStan\Type\MixedType;
use PHPStan\Type\Type;
use Rector\Core\Exception\NotImplementedYetException;
use Rector\Core\Util\StaticInstanceOf;
use Rector\PHPStanStaticTypeMapper\PHPStanStaticTypeMapper;
use Rector\StaticTypeMapper\Mapper\PhpParserNodeMapper;
use Rector\StaticTypeMapper\Naming\NameScopeFactory;
Expand Down Expand Up @@ -99,11 +98,16 @@ public function mapPHPStanPhpDocTypeToPHPStanType(PhpDocTagValueNode $phpDocTagV

return $this->phpDocTypeMapper->mapToPHPStanType($phpDocTagValueNode->bound, $node, $nameScope);
}

if (StaticInstanceOf::isOneOf(
$phpDocTagValueNode,
[ReturnTagValueNode::class, ParamTagValueNode::class, VarTagValueNode::class, ThrowsTagValueNode::class]
)) {
if ($phpDocTagValueNode instanceof ReturnTagValueNode) {
return $this->mapPHPStanPhpDocTypeNodeToPHPStanType($phpDocTagValueNode->type, $node);
}
if ($phpDocTagValueNode instanceof ParamTagValueNode) {
return $this->mapPHPStanPhpDocTypeNodeToPHPStanType($phpDocTagValueNode->type, $node);
}
if ($phpDocTagValueNode instanceof VarTagValueNode) {
return $this->mapPHPStanPhpDocTypeNodeToPHPStanType($phpDocTagValueNode->type, $node);
}
if ($phpDocTagValueNode instanceof ThrowsTagValueNode) {
return $this->mapPHPStanPhpDocTypeNodeToPHPStanType($phpDocTagValueNode->type, $node);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

namespace Rector\StaticTypeMapper\ValueObject\Type;

use PHPStan\TrinaryLogic;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;

final class ShortenedObjectType extends ObjectType
{
Expand All @@ -23,6 +25,12 @@ public function __construct(string $shortName, string $fullyQualifiedName)
$this->fullyQualifiedName = $fullyQualifiedName;
}

public function isSuperTypeOf(Type $type): TrinaryLogic
{
$fullyQualifiedObjectType = new ObjectType($this->fullyQualifiedName);
return $fullyQualifiedObjectType->isSuperTypeOf($type);
}

public function getShortName(): string
{
return $this->getClassName();
Expand Down
10 changes: 7 additions & 3 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -519,12 +519,16 @@ parameters:
message: '#Do not inherit from abstract class, better use composition#'
path: utils/phpstan-extensions/src/Rule/NoInstanceOfStaticReflectionRule.php

# first wave resolved, merge PR
- '#Instead of "(.*?)" use ReflectionProvider service (.*?) for static reflection to work#'

# known internal types on correct location
-
message: '#Instead of "(.*?)" use ReflectionProvider service (.*?) for static reflection to work#'
paths:
- src/Application/RectorApplication.php
- src/Console/Command/ProcessCommand.php

# annotations
-
message: '#Instead of "instanceof/is_a\(\)" use ReflectionProvider service or "\(new ObjectType\(<desired_type\>\)\)\-\>isSuperTypeOf\(<element_type\>\)" for static reflection to work#'
paths:
- packages/BetterPhpDocParser/AnnotationReader/NodeAnnotationReader.php
- packages/BetterPhpDocParser/PhpDocNodeFactory/*NodeFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ use Rector\Tests\Transform\Rector\ClassMethod\SingleToManyMethodRector\Source\On

class SomeClass implements OneToManyInterface
{
/**
* @return class-string<\PhpParser\Node>
*/
public function getNode(): string
{
return 'Echo_';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ use Rector\Tests\Transform\Rector\ClassMethod\SingleToManyMethodRector\Source\On

class MultiReturn implements OneToManyInterface
{
/**
* @return class-string<\PhpParser\Node>
*/
public function getNode(): string
{
if (true) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ use Rector\Tests\Transform\Rector\ClassMethod\SingleToManyMethodRector\Source\On

class ReturnClassConstFetch implements OneToManyInterface
{
/**
* @return class-string<\PhpParser\Node>
*/
public function getNode(): string
{
return self::class;
Expand Down
4 changes: 2 additions & 2 deletions rules/CodeQuality/NodeAnalyzer/ForAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
use Rector\Core\NodeManipulator\AssignManipulator;
use Rector\Core\PhpParser\Comparing\NodeComparator;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\Core\Util\StaticInstanceOf;
use Rector\Core\Util\StaticNodeInstanceOf;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;

Expand Down Expand Up @@ -105,7 +105,7 @@ public function isLoopMatch(array $loopExprs, ?string $keyValueName): bool

/** @var PreInc|PostInc $prePostInc */
$prePostInc = $loopExprs[0];
if (StaticInstanceOf::isOneOf($prePostInc, [PreInc::class, PostInc::class])) {
if (StaticNodeInstanceOf::isOneOf($prePostInc, [PreInc::class, PostInc::class])) {
return $this->nodeNameResolver->isName($prePostInc->var, $keyValueName);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
use PhpParser\Node\Stmt\Return_;
use Rector\Core\NodeManipulator\ForeachManipulator;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\Util\StaticInstanceOf;
use Rector\Core\Util\StaticNodeInstanceOf;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
Expand Down Expand Up @@ -127,7 +127,7 @@ private function matchReturnOrAssignNode(Foreach_ $foreach): ?Node
}

$innerNode = $node->stmts[0] instanceof Expression ? $node->stmts[0]->expr : $node->stmts[0];
if (StaticInstanceOf::isOneOf($innerNode, [Assign::class, Return_::class])) {
if (StaticNodeInstanceOf::isOneOf($innerNode, [Assign::class, Return_::class])) {
return $innerNode;
}

Expand Down
Loading

0 comments on commit 4f27f39

Please sign in to comment.