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