Closed josefsabl closed 11 months ago
@josefsabl This looks like a normal PHP namespacing misunderstanding. Traits are effectively copied into the class they're evaluated within at runtime. So, Type3
is in the SomeNamespace
namespace. Therefore, the annotation you've provided for the @return
would mean it's evaluated as SomeNamespace\Type2
. This is not a GraphQLite issue and more of a misunderstanding for how namespacing works.
I am sorry, but that is not exactly true. There is no problem with namespaces or understanding them.
Of course that typehints in traits are evaluated from the context (namespace) where the trait is defined and not from the context where the trait is used.
What you say would mean that either a) No relative typehints can be used in traits or b) Traits can be used only in namespace where they are defined. And neither is true.
Like I already said, native relative typehints in same trait work as expected.
Let's see:
namespace App
trait MyTrait
{
public function foo(): Type2 { return new Type2; }
}
namespace App;
final class Type1
{
use MyTrait;
}
namespace App\SomeNamespace;
final class Type3
{
use \App\MyTrait;
}
echo (new \ReflectionClass(\App\Type1::class))
->getMethod('foo')
->getReturnType();
echo (new \ReflectionClass(\App\SomeNamespace\Type3::class))
->getMethod('foo')
->getReturnType();
Both of these echos print same correct class of course: \App\Type2
.
I know where are you coming from. The problem lies in the reflection that is used to parse the docblock and the fact that there is no sane way to find out if the method is declared in the class or in the trait.
\ReflectionClass
has getTraits
method and I believe it could be used, but I understand this would be hassle and the problem has easy workaround.
Maybe the issue should be left open for others, I still believe this is a bug.
Anyway, thanks for great library!
Let's assume this class/trait structure:
TypeX
are Graphqlite types.MyTrait
defines field that returns array ofType2
and is used both inType1
andType3
.Let's say it looks like this:
This trait works in
Type1
but throws an error inType3
.Workaround is to declare the return type in trait using absolute path.
For native typehints there is no problem.