Skip to content

Commit

Permalink
#2374 - Implement nullable object return type
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeckerson committed Aug 17, 2022
1 parent 79dc763 commit 53e094e
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 7 deletions.
37 changes: 30 additions & 7 deletions Library/ArgInfoDefinition.php
Original file line number Diff line number Diff line change
Expand Up @@ -167,13 +167,9 @@ public function render(): void

private function richRenderStart(): void
{
if (array_key_exists('object', $this->functionLike->getReturnTypes())) {
$class = 'NULL';

if (1 === count($this->functionLike->getReturnClassTypes())) {
$class = key($this->functionLike->getReturnClassTypes());
$class = escape_class($this->compilationContext->getFullName($class));
}
if (array_key_exists('object', $this->functionLike->getReturnTypes()) && 1 === count($this->functionLike->getReturnClassTypes())) {
$class = key($this->functionLike->getReturnClassTypes());
$class = escape_class($this->compilationContext->getFullName($class));

$this->codePrinter->output(
sprintf(
Expand Down Expand Up @@ -237,6 +233,33 @@ private function richRenderStart(): void
return;
}

if ($this->functionLike->isReturnTypeNullableObject()) {
$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_NULL|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',
1,
)
);
$this->codePrinter->output('#endif');

return;
}

if (count($this->functionLike->getReturnTypes()) > 1) {
$types = [];
$mayBeTypes = $this->functionLike->getMayBeArgTypes();
Expand Down
10 changes: 10 additions & 0 deletions Library/ClassMethod.php
Original file line number Diff line number Diff line change
Expand Up @@ -2340,6 +2340,16 @@ public function isReturnTypesHintDetermined(): bool
return true;
}

/**
* Checks if method's return type is nullable object `?object`.
*
* @return bool
*/
public function isReturnTypeNullableObject(): bool
{
return count($this->returnTypes) === 2 && isset($this->returnTypes['object']) && isset($this->returnTypes['null']);
}

/**
* Checks if the method have compatible return types.
*
Expand Down
15 changes: 15 additions & 0 deletions stub/types/obj.zep
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

namespace Stub\Types;

class Obj
{
public function nullableObjectReturnNull() -> object | null
{
return null;
}

public function nullableObjectReturnObj() -> object | null
{
return new \stdClass();
}
}
28 changes: 28 additions & 0 deletions tests/Extension/Types/ObjTypeTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

/**
* This file is part of the Zephir.
*
* (c) Phalcon Team <team@zephir-lang.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Extension\Types;

use PHPUnit\Framework\TestCase;
use Stub\Types\Obj;

final class ObjTypeTest extends TestCase
{
public function testIntFalse(): void
{
$class = new Obj();

$this->assertNull($class->nullableObjectReturnNull());
$this->assertSame(new \stdClass(), $class->nullableObjectReturnObj());
}
}

0 comments on commit 53e094e

Please sign in to comment.