felipe                                   Fri, 07 May 2010 13:55:27 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=299102

Log:
- Fixed magic method and constructor copy for traits

Changed paths:
    A   php/php-src/trunk/Zend/tests/traits/methods_001.phpt
    A   php/php-src/trunk/Zend/tests/traits/methods_002.phpt
    A   php/php-src/trunk/Zend/tests/traits/methods_003.phpt
    U   php/php-src/trunk/Zend/zend_compile.c

Added: php/php-src/trunk/Zend/tests/traits/methods_001.phpt
===================================================================
--- php/php-src/trunk/Zend/tests/traits/methods_001.phpt                        
        (rev 0)
+++ php/php-src/trunk/Zend/tests/traits/methods_001.phpt        2010-05-07 
13:55:27 UTC (rev 299102)
@@ -0,0 +1,39 @@
+--TEST--
+Testing magic method on trait
+--FILE--
+<?php
+
+trait foo {
+       public function __toString() {
+               return '123';
+       }
+
+       public function __get($x) {
+               var_dump($x);
+       }
+
+       public function __set($attr, $val) {
+               var_dump($attr .'==='. $val);
+       }
+
+       public function __clone() {
+               var_dump(__FUNCTION__);
+       }
+}
+
+class bar {
+       use foo;
+}
+
+$o = new bar;
+echo $o, PHP_EOL;
+$o->xyz;
+$o->xyz = 2;
+clone $o;
+
+?>
+--EXPECT--
+123
+string(3) "xyz"
+string(7) "xyz===2"
+string(7) "__clone"


Property changes on: php/php-src/trunk/Zend/tests/traits/methods_001.phpt
___________________________________________________________________
Added: svn:keywords
   + Id Rev Revision
Added: svn:eol-style
   + native

Added: php/php-src/trunk/Zend/tests/traits/methods_002.phpt
===================================================================
--- php/php-src/trunk/Zend/tests/traits/methods_002.phpt                        
        (rev 0)
+++ php/php-src/trunk/Zend/tests/traits/methods_002.phpt        2010-05-07 
13:55:27 UTC (rev 299102)
@@ -0,0 +1,30 @@
+--TEST--
+Testing collision with magic methods
+--FILE--
+<?php
+
+trait foo {
+       public function __clone() {
+               var_dump(__FUNCTION__);
+       }
+}
+
+trait baz {
+       public function __clone() {
+               var_dump(__FUNCTION__);
+       }
+}
+
+class bar {
+       use foo;
+       use baz;
+}
+
+$o = new bar;
+var_dump(clone $o);
+
+?>
+--EXPECTF--
+Warning: Trait method __clone has not been applied, because there are 
collisions with other trait methods on bar in %s on line %d
+object(bar)#%d (0) {
+}


Property changes on: php/php-src/trunk/Zend/tests/traits/methods_002.phpt
___________________________________________________________________
Added: svn:keywords
   + Id Rev Revision
Added: svn:eol-style
   + native

Added: php/php-src/trunk/Zend/tests/traits/methods_003.phpt
===================================================================
--- php/php-src/trunk/Zend/tests/traits/methods_003.phpt                        
        (rev 0)
+++ php/php-src/trunk/Zend/tests/traits/methods_003.phpt        2010-05-07 
13:55:27 UTC (rev 299102)
@@ -0,0 +1,24 @@
+--TEST--
+Testing __construct and __destruct with Trait
+--FILE--
+<?php
+
+trait foo {
+       public function __construct() {
+               var_dump(__FUNCTION__);
+       }
+       public function __destruct() {
+               var_dump(__FUNCTION__);
+       }
+}
+
+class bar {
+       use foo;
+}
+
+new bar;
+
+?>
+--EXPECT--
+string(11) "__construct"
+string(10) "__destruct"


Property changes on: php/php-src/trunk/Zend/tests/traits/methods_003.phpt
___________________________________________________________________
Added: svn:keywords
   + Id Rev Revision
Added: svn:eol-style
   + native

Modified: php/php-src/trunk/Zend/zend_compile.c
===================================================================
--- php/php-src/trunk/Zend/zend_compile.c       2010-05-07 13:31:13 UTC (rev 
299101)
+++ php/php-src/trunk/Zend/zend_compile.c       2010-05-07 13:55:27 UTC (rev 
299102)
@@ -3329,16 +3329,18 @@
       strncmp(mname, str, mname_len)

 #define _ADD_MAGIC_METHOD(ce, mname, mname_len, fe) { \
-       if (IS_EQUAL(mname, mname_len, "__clone"))      {       (ce)->clone     
                = (fe); (fe)->common.fn_flags = ZEND_ACC_CLONE; } \
-       else if (IS_EQUAL(mname, mname_len, "__get"))           (ce)->__get     
                = (fe); \
