Skip to content

Commit

Permalink
Replace highlight_string() stub with a return type extension
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Aug 26, 2024
1 parent f670288 commit bb4fdfc
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 7 deletions.
5 changes: 5 additions & 0 deletions conf/config.neon
Original file line number Diff line number Diff line change
Expand Up @@ -1497,6 +1497,11 @@ services:
tags:
- phpstan.broker.dynamicFunctionReturnTypeExtension

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

-
class: PHPStan\Type\Php\IntdivThrowTypeExtension
tags:
Expand Down
5 changes: 5 additions & 0 deletions src/Php/PhpVersion.php
Original file line number Diff line number Diff line change
Expand Up @@ -343,4 +343,9 @@ public function hasExitAsFunction(): bool
return $this->versionId >= 80400;
}

public function highlightStringDoesNotReturnFalse(): bool
{
return $this->versionId >= 80400;
}

}
51 changes: 51 additions & 0 deletions src/Type/Php/HighlightStringDynamicReturnTypeExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php declare(strict_types = 1);

namespace PHPStan\Type\Php;

use PhpParser\Node\Expr\FuncCall;
use PHPStan\Analyser\Scope;
use PHPStan\Php\PhpVersion;
use PHPStan\Reflection\FunctionReflection;
use PHPStan\Type\BooleanType;
use PHPStan\Type\Constant\ConstantBooleanType;
use PHPStan\Type\DynamicFunctionReturnTypeExtension;
use PHPStan\Type\StringType;
use PHPStan\Type\Type;
use function count;

final class HighlightStringDynamicReturnTypeExtension implements DynamicFunctionReturnTypeExtension
{

public function __construct(private PhpVersion $phpVersion)
{
}

public function isFunctionSupported(FunctionReflection $functionReflection): bool
{
return $functionReflection->getName() === 'highlight_string';
}

public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type
{
$args = $functionCall->getArgs();
if (count($args) < 2) {
if ($this->phpVersion->highlightStringDoesNotReturnFalse()) {
return new ConstantBooleanType(true);
}

return new BooleanType();
}

$returnType = $scope->getType($args[1]->value);
if ($returnType->isTrue()->yes()) {
return new StringType();
}

if ($this->phpVersion->highlightStringDoesNotReturnFalse()) {
return new ConstantBooleanType(true);
}

return new BooleanType();
}

}
6 changes: 0 additions & 6 deletions stubs/core.stub
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,6 @@ function highlight_file($var, bool $return = false) {}
*/
function show_source($var, bool $return = false) {}

/**
* @param mixed $var
* @return ($return is true ? string : bool)
*/
function highlight_string($var, bool $return = false) {}

/**
* @param mixed $var
* @param bool $return
Expand Down
35 changes: 35 additions & 0 deletions tests/PHPStan/Analyser/nsrt/pr-1244-php-84.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php // lint >= 8.4

namespace Pr1244Php84;

use function PHPStan\Testing\assertType;

function foo() {
/** @var string $string */
$string = doFoo();

assertType('null', var_export());
assertType('null', var_export($string));
assertType('null', var_export($string, false));
assertType('string', var_export($string, true));

assertType('true', highlight_string());
assertType('true', highlight_string($string));
assertType('true', highlight_string($string, false));
assertType('string', highlight_string($string, true));

assertType('bool', highlight_file());
assertType('bool', highlight_file($string));
assertType('bool', highlight_file($string, false));
assertType('string', highlight_file($string, true));

assertType('bool', show_source());
assertType('bool', show_source($string));
assertType('bool', show_source($string, false));
assertType('string', show_source($string, true));

assertType('true', print_r());
assertType('true', print_r($string));
assertType('true', print_r($string, false));
assertType('string', print_r($string, true));
}
2 changes: 1 addition & 1 deletion tests/PHPStan/Analyser/nsrt/pr-1244.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?php
<?php // lint < 8.4

namespace Pr1244;

Expand Down

0 comments on commit bb4fdfc

Please sign in to comment.