From 7c5bbbf1c49dfac73f857cebcdd3f03a343294bc Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Mon, 24 Apr 2023 12:02:01 +0200 Subject: [PATCH] Implement IniGetReturnTypeExtension --- conf/config.neon | 5 ++ phpstan-baseline.neon | 5 -- src/Type/Php/IniGetReturnTypeExtension.php | 62 +++++++++++++++++++ .../Analyser/NodeScopeResolverTest.php | 1 + tests/PHPStan/Analyser/data/ini-get.php | 27 ++++++++ 5 files changed, 95 insertions(+), 5 deletions(-) create mode 100644 src/Type/Php/IniGetReturnTypeExtension.php create mode 100644 tests/PHPStan/Analyser/data/ini-get.php diff --git a/conf/config.neon b/conf/config.neon index 22876a235d..2bdb6ef0e0 100644 --- a/conf/config.neon +++ b/conf/config.neon @@ -1502,6 +1502,11 @@ services: tags: - phpstan.dynamicFunctionThrowTypeExtension + - + class: PHPStan\Type\Php\IniGetReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + - class: PHPStan\Type\Php\JsonThrowTypeExtension tags: diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 4e6b0f3aa3..6084834567 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -141,11 +141,6 @@ parameters: count: 1 path: src/Command/FixerApplication.php - - - message: "#^Parameter \\#1 \\$arg of function escapeshellarg expects string, string\\|false given\\.$#" - count: 1 - path: src/Command/FixerApplication.php - - message: "#^Call to an undefined method React\\\\Promise\\\\PromiseInterface\\:\\:done\\(\\)\\.$#" count: 1 diff --git a/src/Type/Php/IniGetReturnTypeExtension.php b/src/Type/Php/IniGetReturnTypeExtension.php new file mode 100644 index 0000000000..31d1ad9ba4 --- /dev/null +++ b/src/Type/Php/IniGetReturnTypeExtension.php @@ -0,0 +1,62 @@ +getName() === 'ini_get'; + } + + public function getTypeFromFunctionCall( + FunctionReflection $functionReflection, + FuncCall $functionCall, + Scope $scope, + ): ?Type + { + $args = $functionCall->getArgs(); + if (count($args) < 1) { + return null; + } + + $numericString = TypeCombinator::intersect( + new StringType(), + new AccessoryNumericStringType(), + ); + $types = [ + 'date.timezone' => new StringType(), + 'memory_limit' => new StringType(), + 'max_execution_time' => $numericString, + 'max_input_time' => $numericString, + ]; + + $argType = $scope->getType($args[0]->value); + $results = []; + foreach ($argType->getConstantStrings() as $constantString) { + if (!array_key_exists($constantString->getValue(), $types)) { + return null; + } + $results[] = $types[$constantString->getValue()]; + } + + if (count($results) > 0) { + return TypeCombinator::union(...$results); + } + + return null; + } + +} diff --git a/tests/PHPStan/Analyser/NodeScopeResolverTest.php b/tests/PHPStan/Analyser/NodeScopeResolverTest.php index ed101f5642..d5b9218b9a 100644 --- a/tests/PHPStan/Analyser/NodeScopeResolverTest.php +++ b/tests/PHPStan/Analyser/NodeScopeResolverTest.php @@ -1245,6 +1245,7 @@ public function dataFileAsserts(): iterable yield from $this->gatherAssertTypes(__DIR__ . '/data/object-shape.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/memcache-get.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-4302b.php'); + yield from $this->gatherAssertTypes(__DIR__ . '/data/ini-get.php'); } /** diff --git a/tests/PHPStan/Analyser/data/ini-get.php b/tests/PHPStan/Analyser/data/ini-get.php new file mode 100644 index 0000000000..c63f014bbd --- /dev/null +++ b/tests/PHPStan/Analyser/data/ini-get.php @@ -0,0 +1,27 @@ +