Skip to content

Commit

Permalink
Implement IniGetReturnTypeExtension
Browse files Browse the repository at this point in the history
  • Loading branch information
staabm committed Apr 24, 2023
1 parent 2ae899f commit 7c5bbbf
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 5 deletions.
5 changes: 5 additions & 0 deletions conf/config.neon
Original file line number Diff line number Diff line change
Expand Up @@ -1502,6 +1502,11 @@ services:
tags:
- phpstan.dynamicFunctionThrowTypeExtension

-
class: PHPStan\Type\Php\IniGetReturnTypeExtension
tags:
- phpstan.broker.dynamicFunctionReturnTypeExtension

-
class: PHPStan\Type\Php\JsonThrowTypeExtension
tags:
Expand Down
5 changes: 0 additions & 5 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
62 changes: 62 additions & 0 deletions src/Type/Php/IniGetReturnTypeExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php declare(strict_types = 1);

namespace PHPStan\Type\Php;

use PhpParser\Node\Expr\FuncCall;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\FunctionReflection;
use PHPStan\Type\Accessory\AccessoryNumericStringType;
use PHPStan\Type\DynamicFunctionReturnTypeExtension;
use PHPStan\Type\StringType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeCombinator;
use function array_key_exists;
use function count;

class IniGetReturnTypeExtension implements DynamicFunctionReturnTypeExtension
{

public function isFunctionSupported(FunctionReflection $functionReflection): bool
{
return $functionReflection->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;
}

}
1 change: 1 addition & 0 deletions tests/PHPStan/Analyser/NodeScopeResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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');
}

/**
Expand Down
27 changes: 27 additions & 0 deletions tests/PHPStan/Analyser/data/ini-get.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace IniGet;

use function PHPStan\Testing\assertType;

function doFoo() {
assertType('string', ini_get("date.timezone"));
assertType('string', ini_get("memory_limit"));
assertType('numeric-string', ini_get("max_execution_time"));
assertType('numeric-string', ini_get("max_input_time"));

if (rand(1, 0)) {
$x = ini_get("date.timezone");
} else {
$x = ini_get("max_execution_time");
}
assertType('string', $x);

if (rand(1, 0)) {
$key = 'unknown';
} else {
$key = "max_execution_time";
}
assertType('string|false', ini_get($key));
assertType('string|false', ini_get('unknown'));
}

0 comments on commit 7c5bbbf

Please sign in to comment.