sebastian                                Tue, 17 Jan 2012 12:59:33 +0000

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

Log:
Implement ReflectionClass::setFinal() and ReflectionMethod::setFinal().

Patch by Jan Dolecek <juzna...@gmail.com>.

Changed paths:
    U   php/php-src/trunk/NEWS
    U   php/php-src/trunk/ext/reflection/php_reflection.c
    A   php/php-src/trunk/ext/reflection/tests/ReflectionClass_setFinal.phpt
    U   php/php-src/trunk/ext/reflection/tests/ReflectionClass_toString_001.phpt
    A   php/php-src/trunk/ext/reflection/tests/ReflectionMethod_setFinal.phpt

Modified: php/php-src/trunk/NEWS
===================================================================
--- php/php-src/trunk/NEWS      2012-01-17 10:35:39 UTC (rev 322389)
+++ php/php-src/trunk/NEWS      2012-01-17 12:59:33 UTC (rev 322390)
@@ -35,4 +35,9 @@
 - pgsql
   . Added pg_escape_literal() and pg_escape_identifier() (Yasuo)

+- Reflection:
+  . Added ReflectionCLass::setFinal() and ReflectionMethod::setFinal() to allow
+    stubbing and mocking of final classes and methods, for instance.
+    (Sebastian, Jan Dolecek <juzna...@gmail.com>)
+
 <<< NOTE: Insert NEWS from last stable release here prior to actual release! 
>>>

Modified: php/php-src/trunk/ext/reflection/php_reflection.c
===================================================================
--- php/php-src/trunk/ext/reflection/php_reflection.c   2012-01-17 10:35:39 UTC 
(rev 322389)
+++ php/php-src/trunk/ext/reflection/php_reflection.c   2012-01-17 12:59:33 UTC 
(rev 322390)
@@ -3113,6 +3113,28 @@
 }
 /* }}} */

+/* {{{ proto public void ReflectionMethod::setFinal([bool isFinal = true])
+      Sets/unsets class as final */
+ZEND_METHOD(reflection_method, setFinal)
+{
+       reflection_object *intern;
+       zend_function *mptr;
+       zend_bool isFinal = 1;
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &isFinal) == 
FAILURE) {
+               return;
+       }
+
+       GET_REFLECTION_OBJECT_PTR(mptr);
+
+       if (isFinal) {
+               mptr->common.fn_flags |= ZEND_ACC_FINAL;
+       } else {
+               mptr->common.fn_flags &= ~ZEND_ACC_FINAL;
+       }
+}
+/* }}} */
+
 /* {{{ proto public ReflectionClass ReflectionMethod::getDeclaringClass()
    Get the declaring class */
 ZEND_METHOD(reflection_method, getDeclaringClass)
@@ -4047,6 +4069,28 @@
 }
 /* }}} */

+/* {{{ proto public void ReflectionClass::setFinal([bool isFinal = true])
+   Sets/unsets class as final */
+ZEND_METHOD(reflection_class, setFinal)
+{
+       reflection_object *intern;
+       zend_class_entry *ce;
+       zend_bool isFinal = 1;
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &isFinal) == 
FAILURE) {
+               return;
+       }
+
+       GET_REFLECTION_OBJECT_PTR(ce);
+
+       if (isFinal) {
+               ce->ce_flags |= ZEND_ACC_FINAL_CLASS;
+       } else {
+               ce->ce_flags &= ~ZEND_ACC_FINAL_CLASS;
+       }
+}
+/* }}} */
+
 /* {{{ proto public int ReflectionClass::getModifiers()
    Returns a bitfield of the access modifiers for this class */
 ZEND_METHOD(reflection_class, getModifiers)
@@ -5651,6 +5695,10 @@
        ZEND_ARG_INFO(0, value)
 ZEND_END_ARG_INFO()

+ZEND_BEGIN_ARG_INFO(arginfo_reflection_method_setFinal, 0)
+       ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO()
+
 ZEND_BEGIN_ARG_INFO(arginfo_reflection_method_getClosure, 0)
        ZEND_ARG_INFO(0, object)
 ZEND_END_ARG_INFO()
@@ -5664,6 +5712,7 @@
        ZEND_ME(reflection_method, isProtected, arginfo_reflection__void, 0)
        ZEND_ME(reflection_method, isAbstract, arginfo_reflection__void, 0)
        ZEND_ME(reflection_method, isFinal, arginfo_reflection__void, 0)
+       ZEND_ME(reflection_method, setFinal, 
arginfo_reflection_method_setFinal, 0)
        ZEND_ME(reflection_method, isStatic, arginfo_reflection__void, 0)
        ZEND_ME(reflection_method, isConstructor, arginfo_reflection__void, 0)
        ZEND_ME(reflection_method, isDestructor, arginfo_reflection__void, 0)
