Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions Zend/tests/functional_interfaces/001.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
--TEST--
functional interfaces: basic test
--FILE--
<?php
interface IFoo {
public function method();
}

$foo = function () implements IFoo {};

var_dump($foo instanceof IFoo,
$foo instanceof Closure);
--EXPECT--
bool(true)
bool(true)
12 changes: 12 additions & 0 deletions Zend/tests/functional_interfaces/002.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
--TEST--
functional interfaces: verify fail
--FILE--
<?php
interface IFoo {
public function method(string $arg) : void;
}

$foo = function () implements IFoo {};
--EXPECTF--
Fatal error: Declaration of {IFoo}::method() must be compatible with IFoo::method(string $arg): void in %s on line 6

16 changes: 16 additions & 0 deletions Zend/tests/functional_interfaces/003.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
--TEST--
functional interfaces: verify pass
--FILE--
<?php
interface IFoo {
public function method(string $arg) : void;
}

$foo = function (string $arg) implements IFoo : void {};

var_dump($foo instanceof IFoo,
$foo instanceof Closure);
--EXPECTF--
bool(true)
bool(true)

15 changes: 15 additions & 0 deletions Zend/tests/functional_interfaces/004.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
--TEST--
functional interfaces: not functional interface
--FILE--
<?php
interface IFoo {
public function method(string $arg) : void;
public function other();
}

$foo = function (string $arg) implements IFoo : void {};
--EXPECTF--
Fatal error: cannot implement non functional interface IFoo in %s on line 7



14 changes: 14 additions & 0 deletions Zend/tests/functional_interfaces/005.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
--TEST--
functional interfaces: non interface
--FILE--
<?php
class IFoo {
public function method(string $arg) : void {}
}

$foo = function (string $arg) implements IFoo : void {};
--EXPECTF--
Fatal error: cannot implement non interface IFoo in %s on line 6



19 changes: 19 additions & 0 deletions Zend/tests/functional_interfaces/006.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
--TEST--
functional interfaces: interface call
--FILE--
<?php
interface IFoo {
public function method(string $arg) : void;
}

$foo = function (string $arg) implements IFoo : void {
var_dump($arg);
};

$foo->method("turtles ?");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐢!!

--EXPECTF--
string(9) "turtles ?"




7 changes: 7 additions & 0 deletions Zend/tests/functional_interfaces/007.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
--TEST--
functional interfaces: cannot implement self
--FILE--
<?php
function () implements self {};
--EXPECTF--
Fatal error: functional interface cannot implement self in %s on line 2
7 changes: 7 additions & 0 deletions Zend/tests/functional_interfaces/008.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
--TEST--
functional interfaces: cannot implement parent
--FILE--
<?php
function () implements parent {};
--EXPECTF--
Fatal error: functional interface cannot implement parent in %s on line 2
7 changes: 7 additions & 0 deletions Zend/tests/functional_interfaces/009.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
--TEST--
functional interfaces: cannot implement static
--FILE--
<?php
function () implements static {};
--EXPECTF--
Fatal error: functional interface cannot implement static in %s on line 2
30 changes: 30 additions & 0 deletions Zend/tests/functional_interfaces/010.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
--TEST--
functional interfaces: scope/this
--FILE--
<?php
interface ILog {
public function log(string $message, ...$args);
}

class Foo {

public function __construct() {
$this->stream = fopen("php://stdout", "w");
}

public function getLogger() : ILog {
return function (string $message, ... $args) implements ILog {
fprintf($this->stream, $message, ... $args);
};
}

protected $stream;
}

$foo = new Foo();
$logger =
$foo->getLogger();
$logger->log("php7 baby\n");
?>
--EXPECTF--
php7 baby
42 changes: 42 additions & 0 deletions Zend/tests/functional_interfaces/011.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
--TEST--
functional interfaces: call method handling
--FILE--
<?php
class Foo {
private $bar = [];

public function __construct(array $bar) {
$this->bar = $bar;
}

public function getShufflingIterator() : Traversable {

return function() implements IteratorAggregate : Traversable {
shuffle($this->bar);

return new ArrayIterator($this->bar);
};
}
}

$foo = new Foo([
"hello",
"world"
]);

$shuffler =
$foo->getShufflingIterator();

foreach ($shuffler as $key => $value) {
var_dump($value);
}

foreach ($shuffler as $key => $value) {
var_dump($value);
}
?>
--EXPECTF--
string(5) "%s"
string(5) "%s"
string(5) "%s"
string(5) "%s"
25 changes: 25 additions & 0 deletions Zend/tests/functional_interfaces/012.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
--TEST--
functional interfaces: binding
--FILE--
<?php
interface ILog {
public function do() : void;
}

