svn: /php/php-src/trunk/Zend/ tests/traits/methods_001.phpt tests/traits/methods_002.phpt tests/traits/methods_003.phpt zend_compile.c
| From: | Felipe Pena | Date: | Fri, 07 May 2010 13:55:27 +0000 |
| Subject: | svn: /php/php-src/trunk/Zend/ tests/traits/methods_001.phpt tests/traits/methods_002.phpt tests/traits/methods_003.phpt zend_compile.c | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-62575@lists.php.net to get a copy of this message | ||
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;