Let ReflectionMethod keep track of original class

php.internals

Andreas Hennings

3 years ago
Hello list, this proposal will be useful in combination with "Declaration-aware attributes" Problem ======== Currently, ReflectionMethod is not aware of the original class, if the method is declared in a parent class. Methods that are called during a discovery algorithm that need to process a method with its original class typically need two parameters: function processMethod(\ReflectionClass $class, \ReflectionMethod $method) {..} Proposal ======== Let a ReflectionMethod object keep track of the original class. Introduce a new method ReflectionMethod->getOriginalClass() to retrieve it. class B { function f($x) {} } class C extends B {} foreach ([ // There are different ways to get a reflection method object, all of them track the original class. new ReflectionMethod('C', 'f'), (new ReflectionClass('C'))->getMethod('f'), (new ReflectionMethod('C', 'f'))->getParameters()[0]->getDeclaringFunction(), ] as $rm) { // The following won't change: assert($rm->class === 'B'); assert($rm->getDeclaringClass()->getName() === 'B'); // New method: assert($rm->getOriginalClass()->getName() === 'C'); Alternatives ========== At first I thought we might introduce a new class like "VirtualReflectionMethod" which behaves as if the method was declared on the child class. But this is awkward. I think the ->getOriginalClass() is much simpler. --- Andreas

Larry Garfield

3 years ago
-- Larry Garfield larry@garfieldtech.com On Tue, May 30, 2023, at 2:42 AM, Andreas Hennings wrote: > Hello list, > this proposal will be useful in combination with "Declaration-aware attributes" > > > Problem > ======== > Currently, ReflectionMethod is not aware of the original class, if the > method is declared in a parent class. > Methods that are called during a discovery algorithm that need to > process a method with its original class typically need two > parameters: > > function processMethod(\ReflectionClass $class, \ReflectionMethod $method) {..} > > > Proposal > ======== > Let a ReflectionMethod object keep track of the original class. > Introduce a new method ReflectionMethod->getOriginalClass() to retrieve it. > > class B { > function f($x) {} > } > class C extends B {} > > foreach ([ > // There are different ways to get a reflection method object, all > of them track the original class. > new ReflectionMethod('C', 'f'), > (new ReflectionClass('C'))->getMethod('f'), > (new ReflectionMethod('C', 'f'))->getParameters()[0]->getDeclaringFunction(), > ] as $rm) { > // The following won't change: > assert($rm->class === 'B'); > assert($rm->getDeclaringClass()->getName() === 'B'); > // New method: > assert($rm->getOriginalClass()->getName() === 'C'); > > > Alternatives > ========== > > At first I thought we might introduce a new class like > "VirtualReflectionMethod" which behaves as if the method was declared > on the child class. But this is awkward. > > I think the ->getOriginalClass() is much simpler. I would not be opposed to this. I don't know that I have any use cases for it, but I'd be open to it. --Larry Garfield

Andreas Hennings

3 years ago
On Tue, 30 May 2023 at 18:48, Larry Garfield <larry@garfieldtech.com> wrote:
> > > > -- > Larry Garfield > larry@garfieldtech.com > > On Tue, May 30, 2023, at 2:42 AM, Andreas Hennings wrote: > > Hello list, > > this proposal will be useful in combination with "Declaration-aware attributes" > > > > > > Problem > > ======== > > Currently, ReflectionMethod is not aware of the original class, if the > > method is declared in a parent class. > > Methods that are called during a discovery algorithm that need to > > process a method with its original class typically need two > > parameters: > > > > function processMethod(\ReflectionClass $class, \ReflectionMethod $method) {..} > > > > > > Proposal > > ======== > > Let a ReflectionMethod object keep track of the original class. > > Introduce a new method ReflectionMethod->getOriginalClass() to retrieve it. > > > > class B { > > function f($x) {} > > } > > class C extends B {} > > > > foreach ([ > > // There are different ways to get a reflection method object, all > > of them track the original class. > > new ReflectionMethod('C', 'f'), > > (new ReflectionClass('C'))->getMethod('f'), > > (new ReflectionMethod('C', 'f'))->getParameters()[0]->getDeclaringFunction(), > > ] as $rm) { > > // The following won't change: > > assert($rm->class === 'B'); > > assert($rm->getDeclaringClass()->getName() === 'B'); > > // New method: > > assert($rm->getOriginalClass()->getName() === 'C'); > > > > > > Alternatives > > ========== > > > > At first I thought we might introduce a new class like > > "VirtualReflectionMethod" which behaves as if the method was declared > > on the child class. But this is awkward. > > > > I think the ->getOriginalClass() is much simpler. > > > I would not be opposed to this. I don't know that I have any use cases for it, but I'd be open to it.
You can search in your favourite project's /vendor/ directory for methods with two or more parameters that receive reflector objects. "function .*\(.*Reflection\w+ \$\w+, .?Reflection\w+ \$\w+"