]> granicus.if.org Git - php/commitdiff
Fixed problem reported by Patrick ALLAERT. Trait method was not applied properly...
authorStefan Marr <gron@php.net>
Thu, 18 Nov 2010 17:59:04 +0000 (17:59 +0000)
committerStefan Marr <gron@php.net>
Thu, 18 Nov 2010 17:59:04 +0000 (17:59 +0000)
Zend/tests/traits/bugs/alias-semantics02.phpt [new file with mode: 0644]
Zend/tests/traits/error_015.phpt
Zend/tests/traits/language010.phpt
Zend/zend_compile.c

diff --git a/Zend/tests/traits/bugs/alias-semantics02.phpt b/Zend/tests/traits/bugs/alias-semantics02.phpt
new file mode 100644 (file)
index 0000000..e0b5286
--- /dev/null
@@ -0,0 +1,25 @@
+--TEST--
+Semantic of alias operation is to provide an additional identifier for the
+method body of the original method.
+It should also work incase the method is fully qualified.
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+trait THello {
+  public function a() {
+    echo 'A';
+  }
+}
+
+class TraitsTest {
+       use THello { THello::a as b; }
+}
+
+$test = new TraitsTest();
+$test->a();
+$test->b();
+
+?>
+--EXPECTF--    
+AA
\ No newline at end of file
index 571e6f4db59dff9fb0dd0f9388f3d12b5fc2c6e3..ec47c0d8e25782b175f78be4b078c9dcad063b8d 100644 (file)
@@ -1,5 +1,6 @@
 --TEST--
-Trying to add an alias to a trait method where there is another with same name
+Trying to add an alias to a trait method where there is another with same name.
+Should warn about the conflict.
 --FILE--
 <?php
 
@@ -22,4 +23,6 @@ var_dump($x->test());
 
 ?>
 --EXPECTF--
-Fatal error: Failed to add aliased trait method (zzz) to the trait table. There is probably already a trait method with the same name in %s on line %d
+Warning: Trait method test has not been applied, because there are collisions with other trait methods on bar in %s on line %d
+
+Fatal error: Call to undefined method bar::test() in %s on line %d
index f184457bef6450f200f7d398c20fe42609ddbd7d..f7fea6f295046ef639398371877536f7aae22916 100644 (file)
@@ -27,6 +27,4 @@ $o->world();
 
 ?>
 --EXPECTF--    
-Warning: Trait method world has not been applied, because there are collisions with other trait methods on MyClass in %s on line %d
-Hello
-Fatal error: Call to undefined method MyClass::world() in %s on line %d
\ No newline at end of file
+Fatal error: Failed to add trait method (world) to the trait table. There is probably already a trait method with the same name in %s on line %d
\ No newline at end of file
index c49dce6fcb76c0ae4d3f49afe17e5a2ab7295f0f..ec741f9e108620359b34a26e9d3f2c94c8b96b32 100644 (file)
@@ -3674,13 +3674,13 @@ static int zend_traits_copy_functions(zend_function *fn TSRMLS_DC, int num_args,
        target = va_arg(args, HashTable*);
        aliases = va_arg(args, zend_trait_alias**);
        exclude_table = va_arg(args, HashTable*);
-
+  
        fnname_len = strlen(fn->common.function_name);
 
-       /* apply aliases which are qualified with a class name, there should not be any ambiguatty */
+       /* apply aliases which are qualified with a class name, there should not be any ambiguity */
        if (aliases) {
                while (aliases[i]) {
-                       if (fn->common.scope == aliases[i]->trait_method->ce &&
+                       if (!aliases[i]->trait_method->ce || fn->common.scope == aliases[i]->trait_method->ce &&
                                (zend_binary_strcasecmp(aliases[i]->trait_method->method_name,
                                  aliases[i]->trait_method->mname_len,
                                  fn->common.function_name, fnname_len) == 0)) {
@@ -3716,9 +3716,8 @@ static int zend_traits_copy_functions(zend_function *fn TSRMLS_DC, int num_args,
                fn_copy = *fn;
                zend_traits_duplicate_function(&fn_copy, estrndup(fn->common.function_name, fnname_len) TSRMLS_CC);
 
-               /* apply aliases which are not qualified by a class name, or which have not alias name, just setting visibility */
-               /* TODO: i am still not sure, that there will be no ambigousities... */
-
+               /* apply aliases which are not qualified by a class name, or which have not
+     alias name, just setting visibility */
                if (aliases) {
                        i = 0;
                        while (aliases[i]) {
@@ -3726,33 +3725,10 @@ static int zend_traits_copy_functions(zend_function *fn TSRMLS_DC, int num_args,
                                        (zend_binary_strcasecmp(aliases[i]->trait_method->method_name,
                                    aliases[i]->trait_method->mname_len,
                                    fn->common.function_name, fnname_len) == 0)) {
-                                       if (aliases[i]->alias) {
-                                               zend_uint lcname2_len;
-                                               char* lcname2;
-                                               zend_function fn_copy2 = *fn;
-
-                                               zend_traits_duplicate_function(&fn_copy2, estrndup(aliases[i]->alias, aliases[i]->alias_len) TSRMLS_CC);
-
-                                               if (aliases[i]->modifiers) { /* if it is 0, no modifieres has been changed */
-                                                       fn_copy2.common.fn_flags = aliases[i]->modifiers;
-                                                       if (!(aliases[i]->modifiers & ZEND_ACC_PPP_MASK)) {
-                                                               fn_copy2.common.fn_flags |= ZEND_ACC_PUBLIC;
-                                                       }
-                                               }
-
-                                               lcname2_len = aliases[i]->alias_len;
-                                               lcname2 = zend_str_tolower_dup(aliases[i]->alias, lcname2_len);
-
-                                               if (zend_hash_add(target, lcname2, lcname2_len+1, &fn_copy2, sizeof(zend_function), NULL)==FAILURE) {
-                                                       zend_error(E_ERROR, "Failed to add aliased trait method (%s) to the trait table. There is probably already a trait method with the same name", fn_copy2.common.function_name);
-                                               }
-                                               efree(lcname2);
-                                       } else {
-                                               if (aliases[i]->modifiers) { /* if it is 0, no modifieres has been changed */
-                                                       fn_copy.common.fn_flags = aliases[i]->modifiers;
-                                                       if (!(aliases[i]->modifiers & ZEND_ACC_PPP_MASK)) {
-                                                               fn_copy.common.fn_flags |= ZEND_ACC_PUBLIC;
-                                                       }
+                                       if (!aliases[i]->alias && aliases[i]->modifiers) { /* if it is 0, no modifieres has been changed */
+                                               fn_copy.common.fn_flags = aliases[i]->modifiers;
+                                               if (!(aliases[i]->modifiers & ZEND_ACC_PPP_MASK)) {
+                                                       fn_copy.common.fn_flags |= ZEND_ACC_PUBLIC;
                                                }
                                        }
                                }