kbond / foundry-next

MIT License
0 stars 1 forks source link

2.x "real" proxies #3

Closed kbond closed 1 year ago

kbond commented 1 year ago

I'm thinking the following inheritance structure:

/**
 * @template T
 */
abstract class Factory
{
    /**
     * @return T
     */
    public static function createOne(): mixed
    {
        return static::new()->create();
    }

    public static function new(): static
    {
        return new static(); // @phpstan-ignore-line
    }

    /**
     * @return T
     */
    abstract public function create(): mixed;
}

/**
 * @template T of object
 * @extends Factory<T>
 */
abstract class ObjectFactory extends Factory
{
    public function create(): object
    {
        return new \stdClass(); // @phpstan-ignore-line
    }

    /**
     * @return class-string<T>
     */
    abstract public static function class(): string;
}

/**
 * @template T of object
 * @extends ObjectFactory<T>
 */
abstract class PersistentObjectFactory extends ObjectFactory
{
    public function create(): object
    {
        return parent::create();
    }
}

/**
 * @template T of object
 */
interface Proxy
{
    /**
     * @return T
     */
    public function unwrap(): object;
}

/**
 * @template T of object
 * @extends PersistentObjectFactory<T&Proxy<T>>
 *
 * @method static class-string<T> class()
 */
abstract class ProxyObjectFactory extends PersistentObjectFactory
{
    /**
     * @return class-string<T>
     */
    abstract public static function class(): string;
}

class User
{
    public string $name;
}

/**
 * @extends ProxyObjectFactory<User>
 */
class UserFactory extends ProxyObjectFactory
{
    public static function class(): string
    {
        return User::class;
    }
}

I know this works with phpstan (https://phpstan.org/r/056810e5-6867-491e-9c8a-8afd994db84f) but can't get phpstan to pass locally...

kbond commented 1 year ago

Ak, the issue was using final class User {} (the final caused the error because a final class cannot intersect with anything)