php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #80190 ReflectionMethod::getReturnType() does not handle static as part of union type
Submitted: 2020-10-06 06:11 UTC Modified: 2020-10-06 06:46 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: sebastian@php.net Assigned:
Status: Closed Package: Reflection related
PHP Version: 8.0Git-2020-10-06 (Git) OS: Irrelevant
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: sebastian@php.net
New email:
PHP Version: OS:

 

 [2020-10-06 06:11 UTC] sebastian@php.net
Description:
------------
Consider this class:

class C
{
    public function m(): stdClass|static
    {
    }
}

ReflectionMethod::getReturnType() returns for C::m() a ReflectionUnionType that contains only a ReflectionNamedType object for "stdClass" but no information about "static".

This blocks PHPUnit's support for test doubles of objects with methods that declare a return type with a union that includes "static" (https://github.com/sebastianbergmann/phpunit/issues/4480, https://github.com/sebastianbergmann/type/issues/14).

Test script:
---------------
<?php declare(strict_types=1);
class C
{
    public function a(): self
    {
    }

    public function b(): stdClass|self
    {
    }

    public function c(): static
    {
    }

    public function d(): stdClass|static
    {
    }
}

foreach ((new ReflectionClass(C::class))->getMethods() as $method) {
    print $method->getDeclaringClass()->getName() . '::' . $method->getName() . '()' . PHP_EOL;
    print '    $method->getReturnType() returns ' . get_class($method->getReturnType()) . PHP_EOL;
    print '    $method->getReturnType()->__toString() returns ' . $method->getReturnType() . PHP_EOL;

    if ($method->getReturnType() instanceof ReflectionUnionType) {
        print '    $method->getReturnType()->getTypes() returns an array with ' . count($method->getReturnType()->getTypes()) . ' element(s)' . PHP_EOL;

        print '    type(s) in union: ';
        
        $types = [];

        foreach ($method->getReturnType()->getTypes() as $type) {
            $types[] = get_class($type);
        }
        
        print join(', ', $types) . PHP_EOL;
    }

    print PHP_EOL;
}


Expected result:
----------------
C::a()
    $method->getReturnType() returns ReflectionNamedType
    $method->getReturnType()->__toString() returns self

C::b()
    $method->getReturnType() returns ReflectionUnionType
    $method->getReturnType()->__toString() returns stdClass|self
    $method->getReturnType()->getTypes() returns an array with 2 element(s)
    type(s) in union: ReflectionNamedType, ReflectionNamedType

C::c()
    $method->getReturnType() returns ReflectionNamedType
    $method->getReturnType()->__toString() returns static

C::d()
    $method->getReturnType() returns ReflectionUnionType
    $method->getReturnType()->__toString() returns stdClass|static
    $method->getReturnType()->getTypes() returns an array with 1 element(s)
    type(s) in union: ReflectionNamedType, SOMETHING FOR STATIC


Actual result:
--------------
C::a()
    $method->getReturnType() returns ReflectionNamedType
    $method->getReturnType()->__toString() returns self

C::b()
    $method->getReturnType() returns ReflectionUnionType
    $method->getReturnType()->__toString() returns stdClass|self
    $method->getReturnType()->getTypes() returns an array with 2 element(s)
    type(s) in union: ReflectionNamedType, ReflectionNamedType

C::c()
    $method->getReturnType() returns ReflectionNamedType
    $method->getReturnType()->__toString() returns static

C::d()
    $method->getReturnType() returns ReflectionUnionType
    $method->getReturnType()->__toString() returns stdClass|static
    $method->getReturnType()->getTypes() returns an array with 1 element(s)
    type(s) in union: ReflectionNamedType


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-10-06 06:46 UTC] sebastian@php.net
Unfortunately, our arcane issue tracker does not let me edit my original report. If if did, I would make the following edits:

* Change "$method->getReturnType()->getTypes() returns an array with 1 element(s)" to "$method->getReturnType()->getTypes() returns an array with 2 element(s)" for C::d() in the "Expected result" section

* Change "ReflectionNamedType, SOMETHING FOR STATIC" to "ReflectionNamedType, ReflectionNamedType" for C::d() in the "Expected result" section

I think it only makes sense to represent "static" the same way "self" is represented.
 [2020-10-06 08:21 UTC] nikic@php.net
Automatic comment on behalf of nikita.ppv@gmail.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=dee802498e25e22afb35e550dea1f7b3a8aa0129
Log: Fixed bug #80190
 [2020-10-06 08:21 UTC] nikic@php.net
-Status: Open +Status: Closed
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 14:01:29 2024 UTC