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