Skip to content

Commit a2037af

Browse files
committed
Handle more PHPStan type edge-cases
1 parent 6343b3e commit a2037af

File tree

2 files changed

+33
-11
lines changed

2 files changed

+33
-11
lines changed

generator/src/PhpStanFunctions/PhpStanType.php

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -61,29 +61,49 @@ public function __construct(string $data, bool $writeOnly = false)
6161
/** @var int $count */
6262
$count = \count($returnTypes);
6363
if ($count === 0) {
64-
throw new \RuntimeException('Error when trying to extract parameter type');
64+
$returnType = '';
6565
}
6666
foreach ($returnTypes as &$returnType) {
6767
$pos = \strpos($returnType, '?');
6868
if ($pos !== false) {
6969
$nullable = true;
7070
$returnType = \str_replace('?', '', $returnType);
7171
}
72-
//remove the parenthesis only if we are not dealing with a callable
73-
if (\strpos($returnType, 'callable') === false) {
72+
// remove the parenthesis only if we are not dealing with a callable
73+
if (!str_contains($returnType, 'callable')) {
7474
$returnType = \str_replace(['(', ')'], '', $returnType);
7575
}
76-
//here we deal with some weird phpstan typings
77-
if ($returnType === 'non-empty-string') {
76+
77+
// here we deal with some weird phpstan typings
78+
if (str_contains($returnType, 'non-falsy-string')) {
7879
$returnType = 'string';
79-
} elseif ($returnType === 'positive-int') {
80+
}
81+
82+
if (str_contains($returnType, 'non-empty-string')) {
83+
$returnType = 'string';
84+
}
85+
86+
if (str_contains($returnType, '__stringAndStringable')) {
87+
$returnType = 'string';
88+
}
89+
90+
if ($returnType === 'positive-int') {
8091
$returnType = 'int';
8192
} elseif (is_numeric($returnType)) {
8293
$returnType = 'int';
8394
}
84-
if (\strpos($returnType, 'list<') !== false) {
95+
if (str_contains($returnType, 'list<')) {
8596
$returnType = \str_replace('list', 'array', $returnType);
8697
}
98+
99+
if (str_contains($returnType, 'int<')) {
100+
$returnType = 'int';
101+
}
102+
103+
if (\preg_match('/__benevolent\<(.*)\>/', $returnType, $regs)) {
104+
$returnType = $regs[1];
105+
}
106+
87107
$returnType = Type::toRootNamespace($returnType);
88108
}
89109
$this->types = array_unique($returnTypes);
@@ -116,7 +136,7 @@ public function getSignatureType(?int $errorType = null): string
116136
$falsable = $errorType === Method::FALSY_TYPE ? false : $this->falsable;
117137
$types = $this->types;
118138
//no typehint exists for thoses cases
119-
if (\array_intersect(self::NO_SIGNATURE_TYPES, $types)) {
139+
if (\array_intersect(self::NO_SIGNATURE_TYPES, $types) !== []) {
120140
return '';
121141
}
122142

@@ -137,12 +157,14 @@ public function getSignatureType(?int $errorType = null): string
137157
//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>)
138158
if (count(array_unique($types)) > 1) {
139159
return '';
140-
} elseif (\in_array('void', $types) || (count($types) === 0 && !$nullable && !$falsable)) {
160+
}
161+
162+
if (\in_array('void', $types) || ($types === [] && !$nullable && !$falsable)) {
141163
return 'void';
142164
}
143165

144166

145-
$finalType = $types[0];
167+
$finalType = $types[0] ?? '';
146168
if ($finalType === 'bool' && !$nullable && $errorType === Method::FALSY_TYPE) {
147169
// If the function only returns a boolean, since false is for error, true is for success.
148170
// Let's replace this with a "void".

generator/tests/PhpStanFunctions/PhpStanTypeTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ public function testVoid(): void
111111
{
112112
$param = new PhpStanType('');
113113
$this->assertEquals('', $param->getDocBlockType());
114-
$this->assertEquals('', $param->getSignatureType());
114+
$this->assertEquals('void', $param->getSignatureType());
115115

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

0 commit comments

Comments
 (0)