mirror of
https://github.com/php/php-src.git
synced 2024-09-21 09:57:23 +00:00
Added support for "namespace::" prefix that is resolved to current namespace name.
This commit is contained in:
parent
b51708cdf4
commit
9f230a0d79
@ -9,4 +9,4 @@ class Foo extends static {
|
||||
?>
|
||||
==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
|
||||
|
@ -9,4 +9,4 @@ class Foo implements static {
|
||||
?>
|
||||
==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
|
||||
|
56
Zend/tests/ns_057.phpt
Executable file
56
Zend/tests/ns_057.phpt
Executable file
@ -0,0 +1,56 @@
|
||||
--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
|
54
Zend/tests/ns_058.phpt
Executable file
54
Zend/tests/ns_058.phpt
Executable file
@ -0,0 +1,54 @@
|
||||
--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
|
@ -1303,6 +1303,14 @@ void zend_do_receive_arg(zend_uchar op, znode *var, znode *offset, znode *initia
|
||||
zend_op *opline;
|
||||
zend_arg_info *cur_arg_info;
|
||||
|
||||
if (class_type->op_type == IS_CONST &&
|
||||
Z_STRLEN(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) &&
|
||||
@ -1568,6 +1576,14 @@ void zend_do_fetch_class(znode *result, znode *class_name TSRMLS_DC)
|
||||
long fetch_class_op_number;
|
||||
zend_op *opline;
|
||||
|
||||
if (class_name->op_type == IS_CONST &&
|
||||
Z_STRLEN(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);
|
||||
|
||||
@ -1620,13 +1636,20 @@ void zend_do_fetch_class_name(znode *result, znode *class_name_entry, znode *cla
|
||||
result->u.constant.value.str.len = length;
|
||||
}
|
||||
|
||||
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_STRLEN(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) {
|
||||
char *lcname = zend_str_tolower_dup(Z_STRVAL(method_name->u.constant), Z_STRLEN(method_name->u.constant));
|
||||
if ((sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1) == Z_STRLEN(method_name->u.constant) &&
|
||||
@ -1689,6 +1712,7 @@ void zend_do_begin_class_member_function_call(znode *class_name, znode *method_n
|
||||
|
||||
zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *));
|
||||
zend_do_extended_fcall_begin(TSRMLS_C);
|
||||
return 1; /* Dynamic */
|
||||
}
|
||||
|
||||
|
||||
@ -3524,6 +3548,15 @@ void zend_do_fetch_constant(znode *result, znode *constant_container, znode *con
|
||||
}
|
||||
break;
|
||||
case ZEND_RT:
|
||||
if (constant_container &&
|
||||
constant_container->op_type == IS_CONST &&
|
||||
Z_STRLEN(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;
|
||||
|
@ -404,7 +404,7 @@ void zend_do_clone(znode *result, znode *expr TSRMLS_DC);
|
||||
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);
|
||||
|
@ -634,9 +634,9 @@ function_call:
|
||||
| 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);}
|
||||
| class_name T_PAAMAYIM_NEKUDOTAYIM variable_without_objects '(' { zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC); 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);}
|
||||
@ -654,12 +654,14 @@ function_call:
|
||||
class_name:
|
||||
T_STRING { $$ = $1; }
|
||||
| T_STATIC { $$.op_type = IS_CONST; ZVAL_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_STRING(&$$.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_STRING(&$$.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); }
|
||||
;
|
||||
|
Loading…
Reference in New Issue
Block a user