?>
==DONE==
--EXPECTF--
-Parse error: syntax error, unexpected T_STATIC, expecting T_STRING or T_PAAMAYIM_NEKUDOTAYIM in %s on line %d
+Parse error: syntax error, unexpected T_STATIC, expecting T_STRING or T_PAAMAYIM_NEKUDOTAYIM or T_NAMESPACE in %s on line %d
?>
==DONE==
--EXPECTF--
-Parse error: syntax error, unexpected T_STATIC, expecting T_STRING or T_PAAMAYIM_NEKUDOTAYIM in %s on line %d
+Parse error: syntax error, unexpected T_STATIC, expecting T_STRING or T_PAAMAYIM_NEKUDOTAYIM or T_NAMESPACE in %s on line %d
--- /dev/null
+--TEST--
+057: Usage of 'namespace' in compound names (inside namespase)
+--FILE--
+<?php
+namespace test::ns1;
+
+const C = "const ok\n";
+
+function foo() {
+ return "func ok\n";
+}
+
+class foo {
+ const C = "const ok\n";
+ const C2 = namespace::C;
+ static $var = "var ok\n";
+ function __construct() {
+ echo "class ok\n";
+ }
+ static function bar() {
+ return "method ok\n";
+ }
+}
+
+function f1($x=namespace::C) {
+ return $x;
+}
+function f2($x=namespace::foo::C) {
+ return $x;
+}
+
+function f3(namespace::foo $x) {
+ return "ok\n";
+}
+
+echo namespace::C;
+echo namespace::foo();
+echo namespace::foo::C;
+echo namespace::foo::C2;
+echo namespace::foo::$var;
+echo namespace::foo::bar();
+echo namespace::f1();
+echo namespace::f2();
+echo namespace::f3(new namespace::foo());
+?>
+--EXPECTF--
+const ok
+func ok
+const ok
+const ok
+var ok
+method ok
+const ok
+const ok
+class ok
+ok
--- /dev/null
+--TEST--
+058: Usage of 'namespace' in compound names (out of namespase)
+--FILE--
+<?php
+const C = "const ok\n";
+
+function foo() {
+ return "func ok\n";
+}
+
+class foo {
+ const C = "const ok\n";
+ const C2 = namespace::C;
+ static $var = "var ok\n";
+ function __construct() {
+ echo "class ok\n";
+ }
+ static function bar() {
+ return "method ok\n";
+ }
+}
+
+function f1($x=namespace::C) {
+ return $x;
+}
+function f2($x=namespace::foo::C) {
+ return $x;
+}
+
+function f3(namespace::foo $x) {
+ return "ok\n";
+}
+
+echo namespace::C;
+echo namespace::foo();
+echo namespace::foo::C;
+echo namespace::foo::C2;
+echo namespace::foo::$var;
+echo namespace::foo::bar();
+echo namespace::f1();
+echo namespace::f2();
+echo namespace::f3(new namespace::foo());
+?>
+--EXPECT--
+const ok
+func ok
+const ok
+const ok
+var ok
+method ok
+const ok
+const ok
+class ok
+ok
zend_op *opline;
zend_arg_info *cur_arg_info;
+ if (class_type->op_type == IS_CONST &&
+ Z_UNILEN(class_type->u.constant) == 0) {
+ /* Usage of namespace as class name not in namespace */
+ zval_dtor(&class_type->u.constant);
+ zend_error(E_COMPILE_ERROR, "Cannot use 'namespace' as a class name");
+ return;
+ }
+
if (CG(active_op_array)->scope &&
((CG(active_op_array)->fn_flags & ZEND_ACC_STATIC) == 0) &&
(Z_TYPE(varname->u.constant) == IS_STRING || Z_TYPE(varname->u.constant) == IS_UNICODE) &&
long fetch_class_op_number;
zend_op *opline;
+ if (class_name->op_type == IS_CONST &&
+ Z_UNILEN(class_name->u.constant) == 0) {
+ /* Usage of namespace as class name not in namespace */
+ zval_dtor(&class_name->u.constant);
+ zend_error(E_COMPILE_ERROR, "Cannot use 'namespace' as a class name");
+ return;
+ }
+
fetch_class_op_number = get_next_op_number(CG(active_op_array));
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
}
/* }}} */
-void zend_do_begin_class_member_function_call(znode *class_name, znode *method_name TSRMLS_DC) /* {{{ */
+int zend_do_begin_class_member_function_call(znode *class_name, znode *method_name TSRMLS_DC) /* {{{ */
{
znode class_node;
unsigned char *ptr = NULL;
zend_op *opline;
ulong fetch_type = 0;
+ if (class_name->op_type == IS_CONST &&
+ Z_UNILEN(class_name->u.constant) == 0) {
+ /* namespace::func() not in namespace */
+ zval_dtor(&class_name->u.constant);
+ return zend_do_begin_function_call(method_name, 0 TSRMLS_CC);
+ }
+
if (method_name->op_type == IS_CONST) {
zstr lcname;
unsigned int lcname_len;
zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *));
zend_do_extended_fcall_begin(TSRMLS_C);
+ return 1; /* Dynamic */
}
/* }}} */
}
break;
case ZEND_RT:
+ if (constant_container &&
+ constant_container->op_type == IS_CONST &&
+ Z_UNILEN(constant_container->u.constant) == 0) {
+ /* Usage of namespace as class name not in namespace */
+ zval_dtor(&constant_container->u.constant);
+ constant_container = NULL;
+ check_namespace = 0;
+ }
+
if (constant_container ||
!zend_constant_ct_subst(result, &constant_name->u.constant TSRMLS_CC)) {
zend_op *opline;
void zend_do_begin_dynamic_function_call(znode *function_name, int prefix_len TSRMLS_DC);
void zend_do_fetch_class(znode *result, znode *class_name TSRMLS_DC);
void zend_do_fetch_class_name(znode *result, znode *class_entry, znode *class_name TSRMLS_DC);
-void zend_do_begin_class_member_function_call(znode *class_name, znode *method_name TSRMLS_DC);
+int zend_do_begin_class_member_function_call(znode *class_name, znode *method_name TSRMLS_DC);
void zend_do_end_function_call(znode *function_name, znode *result, znode *argument_list, int is_method, int is_dynamic_fcall TSRMLS_DC);
void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC);
void zend_do_handle_exception(TSRMLS_D);
| T_PAAMAYIM_NEKUDOTAYIM T_STRING '(' { $3.u.opline_num = zend_do_begin_function_call(&$2, 0 TSRMLS_CC); }
function_call_parameter_list
')' { zend_do_end_function_call(&$2, &$$, &$5, 0, $3.u.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
- | class_name T_PAAMAYIM_NEKUDOTAYIM T_STRING '(' { zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
+ | class_name T_PAAMAYIM_NEKUDOTAYIM T_STRING '(' { $4.u.opline_num = zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
function_call_parameter_list
- ')' { zend_do_end_function_call(NULL, &$$, &$6, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
+ ')' { zend_do_end_function_call($4.u.opline_num?NULL:&$3, &$$, &$6, $4.u.opline_num, $4.u.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
| variable_class_name T_PAAMAYIM_NEKUDOTAYIM T_STRING '(' { zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
function_call_parameter_list
')' { zend_do_end_function_call(NULL, &$$, &$6, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
class_name:
T_STRING { $$ = $1; }
| T_STATIC { $$.op_type = IS_CONST; ZVAL_ASCII_STRINGL(&$$.u.constant, "static", sizeof("static")-1, 1);}
+ | T_NAMESPACE {if (CG(current_namespace)) { $1.op_type = IS_CONST; $1.u.constant = *CG(current_namespace); zval_copy_ctor(&$1.u.constant); zend_do_build_namespace_name(&$$, NULL, &$1 TSRMLS_CC); } else { $$.op_type = IS_CONST; ZVAL_EMPTY_TEXT(&$$.u.constant); } }
| T_PAAMAYIM_NEKUDOTAYIM T_STRING { zend_do_build_namespace_name(&$$, NULL, &$2 TSRMLS_CC); }
| class_name T_PAAMAYIM_NEKUDOTAYIM T_STRING { zend_do_build_namespace_name(&$$, &$1, &$3 TSRMLS_CC); }
;
fully_qualified_class_name:
T_STRING { $$ = $1; }
+ | T_NAMESPACE {if (CG(current_namespace)) { $1.op_type = IS_CONST; $1.u.constant = *CG(current_namespace); zval_copy_ctor(&$1.u.constant); zend_do_build_namespace_name(&$$, NULL, &$1 TSRMLS_CC); } else { $$.op_type = IS_CONST; ZVAL_EMPTY_TEXT(&$$.u.constant); } }
| T_PAAMAYIM_NEKUDOTAYIM T_STRING { zend_do_build_namespace_name(&$$, NULL, &$2 TSRMLS_CC); }
| fully_qualified_class_name T_PAAMAYIM_NEKUDOTAYIM T_STRING { zend_do_build_namespace_name(&$$, &$1, &$3 TSRMLS_CC); }
;