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 dynamic type checks #3 #5942

Merged
merged 1 commit into from
Mar 21, 2021
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
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