From 946c955ce7bfdc47dd075c6ef4978b97ae183343 Mon Sep 17 00:00:00 2001 From: Marcus Boerger Date: Sun, 12 Mar 2006 15:34:46 +0000 Subject: [PATCH] - Fix ReflectionParameter . Reintroduce getClass() . Change getDeclaringClass() to return what it suggests . Add getDeclaringFunction() . Add getPosition() # This also fixes Bug #36687 ReflectionParameter::getDeclaringClass returns # wrong result --- ext/reflection/php_reflection.c | 62 +++- ext/reflection/tests/parameters_002.phpt | 369 +++++++++++++++++++++++ 2 files changed, 424 insertions(+), 7 deletions(-) create mode 100755 ext/reflection/tests/parameters_002.phpt diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 65545466cb..259bebddcb 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -1796,6 +1796,7 @@ ZEND_METHOD(reflection_parameter, __construct) } efree(lcname.v); } + ce = fptr->common.scope; break; case IS_ARRAY: { @@ -1910,9 +1911,9 @@ ZEND_METHOD(reflection_parameter, getName) } /* }}} */ -/* {{{ proto public ReflectionClass ReflectionParameter::getDeclaringClass() - Returns this parameters's class hint or NULL if there is none */ -ZEND_METHOD(reflection_parameter, getDeclaringClass) +/* {{{ proto public ReflectionFunction ReflectionParameter::getDeclaringFunction() + Returns the ReflectionFunction for the function of this parameter */ +ZEND_METHOD(reflection_parameter, getDeclaringFunction) { reflection_object *intern; parameter_reference *param; @@ -1920,11 +1921,42 @@ ZEND_METHOD(reflection_parameter, getDeclaringClass) METHOD_NOTSTATIC_NUMPARAMS(reflection_parameter_ptr, 0); GET_REFLECTION_OBJECT_PTR(param); - if (!param->arg_info->class_name.v) { - RETURN_NULL(); + if (!param->fptr->common.scope) { + reflection_function_factory(param->fptr, return_value TSRMLS_CC); } else { - zend_class_entry **pce; + reflection_method_factory(param->fptr->common.scope, param->fptr, return_value TSRMLS_CC); + } +} +/* }}} */ + +/* {{{ proto public ReflectionClass|NULL ReflectionParameter::getDeclaringClass() + Returns in which class this parameter is defined (not the typehint of the parameter) */ +ZEND_METHOD(reflection_parameter, getDeclaringClass) +{ + reflection_object *intern; + parameter_reference *param; + + METHOD_NOTSTATIC_NUMPARAMS(reflection_parameter_ptr, 0); + GET_REFLECTION_OBJECT_PTR(param); + + if (param->fptr->common.scope) { + zend_reflection_class_factory(param->fptr->common.scope, return_value TSRMLS_CC); + } +} +/* }}} */ + +/* {{{ proto public ReflectionClass|NULL ReflectionParameter::getClass() + Returns this parameters's class hint or NULL if there is none */ +ZEND_METHOD(reflection_parameter, getClass) +{ + reflection_object *intern; + parameter_reference *param; + zend_class_entry **pce; + METHOD_NOTSTATIC_NUMPARAMS(reflection_parameter_ptr, 0); + GET_REFLECTION_OBJECT_PTR(param); + + if (param->arg_info->class_name.v) { if (zend_u_lookup_class_ex(UG(unicode)?IS_UNICODE:IS_STRING, param->arg_info->class_name, param->arg_info->class_name_len, 1, &pce TSRMLS_CC) == FAILURE) { zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Class %v does not exist", param->arg_info->class_name); @@ -1977,6 +2009,20 @@ ZEND_METHOD(reflection_parameter, isPassedByReference) } /* }}} */ +/* {{{ proto public bool ReflectionParameter::getPosition() + Returns whether this parameter is an optional parameter */ +ZEND_METHOD(reflection_parameter, getPosition) +{ + reflection_object *intern; + parameter_reference *param; + + METHOD_NOTSTATIC_NUMPARAMS(reflection_parameter_ptr, 0); + GET_REFLECTION_OBJECT_PTR(param); + + RETVAL_LONG(param->offset); +} +/* }}} */ + /* {{{ proto public bool ReflectionParameter::isOptional() Returns whether this parameter is an optional parameter */ ZEND_METHOD(reflection_parameter, isOptional) @@ -4364,10 +4410,12 @@ static zend_function_entry reflection_parameter_functions[] = { ZEND_ME(reflection_parameter, __toString, NULL, 0) ZEND_ME(reflection_parameter, getName, NULL, 0) ZEND_ME(reflection_parameter, isPassedByReference, NULL, 0) + ZEND_ME(reflection_parameter, getDeclaringFunction, NULL, 0) ZEND_ME(reflection_parameter, getDeclaringClass, NULL, 0) - ZEND_MALIAS(reflection_parameter, getClass, getDeclaringClass, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED) + ZEND_ME(reflection_parameter, getClass, NULL, 0) ZEND_ME(reflection_parameter, isArray, NULL, 0) ZEND_ME(reflection_parameter, allowsNull, NULL, 0) + ZEND_ME(reflection_parameter, getPosition, NULL, 0) ZEND_ME(reflection_parameter, isOptional, NULL, 0) ZEND_ME(reflection_parameter, isDefaultValueAvailable, NULL, 0) ZEND_ME(reflection_parameter, getDefaultValue, NULL, 0) diff --git a/ext/reflection/tests/parameters_002.phpt b/ext/reflection/tests/parameters_002.phpt new file mode 100755 index 0000000000..c0499f1efe --- /dev/null +++ b/ext/reflection/tests/parameters_002.phpt @@ -0,0 +1,369 @@ +--TEST-- +ReflectionParameter::getclass(), getDeclaringClass(), getDeclaringFunction() +--SKIPIF-- + +--FILE-- +$f(); + echo $f . ': ' . ($c ? ($c instanceof ReflectionMethod ? $c->class . '::' : '') . $c->name : 'NULL') . "()\n"; +} + +function check_params_decl_class($r, $f) +{ + $c = $r->$f(); + echo $f . ': ' . ($c ? $c->name : 'NULL') . "\n"; +} + +function check_params_func($r, $f) +{ + echo $f . ': '; + $v = $r->$f(); + var_dump($v); +} + +function check_params($r) +{ + echo "#####" . ($r instanceof ReflectionMethod ? $r->class . '::' : '') . $r->name . "()#####\n"; + foreach($r->getParameters() as $p) + { + echo "===" . $p->getPosition() . "===\n"; + check_params_func($p, 'getName'); + check_params_func($p, 'isPassedByReference'); + try + { + check_params_decl_class($p, 'getClass'); + } + catch(ReflectionException $e) + { + echo $e->getMessage() . "\n"; + } + check_params_decl_class($p, 'getDeclaringClass'); + check_params_decl_func($p, 'getDeclaringFunction'); + check_params_func($p, 'isArray'); + check_params_func($p, 'allowsNull'); + check_params_func($p, 'isOptional'); + check_params_func($p, 'isDefaultValueAvailable'); + if ($p->isOptional()) + { + check_params_func($p, 'getDefaultValue'); + } + } +} + +check_params(new ReflectionFunction('test')); + +check_params(new ReflectionMethod('test::test')); + +?> +===DONE=== + +--EXPECT-- +#####test()##### +===0=== +getName: string(3) "nix" +isPassedByReference: bool(false) +getClass: NULL +getDeclaringClass: NULL +getDeclaringFunction: test() +isArray: bool(false) +allowsNull: bool(true) +isOptional: bool(false) +isDefaultValueAvailable: bool(false) +===1=== +getName: string(2) "ar" +isPassedByReference: bool(false) +getClass: NULL +getDeclaringClass: NULL +getDeclaringFunction: test() +isArray: bool(true) +allowsNull: bool(false) +isOptional: bool(false) +isDefaultValueAvailable: bool(false) +===2=== +getName: string(3) "ref" +isPassedByReference: bool(true) +getClass: NULL +getDeclaringClass: NULL +getDeclaringFunction: test() +isArray: bool(false) +allowsNull: bool(true) +isOptional: bool(false) +isDefaultValueAvailable: bool(false) +===3=== +getName: string(3) "std" +isPassedByReference: bool(false) +getClass: stdClass +getDeclaringClass: NULL +getDeclaringFunction: test() +isArray: bool(false) +allowsNull: bool(false) +isOptional: bool(false) +isDefaultValueAvailable: bool(false) +===4=== +getName: string(2) "na" +isPassedByReference: bool(false) +Class NonExistingClass does not exist +getDeclaringClass: NULL +getDeclaringFunction: test() +isArray: bool(false) +allowsNull: bool(false) +isOptional: bool(false) +isDefaultValueAvailable: bool(false) +===5=== +getName: string(3) "opt" +isPassedByReference: bool(true) +getClass: stdClass +getDeclaringClass: NULL +getDeclaringFunction: test() +isArray: bool(false) +allowsNull: bool(true) +isOptional: bool(true) +isDefaultValueAvailable: bool(true) +getDefaultValue: NULL +===6=== +getName: string(3) "def" +isPassedByReference: bool(false) +getClass: NULL +getDeclaringClass: NULL +getDeclaringFunction: test() +isArray: bool(false) +allowsNull: bool(true) +isOptional: bool(true) +isDefaultValueAvailable: bool(true) +getDefaultValue: string(6) "FooBar" +#####test::test()##### +===0=== +getName: string(3) "nix" +isPassedByReference: bool(false) +getClass: NULL +getDeclaringClass: test +getDeclaringFunction: test::test() +isArray: bool(false) +allowsNull: bool(true) +isOptional: bool(false) +isDefaultValueAvailable: bool(false) +===1=== +getName: string(2) "ar" +isPassedByReference: bool(false) +getClass: NULL +getDeclaringClass: test +getDeclaringFunction: test::test() +isArray: bool(true) +allowsNull: bool(false) +isOptional: bool(false) +isDefaultValueAvailable: bool(false) +===2=== +getName: string(3) "ref" +isPassedByReference: bool(true) +getClass: NULL +getDeclaringClass: test +getDeclaringFunction: test::test() +isArray: bool(false) +allowsNull: bool(true) +isOptional: bool(false) +isDefaultValueAvailable: bool(false) +===3=== +getName: string(3) "std" +isPassedByReference: bool(false) +getClass: stdClass +getDeclaringClass: test +getDeclaringFunction: test::test() +isArray: bool(false) +allowsNull: bool(false) +isOptional: bool(false) +isDefaultValueAvailable: bool(false) +===4=== +getName: string(2) "na" +isPassedByReference: bool(false) +Class NonExistingClass does not exist +getDeclaringClass: test +getDeclaringFunction: test::test() +isArray: bool(false) +allowsNull: bool(false) +isOptional: bool(false) +isDefaultValueAvailable: bool(false) +===5=== +getName: string(3) "opt" +isPassedByReference: bool(false) +getClass: stdClass +getDeclaringClass: test +getDeclaringFunction: test::test() +isArray: bool(false) +allowsNull: bool(true) +isOptional: bool(true) +isDefaultValueAvailable: bool(true) +getDefaultValue: NULL +===6=== +getName: string(3) "def" +isPassedByReference: bool(false) +getClass: NULL +getDeclaringClass: test +getDeclaringFunction: test::test() +isArray: bool(false) +allowsNull: bool(true) +isOptional: bool(true) +isDefaultValueAvailable: bool(true) +getDefaultValue: string(6) "FooBar" +===DONE=== +--UEXPECT-- +#####test()##### +===0=== +getName: unicode(3) "nix" +isPassedByReference: bool(false) +getClass: NULL +getDeclaringClass: NULL +getDeclaringFunction: test() +isArray: bool(false) +allowsNull: bool(true) +isOptional: bool(false) +isDefaultValueAvailable: bool(false) +===1=== +getName: unicode(2) "ar" +isPassedByReference: bool(false) +getClass: NULL +getDeclaringClass: NULL +getDeclaringFunction: test() +isArray: bool(true) +allowsNull: bool(false) +isOptional: bool(false) +isDefaultValueAvailable: bool(false) +===2=== +getName: unicode(3) "ref" +isPassedByReference: bool(true) +getClass: NULL +getDeclaringClass: NULL +getDeclaringFunction: test() +isArray: bool(false) +allowsNull: bool(true) +isOptional: bool(false) +isDefaultValueAvailable: bool(false) +===3=== +getName: unicode(3) "std" +isPassedByReference: bool(false) +getClass: stdClass +getDeclaringClass: NULL +getDeclaringFunction: test() +isArray: bool(false) +allowsNull: bool(false) +isOptional: bool(false) +isDefaultValueAvailable: bool(false) +===4=== +getName: unicode(2) "na" +isPassedByReference: bool(false) +Class NonExistingClass does not exist +getDeclaringClass: NULL +getDeclaringFunction: test() +isArray: bool(false) +allowsNull: bool(false) +isOptional: bool(false) +isDefaultValueAvailable: bool(false) +===5=== +getName: unicode(3) "opt" +isPassedByReference: bool(true) +getClass: stdClass +getDeclaringClass: NULL +getDeclaringFunction: test() +isArray: bool(false) +allowsNull: bool(true) +isOptional: bool(true) +isDefaultValueAvailable: bool(true) +getDefaultValue: NULL +===6=== +getName: unicode(3) "def" +isPassedByReference: bool(false) +getClass: NULL +getDeclaringClass: NULL +getDeclaringFunction: test() +isArray: bool(false) +allowsNull: bool(true) +isOptional: bool(true) +isDefaultValueAvailable: bool(true) +getDefaultValue: unicode(6) "FooBar" +#####test::test()##### +===0=== +getName: unicode(3) "nix" +isPassedByReference: bool(false) +getClass: NULL +getDeclaringClass: test +getDeclaringFunction: test::test() +isArray: bool(false) +allowsNull: bool(true) +isOptional: bool(false) +isDefaultValueAvailable: bool(false) +===1=== +getName: unicode(2) "ar" +isPassedByReference: bool(false) +getClass: NULL +getDeclaringClass: test +getDeclaringFunction: test::test() +isArray: bool(true) +allowsNull: bool(false) +isOptional: bool(false) +isDefaultValueAvailable: bool(false) +===2=== +getName: unicode(3) "ref" +isPassedByReference: bool(true) +getClass: NULL +getDeclaringClass: test +getDeclaringFunction: test::test() +isArray: bool(false) +allowsNull: bool(true) +isOptional: bool(false) +isDefaultValueAvailable: bool(false) +===3=== +getName: unicode(3) "std" +isPassedByReference: bool(false) +getClass: stdClass +getDeclaringClass: test +getDeclaringFunction: test::test() +isArray: bool(false) +allowsNull: bool(false) +isOptional: bool(false) +isDefaultValueAvailable: bool(false) +===4=== +getName: unicode(2) "na" +isPassedByReference: bool(false) +Class NonExistingClass does not exist +getDeclaringClass: test +getDeclaringFunction: test::test() +isArray: bool(false) +allowsNull: bool(false) +isOptional: bool(false) +isDefaultValueAvailable: bool(false) +===5=== +getName: unicode(3) "opt" +isPassedByReference: bool(false) +getClass: stdClass +getDeclaringClass: test +getDeclaringFunction: test::test() +isArray: bool(false) +allowsNull: bool(true) +isOptional: bool(true) +isDefaultValueAvailable: bool(true) +getDefaultValue: NULL +===6=== +getName: unicode(3) "def" +isPassedByReference: bool(false) +getClass: NULL +getDeclaringClass: test +getDeclaringFunction: test::test() +isArray: bool(false) +allowsNull: bool(true) +isOptional: bool(true) +isDefaultValueAvailable: bool(true) +getDefaultValue: unicode(6) "FooBar" +===DONE=== -- 2.40.0