Skip to content

[DI] Autodiscover TypeMapper via most-specific match - #8372

Merged
TomasVotruba merged 3 commits into
mainfrom
typemapper-autodiscover
Aug 25, 2026
Merged

[DI] Autodiscover TypeMapper via most-specific match#8372
TomasVotruba merged 3 commits into
mainfrom
typemapper-autodiscover

Conversation

@TomasVotruba

Copy link
Copy Markdown
Member

One of three parallel experiments removing order-sensitive registerTagged() collections in favor of autodiscover().

TypeMapper could not be autodiscovered before because PHPStanStaticTypeMapper matched mappers by first instanceof match in registration order — a mapper for a child type (ConstantArrayType) had to be registered before the mapper for its parent (ArrayType), or the parent would always win. autodiscover() uses filesystem order, which does not honor that.

This removes the order dependency instead of encoding it: the consumer now picks the most specific matching mapper (deepest in the type hierarchy), so registration order no longer matters.

privatefunctionmatchTypeMapper(Type$type): ?TypeMapperInterface
{
$matchedTypeMapper = null;
$matchedNodeClass = null;
foreach ($this->typeMappersas$typeMapper) {
foreach ($typeMapper->getNodeClasses() as$nodeClass) {
if (! $typeinstanceof$nodeClass) {
continue;
}
if ($matchedNodeClass === null || is_a($nodeClass, $matchedNodeClass, true)) {
$matchedNodeClass = $nodeClass;
$matchedTypeMapper = $typeMapper;
}
}
}
return$matchedTypeMapper;
}

With that, TYPE_MAPPER_CLASSES (29 entries) drops to a single autodiscover() call, and the now-obsolete TypeMapperOrderTest (which guarded the old registration-order invariant) is removed.

Verified directly against the real mappers:

TypeResolves to
ConstantArrayTypeArrayShapeNode (specific, not the generic array mapper)
ClassStringTypeclass-string (not the StringType mapper)
ObjectType\Foo (not the TypeWithClassName mapper)

Interface added to the class-leak skip list (implementors are now discovered, not referenced).

@TomasVotruba
TomasVotrubaforce-pushed the typemapper-autodiscover branch from 98cdf42 to 1641750CompareAugust 25, 2026 07:31
@TomasVotruba
TomasVotruba enabled auto-merge (squash) August 25, 2026 07:57
@TomasVotruba
TomasVotruba merged commit ba9c1c1 into mainAug 25, 2026
43 of 44 checks passed
@TomasVotruba
TomasVotruba deleted the typemapper-autodiscover branch August 25, 2026 08:05
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@TomasVotruba@actions-user