Commit:    054f3e3ce5af13c2c3a6ccd54f7dc3e2f6cd4f74
Author:    reeze <reeze....@gmail.com>         Tue, 3 Apr 2012 13:47:16 +0800
Parents:   3bf53aa911e1e2128a11aee45c126000635de006
Branches:  PHP-5.4 master

Link:       
http://git.php.net/?p=php-src.git;a=commitdiff;h=054f3e3ce5af13c2c3a6ccd54f7dc3e2f6cd4f74

Log:
Implemented FR #61602 Allow access to name of constant used as default value

Bugs:
https://bugs.php.net/61602

Changed paths:
  M  NEWS
  M  ext/reflection/php_reflection.c
  A  ext/reflection/tests/ReflectionParameter_DefaultValueConstant_basic1.phpt
  A  ext/reflection/tests/ReflectionParameter_DefaultValueConstant_basic2.phpt
  A  ext/reflection/tests/ReflectionParameter_DefaultValueConstant_error.phpt

diff --git a/NEWS b/NEWS
index 6fc9126..01eed64 100644
--- a/NEWS
+++ b/NEWS
@@ -100,6 +100,8 @@ PHP                                                         
               NEWS
     bytes). (Nikita Popov)
 
 - Reflection:
+  . Implemented FR #61602 (Allow access to the name of constant
+    used as function/method parameter's default value). (reeze....@gmail.com)
   . Fixed bug #60968 (Late static binding doesn't work with 
     ReflectionMethod::invokeArgs()). (Laruence)
 
diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c
index 1cf65ce..ef1ed7e 100644
--- a/ext/reflection/php_reflection.c
+++ b/ext/reflection/php_reflection.c
@@ -1457,6 +1457,57 @@ static void 
_reflection_export(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *c
 }
 /* }}} */
 
+/* {{{ _reflection_param_get_default_param */
+static parameter_reference 
*_reflection_param_get_default_param(INTERNAL_FUNCTION_PARAMETERS)
+{
+       reflection_object *intern;
+       parameter_reference *param;
+
+       if (zend_parse_parameters_none() == FAILURE) {
+               return NULL;
+       }
+
+       GET_REFLECTION_OBJECT_PTR(param);
+
+       if (param->fptr->type != ZEND_USER_FUNCTION)
+       {
+               zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
"Cannot determine default value for internal functions");
+               return NULL;
+       }
+
+       if (param->offset < param->required) {
+               zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
"Parameter is not optional");
+               return NULL;
+       }
+
+       return param;
+}
+/* }}} */
+
+/* {{{ _reflection_param_get_default_precv */
+static zend_op 
*_reflection_param_get_default_precv(INTERNAL_FUNCTION_PARAMETERS)
+{
+       zend_op *precv;
+       parameter_reference *param = 
_reflection_param_get_default_param(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+
+       if (zend_parse_parameters_none() == FAILURE) {
+               return NULL;
+       }
+
+       if(!param) {
+               return NULL;
+       }
+
+       precv = _get_recv_op((zend_op_array*)param->fptr, param->offset);
+       if (!precv || precv->opcode != ZEND_RECV_INIT || precv->op2_type == 
IS_UNUSED) {
+               zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
"Internal error");
+               return NULL;
+       }
+
+       return precv;
+}
+/* }}} */
+
 /* {{{ Preventing __clone from being called */
 ZEND_METHOD(reflection, __clone)
 {
@@ -2535,27 +2586,10 @@ ZEND_METHOD(reflection_parameter, 
isDefaultValueAvailable)
    Returns the default value of this parameter or throws an exception */
 ZEND_METHOD(reflection_parameter, getDefaultValue)
 {
-       reflection_object *intern;
-       parameter_reference *param;
-       zend_op *precv;
+       parameter_reference *param =  
_reflection_param_get_default_param(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+       zend_op *precv = 
_reflection_param_get_default_precv(INTERNAL_FUNCTION_PARAM_PASSTHRU);
 
-       if (zend_parse_parameters_none() == FAILURE) {
-               return;
-       }
-       GET_REFLECTION_OBJECT_PTR(param);
-
-       if (param->fptr->type != ZEND_USER_FUNCTION)
-       {
-               zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
"Cannot determine default value for internal functions");
-               return;
-       }
-       if (param->offset < param->required) {
-               zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
"Parameter is not optional");
-               return;
-       }
-       precv = _get_recv_op((zend_op_array*)param->fptr, param->offset);
-       if (!precv || precv->opcode != ZEND_RECV_INIT || precv->op2_type == 
IS_UNUSED) {
-               zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
"Internal error");
+       if(!(param && precv)) {
                return;
        }
 
@@ -2568,6 +2602,34 @@ ZEND_METHOD(reflection_parameter, getDefaultValue)
 }
 /* }}} */
 
