diff options
27 files changed, 121 insertions, 26 deletions
diff --git a/Zend/zend_closures.stub.php b/Zend/zend_closures.stub.php index ad15daa526..0dc92789a0 100644 --- a/Zend/zend_closures.stub.php +++ b/Zend/zend_closures.stub.php @@ -10,6 +10,7 @@ Class Closure /** @return ?Closure */ function bindTo(?object $newthis, $newscope = UNKNOWN) {} + /** @return mixed */ function call(object $newthis, ...$parameters) {} /** diff --git a/Zend/zend_exceptions.stub.php b/Zend/zend_exceptions.stub.php index 12255df3f6..cf631f3c2b 100644 --- a/Zend/zend_exceptions.stub.php +++ b/Zend/zend_exceptions.stub.php @@ -60,5 +60,6 @@ class ErrorException extends Exception { function __construct(string $message = UNKNOWN, int $code = 0, int $severity = E_ERROR, string $filename = UNKNOWN, int $lineno = 0, ?Throwable $previous = null) {} + /** @return int */ final function getSeverity() {} } diff --git a/Zend/zend_generators.stub.php b/Zend/zend_generators.stub.php index 759bd4cd48..3599cc0e69 100644 --- a/Zend/zend_generators.stub.php +++ b/Zend/zend_generators.stub.php @@ -6,15 +6,20 @@ final class Generator implements Iterator function valid(): bool {} + /** @return mixed */ function current() {} + /** @return mixed */ function key() {} function next(): void {} + /** @return mixed */ function send($value) {} + /** @return mixed */ function throw(Throwable $exception) {} + /** @return mixed */ function getReturn() {} } diff --git a/Zend/zend_interfaces.stub.php b/Zend/zend_interfaces.stub.php index 3a908212a4..b78257f53f 100644 --- a/Zend/zend_interfaces.stub.php +++ b/Zend/zend_interfaces.stub.php @@ -10,11 +10,13 @@ interface IteratorAggregate extends Traversable interface Iterator extends Traversable { + /** @return mixed */ function current(); /** @return void */ function next(); + /** @return mixed */ function key(); /** @return bool */ @@ -26,13 +28,17 @@ interface Iterator extends Traversable interface ArrayAccess { + /** @return bool */ function offsetExists($offset); /* actually this should be return by ref but atm cannot be */ + /** @return mixed */ function offsetGet($offset); + /** @return void */ function offsetSet($offset, $value); + /** @return void */ function offsetUnset($offset); } @@ -41,6 +47,7 @@ interface Serializable /** @return string */ function serialize(); + /** @return void */ function unserialize(string $serialized); } diff --git a/build/gen_stub.php b/build/gen_stub.php index e94399fbe3..2207a1348b 100644 --- a/build/gen_stub.php +++ b/build/gen_stub.php @@ -385,25 +385,70 @@ class FileInfo { } } +class DocCommentTag { + /** @var string */ + public $name; + /** @var ?string */ + public $value; + + public function __construct(string $name, ?string $value) { + $this->name = $name; + $this->value = $value; + } + + public function getValue(): string { + if ($this->value === null) { + throw new Exception("@$this->name does not have a value"); + } + + return $this->value; + } + + public function getVariableName(): string { + $value = $this->getValue(); + if ($value === null || strlen($value) === 0 || $value[0] !== '$') { + throw new Exception("@$this->name not followed by variable name"); + } + + return substr($value, 1); + } +} + +/** @return DocCommentTag[] */ +function parseDocComment(DocComment $comment): array { + $commentText = substr($comment->getText(), 2, -2); + $tags = []; + foreach (explode("\n", $commentText) as $commentLine) { + $regex = '/^\*\s*@([a-z-]+)(?:\s+(.+))$/'; + if (preg_match($regex, trim($commentLine), $matches, PREG_UNMATCHED_AS_NULL)) { + $tags[] = new DocCommentTag($matches[1], $matches[2]); + } + } + + return $tags; +} + function parseFunctionLike( string $name, ?string $className, Node\FunctionLike $func, ?string $cond ): FuncInfo { $comment = $func->getDocComment(); $paramMeta = []; $alias = null; + $haveDocReturnType = false; if ($comment) { - $commentText = substr($comment->getText(), 2, -2); - - foreach (explode("\n", $commentText) as $commentLine) { - if (preg_match('/^\*\s*@prefer-ref\s+\$(.+)$/', trim($commentLine), $matches)) { - $varName = $matches[1]; + $tags = parseDocComment($comment); + foreach ($tags as $tag) { + if ($tag->name === 'prefer-ref') { + $varName = $tag->getVariableName(); if (!isset($paramMeta[$varName])) { $paramMeta[$varName] = []; } $paramMeta[$varName]['preferRef'] = true; - } else if (preg_match('/^\*\s*@alias\s+(.+)$/', trim($commentLine), $matches)) { - $alias = $matches[1]; + } else if ($tag->name === 'alias') { + $alias = $tag->getValue(); + } else if ($tag->name === 'return') { + $haveDocReturnType = true; } } } @@ -455,6 +500,10 @@ function parseFunctionLike( } $returnType = $func->getReturnType(); + if ($returnType === null && !$haveDocReturnType && substr($name, 0, 2) !== '__') { + throw new Exception("Missing return type for function $name()"); + } + $return = new ReturnInfo( $func->returnsByRef(), $returnType ? Type::fromNode($returnType) : null); diff --git a/ext/com_dotnet/com_extension.stub.php b/ext/com_dotnet/com_extension.stub.php index 83cfc50350..8e065fb2ba 100644 --- a/ext/com_dotnet/com_extension.stub.php +++ b/ext/com_dotnet/com_extension.stub.php @@ -40,7 +40,7 @@ function variant_not($left): variant {} function variant_round($left, int $decimals): ?variant {} -function variant_cmp($left, $right, int $lcid = UNKNOWN, int $flags = 0) {} +function variant_cmp($left, $right, int $lcid = UNKNOWN, int $flags = 0): int {} function variant_date_to_timestamp(variant $variant): ?int {} @@ -63,4 +63,4 @@ function com_print_typeinfo($comobject, ?string $dispinterface = null, bool $wan function com_message_pump(int $timeoutms = 0): bool {} -function com_load_typelib(string $typelib_name, bool $case_insensitive = true) {} +function com_load_typelib(string $typelib_name, bool $case_insensitive = true): bool {} diff --git a/ext/com_dotnet/com_extension_arginfo.h b/ext/com_dotnet/com_extension_arginfo.h index b8ffef8077..b5eac32332 100644 --- a/ext/com_dotnet/com_extension_arginfo.h +++ b/ext/com_dotnet/com_extension_arginfo.h @@ -51,7 +51,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_variant_round, 0, 2, variant, 1) ZEND_ARG_TYPE_INFO(0, decimals, IS_LONG, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_variant_cmp, 0, 0, 2) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_variant_cmp, 0, 2, IS_LONG, 0) ZEND_ARG_INFO(0, left) ZEND_ARG_INFO(0, right) 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 ZEND_ARG_TYPE_INFO(0, timeoutms, IS_LONG, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_com_load_typelib, 0, 0, 1) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_com_load_typelib, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, typelib_name, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, case_insensitive, _IS_BOOL, 0) ZEND_END_ARG_INFO() diff --git a/ext/dom/domimplementation.stub.php b/ext/dom/domimplementation.stub.php index c103d489b4..86b28d196e 100644 --- a/ext/dom/domimplementation.stub.php +++ b/ext/dom/domimplementation.stub.php @@ -2,6 +2,7 @@ class DOMImplementation { + /** @return void */ public function getFeature(string $feature, string $version) {} /** @return bool */ diff --git a/ext/dom/xpath.stub.php b/ext/dom/xpath.stub.php index 167c5a94ef..a7ea2bb7b0 100644 --- a/ext/dom/xpath.stub.php +++ b/ext/dom/xpath.stub.php @@ -14,7 +14,10 @@ class DOMXPath /** @return bool */ public function registerNamespace(string $prefix, string $namespaceURI) {} - /** @param string|array $restrict */ + /** + * @param string|array $restrict + * @return bool|null + */ public function registerPhpFunctions($restrict = null) {} } #endif diff --git a/ext/gd/gd.stub.php b/ext/gd/gd.stub.php index 5138e2596a..18497cddfe 100644 --- a/ext/gd/gd.stub.php +++ b/ext/gd/gd.stub.php @@ -209,7 +209,7 @@ function imagefttext(GdImage $im, float $size, float $angle, int $x, int $y, int function imagettfbbox(float $size, float $angle, string $font_file, string $text): array|false {} -function imagettftext(GdImage $im, float $size, float $angle, int $x, int $y, int $col, string $font_file, string $text) {} +function imagettftext(GdImage $im, float $size, float $angle, int $x, int $y, int $col, string $font_file, string $text): array|false {} #endif function imagefilter(GdImage $im, int $filtertype, $arg1 = UNKNOWN, $arg2 = UNKNOWN, $arg3 = UNKNOWN, $arg4 = UNKNOWN): bool {} diff --git a/ext/gd/gd_arginfo.h b/ext/gd/gd_arginfo.h index 0d8554864d..e829e3a4bc 100644 --- a/ext/gd/gd_arginfo.h +++ b/ext/gd/gd_arginfo.h @@ -483,7 +483,7 @@ ZEND_END_ARG_INFO() #endif #if defined(HAVE_GD_FREETYPE) -ZEND_BEGIN_ARG_INFO_EX(arginfo_imagettftext, 0, 0, 8) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_imagettftext, 0, 8, MAY_BE_ARRAY|MAY_BE_FALSE) ZEND_ARG_OBJ_INFO(0, im, GdImage, 0) ZEND_ARG_TYPE_INFO(0, size, IS_DOUBLE, 0) ZEND_ARG_TYPE_INFO(0, angle, IS_DOUBLE, 0) diff --git a/ext/intl/common/common.stub.php b/ext/intl/common/common.stub.php index 5d7ef874d1..8bb6e38ce8 100644 --- a/ext/intl/common/common.stub.php +++ b/ext/intl/common/common.stub.php @@ -2,13 +2,18 @@ class IntlIterator implements Iterator { + /** @return mixed */ public function current() {} + /** @return mixed */ public function key() {} + /** @return void */ public function next() {} + /** @return void */ public function rewind() {} + /** @return bool */ public function valid() {} } diff --git a/ext/json/json.stub.php b/ext/json/json.stub.php index 90bedef91e..c5713a7980 100644 --- a/ext/json/json.stub.php +++ b/ext/json/json.stub.php @@ -11,5 +11,6 @@ function json_last_error_msg(): string {} interface JsonSerializable { + /** @return mixed */ public function jsonSerialize(); } diff --git a/ext/phar/phar_object.stub.php b/ext/phar/phar_object.stub.php index 44ec4732da..af7d57cabc 100644 --- a/ext/phar/phar_object.stub.php +++ b/ext/phar/phar_object.stub.php @@ -381,6 +381,7 @@ class PharFileInfo extends SplFileInfo /** @return string */ public function getContent() {} + /** @return mixed */ public function getMetadata() {} /** @return int */ diff --git a/ext/reflection/php_reflection.stub.php b/ext/reflection/php_reflection.stub.php index 05e1b0490d..b96a4f65e9 100644 --- a/ext/reflection/php_reflection.stub.php +++ b/ext/reflection/php_reflection.stub.php @@ -104,8 +104,10 @@ class ReflectionFunction extends ReflectionFunctionAbstract /** @return bool */ public function isDisabled() {} + /** @return mixed */ public function invoke(...$args) {} + /** @return mixed */ public function invokeArgs(array $args) {} /** @return Closure */ @@ -172,8 +174,10 @@ class ReflectionMethod extends ReflectionFunctionAbstract /** @return int */ public function getModifiers() {} + /** @return mixed */ public function invoke(?object $object = null, ...$args) {} + /** @return mixed */ public function invokeArgs(?object $object, array $args) {} /** @return ReflectionClass */ @@ -255,6 +259,7 @@ class ReflectionClass implements Reflector /** @return ReflectionClassConstant[] */ public function getReflectionConstants() {} + /** @return mixed */ public function getConstant(string $name) {} /** @return ReflectionClassConstant|false */ @@ -314,6 +319,7 @@ class ReflectionClass implements Reflector /** @return ?array */ public function getStaticProperties() {} + /** @return mixed */ public function getStaticPropertyValue(string $name, $default = UNKNOWN) {} /** @return void */ @@ -367,6 +373,7 @@ class ReflectionProperty implements Reflector /** @return string|false */ public function getName() {} + /** @return mixed */ public function getValue(?object $object = null) {} /** @return void */ @@ -426,6 +433,7 @@ class ReflectionClassConstant implements Reflector /** @return string|false */ public function getName() {} + /** @return mixed */ public function getValue() {} /** @return bool */ @@ -501,6 +509,7 @@ class ReflectionParameter implements Reflector /** @return bool */ public function isDefaultValueAvailable() {} + /** @return mixed */ public function getDefaultValue() {} /** @return bool */ diff --git a/ext/sockets/sockets.stub.php b/ext/sockets/sockets.stub.php index 86c4cd856e..bdff816f46 100644 --- a/ext/sockets/sockets.stub.php +++ b/ext/sockets/sockets.stub.php @@ -91,7 +91,10 @@ function socket_clear_error($socket = UNKNOWN): void {} */ function socket_import_stream($stream) {} -/** @param resource $socket */ +/** + * @param resource $socket + * @return resource|false + */ function socket_export_stream($socket) {} /** @param resource $socket */ diff --git a/ext/spl/spl_directory.stub.php b/ext/spl/spl_directory.stub.php index de6cda349e..c5a63ef1cd 100755 --- a/ext/spl/spl_directory.stub.php +++ b/ext/spl/spl_directory.stub.php @@ -90,6 +90,7 @@ class SplFileInfo public function __toString(): string {} + /** @return void */ final public function _bad_state_ex() {} } diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 4b39aa32f9..0c1c1ee380 100755 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -238,6 +238,7 @@ function array_sum(array $arg): int|float {} function array_product(array $arg): int|float {} +/** @return mixed */ function array_reduce(array $arg, callable $callback, $initial = null) {} function array_filter(array $arg, callable $callback = UNKNOWN, int $use_keys = 0): array {} @@ -1457,7 +1458,7 @@ function is_object($value): bool {} function is_scalar($value): bool {} /** @param mixed $value */ -function is_callable($value, bool $syntax_only = false, &$callable_name = null) {} +function is_callable($value, bool $syntax_only = false, &$callable_name = null): bool {} /** @param mixed $value */ function is_iterable($value): bool {} @@ -1545,7 +1546,7 @@ function sapi_windows_cp_get(string $kind = UNKNOWN): int {} * @param int|string $in_codepage * @param int|string $out_codepage */ -function sapi_windows_cp_conv($in_codepage, $out_codepage, string $subject) {} +function sapi_windows_cp_conv($in_codepage, $out_codepage, string $subject): ?string {} function sapi_windows_cp_is_utf8(): bool {} diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index 9c1b0162b0..7e0fbe84dc 100755 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -2103,7 +2103,7 @@ ZEND_END_ARG_INFO() #define arginfo_is_scalar arginfo_boolval -ZEND_BEGIN_ARG_INFO_EX(arginfo_is_callable, 0, 0, 1) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_is_callable, 0, 1, _IS_BOOL, 0) ZEND_ARG_INFO(0, value) ZEND_ARG_TYPE_INFO(0, syntax_only, _IS_BOOL, 0) ZEND_ARG_INFO(1, callable_name) @@ -2212,7 +2212,7 @@ ZEND_END_ARG_INFO() #endif #if defined(PHP_WIN32) -ZEND_BEGIN_ARG_INFO_EX(arginfo_sapi_windows_cp_conv, 0, 0, 3) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sapi_windows_cp_conv, 0, 3, IS_STRING, 1) ZEND_ARG_INFO(0, in_codepage) ZEND_ARG_INFO(0, out_codepage) ZEND_ARG_TYPE_INFO(0, subject, IS_STRING, 0) diff --git a/ext/standard/user_filters.stub.php b/ext/standard/user_filters.stub.php index f789dc1f32..9481b0b663 100755 --- a/ext/standard/user_filters.stub.php +++ b/ext/standard/user_filters.stub.php @@ -2,6 +2,7 @@ class php_user_filter { + /** @return int */ public function filter($in, $out, &$consumed, $closing) {} /** @return void */ diff --git a/ext/xml/xml.stub.php b/ext/xml/xml.stub.php index 0f6ed6b24c..60eeaaae33 100644 --- a/ext/xml/xml.stub.php +++ b/ext/xml/xml.stub.php @@ -54,4 +54,4 @@ function xml_parser_free(XmlParser $parser): bool {} function xml_parser_set_option(XmlParser $parser, int $option, $value): bool {} -function xml_parser_get_option(XmlParser $parser, int $option) {} +function xml_parser_get_option(XmlParser $parser, int $option): string|int|false {} diff --git a/ext/xml/xml_arginfo.h b/ext/xml/xml_arginfo.h index 06f6fde985..463ad8b9eb 100644 --- a/ext/xml/xml_arginfo.h +++ b/ext/xml/xml_arginfo.h @@ -76,7 +76,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_xml_parser_set_option, 0, 3, _IS ZEND_ARG_INFO(0, value) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_parser_get_option, 0, 0, 2) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_xml_parser_get_option, 0, 2, MAY_BE_STRING|MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_OBJ_INFO(0, parser, XmlParser, 0) ZEND_ARG_TYPE_INFO(0, option, IS_LONG, 0) ZEND_END_ARG_INFO() diff --git a/ext/xmlrpc/xmlrpc.stub.php b/ext/xmlrpc/xmlrpc.stub.php index 751aa7c325..e2805bd43f 100644 --- a/ext/xmlrpc/xmlrpc.stub.php +++ b/ext/xmlrpc/xmlrpc.stub.php @@ -2,8 +2,10 @@ function xmlrpc_encode($value): ?string {} +/** @return mixed */ function xmlrpc_decode(string $xml, string $encoding = "iso-8859-1") {} +/** @return mixed */ function xmlrpc_decode_request(string $xml, &$method, string $encoding = "iso-8859-1") {} function xmlrpc_encode_request(?string $method, $params, array $output_options = UNKNOWN): ?string {} @@ -21,9 +23,13 @@ function xmlrpc_server_destroy($server): bool {} /** @param resource $server */ function xmlrpc_server_register_method($server, string $method_name, $function): bool {} -/** @param resource $server */ +/** + * @param resource $server + * @return mixed + */ function xmlrpc_server_call_method($server, string $xml, $user_data, array $output_options = UNKNOWN) {} +/** @return mixed */ function xmlrpc_parse_method_descriptions(string $xml) {} /** @param resource $server */ diff --git a/ext/xmlwriter/xmlwriter.stub.php b/ext/xmlwriter/xmlwriter.stub.php index ce476c0705..35a0dec658 100644 --- a/ext/xmlwriter/xmlwriter.stub.php +++ b/ext/xmlwriter/xmlwriter.stub.php @@ -50,7 +50,7 @@ function xmlwriter_text(XMLWriter $xmlwriter, string $content): bool {} function xmlwriter_write_raw(XMLWriter $xmlwriter, string $content): bool {} -function xmlwriter_start_document(XMLWriter $xmlwriter, ?string $version = '1.0', ?string $encoding = null, ?string $standalone = null) {} +function xmlwriter_start_document(XMLWriter $xmlwriter, ?string $version = '1.0', ?string $encoding = null, ?string $standalone = null): bool {} function xmlwriter_end_document(XMLWriter $xmlwriter): bool {} diff --git a/ext/xmlwriter/xmlwriter_arginfo.h b/ext/xmlwriter/xmlwriter_arginfo.h index 54f571cb34..e759a32e10 100644 --- a/ext/xmlwriter/xmlwriter_arginfo.h +++ b/ext/xmlwriter/xmlwriter_arginfo.h @@ -104,7 +104,7 @@ ZEND_END_ARG_INFO() #define arginfo_xmlwriter_write_raw arginfo_xmlwriter_write_cdata -ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_start_document, 0, 0, 1) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_xmlwriter_start_document, 0, 1, _IS_BOOL, 0) ZEND_ARG_OBJ_INFO(0, xmlwriter, XMLWriter, 0) ZEND_ARG_TYPE_INFO(0, version, IS_STRING, 1) ZEND_ARG_TYPE_INFO(0, encoding, IS_STRING, 1) diff --git a/ext/zend_test/test.stub.php b/ext/zend_test/test.stub.php index b823116742..85c733ad3c 100644 --- a/ext/zend_test/test.stub.php +++ b/ext/zend_test/test.stub.php @@ -20,7 +20,7 @@ function zend_test_deprecated(): void {} function zend_create_unterminated_string(string $str): string {} -function zend_terminate_string(string &$str) {} +function zend_terminate_string(string &$str): string {} /** @param mixed $variable */ function zend_leak_variable($variable): void {} diff --git a/ext/zend_test/test_arginfo.h b/ext/zend_test/test_arginfo.h index 89a72f63ae..e0cb219e37 100644 --- a/ext/zend_test/test_arginfo.h +++ b/ext/zend_test/test_arginfo.h @@ -15,7 +15,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_create_unterminated_string, ZEND_ARG_TYPE_INFO(0, str, IS_STRING, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_zend_terminate_string, 0, 0, 1) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_terminate_string, 0, 1, IS_STRING, 0) ZEND_ARG_TYPE_INFO(1, str, IS_STRING, 0) ZEND_END_ARG_INFO() |