Skip to content

Commit 1229db9

Browse files
uekannuekann
authored andcommitted
Support for arrow functions containing arbitrary expr
1 parent 8585e73 commit 1229db9

File tree

2 files changed

+114
-1
lines changed

2 files changed

+114
-1
lines changed

src/Type/Php/ArrayAllFunctionTypeSpecifyingExtension.php

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44

55
use PhpParser\Node\Expr;
66
use PhpParser\Node\Expr\FuncCall;
7+
use PhpParser\Node\Expr\Variable;
78
use PHPStan\Analyser\Scope;
89
use PHPStan\Analyser\SpecifiedTypes;
910
use PHPStan\Analyser\TypeSpecifier;
1011
use PHPStan\Analyser\TypeSpecifierAwareExtension;
1112
use PHPStan\Analyser\TypeSpecifierContext;
1213
use PHPStan\DependencyInjection\AutowiredService;
14+
use PHPStan\Node\Expr\TypeExpr;
1315
use PHPStan\Reflection\FunctionReflection;
1416
use PHPStan\Type\Constant\ConstantBooleanType;
1517
use PHPStan\ShouldNotHappenException;
@@ -38,12 +40,39 @@ public function specifyTypes(FunctionReflection $functionReflection, FuncCall $n
3840
}
3941

4042
$array = $args[0]->value;
43+
$arrayArgType = $scope->getType($array);
44+
$arrayTypes = $arrayArgType->getArrays();
45+
46+
if(count($arrayTypes) === 0) {
47+
return new SpecifiedTypes();
48+
}
49+
4150
$callable = $args[1]->value;
4251

4352

44-
if ($callable instanceof Expr\ArrowFunction && $callable->expr instanceof Expr\FuncCall) {
53+
// if ($callable instanceof Expr\ArrowFunction && $callable->expr instanceof Expr\FuncCall) {
54+
if ($callable instanceof Expr\ArrowFunction) {
4555

4656
$callableParms = $callable->params;
57+
58+
// foreach($arrayTypes as $arrayType) {
59+
// $keyType = $arrayType->getKeyType();
60+
// $itemType = $arrayType->getItemType();
61+
//
62+
// $variables = [];
63+
//
64+
// if (count($callableParms) < 1) {
65+
// continue;
66+
// }
67+
//
68+
// if ($callableParms[0] ?? null instanceof Expr\Variable) {
69+
// $variables[$callableParms[0]->name] = $itemType;
70+
// }
71+
//
72+
// if ($callableParms[1] ?? null instanceof Expr\Variable) {
73+
// $variables[$callableParms[1]->name] = $keyType;
74+
// }
75+
// }
4776
$specifiedTypesInFuncCall = $this->typeSpecifier->specifyTypesInCondition($scope, $callable->expr, $context)->getSureTypes();
4877

4978
if(count($callableParms) >= 1 && $callableParms[0] instanceof Expr\Variable) {
@@ -87,6 +116,18 @@ public function specifyTypes(FunctionReflection $functionReflection, FuncCall $n
87116
return new SpecifiedTypes();
88117
}
89118

119+
// /**
120+
// * @param array<string, TypeExpr> $paramTypes
121+
// */
122+
// private function replaceVariable(Expr $expr, array $paramTypes) : Expr {
123+
// if ($expr instanceof Variable) {
124+
// $variableName = $expr->name;
125+
// if (isset($paramTypes[$variableName])) {
126+
// return $paramTypes[$variableName];
127+
// }
128+
// } elseif ($expr instanceof )
129+
// }
130+
90131
public function setTypeSpecifier(TypeSpecifier $typeSpecifier): void
91132
{
92133
$this->typeSpecifier = $typeSpecifier;

tests/PHPStan/Analyser/TypeSpecifierTest.php

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1364,6 +1364,78 @@ public static function dataCondition(): iterable
13641364
],
13651365
[]
13661366
],
1367+
[
1368+
new FuncCall(
1369+
new Name("array_all"),
1370+
[
1371+
new Arg(new Variable("array")),
1372+
new Arg(
1373+
new Expr\ArrowFunction(
1374+
[
1375+
'expr' => new Expr\BinaryOp\BooleanAnd(
1376+
new FuncCall(new Name("is_int"), [new Arg(new Variable("value"))]),
1377+
new FuncCall(new Name("is_string"), [new Arg(new Variable("key"))]),
1378+
),
1379+
'params' => [new Variable("value"), new Variable("key")],
1380+
],
1381+
[]
1382+
)
1383+
)
1384+
]
1385+
),
1386+
[
1387+
'$array' => 'array<string, int>'
1388+
],
1389+
[]
1390+
],
1391+
[
1392+
new FuncCall(
1393+
new Name("array_all"),
1394+
[
1395+
new Arg(new Variable("array")),
1396+
new Arg(
1397+
new Expr\ArrowFunction(
1398+
[
1399+
'expr' => new Expr\BinaryOp\BooleanAnd(
1400+
new FuncCall(new Name("is_string"), [new Arg(new Variable("value"))]),
1401+
new FuncCall(new Name("is_numeric"), [new Arg(new Variable("value"))]),
1402+
),
1403+
'params' => [new Variable("value"), new Variable("key")],
1404+
],
1405+
[]
1406+
)
1407+
)
1408+
]
1409+
),
1410+
[
1411+
'$array' => 'array<numeric-string>'
1412+
],
1413+
[]
1414+
],
1415+
[
1416+
new FuncCall(
1417+
new Name("array_all"),
1418+
[
1419+
new Arg(new Variable("array")),
1420+
new Arg(
1421+
new Expr\ArrowFunction(
1422+
[
1423+
'expr' => new Expr\BinaryOp\BooleanOr(
1424+
new FuncCall(new Name("is_float"), [new Arg(new Variable("value"))]),
1425+
new FuncCall(new Name("is_bool"), [new Arg(new Variable("value"))]),
1426+
),
1427+
'params' => [new Variable("value"), new Variable("key")],
1428+
],
1429+
[]
1430+
)
1431+
)
1432+
]
1433+
),
1434+
[
1435+
'$array' => 'array<bool|float>'
1436+
],
1437+
[]
1438+
],
13671439
[
13681440
new FuncCall(
13691441
new Name("array_all"),

0 commit comments

Comments
 (0)