Skip to content

Commit

Permalink
Optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Mar 29, 2022
1 parent 35a374a commit 22f755c
Showing 1 changed file with 56 additions and 32 deletions.
88 changes: 56 additions & 32 deletions src/Type/ObjectType.php
Expand Up @@ -37,10 +37,12 @@
use PHPStan\Type\Traits\NonGenericTypeTrait;
use PHPStan\Type\Traits\UndecidedComparisonTypeTrait;
use Traversable;
use function array_key_exists;
use function array_keys;
use function array_map;
use function array_values;
use function count;
use function implode;
use function in_array;
use function sprintf;
use function strtolower;
Expand Down Expand Up @@ -71,10 +73,10 @@ class ObjectType implements TypeWithClassName, SubtractableType
/** @var array<string, array<string, array<string, UnresolvedPropertyPrototypeReflection>>> */
private static array $properties = [];

/** @var array<string, array<string, self>> */
/** @var array<string, array<string, self|null>> */
private static array $ancestors = [];

/** @var array<string, self> */
/** @var array<string, self|null> */
private array $currentAncestors = [];

/** @api */
Expand Down Expand Up @@ -436,6 +438,16 @@ private function describeCache(): string
}

$description = $this->className;

if ($this instanceof GenericObjectType) {
$description .= '<';
$typeDescriptions = [];
foreach ($this->getTypes() as $type) {
$typeDescriptions[] = $type->describe(VerbosityLevel::cache());
}
$description .= '<' . implode(', ', $typeDescriptions) . '>';
}

if ($this->subtractedType !== null) {
$description .= sprintf('~%s', $this->subtractedType->describe(VerbosityLevel::cache()));
}
Expand Down Expand Up @@ -1019,35 +1031,41 @@ public function getTypeWithoutSubtractedType(): Type

public function changeSubtractedType(?Type $subtractedType): Type
{
$classReflection = $this->getClassReflection();
if ($classReflection !== null && $classReflection->isEnum() && $subtractedType !== null) {
$cases = [];
foreach (array_keys($classReflection->getEnumCases()) as $name) {
$cases[$name] = new EnumCaseObjectType($classReflection->getName(), $name);
}

foreach (TypeUtils::flattenTypes($subtractedType) as $subType) {
if (!$subType instanceof EnumCaseObjectType) {
return new self($this->className, $subtractedType);
if ($subtractedType !== null) {
$classReflection = $this->getClassReflection();
if ($classReflection !== null && $classReflection->isEnum()) {
$cases = [];
foreach (array_keys($classReflection->getEnumCases()) as $name) {
$cases[$name] = new EnumCaseObjectType($classReflection->getName(), $name);
}

if ($subType->getClassName() !== $this->getClassName()) {
return new self($this->className, $subtractedType);
foreach (TypeUtils::flattenTypes($subtractedType) as $subType) {
if (!$subType instanceof EnumCaseObjectType) {
return new self($this->className, $subtractedType);
}

if ($subType->getClassName() !== $this->getClassName()) {
return new self($this->className, $subtractedType);
}

unset($cases[$subType->getEnumCaseName()]);
}

unset($cases[$subType->getEnumCaseName()]);
}
$cases = array_values($cases);
if (count($cases) === 0) {
return new NeverType();
}

$cases = array_values($cases);
if (count($cases) === 0) {
return new NeverType();
}
if (count($cases) === 1) {
return $cases[0];
}

if (count($cases) === 1) {
return $cases[0];
return new UnionType(array_values($cases));
}
}

return new UnionType(array_values($cases));
if ($this->subtractedType === null && $subtractedType === null) {
return $this;
}

return new self($this->className, $subtractedType);
Expand Down Expand Up @@ -1110,26 +1128,32 @@ public function getClassReflection(): ?ClassReflection
*/
public function getAncestorWithClassName(string $className): ?TypeWithClassName
{
if (isset($this->currentAncestors[$className])) {
if (array_key_exists($className, $this->currentAncestors)) {
return $this->currentAncestors[$className];
}

$thisReflection = $this->getClassReflection();
if ($thisReflection === null) {
return null;
$description = $this->describeCache();
if (
array_key_exists($description, self::$ancestors)
&& array_key_exists($className, self::$ancestors[$description])
) {
return self::$ancestors[$description][$className];
}

$description = $this->describeCache() . '-' . $thisReflection->getCacheKey();
if (isset(self::$ancestors[$description][$className])) {
return self::$ancestors[$description][$className];
if ($this->className === $className) {
return self::$ancestors[$description][$className] = $this->currentAncestors[$className] = $this;
}

$reflectionProvider = ReflectionProviderStaticAccessor::getInstance();
if (!$reflectionProvider->hasClass($className)) {
return null;
return self::$ancestors[$description][$className] = $this->currentAncestors[$className] = null;
}
$theirReflection = $reflectionProvider->getClass($className);

$thisReflection = $this->getClassReflection();
if ($thisReflection === null) {
return self::$ancestors[$description][$className] = $this->currentAncestors[$className] = null;
}
if ($theirReflection->getName() === $thisReflection->getName()) {
return self::$ancestors[$description][$className] = $this->currentAncestors[$className] = $this;
}
Expand All @@ -1149,7 +1173,7 @@ public function getAncestorWithClassName(string $className): ?TypeWithClassName
}
}

return null;
return self::$ancestors[$description][$className] = $this->currentAncestors[$className] = null;
}

private function getParent(): ?ObjectType
Expand Down

0 comments on commit 22f755c

Please sign in to comment.