Skip to content

Commit 2bcc4ab

Browse files
committed
Verify that all stubs have a return type
1 parent d2c92d7 commit 2bcc4ab

27 files changed

+121
-26
lines changed

Zend/zend_closures.stub.php

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ static function bind(Closure $closure, ?object $newthis, $newscope = UNKNOWN) {}
1010
/** @return ?Closure */
1111
function bindTo(?object $newthis, $newscope = UNKNOWN) {}
1212

13+
/** @return mixed */
1314
function call(object $newthis, ...$parameters) {}
1415

1516
/**

Zend/zend_exceptions.stub.php

+1
Original file line numberDiff line numberDiff line change
@@ -60,5 +60,6 @@ class ErrorException extends Exception
6060
{
6161
function __construct(string $message = UNKNOWN, int $code = 0, int $severity = E_ERROR, string $filename = UNKNOWN, int $lineno = 0, ?Throwable $previous = null) {}
6262

63+
/** @return int */
6364
final function getSeverity() {}
6465
}

Zend/zend_generators.stub.php

+5
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,20 @@ function rewind(): void {}
66

77
function valid(): bool {}
88

9+
/** @return mixed */
910
function current() {}
1011

12+
/** @return mixed */
1113
function key() {}
1214

1315
function next(): void {}
1416

17+
/** @return mixed */
1518
function send($value) {}
1619

20+
/** @return mixed */
1721
function throw(Throwable $exception) {}
1822

23+
/** @return mixed */
1924
function getReturn() {}
2025
}

Zend/zend_interfaces.stub.php

+7
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ function getIterator();
1010

1111
interface Iterator extends Traversable
1212
{
13+
/** @return mixed */
1314
function current();
1415

1516
/** @return void */
1617
function next();
1718

19+
/** @return mixed */
1820
function key();
1921

2022
/** @return bool */
@@ -26,13 +28,17 @@ function rewind();
2628

2729
interface ArrayAccess
2830
{
31+
/** @return bool */
2932
function offsetExists($offset);
3033

3134
/* actually this should be return by ref but atm cannot be */
35+
/** @return mixed */
3236
function offsetGet($offset);
3337

38+
/** @return void */
3439
function offsetSet($offset, $value);
3540

41+
/** @return void */
3642
function offsetUnset($offset);
3743
}
3844

@@ -41,6 +47,7 @@ interface Serializable
4147
/** @return string */
4248
function serialize();
4349

50+
/** @return void */
4451
function unserialize(string $serialized);
4552
}
4653

build/gen_stub.php

+56-7
Original file line numberDiff line numberDiff line change
@@ -385,25 +385,70 @@ public function getAllFuncInfos(): iterable {
385385
}
386386
}
387387

