Roave / StrictPhp

:no_entry_sign: :sparkles: :heavy_exclamation_mark: AOP-based strict type checks for PHP
MIT License
261 stars 8 forks source link

@abstract for properties #46

Closed ovr closed 9 years ago

ovr commented 9 years ago

Hey! I am going to suggest NFR

@abstract strict docblock for properties

Example:

abstract class AbstractExpressionCompiler implements ExpressionCompilerInterface
{
    /**
     * @abstract THIS MOMENT!
     * @var string
     */
    protected $name = 'unknown';

    protected function assertExpression($expression)
    {
        if (!$expression instanceof $this->name) {
            throw new RuntimeException('Passed $expression must be instance of ' . $this->name);
        }
    }
    /**
     * @param  $expr
     * @param Context $context
     * @return CompiledExpression
     */
    public function pass($expr, Context $context)
    {
        $this->assertExpression($expr);
        return $this->compile($expr, $context);
    }
    /**
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }
    /**
     * @param $expr
     * @param Context $context
     * @return mixed
     */
    abstract protected function compile($expr, Context $context);

Usage:

class FunctionCall extends AbstractExpressionCompiler
{
    // if i didnt redeclare needed to notice me about it!
    protected $name = '\PhpParser\Node\Expr\FuncCall';
    /**
     * @param \PhpParser\Node\Expr\FuncCall $expr
     * @param Context $context
     * @return CompiledExpression
     */
    public function compile($expr, Context $context)
    {
    }
}

Maybe someone will be interested to implement it. P.S. Maybe I am newbie and I don't known how to implement it more clearfull

Thanks, :smile_cat:

Ocramius commented 9 years ago

Hey @ovr, what's the actual use-case for abstract properties? A property retains state, not behavior, so I don't see why it would need to be implemented by child classes (that encapsulate state with their own approaches).

Can you clarify on the actual use-case?

malukenho commented 9 years ago

ping @ovr

ovr commented 9 years ago

Sorry but I cannot explain on enlish language my idea, actual use-case in code example without unneeded code

abstract class AbstractExpressionCompiler implements ExpressionCompilerInterface
{
    /**
     * @abstract THIS MOMENT!
     * @var string
     */
    protected $name;
}

class FunctionCall extends AbstractExpressionCompiler
{
    // if i didnt redeclare needed to notice me about it!
    protected $name = '\PhpParser\Node\Expr\FuncCall';
}

About idea, Is it clear now?

malukenho commented 9 years ago

@ovr It's seems for me a use-case for an abstract method or interface getName( ). But we can wait for @Ocramius

ovr commented 9 years ago

It's seems for me a use-case for an abstract method or interface getName( ).

Yeap, you are right It's possible variant but I suggested another way with annotation ;)

danizord commented 9 years ago

Another use-case here: https://github.com/zendframework/zend-servicemanager/blob/develop/src/AbstractPluginManager.php#L36

malukenho commented 9 years ago

@danizord I can't see why this can't be a getResolveClassName(): callable (._. ) I lost some point?

danizord commented 9 years ago

@malukenho I dunno :(

@bakura10 why?

Ocramius commented 9 years ago

@danizord please use absolute links: is that referring to https://github.com/zendframework/zend-servicemanager/blob/34f42a81c86cb27dd331bcf934816c61b58e4b4c/src/AbstractPluginManager.php#L36 ?

Ocramius commented 9 years ago

@ovr I looked at this further, and I see no real use-case for it. I see a use-case for final properties, not for abstract ones (in general, inheritance for overrides is kinda bad :-\ )

danizord commented 9 years ago

@Ocramius yep. SM 3.0 tells people to define a value for $instanceOf in derivations of AbstractPluginManager.

Most plugin manager instances can therefore define the $instanceOf property to indicate what plugin interface is considered valid for the plugin manager, and make no further changes to the abstract plugin manager:

https://github.com/zendframework/zend-servicemanager/blob/fd2c8750df697a7ad801cd6bb2566a93936f69e2/doc/book/migration.md#abstractpluginmanager

ovr commented 9 years ago

@Ocramius

I see no real use-case for it.

I send the example from phpsa project @danizord send the example from Zend Framework

Is it an UNreal use-case(s)?))

About @final for properties :+1:

Ocramius commented 9 years ago

Is it an UNreal use-case(s)?))

I'd rather say the abstract plugin manager constructor should accept such a value (enforcing instantiation-time initialization of it)