]> granicus.if.org Git - php/commitdiff
Cleanup comments and add related tests.
authorDmitry Stogov <dmitry@zend.com>
Thu, 23 Apr 2015 14:52:05 +0000 (17:52 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 23 Apr 2015 14:52:05 +0000 (17:52 +0300)
Zend/tests/closure_058.phpt [new file with mode: 0644]
Zend/tests/closure_059.phpt [new file with mode: 0644]
Zend/zend_closures.c

diff --git a/Zend/tests/closure_058.phpt b/Zend/tests/closure_058.phpt
new file mode 100644 (file)
index 0000000..128661f
--- /dev/null
@@ -0,0 +1,64 @@
+--TEST--
+Closure 058: Closure scope and object
+--FILE--
+<?php
+class A {
+       static function foo() {
+               return function () {var_dump(get_class(),get_called_class());};
+       }
+       function bar() {
+               return function () {var_dump(get_class(),get_called_class(),$this);};
+       }
+}
+$z = "call_user_func";
+
+$a = A::foo();
+$a();
+$a->__invoke();
+$c = array($a,"__invoke");
+$c();
+call_user_func(array($a,"__invoke"));
+$z(array($a,"__invoke"));
+
+echo "\n";
+
+$x = new A();
+$b = $x->bar();
+$b();
+$b->__invoke();
+$c = array($b,"__invoke");
+$c();
+call_user_func(array($b,"__invoke"));
+$z(array($b,"__invoke"));
+--EXPECT--
+string(1) "A"
+string(1) "A"
+string(1) "A"
+string(1) "A"
+string(1) "A"
+string(1) "A"
+string(1) "A"
+string(1) "A"
+string(1) "A"
+string(1) "A"
+
+string(1) "A"
+string(1) "A"
+object(A)#2 (0) {
+}
+string(1) "A"
+string(1) "A"
+object(A)#2 (0) {
+}
+string(1) "A"
+string(1) "A"
+object(A)#2 (0) {
+}
+string(1) "A"
+string(1) "A"
+object(A)#2 (0) {
+}
+string(1) "A"
+string(1) "A"
+object(A)#2 (0) {
+}
diff --git a/Zend/tests/closure_059.phpt b/Zend/tests/closure_059.phpt
new file mode 100644 (file)
index 0000000..de9c574
--- /dev/null
@@ -0,0 +1,38 @@
+--TEST--
+Closure 059: Closure type hinting
+--FILE--
+<?php
+class A {
+}
+
+class B {
+}
+
+$a = new A;
+$b = new B;
+
+$f = function (A $a){};
+
+$f($a);
+$f->__invoke($a);
+call_user_func(array($f,"__invoke"), $a);
+
+try {
+       $f($b);
+} catch (EngineException $e) {
+       echo "Exception: " . $e->getMessage() . "\n";
+}
+try {
+       $f->__invoke($b);
+} catch (EngineException $e) {
+       echo "Exception: " . $e->getMessage() . "\n";
+}
+try {
+       call_user_func(array($f,"__invoke"), $b);
+} catch (EngineException $e) {
+       echo "Exception: " . $e->getMessage() . "\n";
+}
+--EXPECTF--
+Exception: Argument 1 passed to {closure}() must be an instance of A, instance of B %s
+Exception: Argument 1 passed to {closure}() must be an instance of A, instance of B %s
+Exception: Argument 1 passed to {closure}() must be an instance of A, instance of B %s
index 843254c6ef02e1158536015b59bff28e7e8954f1..952e4ed1e0fedf38390f9080fda90efd1d0671db 100644 (file)
@@ -184,7 +184,10 @@ ZEND_API zend_function *zend_get_closure_invoke_method(zend_object *object) /* {
        zend_function *invoke = (zend_function*)emalloc(sizeof(zend_function));
 
        invoke->common = closure->func.common;
-       /* TODO: return ZEND_INTERNAL_FUNCTION, but arg_info representation is suitable for ZEND_USER_FUNCTION ??? */
+       /* We return ZEND_INTERNAL_FUNCTION, but arg_info representation is the
+        * same as for ZEND_USER_FUNCTION (uses zend_string* instead of char*).
+        * This is not a problem, because ZEND_ACC_HAS_TYPE_HINTS is never set,
+        * and we won't check arguments on internal function */
        invoke->type = ZEND_INTERNAL_FUNCTION;
        invoke->internal_function.fn_flags = ZEND_ACC_PUBLIC | ZEND_ACC_CALL_VIA_HANDLER | (closure->func.common.fn_flags & ZEND_ACC_RETURN_REFERENCE);
        invoke->internal_function.handler = ZEND_MN(Closure___invoke);