Skip to content

Commit

Permalink
Handle more PHPStan type edge-cases
Browse files Browse the repository at this point in the history
  • Loading branch information
shish committed Dec 2, 2024
1 parent 6343b3e commit a2037af
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 11 deletions.
42 changes: 32 additions & 10 deletions generator/src/PhpStanFunctions/PhpStanType.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,29 +61,49 @@ public function __construct(string $data, bool $writeOnly = false)
/** @var int $count */
$count = \count($returnTypes);
if ($count === 0) {
throw new \RuntimeException('Error when trying to extract parameter type');
$returnType = '';
}
foreach ($returnTypes as &$returnType) {
$pos = \strpos($returnType, '?');
if ($pos !== false) {
$nullable = true;
$returnType = \str_replace('?', '', $returnType);
}
//remove the parenthesis only if we are not dealing with a callable
if (\strpos($returnType, 'callable') === false) {
// remove the parenthesis only if we are not dealing with a callable
if (!str_contains($returnType, 'callable')) {
$returnType = \str_replace(['(', ')'], '', $returnType);
}
//here we deal with some weird phpstan typings
if ($returnType === 'non-empty-string') {

// here we deal with some weird phpstan typings
if (str_contains($returnType, 'non-falsy-string')) {
$returnType = 'string';
} elseif ($returnType === 'positive-int') {
}

if (str_contains($returnType, 'non-empty-string')) {
$returnType = 'string';
}

if (str_contains($returnType, '__stringAndStringable')) {
$returnType = 'string';
}

if ($returnType === 'positive-int') {
$returnType = 'int';
} elseif (is_numeric($returnType)) {
$returnType = 'int';
}
if (\strpos($returnType, 'list<') !== false) {
if (str_contains($returnType, 'list<')) {
$returnType = \str_replace('list', 'array', $returnType);
}

if (str_contains($returnType, 'int<')) {
$returnType = 'int';
}

if (\preg_match('/__benevolent\<(.*)\>/', $returnType, $regs)) {
$returnType = $regs[1];
}

$returnType = Type::toRootNamespace($returnType);
}
$this->types = array_unique($returnTypes);
Expand Down Expand Up @@ -116,7 +136,7 @@ public function getSignatureType(?int $errorType = null): string
$falsable = $errorType === Method::FALSY_TYPE ? false : $this->falsable;
$types = $this->types;
//no typehint exists for thoses cases
if (\array_intersect(self::NO_SIGNATURE_TYPES, $types)) {
if (\array_intersect(self::NO_SIGNATURE_TYPES, $types) !== []) {
return '';
}

Expand All @@ -137,12 +157,14 @@ public function getSignatureType(?int $errorType = null): string
//if there are several distinct types, no typehint (we use distinct in case doc block contains several times the same type, for example array<int>|array<string>)
if (count(array_unique($types)) > 1) {
return '';
} elseif (\in_array('void', $types) || (count($types) === 0 && !$nullable && !$falsable)) {
}

if (\in_array('void', $types) || ($types === [] && !$nullable && !$falsable)) {
return 'void';
}


$finalType = $types[0];
$finalType = $types[0] ?? '';
if ($finalType === 'bool' && !$nullable && $errorType === Method::FALSY_TYPE) {
// If the function only returns a boolean, since false is for error, true is for success.
// Let's replace this with a "void".
Expand Down
2 changes: 1 addition & 1 deletion generator/tests/PhpStanFunctions/PhpStanTypeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ public function testVoid(): void
{
$param = new PhpStanType('');
$this->assertEquals('', $param->getDocBlockType());
$this->assertEquals('', $param->getSignatureType());
$this->assertEquals('void', $param->getSignatureType());

$param = new PhpStanType('void');
$this->assertEquals('void', $param->getDocBlockType());
Expand Down

0 comments on commit a2037af

Please sign in to comment.