parser-reflection icon indicating copy to clipboard operation
parser-reflection copied to clipboard

Incomplete trait support

Open aik099 opened this issue 1 year ago • 1 comments

If you have a class, that uses traits (which is compiler-assisted copy-paste), then PHP's built-in ReflectionClass object for that class will also return used trait constants/methods/properties as part of a class reflection object (trait method scope/name changes are accounted for).

This library doesn't return trait-provided data as part of class reflection, that uses them.

Sample PHP code:

<?php


trait TraitA
{

	public function sayHello($a_trait = null)
	{
		echo 'Hello';
	}

	public function smallTalk($a_trait = null)
	{
		echo 'a';
	}

}


trait TraitB
{

	public function sayWorld($b_trait = null)
	{
		echo 'World';
	}

	public function sayWorld2($b_trait = null)
	{
		echo 'World2';
	}

	public function smallTalk($b_trait = null)
	{
		echo 'a';
	}

}


class MyHelloWorld
{

	use TraitA, TraitB {
		sayHello as protected sayHelloProtected;
		TraitA::smallTalk as smallTalkTraitA;
		TraitB::smallTalk insteadof TraitA;
	}

	public function sayWorld2($local = null)
	{
		echo 'World2 local';
	}

	// A class can use multiple traits

	public function sayHelloWorld($local = null)
	{
		$this->sayHello();
		echo ' ';
		$this->sayWorld();
		echo "!\n";
	}

}

Here is the introspection code I've used:

function reflect_class($class)
{
    echo 'Class "' . $class . '":' . PHP_EOL;

    $class_reflection = new ReflectionClass($class);

    foreach ( $class_reflection->getMethods() as $method ) {
        echo 'Method ' . get_scope($method) . ' "' . $method->getName() . '" (';

        foreach ( $method->getParameters() as $parameter ) {
            echo $parameter->getName() . ',';
        }

        echo ')' . PHP_EOL;
    }

    echo PHP_EOL;
}

Here is the introspection result:

Class "MyHelloWorld":
Method public "sayWorld2" (local,)
Method public "sayHelloWorld" (local,)
Method protected "sayHelloProtected" (a_trait,)
Method public "sayHello" (a_trait,)
Method public "smallTalkTraitA" (a_trait,)
Method public "sayWorld" (b_trait,)
Method public "smallTalk" (b_trait,)

If I attempt to do the same using this library, then I'll only get class methods defined in itself (that has local, parameter).

Maybe it is related to the #54.

aik099 avatar Dec 16 '24 18:12 aik099

Maybe the approach taken by BetterReflection can be used: https://github.com/Roave/BetterReflection/blob/0f82edc5d371730e530de90a5e3ce4de576cbb7d/src/Reflection/ReflectionClass.php#L1494 .

We already have trait adaptations stored and just need to inject trait constants/properties/method back into class reflection, that uses them.

aik099 avatar Dec 16 '24 19:12 aik099