Skip to content

Commit

Permalink
[NodeTypeResolver] Remove AstResolver usage on ArrayTypeAnalyzer (#5110)
Browse files Browse the repository at this point in the history
  • Loading branch information
samsonasik committed Oct 4, 2023
1 parent d7710f8 commit 39e4f0a
Showing 1 changed file with 6 additions and 59 deletions.
65 changes: 6 additions & 59 deletions packages/NodeTypeResolver/TypeAnalyzer/ArrayTypeAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,53 +8,38 @@
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\StaticPropertyFetch;
use PhpParser\Node\Stmt\ClassLike;
use PhpParser\Node\Stmt\Property;
use PHPStan\PhpDocParser\Ast\Type\ArrayShapeNode;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\Php\PhpPropertyReflection;
use PHPStan\Type\Accessory\HasOffsetType;
use PHPStan\Type\Accessory\NonEmptyArrayType;
use PHPStan\Type\ArrayType;
use PHPStan\Type\IntersectionType;
use PHPStan\Type\IterableType;
use PHPStan\Type\MixedType;
use PHPStan\Type\Type;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\Core\PhpParser\AstResolver;
use Rector\Core\Reflection\ReflectionResolver;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\NodeTypeResolver;

final class ArrayTypeAnalyzer
{
public function __construct(
private readonly NodeNameResolver $nodeNameResolver,
private readonly NodeTypeResolver $nodeTypeResolver,
private readonly PhpDocInfoFactory $phpDocInfoFactory,
private readonly ReflectionResolver $reflectionResolver,
private readonly AstResolver $astResolver
private readonly ReflectionResolver $reflectionResolver
) {
}

public function isArrayType(Expr $expr): bool
{
$nodeType = $this->nodeTypeResolver->getType($expr);
$nodeType = $this->nodeTypeResolver->getNativeType($expr);

if ($this->isIntersectionArrayType($nodeType)) {
return true;
}

// PHPStan false positive, when variable has type[] docblock, but default array is missing
if (($expr instanceof PropertyFetch || $expr instanceof StaticPropertyFetch)) {
if ($this->isPropertyFetchWithArrayDefault($expr)) {
return true;
}

if ($this->isPropertyFetchWithArrayDocblockWithoutDefault($expr)) {
return false;
}
if ((($expr instanceof PropertyFetch || $expr instanceof StaticPropertyFetch) && $this->isPropertyFetchWithArrayDefault(
$expr
))) {
return true;
}

if ($nodeType instanceof MixedType) {
Expand Down Expand Up @@ -95,44 +80,6 @@ private function isIntersectionArrayType(Type $nodeType): bool
return true;
}

private function isPropertyFetchWithArrayDocblockWithoutDefault(Expr $expr): bool
{
if (! $expr instanceof PropertyFetch && ! $expr instanceof StaticPropertyFetch) {
return false;
}

$classReflection = $this->reflectionResolver->resolveClassReflection($expr);
if (! $classReflection instanceof ClassReflection) {
return false;
}

$propertyName = $this->nodeNameResolver->getName($expr->name);
if ($propertyName === null) {
return false;
}

/** @var ClassLike $classLike */
$classLike = $this->astResolver->resolveClassFromClassReflection($classReflection);
$property = $classLike->getProperty($propertyName);

if (! $property instanceof Property) {
return false;
}

$propertyProperty = $property->props[0];
if ($propertyProperty->default instanceof Array_) {
return false;
}

$propertyPhpDocInfo = $this->phpDocInfoFactory->createFromNode($property);
if (! $propertyPhpDocInfo instanceof PhpDocInfo) {
return false;
}

$varType = $propertyPhpDocInfo->getVarType();
return $varType instanceof ArrayType || $varType instanceof ArrayShapeNode || $varType instanceof IterableType;
}

/**
* phpstan bug workaround - https://phpstan.org/r/0443f283-244c-42b8-8373-85e7deb3504c
*/
Expand Down

0 comments on commit 39e4f0a

Please sign in to comment.