From e9ee834fa8f96b62b34eeeede1283c8648ce15d5 Mon Sep 17 00:00:00 2001 From: Martin Jonas Date: Mon, 11 Nov 2024 17:15:04 +0100 Subject: [PATCH] get_defined_vars() return type contains know variables --- conf/config.neon | 5 ++ ...DefinedVarsFunctionReturnTypeExtension.php | 68 +++++++++++++++++++ .../Analyser/nsrt/get-defined-vars.php | 35 ++++++++++ 3 files changed, 108 insertions(+) create mode 100644 src/Type/Php/GetDefinedVarsFunctionReturnTypeExtension.php create mode 100644 tests/PHPStan/Analyser/nsrt/get-defined-vars.php diff --git a/conf/config.neon b/conf/config.neon index 7d1bf16616..8807c41beb 100644 --- a/conf/config.neon +++ b/conf/config.neon @@ -1427,6 +1427,11 @@ services: tags: - phpstan.broker.dynamicFunctionReturnTypeExtension + - + class: PHPStan\Type\Php\GetDefinedVarsFunctionReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + - class: PHPStan\Type\Php\GetParentClassDynamicFunctionReturnTypeExtension tags: diff --git a/src/Type/Php/GetDefinedVarsFunctionReturnTypeExtension.php b/src/Type/Php/GetDefinedVarsFunctionReturnTypeExtension.php new file mode 100644 index 0000000000..d23e0c7a13 --- /dev/null +++ b/src/Type/Php/GetDefinedVarsFunctionReturnTypeExtension.php @@ -0,0 +1,68 @@ +getName() === 'get_defined_vars'; + } + + public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type + { + if ($scope->canAnyVariableExist()) { + return new ArrayType( + new StringType(), + new MixedType(), + ); + } + + $variables = array_values(array_filter( + $scope->getDefinedVariables(), + static fn ($variable) => $variable !== 'this', + )); + + $maybeVariables = array_values( + $scope->getMaybeDefinedVariables(), + ); + + $keys = array_map( + static fn ($variable) => new ConstantStringType($variable), + array_merge($variables, $maybeVariables), + ); + + $values = array_map( + static fn ($variable) => $scope->getVariableType($variable), + array_merge($variables, $maybeVariables), + ); + + if ($maybeVariables !== []) { + $maybeIndexes = range(count($variables), count($variables) + count($maybeVariables)); + } else { + $maybeIndexes = []; + } + + return new ConstantArrayType($keys, $values, [0], $maybeIndexes); + } + +} diff --git a/tests/PHPStan/Analyser/nsrt/get-defined-vars.php b/tests/PHPStan/Analyser/nsrt/get-defined-vars.php new file mode 100644 index 0000000000..34c9a6afb4 --- /dev/null +++ b/tests/PHPStan/Analyser/nsrt/get-defined-vars.php @@ -0,0 +1,35 @@ +