Skip to content

Commit 91ca651

Browse files
committed
Prevent unnecssary Type traversal
1 parent 8c1d275 commit 91ca651

File tree

3 files changed

+43
-30
lines changed

3 files changed

+43
-30
lines changed

src/Analyser/TypeSpecifier.php

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1545,36 +1545,43 @@ private function specifyTypesFromAsserts(TypeSpecifierContext $context, Expr\Cal
15451545

15461546
foreach ($asserts as $assert) {
15471547
foreach ($argsMap[substr($assert->getParameter()->getParameterName(), 1)] ?? [] as $parameterExpr) {
1548-
$assertedType = TypeTraverser::map($assert->getType(), static function (Type $type, callable $traverse) use ($argsMap, $scope): Type {
1549-
if ($type instanceof ConditionalTypeForParameter) {
1550-
$parameterName = substr($type->getParameterName(), 1);
1551-
if (array_key_exists($parameterName, $argsMap)) {
1552-
$argType = TypeCombinator::union(...array_map(static fn (Expr $expr) => $scope->getType($expr), $argsMap[$parameterName]));
1553-
$type = $type->toConditional($argType);
1548+
$assertedType = $assert->getType();
1549+
1550+
if ($assertedType->hasTemplateOrLateResolvableType()) {
1551+
$assertedType = TypeTraverser::map($assertedType, static function (Type $type, callable $traverse) use ($argsMap, $scope): Type {
1552+
if ($type instanceof ConditionalTypeForParameter) {
1553+
$parameterName = substr($type->getParameterName(), 1);
1554+
if (array_key_exists($parameterName, $argsMap)) {
1555+
$argType = TypeCombinator::union(...array_map(static fn (Expr $expr) => $scope->getType($expr), $argsMap[$parameterName]));
1556+
$type = $type->toConditional($argType);
1557+
}
15541558
}
1555-
}
15561559

1557-
return $traverse($type);
1558-
});
1560+
return $traverse($type);
1561+
});
1562+
}
15591563

15601564
$assertExpr = $assert->getParameter()->getExpr($parameterExpr);
15611565

1562-
$templateTypeMap = $parametersAcceptor->getResolvedTemplateTypeMap();
15631566
$containsUnresolvedTemplate = false;
1564-
TypeTraverser::map(
1565-
$assert->getOriginalType(),
1566-
static function (Type $type, callable $traverse) use ($templateTypeMap, &$containsUnresolvedTemplate) {
1567-
if ($type instanceof TemplateType && $type->getScope()->getClassName() !== null) {
1568-
$resolvedType = $templateTypeMap->getType($type->getName());
1569-
if ($resolvedType === null || $type->getBound()->equals($resolvedType)) {
1570-
$containsUnresolvedTemplate = true;
1571-
return $type;
1567+
if ($assert->getOriginalType()->hasTemplateOrLateResolvableType()) {
1568+
$templateTypeMap = $parametersAcceptor->getResolvedTemplateTypeMap();
1569+
1570+
TypeTraverser::map(
1571+
$assert->getOriginalType(),
1572+
static function (Type $type, callable $traverse) use ($templateTypeMap, &$containsUnresolvedTemplate) {
1573+
if ($type instanceof TemplateType && $type->getScope()->getClassName() !== null) {
1574+
$resolvedType = $templateTypeMap->getType($type->getName());
1575+
if ($resolvedType === null || $type->getBound()->equals($resolvedType)) {
1576+
$containsUnresolvedTemplate = true;
1577+
return $type;
1578+
}
15721579
}
1573-
}
15741580

1575-
return $traverse($type);
1576-
},
1577-
);
1581+
return $traverse($type);
1582+
},
1583+
);
1584+
}
15781585

15791586
$newTypes = $this->create(
15801587
$assertExpr,

src/Rules/FunctionDefinitionCheck.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,10 @@ private function checkParametersAcceptor(
561561
$templateTypes = $templateTypeMap->getTypes();
562562
if (count($templateTypes) > 0) {
563563
foreach ($parametersAcceptor->getParameters() as $parameter) {
564+
if (!$parameter->getType()->hasTemplateOrLateResolvableType()) {
565+
continue;
566+
}
567+
564568
TypeTraverser::map($parameter->getType(), static function (Type $type, callable $traverse) use (&$templateTypes): Type {
565569
if ($type instanceof TemplateType) {
566570
unset($templateTypes[$type->getName()]);

src/Rules/PhpDoc/ConditionalReturnTypeRuleHelper.php

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,16 @@ public function check(ExtendedParametersAcceptor $acceptor): array
7777
continue;
7878
}
7979
$templateTypes = [];
80-
TypeTraverser::map($subjectType, static function (Type $type, callable $traverse) use (&$templateTypes): Type {
81-
if ($type instanceof TemplateType) {
82-
$templateTypes[] = $type;
83-
return $type;
84-
}
85-
86-
return $traverse($type);
87-
});
80+
if ($subjectType->hasTemplateOrLateResolvableType()) {
81+
TypeTraverser::map($subjectType, static function (Type $type, callable $traverse) use (&$templateTypes): Type {
82+
if ($type instanceof TemplateType) {
83+
$templateTypes[] = $type;
84+
return $type;
85+
}
86+
87+
return $traverse($type);
88+
});
89+
}
8890

8991
if (count($templateTypes) === 0) {
9092
$errors[] = RuleErrorBuilder::message(sprintf('Conditional return type uses subject type %s which is not part of PHPDoc @template tags.', $subjectType->describe(VerbosityLevel::typeOnly())))

0 commit comments

Comments
 (0)