diff options
-rw-r--r-- | Zend/zend_compile.c | 6 | ||||
-rw-r--r-- | Zend/zend_language_parser.y | 16 | ||||
-rw-r--r-- | tests/classes/interface_doubled.phpt | 8 |
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=== |