-       else if (IS_EQUAL(mname, mname_len, "__set"))           (ce)->__set     
                = (fe); \
-       else if (IS_EQUAL(mname, mname_len, "__call"))          (ce)->__call    
        = (fe); \
-       else if (IS_EQUAL(mname, mname_len, "__unset"))         (ce)->__unset   
        = (fe); \
-       else if (IS_EQUAL(mname, mname_len, "__isset"))         (ce)->__isset   
        = (fe); \
-       else if (IS_EQUAL(mname, mname_len, "__callstatic"))(ce)->__callstatic  
= (fe); \
-       else if (IS_EQUAL(mname, mname_len, "__tostring"))      
(ce)->__tostring        = (fe); \
-       else if (IS_EQUAL(mname, mname_len, "serialize_func"))  
(ce)->serialize_func    = (fe); \
-       else if (IS_EQUAL(mname, mname_len, 
"unserialize_func"))(ce)->unserialize_func  = (fe); \
+       if (!IS_EQUAL(mname, mname_len, "__clone"))     {       (ce)->clone     
                = (fe); (fe)->common.fn_flags |= ZEND_ACC_CLONE; } \
+       else if (!IS_EQUAL(mname, mname_len, "__construct"))  {         
(ce)->constructor = (fe); (fe)->common.fn_flags |= ZEND_ACC_CTOR; } \
+       else if (!IS_EQUAL(mname, mname_len, "__destruct"))  {          
(ce)->destructor = (fe); (fe)->common.fn_flags |= ZEND_ACC_DTOR; } \
+       else if (!IS_EQUAL(mname, mname_len, "__get"))          (ce)->__get     
                = (fe); \
+       else if (!IS_EQUAL(mname, mname_len, "__set"))          (ce)->__set     
                = (fe); \
+       else if (!IS_EQUAL(mname, mname_len, "__call"))         (ce)->__call    
        = (fe); \
+       else if (!IS_EQUAL(mname, mname_len, "__unset"))                
(ce)->__unset           = (fe); \
+       else if (!IS_EQUAL(mname, mname_len, "__isset"))                
(ce)->__isset           = (fe); \
+       else if (!IS_EQUAL(mname, mname_len, "__callstatic"))(ce)->__callstatic 
= (fe); \
+       else if (!IS_EQUAL(mname, mname_len, "__tostring"))     
(ce)->__tostring        = (fe); \
+       else if (!IS_EQUAL(mname, mname_len, "serialize_func")) 
(ce)->serialize_func    = (fe); \
+       else if (!IS_EQUAL(mname, mname_len, 
"unserialize_func"))(ce)->unserialize_func = (fe); \
 }

 /* {{{ Originates from php_runkit_function_copy_ctor
@@ -3433,6 +3435,7 @@
        zend_class_entry *ce = va_arg(args, zend_class_entry*);
        int add = 0;
        zend_function* existing_fn;
+       zend_function fn_copy, *fn_copy_p;
        zend_function* prototype = NULL;                /* is used to determine 
the prototype according to the inheritance chain */

        if (zend_hash_quick_find(&ce->function_table, hash_key->arKey, 
hash_key->nKeyLength, hash_key->h, (void**) &existing_fn) == FAILURE) {
@@ -3472,17 +3475,20 @@
                if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) {
                        ce->ce_flags |= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS;
                }
+               fn_copy = *fn;
+               zend_traits_duplicate_function(&fn_copy, 
estrdup(fn->common.function_name));

-               if (zend_hash_quick_update(&ce->function_table, 
hash_key->arKey, hash_key->nKeyLength, hash_key->h, fn, sizeof(zend_function), 
NULL)==FAILURE) {
+               if (zend_hash_quick_update(&ce->function_table, 
hash_key->arKey, hash_key->nKeyLength, hash_key->h, &fn_copy, 
sizeof(zend_function), (void**)&fn_copy_p)==FAILURE) {
                        zend_error(E_ERROR, "Trait method %s has not been 
applied, because failure occured during updating class method table", 
hash_key->arKey);
                }

-               _ADD_MAGIC_METHOD(ce, hash_key->arKey, hash_key->nKeyLength, 
fn);
+               _ADD_MAGIC_METHOD(ce, hash_key->arKey, hash_key->nKeyLength, 
fn_copy_p);
                /* it could be necessary to update child classes as well */
                /* zend_hash_apply_with_arguments(EG(class_table) TSRMLS_CC, 
(apply_func_args_t)php_runkit_update_children_methods, 5, dce, dce, &dfe, 
dfunc, dfunc_len); */
+
+               zend_function_dtor(fn);
        } else {
                zend_function_dtor(fn);
-               /* efree(fn); */
        }

        return ZEND_HASH_APPLY_REMOVE;

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to