diff --git a/CHANGELOG.md b/CHANGELOG.md index f720297df..3e64b7cdd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org). ## [Unreleased] +## [0.16.2] - 2022-08-22 +### Added +- Added support for `object` return type [#2374](https://github.com/zephir-lang/zephir/issues/2374) + ## [0.16.1] - 2022-08-21 ### Changed - Changed usage of `utf8_decode()` function in favour of `mb_convert_encoding()` [#2376](https://github.com/zephir-lang/zephir/issues/2376) @@ -579,7 +583,8 @@ and this project adheres to [Semantic Versioning](https://semver.org). [#1524](https://github.com/zephir-lang/zephir/issues/1524) -[Unreleased]: https://github.com/zephir-lang/zephir/compare/0.16.0...HEAD +[Unreleased]: https://github.com/zephir-lang/zephir/compare/0.16.2...HEAD +[0.16.2]: https://github.com/zephir-lang/zephir/compare/0.16.1...0.16.2 [0.16.1]: https://github.com/zephir-lang/zephir/compare/0.16.0...0.16.1 [0.16.0]: https://github.com/zephir-lang/zephir/compare/0.15.2...0.16.0 [0.15.2]: https://github.com/zephir-lang/zephir/compare/0.15.1...0.15.2 diff --git a/Library/ArgInfoDefinition.php b/Library/ArgInfoDefinition.php index 8e55bc213..e51759766 100644 --- a/Library/ArgInfoDefinition.php +++ b/Library/ArgInfoDefinition.php @@ -260,6 +260,33 @@ private function richRenderStart(): void return; } + if ($this->functionLike->isReturnTypeObject()) { + $this->codePrinter->output('#if PHP_VERSION_ID >= 80000'); + $this->codePrinter->output( + sprintf( + 'ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(%s, %d, %d, %s)', + $this->name, + (int) $this->returnByRef, + $this->functionLike->getNumberOfRequiredParameters(), + 'MAY_BE_OBJECT', + ) + ); + $this->codePrinter->output('#else'); + $this->codePrinter->output( + sprintf( + 'ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(%s, %d, %d, %s, %d)', + $this->name, + (int) $this->returnByRef, + $this->functionLike->getNumberOfRequiredParameters(), + 'IS_OBJECT', + 0, + ) + ); + $this->codePrinter->output('#endif'); + + return; + } + if (count($this->functionLike->getReturnTypes()) > 1) { $types = []; $mayBeTypes = $this->functionLike->getMayBeArgTypes(); diff --git a/Library/ClassMethod.php b/Library/ClassMethod.php index 7802cf7ce..01e8354bf 100644 --- a/Library/ClassMethod.php +++ b/Library/ClassMethod.php @@ -712,6 +712,11 @@ public function areReturnTypesStringCompatible(): bool return isset($this->returnTypes['string']); } + public function areReturnTypesObjectCompatible(): bool + { + return isset($this->returnTypes['object']); + } + /** * Returned type hints by the method. * @@ -2224,24 +2229,17 @@ public function hasChildReturnStatementType(array $statement): bool } $statements = $statement['else_statements']; - foreach ($statements as $item) { - $type = $item['type'] ?? null; - if ('return' === $type || 'throw' === $type) { - return true; - } - - return $this->hasChildReturnStatementType($item); - } } else { $statements = $statement['statements']; - foreach ($statements as $item) { - $type = $item['type'] ?? null; - if ('return' === $type || 'throw' === $type) { - return true; - } + } - return $this->hasChildReturnStatementType($item); + foreach ($statements as $item) { + $type = $item['type'] ?? null; + if ('return' === $type || 'throw' === $type) { + return true; } + + return $this->hasChildReturnStatementType($item); } return false; @@ -2323,6 +2321,7 @@ public function isReturnTypesHintDetermined(): bool $this->areReturnTypesNullCompatible() || $this->areReturnTypesStringCompatible() || $this->areReturnTypesFalseCompatible() || + $this->areReturnTypesObjectCompatible() || \array_key_exists('array', $this->getReturnTypes()) ) { continue; @@ -2350,6 +2349,16 @@ public function isReturnTypeNullableObject(): bool return count($this->returnTypes) === 2 && isset($this->returnTypes['object']) && isset($this->returnTypes['null']); } + /** + * Checks if method's return type is object `object`. + * + * @return bool + */ + public function isReturnTypeObject(): bool + { + return count($this->returnTypes) === 1 && isset($this->returnTypes['object']); + } + /** * Checks if the method have compatible return types. * diff --git a/Library/Zephir.php b/Library/Zephir.php index 31a6a4b97..9c26c6048 100644 --- a/Library/Zephir.php +++ b/Library/Zephir.php @@ -15,7 +15,7 @@ final class Zephir { - public const VERSION = '0.16.0-$Id$'; + public const VERSION = '0.16.2-$Id$'; public const LOGO = <<<'ASCII' _____ __ _ diff --git a/ext/php_stub.h b/ext/php_stub.h index 1b5391c9f..7b25d95b7 100644 --- a/ext/php_stub.h +++ b/ext/php_stub.h @@ -14,7 +14,7 @@ #define PHP_STUB_VERSION "1.0.0" #define PHP_STUB_EXTNAME "stub" #define PHP_STUB_AUTHOR "Phalcon Team and contributors" -#define PHP_STUB_ZEPVERSION "0.16.0-$Id$" +#define PHP_STUB_ZEPVERSION "0.16.2-$Id$" #define PHP_STUB_DESCRIPTION "Description test for
Test Extension." typedef struct _zephir_struct_db { diff --git a/ext/stub/types/obj.zep.c b/ext/stub/types/obj.zep.c index d2b119f0c..c7c5aea67 100644 --- a/ext/stub/types/obj.zep.c +++ b/ext/stub/types/obj.zep.c @@ -37,6 +37,16 @@ PHP_METHOD(Stub_Types_Obj, nullableObjectReturnObj) + object_init(return_value); + return; +} + +PHP_METHOD(Stub_Types_Obj, objectReturn) +{ + zval *this_ptr = getThis(); + + + object_init(return_value); return; } diff --git a/ext/stub/types/obj.zep.h b/ext/stub/types/obj.zep.h index 6854113fa..a799f6ff6 100644 --- a/ext/stub/types/obj.zep.h +++ b/ext/stub/types/obj.zep.h @@ -5,6 +5,7 @@ ZEPHIR_INIT_CLASS(Stub_Types_Obj); PHP_METHOD(Stub_Types_Obj, nullableObjectReturnNull); PHP_METHOD(Stub_Types_Obj, nullableObjectReturnObj); +PHP_METHOD(Stub_Types_Obj, objectReturn); #if PHP_VERSION_ID >= 80000 ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_stub_types_obj_nullableobjectreturnnull, 0, 0, MAY_BE_NULL|MAY_BE_OBJECT) @@ -20,8 +21,16 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_stub_types_obj_nullableobjectret #endif ZEND_END_ARG_INFO() +#if PHP_VERSION_ID >= 80000 +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_stub_types_obj_objectreturn, 0, 0, MAY_BE_OBJECT) +#else +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_stub_types_obj_objectreturn, 0, 0, IS_OBJECT, 0) +#endif +ZEND_END_ARG_INFO() + ZEPHIR_INIT_FUNCS(stub_types_obj_method_entry) { PHP_ME(Stub_Types_Obj, nullableObjectReturnNull, arginfo_stub_types_obj_nullableobjectreturnnull, ZEND_ACC_PUBLIC) PHP_ME(Stub_Types_Obj, nullableObjectReturnObj, arginfo_stub_types_obj_nullableobjectreturnobj, ZEND_ACC_PUBLIC) + PHP_ME(Stub_Types_Obj, objectReturn, arginfo_stub_types_obj_objectreturn, ZEND_ACC_PUBLIC) PHP_FE_END }; diff --git a/stub/types/obj.zep b/stub/types/obj.zep index 65134b3ee..6d7254c71 100644 --- a/stub/types/obj.zep +++ b/stub/types/obj.zep @@ -12,4 +12,9 @@ class Obj { return new \stdClass(); } + + public function objectReturn() -> object + { + return new \stdClass(); + } } diff --git a/tests/Extension/Types/ObjTypeTest.php b/tests/Extension/Types/ObjTypeTest.php index 0cab73519..cf3539fdf 100644 --- a/tests/Extension/Types/ObjTypeTest.php +++ b/tests/Extension/Types/ObjTypeTest.php @@ -25,5 +25,6 @@ public function testIntFalse(): void $this->assertNull($class->nullableObjectReturnNull()); $this->assertInstanceOf(stdClass::class, $class->nullableObjectReturnObj()); + $this->assertInstanceOf(stdClass::class, $class->objectReturn()); } }