+/* {{{ proto public bool ReflectionParameter::isDefaultValueConstant()
+   Returns whether the default value of this parameter is constant */
+ZEND_METHOD(reflection_parameter, isDefaultValueConstant)
+{
+       zend_op *precv = 
_reflection_param_get_default_precv(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+
+       if (precv && (Z_TYPE_P(precv->op2.zv) & IS_CONSTANT_TYPE_MASK) == 
IS_CONSTANT) {
+               RETURN_TRUE;
+       }
+
+       RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto public mixed ReflectionParameter::getDefaultValueConstantName()
+   Returns the default value's constant name if default value is constant or 
false */
+ZEND_METHOD(reflection_parameter, getDefaultValueConstantName)
+{
+       zend_op *precv = 
_reflection_param_get_default_precv(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+
+       if (precv && (Z_TYPE_P(precv->op2.zv) & IS_CONSTANT_TYPE_MASK) == 
IS_CONSTANT) {
+               RETURN_STRING(Z_STRVAL_P(precv->op2.zv), 1);
+       }
+
+       RETURN_FALSE;
+}
+/* }}} */
+
 /* {{{ proto public static mixed ReflectionMethod::export(mixed class, string 
name [, bool return]) throws ReflectionException
    Exports a reflection object. Returns the output if TRUE is specified for 
return, printing it otherwise. */
 ZEND_METHOD(reflection_method, export)
@@ -5903,6 +5965,8 @@ static const zend_function_entry 
reflection_parameter_functions[] = {
        ZEND_ME(reflection_parameter, isOptional, arginfo_reflection__void, 0)
        ZEND_ME(reflection_parameter, isDefaultValueAvailable, 
arginfo_reflection__void, 0)
        ZEND_ME(reflection_parameter, getDefaultValue, 
arginfo_reflection__void, 0)
+       ZEND_ME(reflection_parameter, isDefaultValueConstant, 
arginfo_reflection__void, 0)
+       ZEND_ME(reflection_parameter, getDefaultValueConstantName, 
arginfo_reflection__void, 0)
        PHP_FE_END
 };
 
diff --git 
a/ext/reflection/tests/ReflectionParameter_DefaultValueConstant_basic1.phpt 
b/ext/reflection/tests/ReflectionParameter_DefaultValueConstant_basic1.phpt
new file mode 100644
index 0000000..cdd00d2
--- /dev/null
+++ b/ext/reflection/tests/ReflectionParameter_DefaultValueConstant_basic1.phpt
@@ -0,0 +1,52 @@
+--TEST--
+ReflectionParameter::isDefaultValueConstant() && getDefaultValueConstantName()
+--FILE--
+<?php
+
+define("CONST_TEST_1", "const1");
+
+function ReflectionParameterTest($test1=array(), $test2 = CONST_TEST_1) {
+       echo $test;
+}
+$reflect = new ReflectionFunction('ReflectionParameterTest');
+foreach($reflect->getParameters() as $param) {
+       if($param->getName() == 'test1') {
+               var_dump($param->isDefaultValueConstant());
+       }
+       if($param->getName() == 'test2') {
+               var_dump($param->isDefaultValueConstant());
+       }
+       if($param->isDefaultValueAvailable() && 
$param->isDefaultValueConstant()) {
+               var_dump($param->getDefaultValueConstantName());
+       }
+}
+
+class Foo2 {
+       const bar = 'Foo2::bar';
+}
+
+class Foo {
+       const bar = 'Foo::bar';
+
+       public function baz($param1 = self::bar, $param2=Foo2::bar, 
$param3=CONST_TEST_1) {
+       }
+}
+
+$method = new ReflectionMethod('Foo', 'baz');
+$params = $method->getParameters();
+
+foreach ($params as $param) {
+    if ($param->isDefaultValueConstant()) {
+        var_dump($param->getDefaultValueConstantName());
+    }
+}
+?>
+==DONE==
+--EXPECT--
+bool(false)
+bool(true)
+string(12) "CONST_TEST_1"
+string(9) "self::bar"
+string(9) "Foo2::bar"
+string(12) "CONST_TEST_1"
+==DONE==
diff --git 
a/ext/reflection/tests/ReflectionParameter_DefaultValueConstant_basic2.phpt 
b/ext/reflection/tests/ReflectionParameter_DefaultValueConstant_basic2.phpt
new file mode 100644
index 0000000..1ee9e93
--- /dev/null
+++ b/ext/reflection/tests/ReflectionParameter_DefaultValueConstant_basic2.phpt
@@ -0,0 +1,30 @@
+--TEST--
+ReflectionParameter::isDefaultValueConstant() && getDefaultValueConstantName() 
for namespace
+--FILE--
+<?php
+
+namespace ReflectionTestNamespace {
+       CONST TEST_CONST_1 = "Test Const 1";
+
+       class TestClass {
+               const TEST_CONST_2 = "Test Const 2 in class";
+       }
+}
+
+namespace {
+       function 
ReflectionParameterTest($test=ReflectionTestNamespace\TestClass::TEST_CONST_2, 
$test2 = ReflectionTestNamespace\CONST_TEST_1) {
+               echo $test;
+       }
+       $reflect = new ReflectionFunction('ReflectionParameterTest');
+       foreach($reflect->getParameters() as $param) {
+               if($param->isDefaultValueAvailable() && 
$param->isDefaultValueConstant()) {
+                       echo $param->getDefaultValueConstantName() . "\n";
+               }
+       }
+       echo "==DONE==";
+}
+?>
+--EXPECT--
+ReflectionTestNamespace\TestClass::TEST_CONST_2
+ReflectionTestNamespace\CONST_TEST_1
+==DONE==
diff --git 
a/ext/reflection/tests/ReflectionParameter_DefaultValueConstant_error.phpt 
b/ext/reflection/tests/ReflectionParameter_DefaultValueConstant_error.phpt
new file mode 100644
index 0000000..984b06e
--- /dev/null
+++ b/ext/reflection/tests/ReflectionParameter_DefaultValueConstant_error.phpt
@@ -0,0 +1,25 @@
+--TEST--
+ReflectionParameter::getDefaultValueConstant() should raise exception on non 
optional parameter
+--FILE--
+<?php
+
+define("CONST_TEST_1", "const1");
+
+function ReflectionParameterTest($test, $test2 = CONST_TEST_1) {
+       echo $test;
+}
+$reflect = new ReflectionFunction('ReflectionParameterTest');
+foreach($reflect->getParameters() as $param) {
+       try {
+               echo $param->getDefaultValueConstantName() . "\n";
+       }
+       catch(ReflectionException $e) {
+               echo $e->getMessage() . "\n";
+       }
+}
+?>
+==DONE==
+--EXPECT--
+Parameter is not optional
+CONST_TEST_1
+==DONE==
-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to