From 478e5d1dd027c68fd1637add6d6ba0913969112a Mon Sep 17 00:00:00 2001 From: Stefan Marr Date: Sun, 9 Jan 2011 19:57:41 +0000 Subject: [PATCH] Added trait_exists() [TRAITS] [DOC] - also changed class_exists() to return false for traits - added related tests, and get_declared_traits() tests in ext/s/t/co --- UPGRADING | 1 + Zend/tests/class_exists_003.phpt | 6 +- Zend/tests/trait_exists_001.phpt | 21 ++ Zend/tests/trait_exists_002.phpt | 21 ++ Zend/tests/trait_exists_003.phpt | 24 +++ Zend/zend_builtin_functions.c | 54 ++++- ext/standard/tests/class_object/AutoTrait.inc | 5 + .../get_declared_traits_basic_001.phpt | 56 +++++ .../get_declared_traits_error_001.phpt | 27 +++ .../get_declared_traits_variation1.phpt | 41 ++++ .../trait_class_exists_variation_003.phpt | 18 ++ .../class_object/trait_exists_basic_001.phpt | 57 ++++++ .../class_object/trait_exists_error_001.phpt | 42 ++++ .../trait_exists_variation_001.phpt | 182 +++++++++++++++++ .../trait_exists_variation_002.phpt | 193 ++++++++++++++++++ 15 files changed, 745 insertions(+), 3 deletions(-) create mode 100644 Zend/tests/trait_exists_001.phpt create mode 100644 Zend/tests/trait_exists_002.phpt create mode 100644 Zend/tests/trait_exists_003.phpt create mode 100644 ext/standard/tests/class_object/AutoTrait.inc create mode 100644 ext/standard/tests/class_object/get_declared_traits_basic_001.phpt create mode 100644 ext/standard/tests/class_object/get_declared_traits_error_001.phpt create mode 100644 ext/standard/tests/class_object/get_declared_traits_variation1.phpt create mode 100644 ext/standard/tests/class_object/trait_class_exists_variation_003.phpt create mode 100644 ext/standard/tests/class_object/trait_exists_basic_001.phpt create mode 100644 ext/standard/tests/class_object/trait_exists_error_001.phpt create mode 100644 ext/standard/tests/class_object/trait_exists_variation_001.phpt create mode 100644 ext/standard/tests/class_object/trait_exists_variation_002.phpt diff --git a/UPGRADING b/UPGRADING index 0d7d1c2811..f17fa7af4d 100755 --- a/UPGRADING +++ b/UPGRADING @@ -322,6 +322,7 @@ UPGRADE NOTES - PHP X.Y - Core: - get_declared_traits() - http_response_code() + - trait_exists() f. New global constants diff --git a/Zend/tests/class_exists_003.phpt b/Zend/tests/class_exists_003.phpt index ad7bafa3a7..cba4675099 100644 --- a/Zend/tests/class_exists_003.phpt +++ b/Zend/tests/class_exists_003.phpt @@ -1,5 +1,5 @@ --TEST-- -Checking if exists interface, abstract and final class +Checking if exists interface, trait, abstract and final class --FILE-- --EXPECT-- bool(false) bool(true) bool(true) +bool(false) diff --git a/Zend/tests/trait_exists_001.phpt b/Zend/tests/trait_exists_001.phpt new file mode 100644 index 0000000000..10ce3fa0cb --- /dev/null +++ b/Zend/tests/trait_exists_001.phpt @@ -0,0 +1,21 @@ +--TEST-- +Testing trait_exists() +--FILE-- + +--EXPECTF-- +bool(true) +bool(false) +bool(false) + +Warning: trait_exists() expects parameter 1 to be string, object given in %s on line %d +NULL diff --git a/Zend/tests/trait_exists_002.phpt b/Zend/tests/trait_exists_002.phpt new file mode 100644 index 0000000000..7b5c899806 --- /dev/null +++ b/Zend/tests/trait_exists_002.phpt @@ -0,0 +1,21 @@ +--TEST-- +Testing trait_exists() inside a namespace +--FILE-- + +--EXPECT-- +bool(false) +bool(true) +bool(true) diff --git a/Zend/tests/trait_exists_003.phpt b/Zend/tests/trait_exists_003.phpt new file mode 100644 index 0000000000..2d57d86486 --- /dev/null +++ b/Zend/tests/trait_exists_003.phpt @@ -0,0 +1,24 @@ +--TEST-- +Checking trait_exists(): interface, trait, abstract and final class +--FILE-- + +--EXPECT-- +bool(false) +bool(false) +bool(false) +bool(true) diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 0d1cf15770..c0e195a254 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -50,6 +50,7 @@ static ZEND_FUNCTION(method_exists); static ZEND_FUNCTION(property_exists); static ZEND_FUNCTION(class_exists); static ZEND_FUNCTION(interface_exists); +static ZEND_FUNCTION(trait_exists); static ZEND_FUNCTION(function_exists); static ZEND_FUNCTION(class_alias); #if ZEND_DEBUG @@ -171,6 +172,11 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_exists, 0, 0, 1) ZEND_ARG_INFO(0, autoload) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_trait_exists, 0, 0, 1) + ZEND_ARG_INFO(0, traitname) + ZEND_ARG_INFO(0, autoload) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(arginfo_function_exists, 0, 0, 1) ZEND_ARG_INFO(0, function_name) ZEND_END_ARG_INFO() @@ -249,6 +255,7 @@ static const zend_function_entry builtin_functions[] = { /* {{{ */ ZEND_FE(property_exists, arginfo_property_exists) ZEND_FE(class_exists, arginfo_class_exists) ZEND_FE(interface_exists, arginfo_class_exists) + ZEND_FE(trait_exists, arginfo_trait_exists) ZEND_FE(function_exists, arginfo_function_exists) ZEND_FE(class_alias, arginfo_class_alias) #if ZEND_DEBUG @@ -1223,11 +1230,11 @@ ZEND_FUNCTION(class_exists) found = zend_hash_find(EG(class_table), name, len+1, (void **) &ce); free_alloca(lc_name, use_heap); - RETURN_BOOL(found == SUCCESS && !((*ce)->ce_flags & ZEND_ACC_INTERFACE)); + RETURN_BOOL(found == SUCCESS && !((*ce)->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT) > ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)); } if (zend_lookup_class(class_name, class_name_len, &ce TSRMLS_CC) == SUCCESS) { - RETURN_BOOL(((*ce)->ce_flags & ZEND_ACC_INTERFACE) == 0); + RETURN_BOOL(((*ce)->ce_flags & (ZEND_ACC_INTERFACE | (ZEND_ACC_TRAIT - ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))) == 0); } else { RETURN_FALSE; } @@ -1277,6 +1284,49 @@ ZEND_FUNCTION(interface_exists) } /* }}} */ +/* {{{ proto bool trait_exists(string traitname [, bool autoload]) + Checks if the trait exists */ +ZEND_FUNCTION(trait_exists) +{ + char *trait_name, *lc_name; + zend_class_entry **ce; + int trait_name_len; + int found; + zend_bool autoload = 1; + ALLOCA_FLAG(use_heap) + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &trait_name, &trait_name_len, &autoload) == FAILURE) { + return; + } + + if (!autoload) { + char *name; + int len; + + lc_name = do_alloca(trait_name_len + 1, use_heap); + zend_str_tolower_copy(lc_name, trait_name, trait_name_len); + + /* Ignore leading "\" */ + name = lc_name; + len = trait_name_len; + if (lc_name[0] == '\\') { + name = &lc_name[1]; + len--; + } + + found = zend_hash_find(EG(class_table), name, len+1, (void **) &ce); + free_alloca(lc_name, use_heap); + RETURN_BOOL(found == SUCCESS && (((*ce)->ce_flags & ZEND_ACC_TRAIT) > ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)); + } + + if (zend_lookup_class(trait_name, trait_name_len, &ce TSRMLS_CC) == SUCCESS) { + RETURN_BOOL(((*ce)->ce_flags & ZEND_ACC_TRAIT) > ZEND_ACC_EXPLICIT_ABSTRACT_CLASS); + } else { + RETURN_FALSE; + } +} +/* }}} */ + /* {{{ proto bool function_exists(string function_name) Checks if the function exists */ diff --git a/ext/standard/tests/class_object/AutoTrait.inc b/ext/standard/tests/class_object/AutoTrait.inc new file mode 100644 index 0000000000..698e975ef7 --- /dev/null +++ b/ext/standard/tests/class_object/AutoTrait.inc @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/ext/standard/tests/class_object/get_declared_traits_basic_001.phpt b/ext/standard/tests/class_object/get_declared_traits_basic_001.phpt new file mode 100644 index 0000000000..69d8de9c31 --- /dev/null +++ b/ext/standard/tests/class_object/get_declared_traits_basic_001.phpt @@ -0,0 +1,56 @@ +--TEST-- +Test get_declared_traits() function : basic functionality +--FILE-- + +--EXPECTF-- +*** Testing get_declared_traits() : basic functionality *** + +-- Testing get_declared_traits() function with Zero arguments -- +array(%d) { +%a +} + +-- Ensure trait is listed -- +bool(true) + +-- Ensure userspace interfaces are not listed -- +bool(false) + +-- Ensure userspace classes are not listed -- +bool(false) +Done \ No newline at end of file diff --git a/ext/standard/tests/class_object/get_declared_traits_error_001.phpt b/ext/standard/tests/class_object/get_declared_traits_error_001.phpt new file mode 100644 index 0000000000..f7a00da0dd --- /dev/null +++ b/ext/standard/tests/class_object/get_declared_traits_error_001.phpt @@ -0,0 +1,27 @@ +--TEST-- +Test get_declared_traits() function : error conditions +--FILE-- + +--EXPECTF-- +*** Testing get_declared_traits() : error conditions *** + +-- Testing get_declared_traits() function with one argument -- + +Warning: get_declared_traits() expects exactly 0 parameters, 1 given in %s on line 13 +NULL +Done diff --git a/ext/standard/tests/class_object/get_declared_traits_variation1.phpt b/ext/standard/tests/class_object/get_declared_traits_variation1.phpt new file mode 100644 index 0000000000..bedd37a3db --- /dev/null +++ b/ext/standard/tests/class_object/get_declared_traits_variation1.phpt @@ -0,0 +1,41 @@ +--TEST-- +Test get_declared_traits() function : testing autoloaded traits +--FILE-- + +--EXPECTF-- +*** Testing get_declared_traits() : testing autoloaded traits *** + +-- before instance is declared -- +bool(false) + +-- after use is declared -- +bool(true) + +DONE diff --git a/ext/standard/tests/class_object/trait_class_exists_variation_003.phpt b/ext/standard/tests/class_object/trait_class_exists_variation_003.phpt new file mode 100644 index 0000000000..6a8e55bda0 --- /dev/null +++ b/ext/standard/tests/class_object/trait_class_exists_variation_003.phpt @@ -0,0 +1,18 @@ +--TEST-- +Test trait_exists() function : usage variations - case sensitivity +--FILE-- + +--EXPECTF-- +bool(true) +Done \ No newline at end of file diff --git a/ext/standard/tests/class_object/trait_exists_basic_001.phpt b/ext/standard/tests/class_object/trait_exists_basic_001.phpt new file mode 100644 index 0000000000..19616ab5c5 --- /dev/null +++ b/ext/standard/tests/class_object/trait_exists_basic_001.phpt @@ -0,0 +1,57 @@ +--TEST-- +Test trait_exists() function : basic functionality +--FILE-- + +--EXPECTF-- +*** Testing trait_exists() : basic functionality *** +Calling trait_exists() on non-existent trait with autoload explicitly enabled: +In __autoload(C) +bool(false) + +Calling trait_exists() on existing trait with autoload explicitly enabled: +bool(true) + +Calling trait_exists() on non-existent trait with autoload explicitly enabled: +bool(false) + +Calling trait_exists() on existing trait with autoload explicitly disabled: +bool(true) + +Calling trait_exists() on non-existent trait with autoload unspecified: +In __autoload(E) +bool(false) + +Calling trait_exists() on existing trait with autoload unspecified: +bool(true) +Done \ No newline at end of file diff --git a/ext/standard/tests/class_object/trait_exists_error_001.phpt b/ext/standard/tests/class_object/trait_exists_error_001.phpt new file mode 100644 index 0000000000..b80f06ed2a --- /dev/null +++ b/ext/standard/tests/class_object/trait_exists_error_001.phpt @@ -0,0 +1,42 @@ +--TEST-- +Test trait_exists() function : error conditions (wrong number of arguments) +--FILE-- + +--EXPECTF-- +*** Testing trait_exists() : error conditions *** + +-- Testing trait_exists() function with Zero arguments -- + +Warning: trait_exists() expects at least 1 parameter, 0 given in %s on line 16 +NULL + +-- Testing trait_exists() function with more than expected no. of arguments -- + +Warning: trait_exists() expects at most 2 parameters, 3 given in %s on line 23 +NULL +Done diff --git a/ext/standard/tests/class_object/trait_exists_variation_001.phpt b/ext/standard/tests/class_object/trait_exists_variation_001.phpt new file mode 100644 index 0000000000..16515de6dc --- /dev/null +++ b/ext/standard/tests/class_object/trait_exists_variation_001.phpt @@ -0,0 +1,182 @@ +--TEST-- +Test trait_exists() function : usage variations - unexpected types for agument 1 +--FILE-- + 'red', 'item' => 'pen'), + + // null data + NULL, + null, + + // boolean data + true, + false, + TRUE, + FALSE, + + // empty data + "", + '', + + // object data + new stdclass(), + + // undefined data + $undefined_var, + + // unset data + $unset_var, +); + +// loop through each element of the array for traitname + +foreach($values as $value) { + echo "\nArg value $value \n"; + var_dump( trait_exists($value, $autoload) ); +}; + +echo "Done"; +?> +--EXPECTF-- +*** Testing trait_exists() : usage variations *** +Error: 8 - Undefined variable: undefined_var, %s(67) +Error: 8 - Undefined variable: unset_var, %s(70) + +Arg value 0 +In __autoload(0) +bool(false) + +Arg value 1 +In __autoload(1) +bool(false) + +Arg value 12345 +In __autoload(12345) +bool(false) + +Arg value -2345 +In __autoload(-2345) +bool(false) + +Arg value 10.5 +In __autoload(10.5) +bool(false) + +Arg value -10.5 +In __autoload(-10.5) +bool(false) + +Arg value 101234567000 +In __autoload(101234567000) +bool(false) + +Arg value 1.07654321E-9 +In __autoload(1.07654321E-9) +bool(false) + +Arg value 0.5 +In __autoload(0.5) +bool(false) + +Arg value Array +Error: 2 - trait_exists() expects parameter 1 to be string, array given, %s(77) +NULL + +Arg value Array +Error: 2 - trait_exists() expects parameter 1 to be string, array given, %s(77) +NULL + +Arg value Array +Error: 2 - trait_exists() expects parameter 1 to be string, array given, %s(77) +NULL + +Arg value Array +Error: 2 - trait_exists() expects parameter 1 to be string, array given, %s(77) +NULL + +Arg value Array +Error: 2 - trait_exists() expects parameter 1 to be string, array given, %s(77) +NULL + +Arg value +bool(false) + +Arg value +bool(false) + +Arg value 1 +In __autoload(1) +bool(false) + +Arg value +bool(false) + +Arg value 1 +In __autoload(1) +bool(false) + +Arg value +bool(false) + +Arg value +bool(false) + +Arg value +bool(false) +Error: 4096 - Object of class stdClass could not be converted to string, %s(76) + +Arg value +Error: 2 - trait_exists() expects parameter 1 to be string, object given, %s(77) +NULL + +Arg value +bool(false) + +Arg value +bool(false) +Done \ No newline at end of file diff --git a/ext/standard/tests/class_object/trait_exists_variation_002.phpt b/ext/standard/tests/class_object/trait_exists_variation_002.phpt new file mode 100644 index 0000000000..d29d81a37c --- /dev/null +++ b/ext/standard/tests/class_object/trait_exists_variation_002.phpt @@ -0,0 +1,193 @@ +--TEST-- +Test trait_exists() function : usage variations - unexpected types for agument 2 +--FILE-- + 'red', 'item' => 'pen'), + + // null data + NULL, + null, + + // boolean data + true, + false, + TRUE, + FALSE, + + // empty data + "", + '', + + // string data + "string", + 'string', + + // object data + new stdclass(), + + // undefined data + $undefined_var, + + // unset data + $unset_var, +); + +// loop through each element of the array for autoload + +foreach($values as $value) { + echo "\nArg value $value \n"; + var_dump( trait_exists($traitname, $value) ); +}; + +echo "Done"; +?> +--EXPECTF-- +*** Testing trait_exists() : usage variations *** +Error: 8 - Undefined variable: undefined_var, %s(71) +Error: 8 - Undefined variable: unset_var, %s(74) + +Arg value 0 +bool(false) + +Arg value 1 +In __autoload(string_val) +bool(false) + +Arg value 12345 +In __autoload(string_val) +bool(false) + +Arg value -2345 +In __autoload(string_val) +bool(false) + +Arg value 10.5 +In __autoload(string_val) +bool(false) + +Arg value -10.5 +In __autoload(string_val) +bool(false) + +Arg value 101234567000 +In __autoload(string_val) +bool(false) + +Arg value 1.07654321E-9 +In __autoload(string_val) +bool(false) + +Arg value 0.5 +In __autoload(string_val) +bool(false) + +Arg value Array +Error: 2 - trait_exists() expects parameter 2 to be boolean, array given, %s(81) +NULL + +Arg value Array +Error: 2 - trait_exists() expects parameter 2 to be boolean, array given, %s(81) +NULL + +Arg value Array +Error: 2 - trait_exists() expects parameter 2 to be boolean, array given, %s(81) +NULL + +Arg value Array +Error: 2 - trait_exists() expects parameter 2 to be boolean, array given, %s(81) +NULL + +Arg value Array +Error: 2 - trait_exists() expects parameter 2 to be boolean, array given, %s(81) +NULL + +Arg value +bool(false) + +Arg value +bool(false) + +Arg value 1 +In __autoload(string_val) +bool(false) + +Arg value +bool(false) + +Arg value 1 +In __autoload(string_val) +bool(false) + +Arg value +bool(false) + +Arg value +bool(false) + +Arg value +bool(false) + +Arg value string +In __autoload(string_val) +bool(false) + +Arg value string +In __autoload(string_val) +bool(false) +Error: 4096 - Object of class stdClass could not be converted to string, %s(80) + +Arg value +Error: 2 - trait_exists() expects parameter 2 to be boolean, object given, %s(81) +NULL + +Arg value +bool(false) + +Arg value +bool(false) +Done \ No newline at end of file -- 2.40.0