summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcus Boerger <helly@php.net>2004-02-11 22:13:39 +0000
committerMarcus Boerger <helly@php.net>2004-02-11 22:13:39 +0000
commitc6cbafa273e69cbc7c2c2a2f6f53f5d15c815ab9 (patch)
tree75b373155e535d0a532e323848b1f22fd6ab4b6a
parente9e1494a59cfcceb0bccb78eb576ab698339332c (diff)
downloadphp-git-c6cbafa273e69cbc7c2c2a2f6f53f5d15c815ab9.tar.gz
Fix: <interface> [extends <interface> [, <ineterface>]* ]
-rw-r--r--Zend/zend_compile.c6
-rw-r--r--Zend/zend_language_parser.y16
-rw-r--r--tests/classes/interface_doubled.phpt8
3 files changed, 21 insertions, 9 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index f3a72527e6..de45f3b6cb 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -2452,7 +2452,7 @@ void zend_do_begin_class_declaration(znode *class_token, znode *class_name, znod
new_class_entry->line_start = zend_get_compiled_lineno(TSRMLS_C);
new_class_entry->ce_flags |= class_token->u.constant.value.lval;
- if (parent_class_name->op_type != IS_UNUSED) {
+ if (parent_class_name && parent_class_name->op_type != IS_UNUSED) {
doing_inheritance = 1;
}
@@ -2542,10 +2542,6 @@ void zend_do_implements_interface(znode *interface_znode TSRMLS_DC)
{
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
- if (CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE) {
- zend_error(E_COMPILE_ERROR, "Interfaces cannot implement other classes/interfaces");
- }
-
opline->opcode = ZEND_ADD_INTERFACE;
opline->op1 = CG(implementing_class);
opline->op2 = *interface_znode;
diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y
index d127af4297..3fdfb44fba 100644
--- a/Zend/zend_language_parser.y
+++ b/Zend/zend_language_parser.y
@@ -274,6 +274,12 @@ unticked_class_declaration_statement:
'{'
class_statement_list
'}' { zend_do_end_class_declaration(&$1, &$2 TSRMLS_CC); }
+ | interface_entry T_STRING
+ { zend_do_begin_class_declaration(&$1, &$2, NULL TSRMLS_CC); }
+ interface_extends_list
+ '{'
+ class_statement_list
+ '}' { zend_do_end_class_declaration(&$1, &$2 TSRMLS_CC); }
;
@@ -281,7 +287,6 @@ class_entry_type:
T_CLASS { $$.u.constant.value.lval = 0; }
| T_ABSTRACT T_CLASS { $$.u.constant.value.lval = ZEND_ACC_ABSTRACT_CLASS; }
| T_FINAL T_CLASS { $$.u.constant.value.lval = ZEND_ACC_FINAL_CLASS; }
- | T_INTERFACE { $$.u.constant.value.lval = ZEND_ACC_INTERFACE; }
;
extends_from:
@@ -289,6 +294,15 @@ extends_from:
| T_EXTENDS fully_qualified_class_name { $$ = $2; }
;
+interface_entry:
+ T_INTERFACE { $$.u.constant.value.lval = ZEND_ACC_INTERFACE; }
+;
+
+interface_extends_list:
+ /* empty */
+ | T_EXTENDS interface_list
+;
+
implements_list:
/* empty */
| T_IMPLEMENTS interface_list
diff --git a/tests/classes/interface_doubled.phpt b/tests/classes/interface_doubled.phpt
index 4c41ce1172..cf3b099740 100644
--- a/tests/classes/interface_doubled.phpt
+++ b/tests/classes/interface_doubled.phpt
@@ -1,5 +1,5 @@
--TEST--
-ZE2 An interface may both inherit and implement base interfaces
+ZE2 An interface extends base interfaces
--SKIPIF--
<?php if (version_compare(zend_version(), '2.0.0-dev', '<')) die('skip ZendEngine 2 needed'); ?>
--FILE--
@@ -25,7 +25,7 @@ interface if_e {
abstract function f_d();
}
-interface if_f extends if_e, if_a, if_b, if_c, if_d, if_e {
+interface if_f extends /*if_e,*/ if_a, if_b, if_c, if_d /*, if_e*/ {
}
class base {
@@ -154,6 +154,7 @@ echo $t->test('if_d');
echo $t->test('if_e');
?>
+===DONE===
--EXPECTF--
class_a
is_a(class_a, if_a) yes
@@ -196,4 +197,5 @@ is_a(class_g, if_a) yes
is_a(class_g, if_b) yes
is_a(class_g, if_c) yes
is_a(class_g, if_d) yes
-is_a(class_g, if_e) yes \ No newline at end of file
+is_a(class_g, if_e) no
+===DONE===