388+
class DocCommentTag {
389+
/** @var string */
390+
public $name;
391+
/** @var ?string */
392+
public $value;
393+
394+
public function __construct(string $name, ?string $value) {
395+
$this->name = $name;
396+
$this->value = $value;
397+
}
398+
399+
public function getValue(): string {
400+
if ($this->value === null) {
401+
throw new Exception("@$this->name does not have a value");
402+
}
403+
404+
return $this->value;
405+
}
406+
407+
public function getVariableName(): string {
408+
$value = $this->getValue();
409+
if ($value === null || strlen($value) === 0 || $value[0] !== '$') {
410+
throw new Exception("@$this->name not followed by variable name");
411+
}
412+
413+
return substr($value, 1);
414+
}
415+
}
416+
417+
/** @return DocCommentTag[] */
418+
function parseDocComment(DocComment $comment): array {
419+
$commentText = substr($comment->getText(), 2, -2);
420+
$tags = [];
421+
foreach (explode("\n", $commentText) as $commentLine) {
422+
$regex = '/^\*\s*@([a-z-]+)(?:\s+(.+))$/';
423+
if (preg_match($regex, trim($commentLine), $matches, PREG_UNMATCHED_AS_NULL)) {
424+
$tags[] = new DocCommentTag($matches[1], $matches[2]);
425+
}
426+
}
427+
428+
return $tags;
429+
}
430+
388431
function parseFunctionLike(
389432
string $name, ?string $className, Node\FunctionLike $func, ?string $cond
390433
): FuncInfo {
391434
$comment = $func->getDocComment();
392435
$paramMeta = [];
393436
$alias = null;
437+
$haveDocReturnType = false;
394438

395439
if ($comment) {
396-
$commentText = substr($comment->getText(), 2, -2);
397-
398-
foreach (explode("\n", $commentText) as $commentLine) {
399-
if (preg_match('/^\*\s*@prefer-ref\s+\$(.+)$/', trim($commentLine), $matches)) {
400-
$varName = $matches[1];
440+
$tags = parseDocComment($comment);
441+
foreach ($tags as $tag) {
442+
if ($tag->name === 'prefer-ref') {
443+
$varName = $tag->getVariableName();
401444
if (!isset($paramMeta[$varName])) {
402445
$paramMeta[$varName] = [];
403446
}
404447
$paramMeta[$varName]['preferRef'] = true;
405-
} else if (preg_match('/^\*\s*@alias\s+(.+)$/', trim($commentLine), $matches)) {
406-
$alias = $matches[1];
448+
} else if ($tag->name === 'alias') {
449+
$alias = $tag->getValue();
450+
} else if ($tag->name === 'return') {
451+
$haveDocReturnType = true;
407452
}
408453
}
409454
}
@@ -455,6 +500,10 @@ function parseFunctionLike(
455500
}
456501

457502
$returnType = $func->getReturnType();
503+
if ($returnType === null && !$haveDocReturnType && substr($name, 0, 2) !== '__') {
504+
throw new Exception("Missing return type for function $name()");
505+
}
506+
458507
$return = new ReturnInfo(
459508
$func->returnsByRef(),
460509
$returnType ? Type::fromNode($returnType) : null);

ext/com_dotnet/com_extension.stub.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ function variant_not($left): variant {}
4040

4141
function variant_round($left, int $decimals): ?variant {}
4242

43-
function variant_cmp($left, $right, int $lcid = UNKNOWN, int $flags = 0) {}
43+
function variant_cmp($left, $right, int $lcid = UNKNOWN, int $flags = 0): int {}
4444

4545
function variant_date_to_timestamp(variant $variant): ?int {}
4646

@@ -63,4 +63,4 @@ function com_print_typeinfo($comobject, ?string $dispinterface = null, bool $wan
6363

6464
function com_message_pump(int $timeoutms = 0): bool {}
6565

66-
function com_load_typelib(string $typelib_name, bool $case_insensitive = true) {}
66+
function com_load_typelib(string $typelib_name, bool $case_insensitive = true): bool {}

ext/com_dotnet/com_extension_arginfo.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_variant_round, 0, 2, variant, 1)
5151
ZEND_ARG_TYPE_INFO(0, decimals, IS_LONG, 0)
5252
ZEND_END_ARG_INFO()
5353

54-
ZEND_BEGIN_ARG_INFO_EX(arginfo_variant_cmp, 0, 0, 2)
54+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_variant_cmp, 0, 2, IS_LONG, 0)
5555
ZEND_ARG_INFO(0, left)
5656
ZEND_ARG_INFO(0, right)
5757
ZEND_ARG_TYPE_INFO(0, lcid, IS_LONG, 0)
@@ -104,7 +104,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_com_message_pump, 0, 0, _IS_BOOL
104104
ZEND_ARG_TYPE_INFO(0, timeoutms, IS_LONG, 0)
105105
ZEND_END_ARG_INFO()
106106

107-
ZEND_BEGIN_ARG_INFO_EX(arginfo_com_load_typelib, 0, 0, 1)
107+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_com_load_typelib, 0, 1, _IS_BOOL, 0)
108108
ZEND_ARG_TYPE_INFO(0, typelib_name, IS_STRING, 0)
109109
ZEND_ARG_TYPE_INFO(0, case_insensitive, _IS_BOOL, 0)
110110
ZEND_END_ARG_INFO()

ext/dom/domimplementation.stub.php

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
class DOMImplementation
44
{
5+
/** @return void */
56
public function getFeature(string $feature, string $version) {}
67

78
/** @return bool */

ext/dom/xpath.stub.php

+4-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ public function query(string $expr, ?DOMNode $context = null, bool $registerNode
1414
/** @return bool */
1515
public function registerNamespace(string $prefix, string $namespaceURI) {}
1616

17-
/** @param string|array $restrict */
17+
/**
18+
* @param string|array $restrict
19+
* @return bool|null
20+
*/
1821
public function registerPhpFunctions($restrict = null) {}
1922
}
2023
#endif

ext/gd/gd.stub.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ function imagefttext(GdImage $im, float $size, float $angle, int $x, int $y, int
209209

210210
function imagettfbbox(float $size, float $angle, string $font_file, string $text): array|false {}
211211

212-
function imagettftext(GdImage $im, float $size, float $angle, int $x, int $y, int $col, string $font_file, string $text) {}
212+
function imagettftext(GdImage $im, float $size, float $angle, int $x, int $y, int $col, string $font_file, string $text): array|false {}
213213
#endif
214214

215215
function imagefilter(GdImage $im, int $filtertype, $arg1 = UNKNOWN, $arg2 = UNKNOWN, $arg3 = UNKNOWN, $arg4 = UNKNOWN): bool {}

ext/gd/gd_arginfo.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ ZEND_END_ARG_INFO()
483483
#endif
484484

485485
#if defined(HAVE_GD_FREETYPE)
486-
ZEND_BEGIN_ARG_INFO_EX(arginfo_imagettftext, 0, 0, 8)
486+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_imagettftext, 0, 8, MAY_BE_ARRAY|MAY_BE_FALSE)
487487
ZEND_ARG_OBJ_INFO(0, im, GdImage, 0)
488488
ZEND_ARG_TYPE_INFO(0, size, IS_DOUBLE, 0)
489489
ZEND_ARG_TYPE_INFO(0, angle, IS_DOUBLE, 0)

ext/intl/common/common.stub.php

+5
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,18 @@
22

33
class IntlIterator implements Iterator
44
{
5+
/** @return mixed */
56
public function current() {}
67

8+
/** @return mixed */
79
public function key() {}
810

11+
/** @return void */
912
public function next() {}
1013

14+
/** @return void */
1115
public function rewind() {}
1216

17+
/** @return bool */
1318
public function valid() {}
1419
}

ext/json/json.stub.php

+1
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ function json_last_error_msg(): string {}
1111

1212
interface JsonSerializable
1313
{
14+
/** @return mixed */
1415
public function jsonSerialize();
1516
}

ext/phar/phar_object.stub.php

+1
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,7 @@ public function getCRC32() {}
381381
/** @return string */
382382
public function getContent() {}
383383

384+
/** @return mixed */
384385
public function getMetadata() {}
385386

386387
/** @return int */

ext/reflection/php_reflection.stub.php

+9
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,10 @@ public function __toString(): string {}
104104
/** @return bool */
105105
public function isDisabled() {}
106106

107+
/** @return mixed */
107108
public function invoke(...$args) {}
108109

110+
/** @return mixed */
109111
public function invokeArgs(array $args) {}
110112

111113
/** @return Closure */
@@ -172,8 +174,10 @@ public function getClosure($object = UNKNOWN) {}
172174
/** @return int */
173175
public function getModifiers() {}
174176

177+
/** @return mixed */
175178
public function invoke(?object $object = null, ...$args) {}
176179

180+
/** @return mixed */
177181
public function invokeArgs(?object $object, array $args) {}
178182

179183
/** @return ReflectionClass */
@@ -255,6 +259,7 @@ public function getConstants() {}
255259
/** @return ReflectionClassConstant[] */
256260
public function getReflectionConstants() {}
257261

262+
/** @return mixed */
258263
public function getConstant(string $name) {}
259264

260265
/** @return ReflectionClassConstant|false */
@@ -314,6 +319,7 @@ public function isSubclassOf($class) {}
314319
/** @return ?array */
315320
public function getStaticProperties() {}
316321

322+
/** @return mixed */
317323
public function getStaticPropertyValue(string $name, $default = UNKNOWN) {}
318324

319325
/** @return void */
@@ -367,6 +373,7 @@ public function __toString(): string {}
367373
/** @return string|false */
368374
public function getName() {}
369375

376+
/** @return mixed */
370377
public function getValue(?object $object = null) {}
371378

372379
/** @return void */
@@ -426,6 +433,7 @@ public function __toString(): string {}
426433
/** @return string|false */
427434
public function getName() {}
428435

436+
/** @return mixed */
429437
public function getValue() {}
430438

431439
/** @return bool */
@@ -501,6 +509,7 @@ public function isOptional() {}
501509
/** @return bool */
502510
public function isDefaultValueAvailable() {}
503511

512+
/** @return mixed */
504513
public function getDefaultValue() {}
505514

506515
/** @return bool */

ext/sockets/sockets.stub.php

+4-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,10 @@ function socket_clear_error($socket = UNKNOWN): void {}
9191
*/
9292
function socket_import_stream($stream) {}
9393

94-
/** @param resource $socket */
94+
/**
95+
* @param resource $socket
96+
* @return resource|false
97+
*/
9598
function socket_export_stream($socket) {}
9699

97100
/** @param resource $socket */

ext/spl/spl_directory.stub.php

+1
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ public function setInfoClass(string $class_name = SplFileInfo::class) {}
9090

9191
public function __toString(): string {}
9292

93+
/** @return void */
9394
final public function _bad_state_ex() {}
9495
}
9596

ext/standard/basic_functions.stub.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ function array_sum(array $arg): int|float {}
238238

239239
function array_product(array $arg): int|float {}
240240

241+
/** @return mixed */
241242
function array_reduce(array $arg, callable $callback, $initial = null) {}
242243

243244
function array_filter(array $arg, callable $callback = UNKNOWN, int $use_keys = 0): array {}
@@ -1457,7 +1458,7 @@ function is_object($value): bool {}
14571458
function is_scalar($value): bool {}
14581459

14591460
/** @param mixed $value */
1460-
function is_callable($value, bool $syntax_only = false, &$callable_name = null) {}
1461+
function is_callable($value, bool $syntax_only = false, &$callable_name = null): bool {}
14611462

14621463
/** @param mixed $value */
14631464
function is_iterable($value): bool {}
@@ -1545,7 +1546,7 @@ function sapi_windows_cp_get(string $kind = UNKNOWN): int {}
15451546
* @param int|string $in_codepage
15461547
* @param int|string $out_codepage
15471548
*/
1548-
function sapi_windows_cp_conv($in_codepage, $out_codepage, string $subject) {}
1549+
function sapi_windows_cp_conv($in_codepage, $out_codepage, string $subject): ?string {}
15491550

15501551
function sapi_windows_cp_is_utf8(): bool {}
15511552

ext/standard/basic_functions_arginfo.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -2103,7 +2103,7 @@ ZEND_END_ARG_INFO()
21032103

21042104
#define arginfo_is_scalar arginfo_boolval
21052105

2106-
ZEND_BEGIN_ARG_INFO_EX(arginfo_is_callable, 0, 0, 1)
2106+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_is_callable, 0, 1, _IS_BOOL, 0)
21072107
ZEND_ARG_INFO(0, value)
21082108
ZEND_ARG_TYPE_INFO(0, syntax_only, _IS_BOOL, 0)
21092109
ZEND_ARG_INFO(1, callable_name)
@@ -2212,7 +2212,7 @@ ZEND_END_ARG_INFO()
22122212
#endif
22132213

22142214
#if defined(PHP_WIN32)
2215-
ZEND_BEGIN_ARG_INFO_EX(arginfo_sapi_windows_cp_conv, 0, 0, 3)
2215+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sapi_windows_cp_conv, 0, 3, IS_STRING, 1)
22162216
ZEND_ARG_INFO(0, in_codepage)
22172217
ZEND_ARG_INFO(0, out_codepage)
22182218
ZEND_ARG_TYPE_INFO(0, subject, IS_STRING, 0)

0 commit comments

Comments
 (0)