Skip to content

Commit 7363c95

Browse files
get_defined_vars() return type contains know variables
1 parent 71d01d6 commit 7363c95

File tree

3 files changed

+67
-0
lines changed

3 files changed

+67
-0
lines changed

conf/config.neon

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1427,6 +1427,11 @@ services:
14271427
tags:
14281428
- phpstan.broker.dynamicFunctionReturnTypeExtension
14291429

1430+
-
1431+
class: PHPStan\Type\Php\GetDefinedVarsFunctionReturnTypeExtension
1432+
tags:
1433+
- phpstan.broker.dynamicFunctionReturnTypeExtension
1434+
14301435
-
14311436
class: PHPStan\Type\Php\GetParentClassDynamicFunctionReturnTypeExtension
14321437
tags:
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Type\Php;
4+
5+
use PhpParser\Node\Expr\FuncCall;
6+
use PHPStan\Analyser\Scope;
7+
use PHPStan\Reflection\FunctionReflection;
8+
use PHPStan\Type\ArrayType;
9+
use PHPStan\Type\Constant\ConstantArrayType;
10+
use PHPStan\Type\Constant\ConstantStringType;
11+
use PHPStan\Type\DynamicFunctionReturnTypeExtension;
12+
use PHPStan\Type\MixedType;
13+
use PHPStan\Type\Type;
14+
15+
// based on code by @ruddk
16+
final class GetDefinedVarsFunctionReturnTypeExtension implements DynamicFunctionReturnTypeExtension
17+
{
18+
19+
public function isFunctionSupported(FunctionReflection $functionReflection): bool
20+
{
21+
return $functionReflection->getName() === 'get_defined_vars';
22+
}
23+
24+
public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): ?Type
25+
{
26+
if ($scope->canAnyVariableExist()) {
27+
return new ArrayType(
28+
new StringType(),
29+
new MixedType(),
30+
);
31+
}
32+
33+
$variables = array_values(array_filter(
34+
$scope->getDefinedVariables(),
35+
fn($variable) => $variable !== 'this',
36+
));
37+
38+
$keys = array_map(
39+
fn($variable) => new ConstantStringType($variable),
40+
$variables,
41+
);
42+
43+
$values = array_map(
44+
fn($variable) => $scope->getVariableType($variable),
45+
$variables,
46+
);
47+
48+
return new ConstantArrayType($keys, $values);
49+
}
50+
51+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace GetDefinedVars;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
function doFoo(int $param) {
8+
$local = "foo";
9+
assertType('array{param: int, local: \'foo\'}', get_defined_vars());
10+
assertType('array{\'param\', \'local\'}', array_keys(get_defined_vars()));
11+
}

0 commit comments

Comments
 (0)