Skip to content

Instantly share code, notes, and snippets.

@rvanvelzen
Created May 3, 2024 14:23
Show Gist options
  • Save rvanvelzen/5bd097289e857cc8590adf278e77def5 to your computer and use it in GitHub Desktop.
Save rvanvelzen/5bd097289e857cc8590adf278e77def5 to your computer and use it in GitHub Desktop.
diff --git a/src/PhpDoc/TypeNodeResolver.php b/src/PhpDoc/TypeNodeResolver.php
index e080c998e..b0215d092 100644
--- a/src/PhpDoc/TypeNodeResolver.php
+++ b/src/PhpDoc/TypeNodeResolver.php
@@ -83,6 +83,7 @@ use PHPStan\Type\MixedType;
use PHPStan\Type\NonAcceptingNeverType;
use PHPStan\Type\NonexistentParentClassType;
use PHPStan\Type\NullType;
+use PHPStan\Type\ObjectReferenceType;
use PHPStan\Type\ObjectShapeType;
use PHPStan\Type\ObjectType;
use PHPStan\Type\ObjectWithoutClassType;
@@ -755,6 +756,13 @@ class TypeNodeResolver
return TypeCombinator::union(...$result);
}
+ return new ErrorType();
+ } elseif ($mainTypeName === 'object') {
+ if (count($genericTypes) === 1) {
+ $type = new ObjectReferenceType($genericTypes[0]);
+ return $type->isResolvable() ? $type->resolve() : $type;
+ }
+
return new ErrorType();
}
diff --git a/src/Type/ObjectReferenceType.php b/src/Type/ObjectReferenceType.php
new file mode 100644
index 000000000..7cf478001
--- /dev/null
+++ b/src/Type/ObjectReferenceType.php
@@ -0,0 +1,103 @@
+<?php declare(strict_types = 1);
+
+namespace PHPStan\Type;
+
+use PHPStan\PhpDocParser\Ast\Type\GenericTypeNode;
+use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
+use PHPStan\PhpDocParser\Ast\Type\TypeNode;
+use PHPStan\Type\Generic\TemplateTypeVariance;
+use PHPStan\Type\Traits\LateResolvableTypeTrait;
+use PHPStan\Type\Traits\NonGeneralizableTypeTrait;
+use function sprintf;
+
+class ObjectReferenceType implements CompoundType, LateResolvableType
+{
+
+ use LateResolvableTypeTrait;
+ use NonGeneralizableTypeTrait;
+
+ public function __construct(private Type $type)
+ {
+ }
+
+ public function getType(): Type
+ {
+ return $this->type;
+ }
+
+ public function getReferencedClasses(): array
+ {
+ return $this->type->getReferencedClasses();
+ }
+
+ public function getReferencedTemplateTypes(TemplateTypeVariance $positionVariance): array
+ {
+ return $this->type->getReferencedTemplateTypes($positionVariance);
+ }
+
+ public function equals(Type $type): bool
+ {
+ return $type instanceof self
+ && $this->type->equals($type->type);
+ }
+
+ public function describe(VerbosityLevel $level): string
+ {
+ return sprintf('object<%s>', $this->type->describe($level));
+ }
+
+ public function isResolvable(): bool
+ {
+ return !TypeUtils::containsTemplateType($this->type);
+ }
+
+ protected function getResult(): Type
+ {
+ return $this->type->getObjectTypeOrClassStringObjectType();
+ }
+
+ /**
+ * @param callable(Type): Type $cb
+ */
+ public function traverse(callable $cb): Type
+ {
+ $type = $cb($this->type);
+
+ if ($this->type === $type) {
+ return $this;
+ }
+
+ return new self($type);
+ }
+
+ public function traverseSimultaneously(Type $right, callable $cb): Type
+ {
+ if (!$right instanceof self) {
+ return $this;
+ }
+
+ $type = $cb($this->type, $right->type);
+
+ if ($this->type === $type) {
+ return $this;
+ }
+
+ return new self($type);
+ }
+
+ public function toPhpDocNode(): TypeNode
+ {
+ return new GenericTypeNode(new IdentifierTypeNode('object'), [$this->type->toPhpDocNode()]);
+ }
+
+ /**
+ * @param mixed[] $properties
+ */
+ public static function __set_state(array $properties): Type
+ {
+ return new self(
+ $properties['type'],
+ );
+ }
+
+}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment