mirror of
https://github.com/php/php-src.git
synced 2025-08-19 17:04:47 +02:00
Implement ReflectionClass::setFinal() and ReflectionMethod::setFinal().
Patch by Jan Dolecek <juzna.cz@gmail.com>.
This commit is contained in:
parent
9025d6219d
commit
e76c1cc03c
5 changed files with 130 additions and 2 deletions
5
NEWS
5
NEWS
|
@ -35,4 +35,9 @@ PHP NEWS
|
|||
- 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.cz@gmail.com>)
|
||||
|
||||
<<< NOTE: Insert NEWS from last stable release here prior to actual release! >>>
|
||||
|
|
|
@ -3113,6 +3113,28 @@ ZEND_METHOD(reflection_method, getModifiers)
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ 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 @@ ZEND_METHOD(reflection_class, isAbstract)
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ 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_BEGIN_ARG_INFO(arginfo_reflection_method_setAccessible, 0)
|
|||
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 @@ static const zend_function_entry reflection_method_functions[] = {
|
|||
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_BEGIN_ARG_INFO(arginfo_reflection_class_isInstance, 0)
|
|||
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 @@ static const zend_function_entry reflection_class_functions[] = {
|
|||
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)
|
||||
|
|
33
ext/reflection/tests/ReflectionClass_setFinal.phpt
Normal file
33
ext/reflection/tests/ReflectionClass_setFinal.phpt
Normal file
|
@ -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
|
|
@ -8,7 +8,7 @@ Steve Seear <stevseea@php.net>
|
|||
$rc = new ReflectionClass("ReflectionClass");
|
||||
echo $rc;
|
||||
?>
|
||||
--EXPECTF--
|
||||
--EXPECT--
|
||||
Class [ <internal:Reflection> class ReflectionClass implements Reflector ] {
|
||||
|
||||
- Constants [3] {
|
||||
|
@ -34,7 +34,7 @@ Class [ <internal:Reflection> class ReflectionClass implements Reflector ] {
|
|||
Property [ <default> public $name ]
|
||||
}
|
||||
|
||||
- Methods [49] {
|
||||
- Methods [50] {
|
||||
Method [ <internal:Reflection> final private method __clone ] {
|
||||
|
||||
- Parameters [0] {
|
||||
|
@ -230,6 +230,13 @@ Class [ <internal:Reflection> class ReflectionClass implements Reflector ] {
|
|||
}
|
||||
}
|
||||
|
||||
Method [ <internal:Reflection> public method setFinal ] {
|
||||
|
||||
- Parameters [1] {
|
||||
Parameter #0 [ <required> $value ]
|
||||
}
|
||||
}
|
||||
|
||||
Method [ <internal:Reflection> public method getModifiers ] {
|
||||
|
||||
- Parameters [0] {
|
||||
|
|
29
ext/reflection/tests/ReflectionMethod_setFinal.phpt
Normal file
29
ext/reflection/tests/ReflectionMethod_setFinal.phpt
Normal file
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue