relationParserHelper = $relationParserHelper; $this->builderHelper = $builderHelper; } public function hasProperty(ClassReflection $classReflection, string $propertyName): bool { if (! $classReflection->isSubclassOf(Model::class)) { return false; } if (ReflectionHelper::hasPropertyTag($classReflection, $propertyName)) { return false; } $hasNativeMethod = $classReflection->hasNativeMethod($propertyName); if (! $hasNativeMethod) { return false; } $returnType = ParametersAcceptorSelector::selectSingle($classReflection->getNativeMethod($propertyName)->getVariants())->getReturnType(); if (! (new ObjectType(Relation::class))->isSuperTypeOf($returnType)->yes()) { return false; } return true; } public function getProperty(ClassReflection $classReflection, string $propertyName): PropertyReflection { $method = $classReflection->getMethod($propertyName, new OutOfClassScope()); /** @var ObjectType $returnType */ $returnType = ParametersAcceptorSelector::selectSingle($method->getVariants())->getReturnType(); if ($returnType instanceof GenericObjectType) { /** @var ObjectType $relatedModelType */ $relatedModelType = $returnType->getTypes()[0]; $relatedModelClassName = $relatedModelType->getClassName(); } else { $relatedModelClassName = $this ->relationParserHelper ->findRelatedModelInRelationMethod($method); } if ($relatedModelClassName === null) { $relatedModelClassName = Model::class; } $relatedModel = new ObjectType($relatedModelClassName); $collectionClass = $this->builderHelper->determineCollectionClassName($relatedModelClassName); if (Str::contains($returnType->getClassName(), 'Many')) { return new ModelProperty( $classReflection, new GenericObjectType($collectionClass, [$relatedModel]), new NeverType(), false ); } if (Str::endsWith($returnType->getClassName(), 'MorphTo')) { return new ModelProperty($classReflection, new UnionType([ new ObjectType(Model::class), new MixedType(), ]), new NeverType(), false); } return new ModelProperty($classReflection, new UnionType([ $relatedModel, new NullType(), ]), new NeverType(), false); } }