Skip to content

Commit 407c372

Browse files
uekannuekann
authored andcommitted
Support for closures containing only return statements
1 parent 6cfcc89 commit 407c372

File tree

1 file changed

+35
-33
lines changed

1 file changed

+35
-33
lines changed

src/Type/Php/ArrayAllFunctionTypeSpecifyingExtension.php

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use PhpParser\Node\Expr;
66
use PhpParser\Node\Expr\FuncCall;
77
use PhpParser\Node\Expr\Variable;
8+
use PhpParser\Node\Stmt;
89
use PHPStan\Analyser\Scope;
910
use PHPStan\Analyser\SpecifiedTypes;
1011
use PHPStan\Analyser\TypeSpecifier;
@@ -41,44 +42,45 @@ public function specifyTypes(FunctionReflection $functionReflection, FuncCall $n
4142
}
4243

4344
$array = $args[0]->value;
44-
$arrayArgType = $scope->getType($array);
45-
$arrayTypes = $arrayArgType->getArrays();
46-
47-
if (count($arrayTypes) === 0) {
45+
$callable = $args[1]->value;
46+
if ($callable instanceof Expr\ArrowFunction) {
47+
$callableExpr = $callable->expr;
48+
} elseif (
49+
$callable instanceof Expr\Closure &&
50+
count($callable->stmts) === 1 &&
51+
$callable->stmts[0] instanceof Stmt\Return_
52+
) {
53+
$callableExpr = $callable->stmts[0]->expr;
54+
} else {
4855
return new SpecifiedTypes();
4956
}
5057

51-
$callable = $args[1]->value;
58+
$callableParams = $callable->params;
59+
$specifiedTypesInFuncCall = $this->typeSpecifier->specifyTypesInCondition($scope, $callableExpr, $context)->getSureTypes();
5260

53-
if ($callable instanceof Expr\ArrowFunction) {
61+
if (
62+
isset($callableParams[0]) &&
63+
$callableParams[0]->var instanceof Variable &&
64+
is_string($callableParams[0]->var->name)
65+
) {
66+
$valueType = $this->fetchTypeByVariable($specifiedTypesInFuncCall, $callableParams[0]->var->name);
67+
}
68+
69+
if (
70+
isset($callableParams[1]) &&
71+
$callableParams[1]->var instanceof Variable &&
72+
is_string($callableParams[1]->var->name)
73+
) {
74+
$keyType = $this->fetchTypeByVariable($specifiedTypesInFuncCall, $callableParams[1]->var->name);
75+
}
5476

55-
$callableParams = $callable->params;
56-
$specifiedTypesInFuncCall = $this->typeSpecifier->specifyTypesInCondition($scope, $callable->expr, $context)->getSureTypes();
57-
58-
if (
59-
isset($callableParams[0]) &&
60-
$callableParams[0]->var instanceof Variable &&
61-
is_string($callableParams[0]->var->name)
62-
) {
63-
$valueType = $this->fetchTypeByVariable($specifiedTypesInFuncCall, $callableParams[0]->var->name);
64-
}
65-
66-
if (
67-
isset($callableParams[1]) &&
68-
$callableParams[1]->var instanceof Variable &&
69-
is_string($callableParams[1]->var->name)
70-
) {
71-
$keyType = $this->fetchTypeByVariable($specifiedTypesInFuncCall, $callableParams[1]->var->name);
72-
}
73-
74-
if (isset($keyType) || isset($valueType)) {
75-
return $this->typeSpecifier->create(
76-
$array,
77-
new ArrayType($keyType ?? new MixedType(), $valueType ?? new MixedType()),
78-
$context,
79-
$scope,
80-
);
81-
}
77+
if (isset($keyType) || isset($valueType)) {
78+
return $this->typeSpecifier->create(
79+
$array,
80+
new ArrayType($keyType ?? new MixedType(), $valueType ?? new MixedType()),
81+
$context,
82+
$scope,
83+
);
8284
}
8385

8486
return new SpecifiedTypes();

0 commit comments

Comments
 (0)