For now, we don't have any mechanism for annotations or attributes except
for doc-comments.

Thanks. Dmitry.

On Thu, Feb 5, 2015 at 3:27 PM, Alexander Lisachenko <
lisachenko...@gmail.com> wrote:

> So, is it possible to use annotations for defining such metadata on
> engine-level? This will be a good way to do this and to define custom
> handlers via AST hooks, that can be able to patch method definition node
> with concrete opcodes.
>
> 2015-02-05 15:24 GMT+03:00 Alexander Lisachenko <lisachenko...@gmail.com>:
>
>> Hello, internals!
>>
>> From my point of view, contracts should not affect execution of source
>> code in production env, or can be enabled partially. I have implemented DbC
>> paradigm on top of the AOP layer, so each contract can be defined via
>> annotation and looks pretty nice, for example :
>>
>> use PhpDeal\Annotation as Contract;
>>
>> /**
>>  * Simple trade account class
>>  * @Contract\Invariant("$this->balance > 0")
>>  */
>> class Account implements AccountContract
>> {
>>
>>     /**
>>      * Current balance
>>      *
>>      * @var float
>>      */
>>     protected $balance = 0.0;
>>
>>     /**
>>      * Deposits fixed amount of money to the account
>>      *
>>      * @param float $amount
>>      *
>>      * @Contract\Verify("$amount>0 && is_numeric($amount)")
>>      * @Contract\Ensure("$this->balance == $__old->balance+$amount")
>>      */
>>     public function deposit($amount)
>>     {
>>         $this->balance += $amount;
>>     }
>>
>>     /**
>>      * Returns current balance
>>      *
>>      * @Contract\Ensure("$__result == $this->balance")
>>      * @return float
>>      */
>>     public function getBalance()
>>     {
>>         return $this->balance;
>>     }
>> }
>>
>> All contracts (verify|ensure) are enforced only when DbC is enabled and
>> doesn't have an impact on execution for production mode. Moreover, all
>> annotations are parsed only once, decorators are generated too, so overhead
>> is minimal even for debug mode. Engine takes care to insert appropriate
>> before/around checks via an aspect
>> https://github.com/lisachenko/php-deal/blob/master/src/PhpDeal/Aspect/ContractCheckerAspect.php
>>
>> Here is a simple snippet of pointcut definition and advice body:
>>
>>     /**
>>      * Verifies pre-condition contract for the method
>>      *
>>      * @param MethodInvocation $invocation
>>      * @Before("@annotation(PhpDeal\Annotation\Verify)")
>>      *
>>      * @throws ContractViolation
>>      */
>>     public function preConditionContract(MethodInvocation $invocation)
>>     {
>>         $object = $invocation->getThis();
>>         $args   = $this->getMethodArguments($invocation);
>>         $scope  = $invocation->getMethod()->getDeclaringClass()->name;
>>
>>         foreach ($invocation->getMethod()->getAnnotations() as $annotation) {
>>             if (!$annotation instanceof Contract\Verify) {
>>                 continue;
>>             }
>>
>>             if (!$this->isContractSatisfied($object, $scope, $args, 
>> $annotation)) {
>>                 throw new ContractViolation($invocation, $annotation->value);
>>             };
>>         }
>>     }
>>
>>
>>
>>
>>
>> 2015-02-05 15:13 GMT+03:00 Patrick Schaaf <p...@bof.de>:
>>
>>> On Thursday 05 February 2015 15:14:04 Dmitry Stogov wrote:
>>> >
>>> > function foo()
>>> >     requre(<input-assert-expression>)
>>> >     ensure(<output-assert-expression>)
>>> > {
>>> >   ...
>>> > }
>>> >
>>> > It would require only one new reserved word "ensure".
>>>
>>> Regarding syntax.... This could be another place where the irrationally-
>>> dreaded declare would make sense:
>>>
>>> function foo() {
>>>     declare(pre) {
>>>       if (whatever...) return false;
>>>       // arbitrary PHP code
>>>     }
>>>     declare(post=$resultvar) {
>>>       if ($resultvar == XXX) return true;
>>>       return false;
>>>     }
>>> }
>>>
>>> This way, no new reserved words are needed at all, and the programmer
>>> can give
>>> a name to the "variable that holds the result" locally to avoid clashes
>>> with
>>> anything else in the function.
>>>
>>> I'm a bit undecided whether returning true/false there to give the
>>> verdict,
>>> would be the best way. Maybe better would be another use for declare,
>>> without
>>> a block, to declare that the pre/postcondition failed - giving a nice
>>> place to
>>> put a suitable message, too. And again without introducing any extra
>>> keywords:
>>>
>>> function foo() {
>>>     declare(post=$resultvar) {
>>>         if ($resultvar == XXX) declare(fail="My $resultvar looks fishy");
>>>     }
>>> }
>>>
>>> best regards
>>>   Patrick
>>>
>>> --
>>> PHP Internals - PHP Runtime Development Mailing List
>>> To unsubscribe, visit: http://www.php.net/unsub.php
>>>
>>>
>>
>

Reply via email to