Skip to content

Commit 2fe4e0f

Browse files
committed
Infer types of StaticPropertyFetch with a dynamic name
1 parent 244093e commit 2fe4e0f

File tree

1 file changed

+44
-36
lines changed

1 file changed

+44
-36
lines changed

src/Analyser/MutatingScope.php

+44-36
Original file line numberDiff line numberDiff line change
@@ -2212,52 +2212,60 @@ static function (Node $node, Scope $scope) use ($arrowScope, &$arrowFunctionImpu
22122212
);
22132213
}
22142214

2215-
if (
2216-
$node instanceof Expr\StaticPropertyFetch
2217-
&& $node->name instanceof Node\VarLikeIdentifier
2218-
) {
2219-
if ($this->nativeTypesPromoted) {
2220-
$propertyReflection = $this->propertyReflectionFinder->findPropertyReflectionFromNode($node, $this);
2221-
if ($propertyReflection === null) {
2222-
return new ErrorType();
2223-
}
2224-
if (!$propertyReflection->hasNativeType()) {
2225-
return new MixedType();
2226-
}
2215+
if ($node instanceof Expr\StaticPropertyFetch) {
2216+
if ($node->name instanceof Node\VarLikeIdentifier) {
2217+
if ($this->nativeTypesPromoted) {
2218+
$propertyReflection = $this->propertyReflectionFinder->findPropertyReflectionFromNode($node, $this);
2219+
if ($propertyReflection === null) {
2220+
return new ErrorType();
2221+
}
2222+
if (!$propertyReflection->hasNativeType()) {
2223+
return new MixedType();
2224+
}
22272225

2228-
$nativeType = $propertyReflection->getNativeType();
2226+
$nativeType = $propertyReflection->getNativeType();
22292227

2230-
if ($node->class instanceof Expr) {
2231-
return $this->getNullsafeShortCircuitingType($node->class, $nativeType);
2228+
if ($node->class instanceof Expr) {
2229+
return $this->getNullsafeShortCircuitingType($node->class, $nativeType);
2230+
}
2231+
2232+
return $nativeType;
22322233
}
22332234

2234-
return $nativeType;
2235-
}
2235+
$typeCallback = function () use ($node): Type {
2236+
if ($node->class instanceof Name) {
2237+
$staticPropertyFetchedOnType = $this->resolveTypeByName($node->class);
2238+
} else {
2239+
$staticPropertyFetchedOnType = TypeCombinator::removeNull($this->getType($node->class))->getObjectTypeOrClassStringObjectType();
2240+
}
22362241

2237-
$typeCallback = function () use ($node): Type {
2238-
if ($node->class instanceof Name) {
2239-
$staticPropertyFetchedOnType = $this->resolveTypeByName($node->class);
2240-
} else {
2241-
$staticPropertyFetchedOnType = TypeCombinator::removeNull($this->getType($node->class))->getObjectTypeOrClassStringObjectType();
2242-
}
2242+
$returnType = $this->propertyFetchType(
2243+
$staticPropertyFetchedOnType,
2244+
$node->name->toString(),
2245+
$node,
2246+
);
2247+
if ($returnType === null) {
2248+
return new ErrorType();
2249+
}
2250+
return $returnType;
2251+
};
22432252

2244-
$returnType = $this->propertyFetchType(
2245-
$staticPropertyFetchedOnType,
2246-
$node->name->toString(),
2247-
$node,
2248-
);
2249-
if ($returnType === null) {
2250-
return new ErrorType();
2253+
$fetchType = $typeCallback();
2254+
if ($node->class instanceof Expr) {
2255+
return $this->getNullsafeShortCircuitingType($node->class, $fetchType);
22512256
}
2252-
return $returnType;
2253-
};
22542257

2255-
$fetchType = $typeCallback();
2256-
if ($node->class instanceof Expr) {
2257-
return $this->getNullsafeShortCircuitingType($node->class, $fetchType);
2258+
return $fetchType;
22582259
}
22592260

2260-
return $fetchType;
2261+
$nameType = $this->getType($node->name);
2262+
if (count($nameType->getConstantStrings()) > 0) {
2263+
return TypeCombinator::union(
2264+
...array_map(fn ($constantString) => $this
2265+
->filterByTruthyValue(new BinaryOp\Identical($node->name, new String_($constantString->getValue())))
2266+
->getType(new Expr\StaticPropertyFetch($node->class, new Node\VarLikeIdentifier($constantString->getValue()))), $nameType->getConstantStrings()),
2267+
);
2268+
}
22612269
}
22622270

22632271
if ($node instanceof FuncCall) {

0 commit comments

Comments
 (0)