On Fri, 2008-01-04 at 18:09 +0100, Pierre wrote:
> On Jan 4, 2008 6:01 PM, Sam Barrow <[EMAIL PROTECTED]> wrote:
> >
> > On Fri, 2008-01-04 at 17:53 +0100, Pierre wrote:
> > > On Jan 4, 2008 5:53 PM, Pierre <[EMAIL PROTECTED]> wrote:
> > > > On Jan 4, 2008 4:52 PM, Gregory Beaver <[EMAIL PROTECTED]> wrote:
> > > >
> > > > > But I *don't* want my functions to take an argument of arbitrary type 
> > > > > -
> > > > > it is in fact you who are missing the point.  A type hint is a poor
> > > > > solution to a real problem that is much more easily solved via simple
> > > > > input validation and graceful error handling.  The current situation 
> > > > > in
> > > > > PHP provides a much more flexible solution to the same problem.
> > > >
> > > > Unlike our OO strictness (E_FATAL!!), nothing will prevent you to use
> > >
> > > Read: othing will prevent you to >do not< use it :)
> > >
> >
> > So you're saying if you don't like it just don't use it?
> 
> Yes, that's the meaning of "optional" I suppose :)
> 
> My idea about it (I did not test the patch, so correct me if I
> misunderstood the proposal) was to leave the default as it is now:
> 
> function($a) > what Greg likes to always use ;)
> function(mixed $a) > little syntax sugar, same as the previous one
> function(int $a)
> etc.
> 

Exactly. I just added the "mixed" type hint which is the same as using
no type hint. The new patch is attached.

Extra keywords (real, long, double, etc.) have been taken out. The
available type hints are now mixed, int, float, bool, string, scalar,
num, resource, and object. And of course array and class type hints
still work.

Index: Zend/zend_API.h
===================================================================
RCS file: /repository/ZendEngine2/zend_API.h,v
retrieving revision 1.207.2.8.2.8.2.6
diff -u -r1.207.2.8.2.8.2.6 zend_API.h
--- Zend/zend_API.h	31 Dec 2007 07:17:04 -0000	1.207.2.8.2.8.2.6
+++ Zend/zend_API.h	4 Jan 2008 15:22:11 -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.35
diff -u -r1.647.2.27.2.41.2.35 zend_compile.c
--- Zend/zend_compile.c	31 Dec 2007 07:17:04 -0000	1.647.2.27.2.41.2.35
+++ Zend/zend_compile.c	4 Jan 2008 15:22:11 -0000
@@ -1372,26 +1372,42 @@
 	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("int", 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("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("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 if (strcasecmp("mixed", class_type->u.constant.value.str.val) != 0) {
+ 				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;
@@ -2311,6 +2327,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.12
diff -u -r1.316.2.8.2.12.2.12 zend_compile.h
--- Zend/zend_compile.h	31 Dec 2007 07:17:04 -0000	1.316.2.8.2.12.2.12
+++ Zend/zend_compile.h	4 Jan 2008 15:22:11 -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.7
diff -u -r1.71.2.5.2.7.2.7 zend_constants.c
--- Zend/zend_constants.c	31 Dec 2007 07:17:04 -0000	1.71.2.5.2.7.2.7
+++ Zend/zend_constants.c	4 Jan 2008 15:22:11 -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.11
diff -u -r1.716.2.12.2.24.2.11 zend_execute.c
--- Zend/zend_execute.c	31 Dec 2007 07:17:04 -0000	1.716.2.12.2.24.2.11
+++ Zend/zend_execute.c	4 Jan 2008 15:22:12 -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

Reply via email to