Skip to content

Commit

Permalink
[DX] Move from deprecated getStaticType() to getType() (#974)
Browse files Browse the repository at this point in the history
  • Loading branch information
TomasVotruba committed Oct 7, 2021
1 parent f6f7431 commit f2afe8e
Show file tree
Hide file tree
Showing 39 changed files with 163 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use PhpParser\Node\Name;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
use Rector\Tests\NodeTypeResolver\PerNodeTypeResolver\AbstractNodeTypeResolverTest;
use Rector\Tests\NodeTypeResolver\Source\AnotherClass;

Expand All @@ -23,7 +24,7 @@ public function test(string $file, int $nodePosition, Type $expectedType): void
{
$nameNodes = $this->getNodesForFileOfType($file, Name::class);

$resolvedType = $this->nodeTypeResolver->resolve($nameNodes[$nodePosition]);
$resolvedType = $this->nodeTypeResolver->getType($nameNodes[$nodePosition]);
$this->assertEquals($expectedType, $resolvedType);
}

Expand All @@ -32,9 +33,9 @@ public function test(string $file, int $nodePosition, Type $expectedType): void
*/
public function provideData(): Iterator
{
$expectedObjectType = new ObjectType(AnotherClass::class);
$expectedFullyQualifiedObjectType = new FullyQualifiedObjectType(AnotherClass::class);

# test new
yield [__DIR__ . '/Source/ParentCall.php', 2, $expectedObjectType];
yield [__DIR__ . '/Source/ParentCall.php', 2, $expectedFullyQualifiedObjectType];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Rector\Tests\NodeTypeResolver\PerNodeTypeResolver\PropertyFetchTypeRes

use Rector\Tests\NodeTypeResolver\PerNodeTypeResolver\PropertyFetchTypeResolver\Source\ClassWithTypedPropertyTypes;

final class NonExistingObjectType
final class SomeNonExistingObjectType
{
public function run(ClassWithTypedPropertyTypes $props): void
{
Expand Down
11 changes: 9 additions & 2 deletions packages/NodeTypeResolver/NodeTypeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,11 @@ public function getType(Node $node): Type

$type = $this->genericClassStringTypeCorrector->correct($type);

if ($type instanceof ObjectType) {
// we want to keep aliased object types
$type = $this->objectTypeSpecifier->narrowToFullyQualifiedOrAliasedObjectType($node, $type);
}

return $this->hasOffsetTypeCorrector->correct($type);
}

Expand Down Expand Up @@ -186,9 +191,7 @@ public function getType(Node $node): Type
}

$type = $scope->getType($node);

$type = $this->accessoryNonEmptyStringTypeCorrector->correct($type);

$type = $this->genericClassStringTypeCorrector->correct($type);

// hot fix for phpstan not resolving chain method calls
Expand Down Expand Up @@ -222,6 +225,10 @@ public function getNativeType(Expr $expr): Type
return $scope->getNativeType($expr);
}

/**
* @deprecated
* @see Use NodeTypeResolver::getType() instead
*/
public function getStaticType(Node $node): Type
{
if ($node instanceof Param || $node instanceof New_ || $node instanceof Return_) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public function __construct(

public function isStringOrUnionStringOnlyType(Node $node): bool
{
$nodeType = $this->nodeTypeResolver->getStaticType($node);
$nodeType = $this->nodeTypeResolver->getType($node);
if ($nodeType instanceof StringType) {
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ public function mapToPhpParserNode(Type $type, TypeKind $typeKind): ?Node
return null;
}

if ($typeKind->equals(TypeKind::PARAM())) {
return null;
}

// return type cannot be only null
if ($typeKind->equals(TypeKind::RETURN())) {
return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

declare(strict_types=1);

namespace Rector\StaticTypeMapper\ValueObject\Type;

use PHPStan\Type\ObjectType;

final class NonExistingObjectType extends ObjectType
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

declare(strict_types=1);

namespace Rector\StaticTypeMapper\ValueObject\Type;

use PHPStan\TrinaryLogic;
use PHPStan\Type\Generic\GenericObjectType;
use PHPStan\Type\Type;

final class ShortenedGenericObjectType extends GenericObjectType
{
/**
* @param class-string $fullyQualifiedName
*/
public function __construct(
string $shortName,
array $types,
private string $fullyQualifiedName
) {
parent::__construct($shortName, $types);
}

public function isSuperTypeOf(Type $type): TrinaryLogic
{
$genericObjectType = new GenericObjectType($this->fullyQualifiedName, $this->getTypes());
return $genericObjectType->isSuperTypeOf($type);
}

public function getShortName(): string
{
return $this->getClassName();
}

/**
* @return class-string
*/
public function getFullyQualifiedName(): string
{
return $this->fullyQualifiedName;
}
}
4 changes: 4 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -514,3 +514,7 @@ parameters:

# internal tag
- '#Unknown PHPDoc tag\: @phpstan\-rule#'
- '#Cognitive complexity for "Rector\\TypeDeclaration\\PHPStan\\Type\\ObjectTypeSpecifier\:\:matchShortenedObjectType\(\)" is 14, keep it under 9#'
-
message: '#Class cognitive complexity is 31, keep it under 30#'
path: rules/Php74/Rector/Property/TypedPropertyRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace Rector\Php74\Tests\Rector\Property\TypedPropertyRector\Fixture;
/**
* @template T of object
*/
final class GenericObjectType
final class SomeGenericObjectType
{
/**
* @var T
Expand All @@ -29,7 +29,7 @@ namespace Rector\Php74\Tests\Rector\Property\TypedPropertyRector\Fixture;
/**
* @template T of object
*/
final class GenericObjectType
final class SomeGenericObjectType
{
/**
* @var T
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\AddArrayReturnDocTypeRector\Fixture;

use PhpParser\Node;
use PhpParser\Node\Scalar\String_;
use PhpParser\NodeFinder;

Expand Down
2 changes: 1 addition & 1 deletion rules/CodeQuality/NodeAnalyzer/LocalPropertyAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ private function resolvePropertyFetchType(PropertyFetch $propertyFetch): Type

// possible get type
if ($parentNode instanceof Assign) {
return $this->nodeTypeResolver->getStaticType($parentNode->expr);
return $this->nodeTypeResolver->getType($parentNode->expr);
}

if ($parentNode instanceof ArrayDimFetch) {
Expand Down
2 changes: 1 addition & 1 deletion rules/CodeQuality/NodeManipulator/ExprBoolCaster.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public function boolCastOrNullCompareIfNeeded(Expr $expr): Expr
return new Bool_($expr);
}

$exprStaticType = $this->nodeTypeResolver->getStaticType($expr);
$exprStaticType = $this->nodeTypeResolver->getType($expr);
// if we remove null type, still has to be trueable
if ($exprStaticType instanceof UnionType) {
$unionTypeWithoutNullType = $this->typeUnwrapper->removeNullTypeFromUnionType($exprStaticType);
Expand Down
4 changes: 2 additions & 2 deletions rules/CodeQuality/TypeResolver/ArrayDimFetchTypeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public function resolve(ArrayDimFetch $arrayDimFetch): ArrayType
private function resolveDimType(ArrayDimFetch $arrayDimFetch): Type
{
if ($arrayDimFetch->dim !== null) {
return $this->nodeTypeResolver->getStaticType($arrayDimFetch->dim);
return $this->nodeTypeResolver->getType($arrayDimFetch->dim);
}

return new MixedType();
Expand All @@ -40,7 +40,7 @@ private function resolveValueStaticType(ArrayDimFetch $arrayDimFetch): Type
{
$parentParent = $arrayDimFetch->getAttribute(AttributeKey::PARENT_NODE);
if ($parentParent instanceof Assign) {
return $this->nodeTypeResolver->getStaticType($parentParent->expr);
return $this->nodeTypeResolver->getType($parentParent->expr);
}

return new MixedType();
Expand Down
2 changes: 1 addition & 1 deletion rules/Defluent/NodeAnalyzer/ExprStringTypeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public function __construct(

public function resolve(Expr $expr): ?string
{
$exprStaticType = $this->nodeTypeResolver->getStaticType($expr);
$exprStaticType = $this->nodeTypeResolver->getType($expr);
$exprStaticType = $this->typeUnwrapper->unwrapNullableType($exprStaticType);

if (! $exprStaticType instanceof TypeWithClassName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,14 @@ public function isFluentClassMethodOfMethodCall(MethodCall $methodCall): bool
return false;
}

$calleeStaticType = $this->nodeTypeResolver->getStaticType($methodCall->var);
$calleeStaticType = $this->nodeTypeResolver->getType($methodCall->var);

// we're not sure
if ($calleeStaticType instanceof MixedType) {
return false;
}

$methodReturnStaticType = $this->nodeTypeResolver->getStaticType($methodCall);
$methodReturnStaticType = $this->nodeTypeResolver->getType($methodCall);

// is fluent type
if (! $calleeStaticType->equals($methodReturnStaticType)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ private function createAssignAndRootExprForVariableOrPropertyFetch(MethodCall $m
$isFirstCallFactory = $this->isFirstMethodCallFactory($methodCall);

// the method call, does not belong to the
$staticType = $this->nodeTypeResolver->getStaticType($methodCall);
$staticType = $this->nodeTypeResolver->getType($methodCall);
$parentNode = $methodCall->getAttribute(AttributeKey::PARENT_NODE);

// no assign
Expand Down
4 changes: 2 additions & 2 deletions rules/Defluent/NodeAnalyzer/GetterMethodCallAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ public function isGetterMethodCall(MethodCall $methodCall): bool
return false;
}

$methodCallStaticType = $this->nodeTypeResolver->getStaticType($methodCall);
$methodCallVarStaticType = $this->nodeTypeResolver->getStaticType($methodCall->var);
$methodCallStaticType = $this->nodeTypeResolver->getType($methodCall);
$methodCallVarStaticType = $this->nodeTypeResolver->getType($methodCall->var);

// getter short call type
return ! $methodCallStaticType->equals($methodCallVarStaticType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ public function __construct(

public function isNewMethodCallReturningSelf(MethodCall $methodCall): bool
{
$newStaticType = $this->nodeTypeResolver->getStaticType($methodCall->var);
$methodCallStaticType = $this->nodeTypeResolver->getStaticType($methodCall);
$newStaticType = $this->nodeTypeResolver->getType($methodCall->var);
$methodCallStaticType = $this->nodeTypeResolver->getType($methodCall);

return $methodCallStaticType->equals($newStaticType);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public function createFromFluentMethodCalls(FluentMethodCalls $fluentMethodCalls
} else {
// we need a variable to assign the stuff into
// the method call, does not belong to the
$staticType = $this->nodeTypeResolver->getStaticType($rootMethodCall);
$staticType = $this->nodeTypeResolver->getType($rootMethodCall);
if (! $staticType instanceof ObjectType) {
return null;
}
Expand Down
4 changes: 2 additions & 2 deletions rules/Naming/Naming/ExpectedNameResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ public function resolveForCall(MethodCall | StaticCall | FuncCall $expr): ?strin
return null;
}

$returnedType = $this->nodeTypeResolver->getStaticType($expr);
$returnedType = $this->nodeTypeResolver->getType($expr);

if ($returnedType instanceof ArrayType) {
return null;
Expand Down Expand Up @@ -154,7 +154,7 @@ public function resolveForForeach(MethodCall | StaticCall | FuncCall $expr): ?st
return null;
}

$returnedType = $this->nodeTypeResolver->getStaticType($expr);
$returnedType = $this->nodeTypeResolver->getType($expr);
if ($returnedType->isIterable()->no()) {
return null;
}
Expand Down
2 changes: 1 addition & 1 deletion rules/Naming/Naming/VariableNaming.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public function resolveFromFuncCallFirstArgumentWithSuffix(

public function resolveFromNode(Node $node): ?string
{
$nodeType = $this->nodeTypeResolver->getStaticType($node);
$nodeType = $this->nodeTypeResolver->getType($node);
return $this->resolveFromNodeAndType($node, $nodeType);
}

Expand Down
17 changes: 2 additions & 15 deletions rules/Php73/NodeTypeAnalyzer/NodeTypeAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,15 @@

namespace Rector\Php73\NodeTypeAnalyzer;

use PhpParser\Node\Expr;
use PHPStan\Type\Accessory\AccessoryNumericStringType;
use PHPStan\Type\IntersectionType;
use PHPStan\Type\StringType;
use PHPStan\Type\Type;
use PHPStan\Type\UnionType;
use Rector\NodeTypeResolver\NodeTypeResolver;

final class NodeTypeAnalyzer
{
public function __construct(
private NodeTypeResolver $nodeTypeResolver
) {
}

public function isStringTypeExpr(Expr $expr): bool
{
$staticType = $this->nodeTypeResolver->getStaticType($expr);
return $this->isStringType($staticType);
}

private function isStringType(Type $type): bool
public function isStringyType(Type $type): bool
{
if ($type instanceof StringType) {
return true;
Expand All @@ -37,7 +24,7 @@ private function isStringType(Type $type): bool

if ($type instanceof IntersectionType || $type instanceof UnionType) {
foreach ($type->getTypes() as $innerType) {
if (! $this->isStringType($innerType)) {
if (! $this->isStringyType($innerType)) {
return false;
}
}
Expand Down
13 changes: 10 additions & 3 deletions rules/Php73/Rector/FuncCall/StringifyStrNeedlesRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\Cast\String_;
use PhpParser\Node\Expr\FuncCall;
use PHPStan\Type\StringType;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\Php73\NodeTypeAnalyzer\NodeTypeAnalyzer;
Expand Down Expand Up @@ -90,12 +91,18 @@ public function refactor(Node $node): ?Node
}

// is argument string?
$needleArgNode = $node->args[1]->value;
if ($this->nodeTypeAnalyzer->isStringTypeExpr($needleArgNode)) {
$needleArgValue = $node->args[1]->value;

$needleType = $this->getType($needleArgValue);
if ($needleType instanceof StringType) {
return null;
}

if ($this->nodeTypeAnalyzer->isStringyType($needleType)) {
return null;
}

if ($needleArgNode instanceof String_) {
if ($needleArgValue instanceof String_) {
return null;
}

Expand Down
2 changes: 1 addition & 1 deletion rules/Php74/Rector/Assign/NullCoalescingOperatorRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public function getNodeTypes(): array
/**
* @param Assign $node
*/
public function refactor(Node $node): ?Node
public function refactor(Node $node): ?AssignCoalesce
{
if (! $node->expr instanceof Coalesce) {
return null;
Expand Down

0 comments on commit f2afe8e

Please sign in to comment.