Skip to content

Commit ecab3bd

Browse files
adaamzondrejmirtes
authored andcommitted
Component::lookup return type extension
1 parent 9d0069a commit ecab3bd

File tree

3 files changed

+52
-0
lines changed

3 files changed

+52
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ This extension provides following features:
1212
* `Nette\ComponentModel\Container::getComponent()` knows type of the component because it reads the return type on `createComponent*` (this works best in presenters and controls)
1313
* `Nette\DI\Container::getByType` and `createInstance` return type based on first parameter (`Foo::class`).
1414
* `Nette\Forms\Container::getValues` return type based on `$asArray` parameter.
15+
* `Nette\ComponentModel\Component::lookup` return type based on `$throw` parameter.
1516
* Dynamic methods of [Nette\Utils\Html](https://doc.nette.org/en/2.4/html-elements)
1617
* Magic [Nette\Object and Nette\SmartObject](https://doc.nette.org/en/2.4/php-language-enhancements) properties
1718
* Event listeners through the `on*` properties

extension.neon

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ services:
3333
tags:
3434
- phpstan.broker.dynamicMethodReturnTypeExtension
3535

36+
-
37+
class: PHPStan\Type\Nette\ComponentLookupDynamicReturnTypeExtension
38+
tags:
39+
- phpstan.broker.dynamicMethodReturnTypeExtension
40+
3641
-
3742
class: PHPStan\Type\Nette\FormsBaseControlDynamicReturnTypeExtension
3843
tags:
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Type\Nette;
4+
5+
use PhpParser\Node\Expr\MethodCall;
6+
use PHPStan\Analyser\Scope;
7+
use PHPStan\Reflection\MethodReflection;
8+
use PHPStan\Type\Constant\ConstantBooleanType;
9+
use PHPStan\Type\DynamicMethodReturnTypeExtension;
10+
use PHPStan\Type\Type;
11+
use PHPStan\Type\TypeCombinator;
12+
13+
final class ComponentLookupDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension
14+
{
15+
16+
public function getClass(): string
17+
{
18+
return \Nette\ComponentModel\Component::class;
19+
}
20+
21+
public function isMethodSupported(MethodReflection $methodReflection): bool
22+
{
23+
return $methodReflection->getName() === 'lookup';
24+
}
25+
26+
public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): Type
27+
{
28+
if (count($methodCall->args) < 2) {
29+
return $methodReflection->getReturnType();
30+
}
31+
32+
$paramNeedExpr = $methodCall->args[1]->value;
33+
$paramNeedType = $scope->getType($paramNeedExpr);
34+
35+
if ($paramNeedType instanceof ConstantBooleanType) {
36+
if ($paramNeedType->getValue()) {
37+
return TypeCombinator::removeNull($methodReflection->getReturnType());
38+
}
39+
40+
return TypeCombinator::addNull($methodReflection->getReturnType());
41+
}
42+
43+
return $methodReflection->getReturnType();
44+
}
45+
46+
}

0 commit comments

Comments
 (0)