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