class Foo {}

$logger = function() implements ILog : void {
var_dump($this instanceof Foo);
};

$foo = new Foo();

$bound = Closure::bind($logger, $foo);

var_dump($bound instanceof ILog);

$bound();
?>
--EXPECT--
bool(true)
bool(true)
70 changes: 70 additions & 0 deletions Zend/tests/functional_interfaces/013.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
--TEST--
functional interfaces: call method without ce and proxy
--FILE--
<?php
class Foo {
private $bar = [];

public function fill($limit = 100) {
for ($i = 0; $i < $limit; $i++) {
$this->bar[] = mt_rand($i, $limit);
}
}

public function getEvenCounter() : Countable {
return function () implements Countable {
$counter = 0;
foreach ($this->bar as $value) {
if ($value % 2 === 0)
$counter++;
}
return $counter;
};
}

public function getOddCounter() : Countable {
return function () implements Countable {
$counter = 0;
foreach ($this->bar as $value) {
if ($value % 2 !== 0) {
$counter++;
}
}
return $counter;
};
}
}

$foo = new Foo();

$even = $foo->getEvenCounter();
$odd = $foo->getOddCounter();

$it = 0;

while (++$it<10) {
$foo->fill(50);
var_dump(
count($even),
count($odd));
}
?>
--EXPECTF--
int(%d)
int(%d)
int(%d)
int(%d)
int(%d)
int(%d)
int(%d)
int(%d)
int(%d)
int(%d)
int(%d)
int(%d)
int(%d)
int(%d)
int(%d)
int(%d)
int(%d)
int(%d)
12 changes: 12 additions & 0 deletions Zend/tests/functional_interfaces/014.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
--TEST--
functional interfaces: non static implementation of static interface
--FILE--
<?php
interface IFoo {
public static function method();
}

$cb = function () implements IFoo {};
--EXPECTF--
Fatal error: cannot create non static implementation of static functional interface IFoo in %s on line 6

12 changes: 12 additions & 0 deletions Zend/tests/functional_interfaces/015.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
--TEST--
functional interfaces: static implementation of non static interface
--FILE--
<?php
interface IFoo {
public function method();
}

$cb = static function () implements IFoo {};
--EXPECTF--
Fatal error: cannot create static implementation of non static functional interface IFoo in %s on line 6

6 changes: 5 additions & 1 deletion Zend/zend_ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ ZEND_API zend_ast *zend_ast_create_zval_ex(zval *zv, zend_ast_attr attr) {

ZEND_API zend_ast *zend_ast_create_decl(
zend_ast_kind kind, uint32_t flags, uint32_t start_lineno, zend_string *doc_comment,
zend_string *name, zend_ast *child0, zend_ast *child1, zend_ast *child2, zend_ast *child3
zend_string *name, zend_ast *child0, zend_ast *child1, zend_ast *child2, zend_ast *child3, zend_ast *child4
) {
zend_ast_decl *ast;

Expand All @@ -87,6 +87,7 @@ ZEND_API zend_ast *zend_ast_create_decl(
ast->child[1] = child1;
ast->child[2] = child2;
ast->child[3] = child3;
ast->child[4] = child4;

return (zend_ast *) ast;
}
Expand Down Expand Up @@ -472,6 +473,9 @@ static void zend_ast_destroy_ex(zend_ast *ast, zend_bool free) {
zend_ast_destroy_ex(decl->child[1], free);
zend_ast_destroy_ex(decl->child[2], free);
zend_ast_destroy_ex(decl->child[3], free);
if (decl->child[4]) {
zend_ast_destroy_ex(decl->child[4], free);
}
break;
}
default:
Expand Down
4 changes: 2 additions & 2 deletions Zend/zend_ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ typedef struct _zend_ast_decl {
unsigned char *lex_pos;
zend_string *doc_comment;
zend_string *name;
zend_ast *child[4];
zend_ast *child[5];
} zend_ast_decl;

typedef void (*zend_ast_process_t)(zend_ast *ast);
Expand All @@ -197,7 +197,7 @@ ZEND_API zend_ast *zend_ast_create(zend_ast_kind kind, ...);

ZEND_API zend_ast *zend_ast_create_decl(
zend_ast_kind kind, uint32_t flags, uint32_t start_lineno, zend_string *doc_comment,
zend_string *name, zend_ast *child0, zend_ast *child1, zend_ast *child2, zend_ast *child3
zend_string *name, zend_ast *child0, zend_ast *child1, zend_ast *child2, zend_ast *child3, zend_ast *child4
);

ZEND_API zend_ast *zend_ast_create_list(uint32_t init_children, zend_ast_kind kind, ...);
Expand Down
Loading