Just so anyone who wants it has it, I have attached the last version of my patch.
Note that it still issues a fatal error but this can be changed very easily, would take me about 2 minutes. Full specs: Type hinting patch allows for 8 new type hints, in addition to array and class type hinting. - Integers (specified by "int", "integer", or "long") - Floats (specified by "float", "double", or "real") - Numbers (matches integers and floats, specified by "num" or "number") - Strings (specified by "string") - Booleans (specified by "bool" or "boolean") - Scalars (matches strings, booleans, and numbers; specified by "scalar") - Resources (specified by "resource") - Objects (matches any object, specified by "object") The patch specifies a constant, PATCH_SCALAR_TYPE_HINTING, just there to indicate that the patch is installed. On Thu, 2008-01-03 at 20:23 +0100, Derick Rethans wrote: > On Thu, 3 Jan 2008, Stanislav Malyshev wrote: > > > > When the type hint says I want an integer, then only integer should be > > > accepted; no casting should be done. It may give predictable results > > > > Why people that want Java just don't use Java I wonder? PHP never was a > > strict > > static typed language. > > Broken record perhaps? I am getting a bit tired of this "just use Java > argument", it's perhaps even a bit arrogant. From what I read there is > plenty of people that want type hints for static types - there's a few > patches out there, it doesn't slow down the general case. So why should > we *not* add it? (And yes, I changed my mind) > > regards, > Derick > > -- > Derick Rethans > http://derickrethans.nl | http://ezcomponents.org | http://xdebug.org >
Index: Zend/zend_API.h =================================================================== RCS file: /repository/ZendEngine2/zend_API.h,v retrieving revision 1.207.2.8.2.8.2.5 diff -u -r1.207.2.8.2.8.2.5 zend_API.h --- Zend/zend_API.h 2 Nov 2007 19:40:37 -0000 1.207.2.8.2.8.2.5 +++ Zend/zend_API.h 21 Dec 2007 20:56:40 -0000 @@ -69,7 +69,7 @@ #define ZEND_ARG_ARRAY_INFO(pass_by_ref, name, allow_null) { #name, sizeof(#name)-1, NULL, 0, 1, allow_null, pass_by_ref, 0, 0 }, #define ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, return_reference, required_num_args) \ const zend_arg_info name[] = { \ - { NULL, 0, NULL, 0, 0, 0, pass_rest_by_reference, return_reference, required_num_args }, + { NULL, 0, NULL, 0, 0, 0, pass_rest_by_reference, return_reference, required_num_args, 0, 0, 0 }, #define ZEND_BEGIN_ARG_INFO(name, pass_rest_by_reference) \ ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, ZEND_RETURN_VALUE, -1) #define ZEND_END_ARG_INFO() }; Index: Zend/zend_compile.c =================================================================== RCS file: /repository/ZendEngine2/zend_compile.c,v retrieving revision 1.647.2.27.2.41.2.31 diff -u -r1.647.2.27.2.41.2.31 zend_compile.c --- Zend/zend_compile.c 13 Dec 2007 10:02:03 -0000 1.647.2.27.2.41.2.31 +++ Zend/zend_compile.c 21 Dec 2007 20:56:41 -0000 @@ -1341,26 +1341,54 @@ cur_arg_info->pass_by_reference = pass_by_reference; cur_arg_info->class_name = NULL; cur_arg_info->class_name_len = 0; + cur_arg_info->scalar_type_hint = 0; + cur_arg_info->number_type_hint = 0; + cur_arg_info->type_hint = 0; if (class_type->op_type != IS_UNUSED) { - cur_arg_info->allow_null = 0; if (class_type->u.constant.type == IS_STRING) { - if (ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type(Z_STRVAL(class_type->u.constant), Z_STRLEN(class_type->u.constant))) { - zend_resolve_class_name(class_type, &opline->extended_value, 1 TSRMLS_CC); - } - cur_arg_info->class_name = class_type->u.constant.value.str.val; - cur_arg_info->class_name_len = class_type->u.constant.value.str.len; - if (op == ZEND_RECV_INIT) { - if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL"))) { - cur_arg_info->allow_null = 1; - } else { - zend_error(E_COMPILE_ERROR, "Default value for parameters with a class type hint can only be NULL"); + if (strcasecmp("scalar", class_type->u.constant.value.str.val) == 0) { + cur_arg_info->scalar_type_hint = 1; + } else if (strcasecmp("num", class_type->u.constant.value.str.val) == 0) { + cur_arg_info->number_type_hint = 1; + } else if (strcasecmp("number", class_type->u.constant.value.str.val) == 0) { + cur_arg_info->number_type_hint = 1; + } else if (strcasecmp("int", class_type->u.constant.value.str.val) == 0) { + cur_arg_info->type_hint = IS_LONG; + } else if (strcasecmp("integer", class_type->u.constant.value.str.val) == 0) { + cur_arg_info->type_hint = IS_LONG; + } else if (strcasecmp("long", class_type->u.constant.value.str.val) == 0) { + cur_arg_info->type_hint = IS_LONG; + } else if (strcasecmp("float", class_type->u.constant.value.str.val) == 0) { + cur_arg_info->type_hint = IS_DOUBLE; + } else if (strcasecmp("double", class_type->u.constant.value.str.val) == 0) { + cur_arg_info->type_hint = IS_DOUBLE; + } else if (strcasecmp("real", class_type->u.constant.value.str.val) == 0) { + cur_arg_info->type_hint = IS_DOUBLE; + } else if (strcasecmp("string", class_type->u.constant.value.str.val) == 0) { + cur_arg_info->type_hint = IS_STRING; + } else if (strcasecmp("bool", class_type->u.constant.value.str.val) == 0) { + cur_arg_info->type_hint = IS_BOOL; + } else if (strcasecmp("boolean", class_type->u.constant.value.str.val) == 0) { + cur_arg_info->type_hint = IS_BOOL; + } else if (strcasecmp("object", class_type->u.constant.value.str.val) == 0) { + cur_arg_info->type_hint = IS_OBJECT; + } else if (strcasecmp("resource", class_type->u.constant.value.str.val) == 0) { + cur_arg_info->type_hint = IS_RESOURCE; + } else { + zend_resolve_class_name(class_type, &opline->extended_value, 1 TSRMLS_CC); + cur_arg_info->class_name = class_type->u.constant.value.str.val; + cur_arg_info->class_name_len = class_type->u.constant.value.str.len; + if (op == ZEND_RECV_INIT) { + if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL"))) { + cur_arg_info->allow_null = 1; + } else { + zend_error(E_COMPILE_ERROR, "Default value for parameters with a class type hint can only be NULL"); + } } } } else { cur_arg_info->array_type_hint = 1; - cur_arg_info->class_name = NULL; - cur_arg_info->class_name_len = 0; if (op == ZEND_RECV_INIT) { if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL"))) { cur_arg_info->allow_null = 1; @@ -2278,6 +2306,16 @@ /* Only one has an array type hint and the other one doesn't */ return 0; } + if (fe->common.arg_info[i].scalar_type_hint != proto->common.arg_info[i].scalar_type_hint) { + return 0; + } + if (fe->common.arg_info[i].number_type_hint != proto->common.arg_info[i].number_type_hint) { + return 0; + } + if (fe->common.arg_info[i].type_hint != proto->common.arg_info[i].type_hint) { + return 0; + } + if (fe->common.arg_info[i].pass_by_reference != proto->common.arg_info[i].pass_by_reference) { return 0; } Index: Zend/zend_compile.h =================================================================== RCS file: /repository/ZendEngine2/zend_compile.h,v retrieving revision 1.316.2.8.2.12.2.11 diff -u -r1.316.2.8.2.12.2.11 zend_compile.h --- Zend/zend_compile.h 13 Dec 2007 10:02:03 -0000 1.316.2.8.2.12.2.11 +++ Zend/zend_compile.h 21 Dec 2007 20:56:41 -0000 @@ -167,6 +167,9 @@ zend_bool pass_by_reference; zend_bool return_reference; int required_num_args; + zend_bool scalar_type_hint; + zend_bool number_type_hint; + zend_uint type_hint; } zend_arg_info; typedef struct _zend_compiled_variable { Index: Zend/zend_constants.c =================================================================== RCS file: /repository/ZendEngine2/zend_constants.c,v retrieving revision 1.71.2.5.2.7.2.6 diff -u -r1.71.2.5.2.7.2.6 zend_constants.c --- Zend/zend_constants.c 20 Nov 2007 16:34:25 -0000 1.71.2.5.2.7.2.6 +++ Zend/zend_constants.c 21 Dec 2007 20:56:41 -0000 @@ -148,6 +148,14 @@ c.value.value.lval = ZEND_DEBUG; c.value.type = IS_BOOL; zend_register_constant(&c TSRMLS_CC); + + c.flags = CONST_PERSISTENT | CONST_CS; + + c.name = zend_strndup(ZEND_STRL("PATCH_SCALAR_TYPE_HINTING")); + c.name_len = sizeof("PATCH_SCALAR_TYPE_HINTING"); + c.value.value.lval = ZTS_V; + c.value.type = IS_BOOL; + zend_register_constant(&c TSRMLS_CC); } } Index: Zend/zend_execute.c =================================================================== RCS file: /repository/ZendEngine2/zend_execute.c,v retrieving revision 1.716.2.12.2.24.2.9 diff -u -r1.716.2.12.2.24.2.9 zend_execute.c --- Zend/zend_execute.c 14 Dec 2007 14:14:50 -0000 1.716.2.12.2.24.2.9 +++ Zend/zend_execute.c 21 Dec 2007 20:56:41 -0000 @@ -517,6 +517,27 @@ need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC); return zend_verify_arg_error(zf, arg_num, cur_arg_info, need_msg, class_name, zend_zval_type_name(arg), "" TSRMLS_CC); } + } else if (cur_arg_info->type_hint != 0) { + if (!arg) { + return zend_verify_arg_error(zf, arg_num, cur_arg_info, "be of type ", zend_get_type_by_const(cur_arg_info->type_hint), "none", "" TSRMLS_CC); + } + if (Z_TYPE_P(arg) != cur_arg_info->type_hint && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) { + return zend_verify_arg_error(zf, arg_num, cur_arg_info, "be of type ", zend_get_type_by_const(cur_arg_info->type_hint), zend_zval_type_name(arg), "" TSRMLS_CC); + } + } else if (cur_arg_info->scalar_type_hint) { + if (!arg) { + return zend_verify_arg_error(zf, arg_num, cur_arg_info, "be a scalar", "", "none", "" TSRMLS_CC); + } + if (Z_TYPE_P(arg) != IS_LONG && Z_TYPE_P(arg) != IS_DOUBLE && Z_TYPE_P(arg) != IS_BOOL && Z_TYPE_P(arg) != IS_STRING && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) { + return zend_verify_arg_error(zf, arg_num, cur_arg_info, "be a scalar", "", zend_zval_type_name(arg), "" TSRMLS_CC); + } + } else if (cur_arg_info->number_type_hint) { + if (!arg) { + return zend_verify_arg_error(zf, arg_num, cur_arg_info, "be a number", "", "none", "" TSRMLS_CC); + } + if (Z_TYPE_P(arg) != IS_LONG && Z_TYPE_P(arg) != IS_DOUBLE && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) { + return zend_verify_arg_error(zf, arg_num, cur_arg_info, "be a number", "", zend_zval_type_name(arg), "" TSRMLS_CC); + } } else if (cur_arg_info->array_type_hint) { if (!arg) { return zend_verify_arg_error(zf, arg_num, cur_arg_info, "be an array", "", "none", "" TSRMLS_CC);
-- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php