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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 5 additions & 0 deletions
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

Lines changed: 7 additions & 0 deletions
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

Lines changed: 56 additions & 7 deletions
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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 4 additions & 1 deletion
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

Lines changed: 1 addition & 1 deletion
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 {}

0 commit comments

Comments
 (0)