Skip to content

Commit 426d662

Browse files
committed
getComponent() by default does not return null for unknown components
1 parent 157a414 commit 426d662

4 files changed

+26
-5
lines changed

src/Type/Nette/ComponentModelArrayAccessDynamicReturnTypeExtension.php

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use PHPStan\Reflection\MethodReflection;
88
use PHPStan\Reflection\ParametersAcceptorSelector;
99
use PHPStan\Type\DynamicMethodReturnTypeExtension;
10+
use PHPStan\Type\NullType;
1011
use PHPStan\Type\Type;
1112
use PHPStan\Type\TypeCombinator;
1213
use function count;
@@ -36,6 +37,7 @@ public function getTypeFromMethodCall(
3637
{
3738
$calledOnType = $scope->getType($methodCall->var);
3839
$defaultType = ParametersAcceptorSelector::selectSingle($calledOnType->getMethod('createComponent', $scope)->getVariants())->getReturnType();
40+
$defaultType = TypeCombinator::remove($defaultType, new NullType());
3941
$args = $methodCall->getArgs();
4042
if (count($args) !== 1) {
4143
return $defaultType;

src/Type/Nette/ComponentModelDynamicReturnTypeExtension.php

+14-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use PHPStan\Reflection\MethodReflection;
88
use PHPStan\Reflection\ParametersAcceptorSelector;
99
use PHPStan\Type\DynamicMethodReturnTypeExtension;
10+
use PHPStan\Type\NullType;
1011
use PHPStan\Type\Type;
1112
use PHPStan\Type\TypeCombinator;
1213
use function count;
@@ -37,10 +38,22 @@ public function getTypeFromMethodCall(
3738
$calledOnType = $scope->getType($methodCall->var);
3839
$defaultType = ParametersAcceptorSelector::selectSingle($calledOnType->getMethod('createComponent', $scope)->getVariants())->getReturnType();
3940
$args = $methodCall->getArgs();
40-
if (count($args) !== 1) {
41+
if (count($args) < 1) {
4142
return $defaultType;
4243
}
4344

45+
$throw = true;
46+
if (isset($args[1])) {
47+
$throwType = $scope->getType($args[1]->value);
48+
if ($throwType->isTrue()->no()) {
49+
$throw = false;
50+
}
51+
}
52+
53+
if ($throw) {
54+
$defaultType = TypeCombinator::remove($defaultType, new NullType());
55+
}
56+
4457
$argType = $scope->getType($args[0]->value);
4558
if (count($argType->getConstantStrings()) === 0) {
4659
return $defaultType;

tests/Type/Nette/data/componentModel.php

+8-2
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,19 @@ public function createComponent(string $name): AnotherControl {
3535

3636
$someControl = new SomeControl();
3737
assertType('PHPStan\Type\Nette\Data\ComponentModel\SomeControl', $someControl->getComponent('some'));
38-
assertType('Nette\ComponentModel\IComponent|null', $someControl->getComponent('unknown'));
38+
assertType('Nette\ComponentModel\IComponent', $someControl->getComponent('unknown'));
39+
assertType('Nette\ComponentModel\IComponent|null', $someControl->getComponent('unknown', false));
40+
assertType('Nette\ComponentModel\IComponent', $someControl->getComponent('unknown', true));
3941

4042
$anotherControl = new AnotherControl();
4143
assertType('PHPStan\Type\Nette\Data\ComponentModel\AnotherControl', $anotherControl->getComponent('another'));
4244
assertType('PHPStan\Type\Nette\Data\ComponentModel\SomeControl', $anotherControl->getComponent('some'));
43-
assertType('Nette\ComponentModel\IComponent|null', $anotherControl->getComponent('unknown'));
45+
assertType('Nette\ComponentModel\IComponent', $anotherControl->getComponent('unknown'));
46+
assertType('Nette\ComponentModel\IComponent|null', $anotherControl->getComponent('unknown', false));
47+
assertType('Nette\ComponentModel\IComponent', $anotherControl->getComponent('unknown', true));
4448

4549
$overrideCreateControl = new OverrideCreateControl();
4650
assertType('PHPStan\Type\Nette\Data\ComponentModel\AnotherControl', $overrideCreateControl->getComponent('some'));
4751
assertType('PHPStan\Type\Nette\Data\ComponentModel\AnotherControl', $overrideCreateControl->getComponent('unknown'));
52+
assertType('PHPStan\Type\Nette\Data\ComponentModel\AnotherControl', $overrideCreateControl->getComponent('unknown', false));
53+
assertType('PHPStan\Type\Nette\Data\ComponentModel\AnotherControl', $overrideCreateControl->getComponent('unknown', true));

tests/Type/Nette/data/componentModelArrayAccess.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,12 @@ public function createComponent(string $name): AnotherControl {
3535

3636
$someControl = new SomeControl();
3737
assertType('PHPStan\Type\Nette\Data\ComponentModelArrayAccess\SomeControl', $someControl['some']);
38-
assertType('Nette\ComponentModel\IComponent|null', $someControl['unknown']);
38+
assertType('Nette\ComponentModel\IComponent', $someControl['unknown']);
3939

4040
$anotherControl = new AnotherControl();
4141
assertType('PHPStan\Type\Nette\Data\ComponentModelArrayAccess\AnotherControl', $anotherControl['another']);
4242
assertType('PHPStan\Type\Nette\Data\ComponentModelArrayAccess\SomeControl', $anotherControl['some']);
43-
assertType('Nette\ComponentModel\IComponent|null', $anotherControl['unknown']);
43+
assertType('Nette\ComponentModel\IComponent', $anotherControl['unknown']);
4444

4545
$overrideCreateControl = new OverrideCreateControl();
4646
assertType('PHPStan\Type\Nette\Data\ComponentModelArrayAccess\AnotherControl', $overrideCreateControl['some']);

0 commit comments

Comments
 (0)