Hello all! Attached is a patch (against 5_2) to allow scalar type hinting \o/
I realize that maaany will be against it so I won't be pushing it (a lot), just wanted the patch archived somewhere :) A .tar.bz2 archive can be found at http://home.oslo.nith.no/~maghan/scalar.type.hint.tar.bz2 containing the patch, phpt fixes and new phpt tests. -Hannes (maybe I should had said "if there are no objections I'll commit this by the end of next week" hoping everyone were busy and wouldn't notice this mail *evil wink*)
Index: Zend/zend_API.h =================================================================== RCS file: /repository/ZendEngine2/zend_API.h,v retrieving revision 1.207.2.8.2.5 diff -u -r1.207.2.8.2.5 zend_API.h --- Zend/zend_API.h 18 Jul 2006 09:06:32 -0000 1.207.2.8.2.5 +++ Zend/zend_API.h 3 Nov 2006 13:28:51 -0000 @@ -62,8 +62,8 @@ #define ZEND_ARG_INFO(pass_by_ref, name) { #name, sizeof(#name)-1, NULL, 0, 0, 0, pass_by_ref, 0, 0 }, #define ZEND_ARG_PASS_INFO(pass_by_ref) { NULL, 0, NULL, 0, 0, 0, pass_by_ref, 0, 0 }, -#define ZEND_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null) { #name, sizeof(#name)-1, #classname, sizeof(#classname)-1, 0, allow_null, pass_by_ref, 0, 0 }, -#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_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null) { #name, sizeof(#name)-1, #classname, sizeof(#classname)-1, IS_OBJECT, allow_null, pass_by_ref, 0, 0 }, +#define ZEND_ARG_ARRAY_INFO(pass_by_ref, name, allow_null) { #name, sizeof(#name)-1, NULL, 0, IS_ARRAY, allow_null, pass_by_ref, 0, 0 }, #define ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, return_reference, required_num_args) \ zend_arg_info name[] = { \ { NULL, 0, NULL, 0, 0, 0, pass_rest_by_reference, return_reference, required_num_args }, Index: Zend/zend_compile.c =================================================================== RCS file: /repository/ZendEngine2/zend_compile.c,v retrieving revision 1.647.2.27.2.20 diff -u -r1.647.2.27.2.20 zend_compile.c --- Zend/zend_compile.c 20 Oct 2006 02:44:02 -0000 1.647.2.27.2.20 +++ Zend/zend_compile.c 3 Nov 2006 13:28:51 -0000 @@ -1278,13 +1278,18 @@ cur_arg_info = &CG(active_op_array)->arg_info[CG(active_op_array)->num_args-1]; cur_arg_info->name = estrndup(varname->u.constant.value.str.val, varname->u.constant.value.str.len); cur_arg_info->name_len = varname->u.constant.value.str.len; - cur_arg_info->array_type_hint = 0; + cur_arg_info->class_name = NULL; + cur_arg_info->class_name_len = 0; + cur_arg_info->type_hint = 0; cur_arg_info->allow_null = 1; cur_arg_info->pass_by_reference = pass_by_reference; if (class_type->op_type != IS_UNUSED) { cur_arg_info->allow_null = 0; - if (class_type->u.constant.type == IS_STRING) { + cur_arg_info->type_hint = class_type->u.constant.type; + + switch (class_type->u.constant.type) { + case IS_OBJECT: 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) { @@ -1294,10 +1299,9 @@ 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; + break; + + case IS_ARRAY: 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; @@ -1305,11 +1309,23 @@ zend_error(E_COMPILE_ERROR, "Default value for parameters with array type hint can only be an array or NULL"); } } + break; + + /* scalar type hinting */ + case IS_BOOL: + case IS_STRING: + case IS_LONG: + case IS_DOUBLE: + if (op == ZEND_RECV_INIT && Z_TYPE(initialization->u.constant) != class_type->u.constant.type) { + zend_error(E_COMPILE_ERROR, "Default value for parameters with %s type hint can only be %s", zend_get_type_by_const(class_type->u.constant.type), zend_get_type_by_const(class_type->u.constant.type)); + } + break; + + default: + zend_error(E_COMPILE_ERROR, "Unkown type hint"); } - } else { - cur_arg_info->class_name = NULL; - cur_arg_info->class_name_len = 0; } + opline->result.u.EA.type |= EXT_TYPE_UNUSED; } @@ -1950,8 +1966,8 @@ && strcmp(fe->common.arg_info[i].class_name, proto->common.arg_info[i].class_name)!=0) { return 0; } - if (fe->common.arg_info[i].array_type_hint != proto->common.arg_info[i].array_type_hint) { - /* Only one has an array type hint and the other one doesn't */ + if (fe->common.arg_info[i].type_hint != proto->common.arg_info[i].type_hint) { + /* Incompatible type hint */ return 0; } if (fe->common.arg_info[i].pass_by_reference != proto->common.arg_info[i].pass_by_reference) { Index: Zend/zend_compile.h =================================================================== RCS file: /repository/ZendEngine2/zend_compile.h,v retrieving revision 1.316.2.8.2.7 diff -u -r1.316.2.8.2.7 zend_compile.h --- Zend/zend_compile.h 26 Sep 2006 10:30:50 -0000 1.316.2.8.2.7 +++ Zend/zend_compile.h 3 Nov 2006 13:28:51 -0000 @@ -159,7 +159,7 @@ zend_uint name_len; char *class_name; zend_uint class_name_len; - zend_bool array_type_hint; + zend_uint type_hint; zend_bool allow_null; zend_bool pass_by_reference; zend_bool return_reference; Index: Zend/zend_execute.c =================================================================== RCS file: /repository/ZendEngine2/zend_execute.c,v retrieving revision 1.716.2.12.2.12 diff -u -r1.716.2.12.2.12 zend_execute.c --- Zend/zend_execute.c 2 Oct 2006 11:09:52 -0000 1.716.2.12.2.12 +++ Zend/zend_execute.c 3 Nov 2006 13:28:52 -0000 @@ -513,12 +513,12 @@ need_msg = zend_verify_arg_class_kind(cur_arg_info, &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->array_type_hint) { + } else if (cur_arg_info->type_hint) { if (!arg) { - return zend_verify_arg_error(zf, arg_num, cur_arg_info, "be an array", "", "none", "" TSRMLS_CC); + return zend_verify_arg_error(zf, arg_num, cur_arg_info, "be ", zend_get_type_by_const(cur_arg_info->type_hint), "none", "" TSRMLS_CC); } - if (Z_TYPE_P(arg) != IS_ARRAY && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) { - return zend_verify_arg_error(zf, arg_num, cur_arg_info, "be an array", "", zend_zval_type_name(arg), "" 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 ", zend_get_type_by_const(cur_arg_info->type_hint), "", zend_zval_type_name(arg) TSRMLS_CC); } } return 1; Index: Zend/zend_language_parser.y =================================================================== RCS file: /repository/ZendEngine2/zend_language_parser.y,v retrieving revision 1.160.2.4.2.1 diff -u -r1.160.2.4.2.1 zend_language_parser.y --- Zend/zend_language_parser.y 11 May 2006 21:07:39 -0000 1.160.2.4.2.1 +++ Zend/zend_language_parser.y 3 Nov 2006 13:28:52 -0000 @@ -129,6 +129,10 @@ %token T_DOUBLE_ARROW %token T_LIST %token T_ARRAY +%token T_BOOL_HINT +%token T_STRING_HINT +%token T_INT_HINT +%token T_DOUBLE_HINT %token T_CLASS_C %token T_METHOD_C %token T_FUNC_C @@ -438,8 +442,12 @@ optional_class_type: /* empty */ { $$.op_type = IS_UNUSED; } - | T_STRING { $$ = $1; } - | T_ARRAY { $$.op_type = IS_CONST; Z_TYPE($$.u.constant)=IS_NULL;} + | T_ARRAY { $$.op_type = IS_CONST; Z_TYPE($$.u.constant)=IS_ARRAY;} + | T_BOOL_HINT { $$.op_type = IS_CONST; Z_TYPE($$.u.constant)=IS_BOOL;} + | T_STRING_HINT { $$.op_type = IS_CONST; Z_TYPE($$.u.constant)=IS_STRING;} + | T_INT_HINT { $$.op_type = IS_CONST; Z_TYPE($$.u.constant)=IS_LONG;} + | T_DOUBLE_HINT { $$.op_type = IS_CONST; Z_TYPE($$.u.constant)=IS_DOUBLE;} + | T_STRING { $$.op_type = IS_CONST; Z_TYPE($$.u.constant)=IS_OBJECT;} ; Index: Zend/zend_language_scanner.l =================================================================== RCS file: /repository/ZendEngine2/zend_language_scanner.l,v retrieving revision 1.131.2.11 diff -u -r1.131.2.11 zend_language_scanner.l --- Zend/zend_language_scanner.l 13 Apr 2006 13:48:28 -0000 1.131.2.11 +++ Zend/zend_language_scanner.l 3 Nov 2006 13:28:52 -0000 @@ -1079,6 +1079,22 @@ return T_ARRAY; } +<ST_IN_SCRIPTING>("bool"|"boolean") { + return T_BOOL_HINT; +} + +<ST_IN_SCRIPTING>"string" { + return T_STRING_HINT; +} + +<ST_IN_SCRIPTING>("int"|"integer") { + return T_INT_HINT; +} + +<ST_IN_SCRIPTING>("real"|"double"|"float") { + return T_DOUBLE_HINT; +} + <ST_IN_SCRIPTING>"++" { return T_INC; } Index: ext/reflection/php_reflection.c =================================================================== RCS file: /repository/php-src/ext/reflection/php_reflection.c,v retrieving revision 1.164.2.33.2.31 diff -u -r1.164.2.33.2.31 php_reflection.c --- ext/reflection/php_reflection.c 18 Oct 2006 16:35:15 -0000 1.164.2.33.2.31 +++ ext/reflection/php_reflection.c 3 Nov 2006 13:28:52 -0000 @@ -610,7 +610,7 @@ if (arg_info->allow_null) { string_printf(str, "or NULL "); } - } else if (arg_info->array_type_hint) { + } else if (arg_info->type_hint == IS_ARRAY) { string_printf(str, "array "); if (arg_info->allow_null) { string_printf(str, "or NULL "); @@ -2015,7 +2015,7 @@ METHOD_NOTSTATIC_NUMPARAMS(reflection_parameter_ptr, 0); GET_REFLECTION_OBJECT_PTR(param); - RETVAL_BOOL(param->arg_info->array_type_hint); + RETVAL_BOOL(param->arg_info->type_hint == IS_ARRAY); } /* }}} */
-- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php