summaryrefslogtreecommitdiff
path: root/ext/reflection/php_reflection.c
diff options
context:
space:
mode:
authorMark A. Hershberger <mah@debian.(none)>2009-03-25 00:37:27 -0400
committerMark A. Hershberger <mah@debian.(none)>2009-03-25 00:37:27 -0400
commit2d4e5b09576bb4f0ba716cc82cdf29ea04d9184b (patch)
tree41ccc042009cba53e4ce43e727fcba4c1cfbf7f3 /ext/reflection/php_reflection.c
parentd29a4fd2dd3b5d4cf6e80b602544d7b71d794e76 (diff)
downloadphp-2d4e5b09576bb4f0ba716cc82cdf29ea04d9184b.tar.gz
Imported Upstream version 5.2.2upstream/5.2.2
Diffstat (limited to 'ext/reflection/php_reflection.c')
-rw-r--r--ext/reflection/php_reflection.c144
1 files changed, 93 insertions, 51 deletions
diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c
index 0685541ad..ac0c325c7 100644
--- a/ext/reflection/php_reflection.c
+++ b/ext/reflection/php_reflection.c
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2006 The PHP Group |
+ | Copyright (c) 1997-2007 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -20,7 +20,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: php_reflection.c,v 1.164.2.33.2.31 2006/10/18 16:35:15 johannes Exp $ */
+/* $Id: php_reflection.c,v 1.164.2.33.2.37 2007/04/12 18:39:46 johannes Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -179,7 +179,7 @@ static void string_free(string *str)
/* Struct for properties */
typedef struct _property_reference {
zend_class_entry *ce;
- zend_property_info *prop;
+ zend_property_info prop;
} property_reference;
/* Struct for parameters */
@@ -271,7 +271,7 @@ static zend_object_value reflection_objects_new(zend_class_entry *class_type TSR
return retval;
}
-static zval * reflection_instanciate(zend_class_entry *pce, zval *object TSRMLS_DC)
+static zval * reflection_instantiate(zend_class_entry *pce, zval *object TSRMLS_DC)
{
if (!object) {
ALLOC_ZVAL(object);
@@ -747,23 +747,27 @@ static void _function_string(string *str, zend_function *fptr, zend_class_entry
string_printf(str, "static ");
}
- /* These are mutually exclusive */
- switch (fptr->common.fn_flags & ZEND_ACC_PPP_MASK) {
- case ZEND_ACC_PUBLIC:
- string_printf(str, "public ");
- break;
- case ZEND_ACC_PRIVATE:
- string_printf(str, "private ");
- break;
- case ZEND_ACC_PROTECTED:
- string_printf(str, "protected ");
- break;
- default:
- string_printf(str, "<visibility error> ");
- break;
+ if (fptr->common.scope) {
+ /* These are mutually exclusive */
+ switch (fptr->common.fn_flags & ZEND_ACC_PPP_MASK) {
+ case ZEND_ACC_PUBLIC:
+ string_printf(str, "public ");
+ break;
+ case ZEND_ACC_PRIVATE:
+ string_printf(str, "private ");
+ break;
+ case ZEND_ACC_PROTECTED:
+ string_printf(str, "protected ");
+ break;
+ default:
+ string_printf(str, "<visibility error> ");
+ break;
+ }
+ string_printf(str, "method ");
+ } else {
+ string_printf(str, "function ");
}
- string_printf(str, fptr->common.scope ? "method " : "function ");
if (fptr->op_array.return_reference) {
string_printf(str, "&");
}
@@ -1026,7 +1030,7 @@ PHPAPI void zend_reflection_class_factory(zend_class_entry *ce, zval *object TSR
MAKE_STD_ZVAL(name);
ZVAL_STRINGL(name, ce->name, ce->name_length, 1);
- reflection_instanciate(reflection_class_ptr, object TSRMLS_CC);
+ reflection_instantiate(reflection_class_ptr, object TSRMLS_CC);
intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
intern->ptr = ce;
intern->free_ptr = 0;
@@ -1052,7 +1056,7 @@ static void reflection_extension_factory(zval *object, char *name_str TSRMLS_DC)
}
free_alloca(lcname);
- reflection_instanciate(reflection_extension_ptr, object TSRMLS_CC);
+ reflection_instantiate(reflection_extension_ptr, object TSRMLS_CC);
intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
MAKE_STD_ZVAL(name);
ZVAL_STRINGL(name, module->name, name_len, 1);
@@ -1076,7 +1080,7 @@ static void reflection_parameter_factory(zend_function *fptr, struct _zend_arg_i
} else {
ZVAL_NULL(name);
}
- reflection_instanciate(reflection_parameter_ptr, object TSRMLS_CC);
+ reflection_instantiate(reflection_parameter_ptr, object TSRMLS_CC);
intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
reference = (parameter_reference*) emalloc(sizeof(parameter_reference));
reference->arg_info = arg_info;
@@ -1099,7 +1103,7 @@ static void reflection_function_factory(zend_function *function, zval *object TS
MAKE_STD_ZVAL(name);
ZVAL_STRING(name, function->common.function_name, 1);
- reflection_instanciate(reflection_function_ptr, object TSRMLS_CC);
+ reflection_instantiate(reflection_function_ptr, object TSRMLS_CC);
intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
intern->ptr = function;
intern->free_ptr = 0;
@@ -1119,7 +1123,7 @@ static void reflection_method_factory(zend_class_entry *ce, zend_function *metho
MAKE_STD_ZVAL(classname);
ZVAL_STRING(name, method->common.function_name, 1);
ZVAL_STRINGL(classname, ce->name, ce->name_length, 1);
- reflection_instanciate(reflection_method_ptr, object TSRMLS_CC);
+ reflection_instantiate(reflection_method_ptr, object TSRMLS_CC);
intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
intern->ptr = method;
intern->free_ptr = 0;
@@ -1142,14 +1146,19 @@ static void reflection_property_factory(zend_class_entry *ce, zend_property_info
if (!(prop->flags & ZEND_ACC_PRIVATE)) {
/* we have to search the class hierarchy for this (implicit) public or protected property */
- zend_class_entry *tmp_ce = ce;
- zend_property_info *tmp_info;
-
+ zend_class_entry *tmp_ce = ce, *store_ce = ce;
+ zend_property_info *tmp_info = NULL;
+
while (tmp_ce && zend_hash_find(&tmp_ce->properties_info, prop_name, strlen(prop_name) + 1, (void **) &tmp_info) != SUCCESS) {
ce = tmp_ce;
- prop = tmp_info;
tmp_ce = tmp_ce->parent;
}
+
+ if (tmp_info && !(tmp_info->flags & ZEND_ACC_SHADOW)) { /* found something and it's not a parent's private */
+ prop = tmp_info;
+ } else { /* not found, use initial value */
+ ce = store_ce;
+ }
}
MAKE_STD_ZVAL(name);
@@ -1157,11 +1166,11 @@ static void reflection_property_factory(zend_class_entry *ce, zend_property_info
ZVAL_STRING(name, prop_name, 1);
ZVAL_STRINGL(classname, ce->name, ce->name_length, 1);
- reflection_instanciate(reflection_property_ptr, object TSRMLS_CC);
+ reflection_instantiate(reflection_property_ptr, object TSRMLS_CC);
intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
reference = (property_reference*) emalloc(sizeof(property_reference));
reference->ce = ce;
- reference->prop = prop;
+ reference->prop = *prop;
intern->ptr = reference;
intern->free_ptr = 1;
intern->ce = ce;
@@ -1995,7 +2004,40 @@ ZEND_METHOD(reflection_parameter, getClass)
GET_REFLECTION_OBJECT_PTR(param);
if (param->arg_info->class_name) {
- if (zend_lookup_class(param->arg_info->class_name, param->arg_info->class_name_len, &pce TSRMLS_CC) == FAILURE) {
+ /* Class name is stored as a string, we might also get "self" or "parent"
+ * - For "self", simply use the function scope. If scope is NULL then
+ * the function is global and thus self does not make any sense
+ *
+ * - For "parent", use the function scope's parent. If scope is NULL then
+ * the function is global and thus parent does not make any sense.
+ * If the parent is NULL then the class does not extend anything and
+ * thus parent does not make any sense, either.
+ *
+ * TODO: Think about moving these checks to the compiler or some sort of
+ * lint-mode.
+ */
+ if (0 == strncmp(param->arg_info->class_name, "self", sizeof("self")- 1)) {
+ zend_class_entry *ce= param->fptr->common.scope;
+ if (!ce) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Parameter uses 'self' as type hint but function is not a class member!");
+ return;
+ }
+ pce= &ce;
+ } else if (0 == strncmp(param->arg_info->class_name, "parent", sizeof("parent")- 1)) {
+ zend_class_entry *ce= param->fptr->common.scope;
+ if (!ce) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Parameter uses 'parent' as type hint but function is not a class member!");
+ return;
+ }
+ if (!ce->parent) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Parameter uses 'parent' as type hint although class does not have a parent!");
+ return;
+ }
+ pce= &ce->parent;
+ } else if (zend_lookup_class(param->arg_info->class_name, param->arg_info->class_name_len, &pce TSRMLS_CC) == FAILURE) {
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
"Class %s does not exist", param->arg_info->class_name);
return;
@@ -3165,7 +3207,7 @@ static int _adddynproperty(zval **pptr, int num_args, va_list args, zend_hash_ke
ZVAL_STRINGL(&member, hash_key->arKey, hash_key->nKeyLength-1, 0);
if (zend_get_property_info(ce, &member, 1 TSRMLS_CC) == &EG(std_property_info)) {
- ALLOC_ZVAL(property);
+ MAKE_STD_ZVAL(property);
reflection_property_factory(ce, &EG(std_property_info), property TSRMLS_CC);
add_next_index_zval(retval, property);
}
@@ -3804,7 +3846,7 @@ ZEND_METHOD(reflection_property, __construct)
reference = (property_reference*) emalloc(sizeof(property_reference));
reference->ce = ce;
- reference->prop = property_info;
+ reference->prop = *property_info;
intern->ptr = reference;
intern->free_ptr = 1;
intern->ce = ce;
@@ -3822,7 +3864,7 @@ ZEND_METHOD(reflection_property, __toString)
METHOD_NOTSTATIC_NUMPARAMS(reflection_property_ptr, 0);
GET_REFLECTION_OBJECT_PTR(ref);
string_init(&str);
- _property_string(&str, ref->prop, NULL, "" TSRMLS_CC);
+ _property_string(&str, &ref->prop, NULL, "" TSRMLS_CC);
RETURN_STRINGL(str.string, str.len - 1, 0);
}
/* }}} */
@@ -3843,7 +3885,7 @@ static void _property_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask)
METHOD_NOTSTATIC_NUMPARAMS(reflection_property_ptr, 0);
GET_REFLECTION_OBJECT_PTR(ref);
- RETURN_BOOL(ref->prop->flags & mask);
+ RETURN_BOOL(ref->prop.flags & mask);
}
/* {{{ proto public bool ReflectionProperty::isPublic()
@@ -3896,7 +3938,7 @@ ZEND_METHOD(reflection_property, getModifiers)
METHOD_NOTSTATIC_NUMPARAMS(reflection_property_ptr, 0);
GET_REFLECTION_OBJECT_PTR(ref);
- RETURN_LONG(ref->prop->flags);
+ RETURN_LONG(ref->prop.flags);
}
/* }}} */
@@ -3912,7 +3954,7 @@ ZEND_METHOD(reflection_property, getValue)
METHOD_NOTSTATIC(reflection_property_ptr);
GET_REFLECTION_OBJECT_PTR(ref);
- if (!(ref->prop->flags & ZEND_ACC_PUBLIC)) {
+ if (!(ref->prop.flags & ZEND_ACC_PUBLIC)) {
_default_get_entry(getThis(), "name", sizeof("name"), &name TSRMLS_CC);
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
"Cannot access non-public member %s::%s", intern->ce->name, Z_STRVAL(name));
@@ -3920,10 +3962,10 @@ ZEND_METHOD(reflection_property, getValue)
return;
}
- if ((ref->prop->flags & ZEND_ACC_STATIC)) {
+ if ((ref->prop.flags & ZEND_ACC_STATIC)) {
zend_update_class_constants(intern->ce TSRMLS_CC);
- if (zend_hash_quick_find(CE_STATIC_MEMBERS(intern->ce), ref->prop->name, ref->prop->name_length + 1, ref->prop->h, (void **) &member) == FAILURE) {
- zend_error(E_ERROR, "Internal error: Could not find the property %s::%s", intern->ce->name, ref->prop->name);
+ if (zend_hash_quick_find(CE_STATIC_MEMBERS(intern->ce), ref->prop.name, ref->prop.name_length + 1, ref->prop.h, (void **) &member) == FAILURE) {
+ zend_error(E_ERROR, "Internal error: Could not find the property %s::%s", intern->ce->name, ref->prop.name);
/* Bails out */
}
*return_value= **member;
@@ -3933,7 +3975,7 @@ ZEND_METHOD(reflection_property, getValue)
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &object) == FAILURE) {
return;
}
- member_p = zend_read_property(Z_OBJCE_P(object), object, ref->prop->name, ref->prop->name_length, 1 TSRMLS_CC);
+ member_p = zend_read_property(Z_OBJCE_P(object), object, ref->prop.name, ref->prop.name_length, 1 TSRMLS_CC);
*return_value= *member_p;
zval_copy_ctor(return_value);
INIT_PZVAL(return_value);
@@ -3961,7 +4003,7 @@ ZEND_METHOD(reflection_property, setValue)
METHOD_NOTSTATIC(reflection_property_ptr);
GET_REFLECTION_OBJECT_PTR(ref);
- if (!(ref->prop->flags & ZEND_ACC_PUBLIC)) {
+ if (!(ref->prop.flags & ZEND_ACC_PUBLIC)) {
_default_get_entry(getThis(), "name", sizeof("name"), &name TSRMLS_CC);
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
"Cannot access non-public member %s::%s", intern->ce->name, Z_STRVAL(name));
@@ -3969,7 +4011,7 @@ ZEND_METHOD(reflection_property, setValue)
return;
}
- if ((ref->prop->flags & ZEND_ACC_STATIC)) {
+ if ((ref->prop.flags & ZEND_ACC_STATIC)) {
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "z", &value) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &tmp, &value) == FAILURE) {
return;
@@ -3978,8 +4020,8 @@ ZEND_METHOD(reflection_property, setValue)
zend_update_class_constants(intern->ce TSRMLS_CC);
prop_table = CE_STATIC_MEMBERS(intern->ce);
- if (zend_hash_quick_find(prop_table, ref->prop->name, ref->prop->name_length + 1, ref->prop->h, (void **) &variable_ptr) == FAILURE) {
- zend_error(E_ERROR, "Internal error: Could not find the property %s::%s", intern->ce->name, ref->prop->name);
+ if (zend_hash_quick_find(prop_table, ref->prop.name, ref->prop.name_length + 1, ref->prop.h, (void **) &variable_ptr) == FAILURE) {
+ zend_error(E_ERROR, "Internal error: Could not find the property %s::%s", intern->ce->name, ref->prop.name);
/* Bails out */
}
if (*variable_ptr == value) {
@@ -4002,13 +4044,13 @@ ZEND_METHOD(reflection_property, setValue)
if (PZVAL_IS_REF(value)) {
SEPARATE_ZVAL(&value);
}
- zend_hash_quick_update(prop_table, ref->prop->name, ref->prop->name_length+1, ref->prop->h, &value, sizeof(zval *), (void **) &foo);
+ zend_hash_quick_update(prop_table, ref->prop.name, ref->prop.name_length+1, ref->prop.h, &value, sizeof(zval *), (void **) &foo);
}
} else {
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "oz", &object, &value) == FAILURE) {
return;
}
- zend_update_property(Z_OBJCE_P(object), object, ref->prop->name, ref->prop->name_length, value TSRMLS_CC);
+ zend_update_property(Z_OBJCE_P(object), object, ref->prop.name, ref->prop.name_length, value TSRMLS_CC);
}
}
/* }}} */
@@ -4027,7 +4069,7 @@ ZEND_METHOD(reflection_property, getDeclaringClass)
METHOD_NOTSTATIC_NUMPARAMS(reflection_property_ptr, 0);
GET_REFLECTION_OBJECT_PTR(ref);
- if (zend_unmangle_property_name(ref->prop->name, ref->prop->name_length, &class_name, &prop_name) != SUCCESS) {
+ if (zend_unmangle_property_name(ref->prop.name, ref->prop.name_length, &class_name, &prop_name) != SUCCESS) {
RETURN_FALSE;
}
@@ -4055,8 +4097,8 @@ ZEND_METHOD(reflection_property, getDocComment)
METHOD_NOTSTATIC_NUMPARAMS(reflection_property_ptr, 0);
GET_REFLECTION_OBJECT_PTR(ref);
- if (ref->prop->doc_comment) {
- RETURN_STRINGL(ref->prop->doc_comment, ref->prop->doc_comment_len, 1);
+ if (ref->prop.doc_comment) {
+ RETURN_STRINGL(ref->prop.doc_comment, ref->prop.doc_comment_len, 1);
}
RETURN_FALSE;
}
@@ -4851,7 +4893,7 @@ PHP_MINFO_FUNCTION(reflection) /* {{{ */
php_info_print_table_start();
php_info_print_table_header(2, "Reflection", "enabled");
- php_info_print_table_row(2, "Version", "$Id: php_reflection.c,v 1.164.2.33.2.31 2006/10/18 16:35:15 johannes Exp $");
+ php_info_print_table_row(2, "Version", "$Id: php_reflection.c,v 1.164.2.33.2.37 2007/04/12 18:39:46 johannes Exp $");
php_info_print_table_end();
} /* }}} */