diff --git a/src/Analyser/TypeSpecifier.php b/src/Analyser/TypeSpecifier.php index 37a2646a45e..ef69051f2ad 100644 --- a/src/Analyser/TypeSpecifier.php +++ b/src/Analyser/TypeSpecifier.php @@ -31,6 +31,8 @@ use PHPStan\Type\Accessory\HasOffsetType; use PHPStan\Type\Accessory\HasPropertyType; use PHPStan\Type\Accessory\NonEmptyArrayType; +use PHPStan\Type\ArrayType; +use PHPStan\Type\BooleanType; use PHPStan\Type\ConditionalTypeForParameter; use PHPStan\Type\Constant\ConstantArrayTypeBuilder; use PHPStan\Type\Constant\ConstantBooleanType; @@ -54,9 +56,11 @@ use PHPStan\Type\NullType; use PHPStan\Type\ObjectType; use PHPStan\Type\ObjectWithoutClassType; +use PHPStan\Type\ResourceType; use PHPStan\Type\StaticMethodTypeSpecifyingExtension; use PHPStan\Type\StaticType; use PHPStan\Type\StaticTypeFactory; +use PHPStan\Type\StringType; use PHPStan\Type\Type; use PHPStan\Type\TypeCombinator; use PHPStan\Type\TypeTraverser; @@ -1076,7 +1080,31 @@ private function specifyTypesForConstantStringBinaryExpression( && strtolower($exprNode->name->toString()) === 'gettype' && isset($exprNode->getArgs()[0]) ) { - $type = GetTypeHelper::typeFromString($constantType->getValue()); + $type = null; + if ($constantType->getValue() === 'string') { + $type = new StringType(); + } + if ($constantType->getValue() === 'array') { + $type = new ArrayType(new MixedType(), new MixedType()); + } + if ($constantType->getValue() === 'boolean') { + $type = new BooleanType(); + } + if ($constantType->getValue() === 'resource' || $constantType->getValue() === 'resource (closed)') { + $type = new ResourceType(); + } + if ($constantType->getValue() === 'integer') { + $type = new IntegerType(); + } + if ($constantType->getValue() === 'double') { + $type = new FloatType(); + } + if ($constantType->getValue() === 'NULL') { + $type = new NullType(); + } + if ($constantType->getValue() === 'object') { + $type = new ObjectWithoutClassType(); + } if ($type !== null) { return $this->create($exprNode->getArgs()[0]->value, $type, $context, false, $scope, $rootExpr); diff --git a/src/Reflection/InitializerExprTypeResolver.php b/src/Reflection/InitializerExprTypeResolver.php index ab4f202de24..295053eeca9 100644 --- a/src/Reflection/InitializerExprTypeResolver.php +++ b/src/Reflection/InitializerExprTypeResolver.php @@ -6,6 +6,8 @@ use PhpParser\Node\Expr; use PhpParser\Node\Expr\Array_; use PhpParser\Node\Expr\BinaryOp; +use PhpParser\Node\Expr\ClassConstFetch; +use PhpParser\Node\Expr\ConstFetch; use PhpParser\Node\Identifier; use PhpParser\Node\Name; use PhpParser\Node\Scalar\DNumber; @@ -105,7 +107,7 @@ public function getType(Expr $expr, InitializerExprContext $context): Type if ($expr instanceof String_) { return new ConstantStringType($expr->value); } - if ($expr instanceof Expr\ConstFetch) { + if ($expr instanceof ConstFetch) { $constName = (string) $expr->name; $loweredConstName = strtolower($constName); if ($loweredConstName === 'true') { @@ -157,7 +159,7 @@ public function getType(Expr $expr, InitializerExprContext $context): Type $dim = $this->getType($expr->dim, $context); return $var->getOffsetValueType($dim); } - if ($expr instanceof Expr\ClassConstFetch && $expr->name instanceof Identifier) { + if ($expr instanceof ClassConstFetch && $expr->name instanceof Identifier) { return $this->getClassConstFetchType($expr->class, $expr->name->toString(), $context->getClassName(), fn (Expr $expr): Type => $this->getType($expr, $context)); } if ($expr instanceof Expr\UnaryPlus) { @@ -538,7 +540,7 @@ private function builtDegradedConstantArray(Array_ $node, callable $getTypeCallb $isList = false; $itemKeyType = $getTypeCallback($key); - if (!$itemKeyType instanceof ConstantScalarType) { + if (!$itemKeyType instanceof ConstantScalarType || $key instanceof ClassConstFetch) { throw new OversizedConstantArrayTypeException(); } if (!$itemKeyType->isNonEmptyString()->yes()) { @@ -557,7 +559,7 @@ private function builtDegradedConstantArray(Array_ $node, callable $getTypeCallb } $itemValueType = $getTypeCallback($value); - if (!$itemValueType instanceof ConstantScalarType) { + if (!$itemValueType instanceof ConstantScalarType || $value instanceof ClassConstFetch) { throw new OversizedConstantArrayTypeException(); } if (!$itemValueType->isNonEmptyString()->yes()) {