@@ -5733,6 +5782,10 @@
        ZEND_ARG_INFO(0, object)
 ZEND_END_ARG_INFO()

+ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_setFinal, 0)
+       ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO()
+
 ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_newInstance, 0)
        ZEND_ARG_INFO(0, args)
 ZEND_END_ARG_INFO()
@@ -5785,6 +5838,7 @@
        ZEND_ME(reflection_class, isTrait, arginfo_reflection__void, 0)
        ZEND_ME(reflection_class, isAbstract, arginfo_reflection__void, 0)
        ZEND_ME(reflection_class, isFinal, arginfo_reflection__void, 0)
+       ZEND_ME(reflection_class, setFinal, arginfo_reflection_class_setFinal, 
0)
        ZEND_ME(reflection_class, getModifiers, arginfo_reflection__void, 0)
        ZEND_ME(reflection_class, isInstance, 
arginfo_reflection_class_isInstance, 0)
        ZEND_ME(reflection_class, newInstance, 
arginfo_reflection_class_newInstance, 0)

Added: php/php-src/trunk/ext/reflection/tests/ReflectionClass_setFinal.phpt
===================================================================
--- php/php-src/trunk/ext/reflection/tests/ReflectionClass_setFinal.phpt        
                        (rev 0)
+++ php/php-src/trunk/ext/reflection/tests/ReflectionClass_setFinal.phpt        
2012-01-17 12:59:33 UTC (rev 322390)
@@ -0,0 +1,33 @@
+--TEST--
+Test ReflectionClass::setFinal().
+--FILE--
+<?php
+class a {
+    public final function b() {
+        print __METHOD__;
+    }
+}
+
+$c = new ReflectionClass('a');
+$c->setFinal(FALSE);
+
+var_dump($c->isFinal());
+
+# Not sure if it is by design that the following two lines are required
+$m = new ReflectionMethod('a', 'b');
+$m->setFinal(FALSE);
+
+if (TRUE) {
+    class c extends a {
+        public function b() {
+            print __METHOD__;
+        }
+    }
+}
+
+$o = new c;
+$o->b();
+?>
+--EXPECT--
+bool(false)
+c::b


Property changes on: 
php/php-src/trunk/ext/reflection/tests/ReflectionClass_setFinal.phpt
___________________________________________________________________
Added: svn:keywords
   + Id Rev Revision
Added: svn:eol-style
   + native

Modified: 
php/php-src/trunk/ext/reflection/tests/ReflectionClass_toString_001.phpt
===================================================================
--- php/php-src/trunk/ext/reflection/tests/ReflectionClass_toString_001.phpt    
2012-01-17 10:35:39 UTC (rev 322389)
+++ php/php-src/trunk/ext/reflection/tests/ReflectionClass_toString_001.phpt    
2012-01-17 12:59:33 UTC (rev 322390)
@@ -8,7 +8,7 @@
 $rc = new ReflectionClass("ReflectionClass");
 echo $rc;
 ?>
---EXPECTF--
+--EXPECT--
 Class [ <internal:Reflection> class ReflectionClass implements Reflector ] {

   - Constants [3] {
@@ -34,7 +34,7 @@
     Property [ <default> public $name ]
   }

-  - Methods [49] {
+  - Methods [50] {
     Method [ <internal:Reflection> final private method __clone ] {

       - Parameters [0] {
@@ -230,6 +230,13 @@
       }
     }

+    Method [ <internal:Reflection> public method setFinal ] {
+
+      - Parameters [1] {
+        Parameter #0 [ <required> $value ]
+      }
+    }
+
     Method [ <internal:Reflection> public method getModifiers ] {

       - Parameters [0] {

Added: php/php-src/trunk/ext/reflection/tests/ReflectionMethod_setFinal.phpt
===================================================================
--- php/php-src/trunk/ext/reflection/tests/ReflectionMethod_setFinal.phpt       
                        (rev 0)
+++ php/php-src/trunk/ext/reflection/tests/ReflectionMethod_setFinal.phpt       
2012-01-17 12:59:33 UTC (rev 322390)
@@ -0,0 +1,29 @@
+--TEST--
+Test ReflectionMethod::setFinal().
+--FILE--
+<?php
+class a {
+    public final function b() {
+        print __METHOD__;
+    }
+}
+
+$m = new ReflectionMethod('a', 'b');
+$m->setFinal(FALSE);
+
+var_dump($m->isFinal());
+
+if (TRUE) {
+    class c extends a {
+        public function b() {
+            print __METHOD__;
+        }
+    }
+}
+
+$o = new c;
+$o->b();
+?>
+--EXPECT--
+bool(false)
+c::b


Property changes on: 
php/php-src/trunk/ext/reflection/tests/ReflectionMethod_setFinal.phpt
___________________________________________________________________
Added: svn:keywords
   + Id Rev Revision
Added: svn:eol-style
   + native

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

Reply via email to