from helper methods to isStaticType() with PHPStan object typing (#1946)

from helper methods to isStaticType() with PHPStan object typing
This commit is contained in:
Tomáš Votruba 2019-09-03 10:25:56 +02:00 committed by GitHub
commit e72491feb2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 77 additions and 96 deletions

View File

@ -6,6 +6,7 @@ use PhpParser\Node;
use PhpParser\Node\Expr\BinaryOp\Identical;
use PhpParser\Node\Expr\BinaryOp\NotIdentical;
use PhpParser\Node\Expr\BooleanNot;
use PHPStan\Type\BooleanType;
use Rector\Rector\AbstractRector;
use Rector\RectorDefinition\CodeSample;
use Rector\RectorDefinition\RectorDefinition;
@ -74,11 +75,11 @@ CODE_SAMPLE
if ($node->expr instanceof Identical) {
$identical = $node->expr;
if (! $this->isBoolType($identical->left)) {
if (! $this->isStaticType($identical->left, BooleanType::class)) {
return null;
}
if (! $this->isBoolType($identical->right)) {
if (! $this->isStaticType($identical->right, BooleanType::class)) {
return null;
}
@ -90,11 +91,11 @@ CODE_SAMPLE
private function processIdentical(Identical $identical): ?NotIdentical
{
if (! $this->isBoolType($identical->left)) {
if (! $this->isStaticType($identical->left, BooleanType::class)) {
return null;
}
if (! $this->isBoolType($identical->right)) {
if (! $this->isStaticType($identical->right, BooleanType::class)) {
return null;
}

View File

@ -7,6 +7,7 @@ use PhpParser\Node\Expr;
use PhpParser\Node\Expr\BinaryOp\Identical;
use PhpParser\Node\Expr\BinaryOp\NotIdentical;
use PhpParser\Node\Expr\BooleanNot;
use PHPStan\Type\BooleanType;
use Rector\Rector\AbstractRector;
use Rector\RectorDefinition\CodeSample;
use Rector\RectorDefinition\RectorDefinition;
@ -55,11 +56,11 @@ CODE_SAMPLE
*/
public function refactor(Node $node): ?Node
{
if ($this->isBoolType($node->left) && ! $this->isBool($node->left)) {
if ($this->isStaticType($node->left, BooleanType::class) && ! $this->isBool($node->left)) {
return $this->processBoolTypeToNotBool($node, $node->left, $node->right);
}
if ($this->isBoolType($node->right) && ! $this->isBool($node->right)) {
if ($this->isStaticType($node->right, BooleanType::class) && ! $this->isBool($node->right)) {
return $this->processBoolTypeToNotBool($node, $node->right, $node->left);
}

View File

@ -17,6 +17,9 @@ use PhpParser\Node\Scalar\LNumber;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt\ElseIf_;
use PhpParser\Node\Stmt\If_;
use PHPStan\Type\BooleanType;
use PHPStan\Type\FloatType;
use PHPStan\Type\IntegerType;
use Rector\Rector\AbstractRector;
use Rector\RectorDefinition\CodeSample;
use Rector\RectorDefinition\RectorDefinition;
@ -84,7 +87,7 @@ CODE_SAMPLE
$isNegated = false;
}
if ($this->isBoolType($conditionNode)) {
if ($this->isStaticType($conditionNode, BooleanType::class)) {
return null;
}
@ -113,11 +116,11 @@ CODE_SAMPLE
return $this->resolveString($isNegated, $expr);
}
if ($this->isIntegerType($expr)) {
if ($this->isStaticType($expr, IntegerType::class)) {
return $this->resolveInteger($isNegated, $expr);
}
if ($this->isFloatType($expr)) {
if ($this->isStaticType($expr, FloatType::class)) {
return $this->resolveFloat($isNegated, $expr);
}

View File

@ -11,6 +11,7 @@ use PhpParser\Node\Expr\BooleanNot;
use PhpParser\Node\Expr\Cast\Bool_;
use PhpParser\Node\Stmt\If_;
use PhpParser\Node\Stmt\Return_;
use PHPStan\Type\BooleanType;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\Rector\AbstractRector;
use Rector\RectorDefinition\CodeSample;
@ -168,7 +169,7 @@ CODE_SAMPLE
return $expr;
}
if ($this->isBoolType($expr)) {
if ($this->isStaticType($expr, BooleanType::class)) {
return $expr;
}

View File

@ -4,6 +4,7 @@ namespace Rector\CodeQuality\Rector\Ternary;
use PhpParser\Node;
use PhpParser\Node\Expr\Ternary;
use PHPStan\Type\BooleanType;
use Rector\Rector\AbstractRector;
use Rector\RectorDefinition\CodeSample;
use Rector\RectorDefinition\RectorDefinition;
@ -52,7 +53,7 @@ CODE_SAMPLE
*/
public function refactor(Node $node): ?Node
{
if (! $this->isBoolType($node->cond)) {
if (! $this->isStaticType($node->cond, BooleanType::class)) {
return null;
}

View File

@ -8,6 +8,7 @@ use PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BooleanNot;
use PhpParser\Node\Expr\Cast\Bool_;
use PhpParser\Node\Expr\Ternary;
use PHPStan\Type\BooleanType;
use Rector\PhpParser\Node\AssignAndBinaryMap;
use Rector\Rector\AbstractRector;
use Rector\RectorDefinition\CodeSample;
@ -89,7 +90,7 @@ final class UnnecessaryTernaryExpressionRector extends AbstractRector
private function processNonBinaryCondition(Expr $ifExpression, Expr $elseExpression, Expr $condition): ?Node
{
if ($this->isTrue($ifExpression) && $this->isFalse($elseExpression)) {
if ($this->isBoolType($condition)) {
if ($this->isStaticType($condition, BooleanType::class)) {
return $condition;
}
@ -97,7 +98,7 @@ final class UnnecessaryTernaryExpressionRector extends AbstractRector
}
if ($this->isFalse($ifExpression) && $this->isTrue($elseExpression)) {
if ($this->isBoolType($condition)) {
if ($this->isStaticType($condition, BooleanType::class)) {
return new BooleanNot($condition);
}

View File

@ -13,6 +13,7 @@ use PhpParser\Node\Identifier;
use PhpParser\Node\Name;
use PhpParser\Node\Name\FullyQualified;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTextNode;
use PHPStan\Type\BooleanType;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockManipulator;
@ -218,7 +219,7 @@ final class AssertManipulator
$call->name = new Identifier($method);
}
if (! $this->nodeTypeResolver->isBoolType($staticCall->args[0]->value)) {
if (! $this->nodeTypeResolver->isStaticType($staticCall->args[0]->value, BooleanType::class)) {
$call->args[0]->value = new Bool_($staticCall->args[0]->value);
}

View File

@ -6,6 +6,8 @@ use PhpParser\Node;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Scalar\DNumber;
use PhpParser\Node\Scalar\LNumber;
use PHPStan\Type\IntegerType;
use PHPStan\Type\StringType;
use Rector\NodeTypeResolver\NodeTypeResolver;
use Rector\PhpParser\Node\Manipulator\ConstFetchManipulator;
@ -41,11 +43,11 @@ final class NodeToStringTypeResolver
return 'float';
}
if ($this->nodeTypeResolver->isIntType($node)) {
if ($this->nodeTypeResolver->isStaticType($node, IntegerType::class)) {
return 'int';
}
if ($this->nodeTypeResolver->isStringType($node)) {
if ($this->nodeTypeResolver->isStaticType($node, StringType::class)) {
return 'string';
}

View File

@ -29,7 +29,6 @@ use PHPStan\Broker\Broker;
use PHPStan\Type\Accessory\HasOffsetType;
use PHPStan\Type\Accessory\NonEmptyArrayType;
use PHPStan\Type\ArrayType;
use PHPStan\Type\BooleanType;
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\FloatType;
use PHPStan\Type\IntegerType;
@ -41,6 +40,7 @@ use PHPStan\Type\ObjectWithoutClassType;
use PHPStan\Type\StringType;
use PHPStan\Type\Type;
use PHPStan\Type\UnionType;
use Rector\Exception\ShouldNotHappenException;
use Rector\NodeTypeResolver\Contract\NodeTypeResolverAwareInterface;
use Rector\NodeTypeResolver\Contract\PerNodeTypeResolver\PerNodeTypeResolverInterface;
use Rector\NodeTypeResolver\Node\AttributeKey;
@ -191,24 +191,9 @@ final class NodeTypeResolver
return $types;
}
public function isStringType(Node $node): bool
{
return $this->getNodeStaticType($node) instanceof StringType;
}
public function isIntType(Node $node): bool
{
return $this->getNodeStaticType($node) instanceof IntegerType;
}
public function isFloatType(Node $node): bool
{
return $this->getNodeStaticType($node) instanceof FloatType;
}
public function isStringyType(Node $node): bool
{
$nodeType = $this->getNodeStaticType($node);
$nodeType = $this->getStaticType($node);
if ($nodeType instanceof StringType) {
return true;
}
@ -226,17 +211,12 @@ final class NodeTypeResolver
return false;
}
public function isNullType(Node $node): bool
{
return $this->getNodeStaticType($node) instanceof NullType;
}
/**
* e.g. string|null, ObjectNull|null
*/
public function isNullableType(Node $node): bool
{
$nodeType = $this->getNodeStaticType($node);
$nodeType = $this->getStaticType($node);
if (! $nodeType instanceof UnionType) {
return false;
}
@ -244,14 +224,9 @@ final class NodeTypeResolver
return $nodeType->isSuperTypeOf(new NullType())->yes();
}
public function isBoolType(Node $node): bool
{
return $this->getNodeStaticType($node) instanceof BooleanType;
}
public function isCountableType(Node $node): bool
{
$nodeType = $this->getNodeStaticType($node);
$nodeType = $this->getStaticType($node);
if ($nodeType === null) {
return false;
}
@ -266,7 +241,7 @@ final class NodeTypeResolver
public function isArrayType(Node $node): bool
{
$nodeStaticType = $this->getNodeStaticType($node);
$nodeStaticType = $this->getStaticType($node);
if ($nodeStaticType === null) {
return false;
}
@ -296,7 +271,7 @@ final class NodeTypeResolver
return $nodeStaticType instanceof ArrayType;
}
public function getNodeStaticType(Node $node): ?Type
public function getStaticType(Node $node): ?Type
{
if ($node instanceof String_) {
return new ConstantStringType($node->value);
@ -330,7 +305,7 @@ final class NodeTypeResolver
public function resolveSingleTypeToStrings(Node $node): array
{
if ($this->isArrayType($node)) {
$arrayType = $this->getNodeStaticType($node);
$arrayType = $this->getStaticType($node);
if ($arrayType instanceof ArrayType) {
$itemTypes = $this->staticTypeToStringResolver->resolveObjectType($arrayType->getItemType());
@ -350,14 +325,14 @@ final class NodeTypeResolver
return ['string'];
}
$nodeStaticType = $this->getNodeStaticType($node);
$nodeStaticType = $this->getStaticType($node);
return $this->staticTypeToStringResolver->resolveObjectType($nodeStaticType);
}
public function isNullableObjectType(Node $node): bool
{
$nodeType = $this->getNodeStaticType($node);
$nodeType = $this->getStaticType($node);
if (! $nodeType instanceof UnionType) {
return false;
}
@ -381,7 +356,26 @@ final class NodeTypeResolver
public function isNumberType(Node $node): bool
{
return $this->isIntType($node) || $this->isFloatType($node);
return $this->isStaticType($node, IntegerType::class) || $this->isStaticType($node, FloatType::class);
}
public function isStaticType(Node $node, string $staticTypeClass): bool
{
if (! is_a($staticTypeClass, Type::class, true)) {
throw new ShouldNotHappenException(sprintf(
'"%s" in "%s()" must be type of "%s"',
$staticTypeClass,
__METHOD__,
Type::class
));
}
$nodeStaticType = $this->getStaticType($node);
if ($nodeStaticType === null) {
return false;
}
return is_a($nodeStaticType, $staticTypeClass);
}
private function addPerNodeTypeResolver(PerNodeTypeResolverInterface $perNodeTypeResolver): void
@ -611,7 +605,7 @@ final class NodeTypeResolver
return null;
}
$paramStaticType = $this->getNodeStaticType($node);
$paramStaticType = $this->getStaticType($node);
return NodeTraverser::STOP_TRAVERSAL;
}

View File

@ -6,6 +6,7 @@ use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Identifier;
use PHPStan\Type\StringType;
use Rector\Rector\AbstractPHPUnitRector;
use Rector\RectorDefinition\CodeSample;
use Rector\RectorDefinition\RectorDefinition;
@ -78,7 +79,7 @@ CODE_SAMPLE
return null;
}
if (! $this->isStringType($node->args[1]->value)) {
if (! $this->isStaticType($node->args[1]->value, StringType::class)) {
return null;
}

View File

@ -12,6 +12,7 @@ use PhpParser\Node\Expr\Ternary;
use PhpParser\Node\Name;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Scalar\LNumber;
use PHPStan\Type\NullType;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\Rector\AbstractRector;
use Rector\RectorDefinition\CodeSample;
@ -71,7 +72,7 @@ CODE_SAMPLE
return null;
}
if ($this->isNullableType($countedNode) || $this->isNullType($countedNode)) {
if ($this->isNullableType($countedNode) || $this->isStaticType($countedNode, NullType::class)) {
$identicalNode = new Identical($countedNode, $this->createNull());
$ternaryNode = new Ternary($identicalNode, new LNumber(0), $node);
} else {

View File

@ -11,6 +11,7 @@ use PhpParser\Node\Expr\Ternary;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name;
use PHPStan\Analyser\Scope;
use PHPStan\Type\NullType;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\Rector\AbstractRector;
use Rector\RectorDefinition\CodeSample;
@ -87,7 +88,7 @@ CODE_SAMPLE
}
$valueNode = $node->args[0]->value;
if (! $this->isNullableType($valueNode) && ! $this->isNullType($valueNode)) {
if (! $this->isNullableType($valueNode) && ! $this->isStaticType($valueNode, NullType::class)) {
return null;
}

View File

@ -5,6 +5,7 @@ namespace Rector\Php\Rector\List_;
use PhpParser\Node;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\List_;
use PHPStan\Type\StringType;
use Rector\Rector\AbstractRector;
use Rector\RectorDefinition\CodeSample;
use Rector\RectorDefinition\RectorDefinition;
@ -41,7 +42,7 @@ final class ListSplitStringRector extends AbstractRector
return null;
}
if (! $this->isStringType($node->expr)) {
if (! $this->isStaticType($node->expr, StringType::class)) {
return null;
}

View File

@ -11,6 +11,7 @@ use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\New_;
use PhpParser\Node\Scalar\String_;
use PHPStan\Type\StringType;
use Rector\PhpParser\NodeTransformer;
use Rector\Rector\AbstractRector;
use Rector\RectorDefinition\CodeSample;
@ -103,7 +104,7 @@ CODE_SAMPLE
}
// type analyzer
if ($this->isStringType($firstArgument)) {
if ($this->isStaticType($firstArgument, StringType::class)) {
$this->processStringType($node, $argumentPosition, $firstArgument);
}

View File

@ -35,7 +35,7 @@ final class AssignToPropertyTypeInferer extends AbstractTypeInferer
return null;
}
$exprStaticType = $this->nodeTypeResolver->getNodeStaticType($node->expr);
$exprStaticType = $this->nodeTypeResolver->getStaticType($node->expr);
if ($exprStaticType === null) {
return null;
}

View File

@ -53,7 +53,7 @@ final class PropertyNodeParamTypeInferer extends AbstractTypeInferer implements
}
/** @var Assign $node */
$staticType = $this->nodeTypeResolver->getNodeStaticType($node->var);
$staticType = $this->nodeTypeResolver->getStaticType($node->var);
/** @var Type|null $staticType */
if ($staticType) {

View File

@ -106,7 +106,7 @@ final class ConstructorPropertyTypeInferer extends AbstractTypeInferer implement
return null;
}
$paramStaticType = $this->nodeTypeResolver->getNodeStaticType($node);
$paramStaticType = $this->nodeTypeResolver->getStaticType($node);
return NodeTraverser::STOP_TRAVERSAL;
});
@ -173,7 +173,7 @@ final class ConstructorPropertyTypeInferer extends AbstractTypeInferer implement
}
if ($param->default) {
$defaultValueStaticType = $this->nodeTypeResolver->getNodeStaticType($param->default);
$defaultValueStaticType = $this->nodeTypeResolver->getStaticType($param->default);
if ($defaultValueStaticType instanceof NullType) {
return true;
}

View File

@ -18,7 +18,7 @@ final class DefaultValuePropertyTypeInferer extends AbstractTypeInferer implemen
return [];
}
$nodeStaticType = $this->nodeTypeResolver->getNodeStaticType($propertyProperty->default);
$nodeStaticType = $this->nodeTypeResolver->getStaticType($propertyProperty->default);
if ($nodeStaticType === null) {
return [];
}

View File

@ -35,7 +35,7 @@ final class SingleMethodAssignedNodePropertyTypeInferer extends AbstractTypeInfe
return [];
}
$nodeStaticType = $this->nodeTypeResolver->getNodeStaticType($assignedNode);
$nodeStaticType = $this->nodeTypeResolver->getStaticType($assignedNode);
$stringTypes = $this->staticTypeToStringResolver->resolveObjectType($nodeStaticType);
if ($stringTypes === []) {

View File

@ -69,7 +69,7 @@ final class ValueResolver
return $this->nameResolver->getName($expr);
}
$nodeStaticType = $this->nodeTypeResolver->getNodeStaticType($expr);
$nodeStaticType = $this->nodeTypeResolver->getStaticType($expr);
if ($nodeStaticType instanceof ConstantArrayType) {
return $this->extractConstantArrayTypeValue($nodeStaticType);

View File

@ -39,43 +39,24 @@ trait NodeTypeResolverTrait
return (bool) array_intersect($types, $nodeTypes);
}
/**
* @param string[] $types
* @return string[]
*/
protected function matchTypes(Node $node, array $types): array
{
return $this->isTypes($node, $types) ? $this->getTypes($node) : [];
}
protected function isStringType(Node $node): bool
{
return $this->nodeTypeResolver->isStringType($node);
}
protected function isStringyType(Node $node): bool
{
return $this->nodeTypeResolver->isStringyType($node);
}
protected function isIntegerType(Node $node): bool
{
return $this->nodeTypeResolver->isIntType($node);
}
protected function isNumberType(Node $node): bool
{
return $this->nodeTypeResolver->isNumberType($node);
}
protected function isFloatType(Node $node): bool
protected function isStaticType(Node $node, string $staticTypeClass): bool
{
return $this->nodeTypeResolver->isFloatType($node);
return $this->nodeTypeResolver->isStaticType($node, $staticTypeClass);
}
protected function getStaticType(Node $node): ?Type
{
return $this->nodeTypeResolver->getNodeStaticType($node);
return $this->nodeTypeResolver->getStaticType($node);
}
protected function isNullableType(Node $node): bool
@ -88,16 +69,6 @@ trait NodeTypeResolverTrait
return $this->nodeTypeResolver->isNullableObjectType($node);
}
protected function isNullType(Node $node): bool
{
return $this->nodeTypeResolver->isNullType($node);
}
protected function isBoolType(Node $node): bool
{
return $this->nodeTypeResolver->isBoolType($node);
}
protected function isCountableType(Node $node): bool
{
return $this->nodeTypeResolver->isCountableType($node);