mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Make class name references use the class_name production
Throw a compile error for "static" references instead, where it isn't already the case. Also extract the code that does that -- we have quite a few places where we get a const class ref and require it to be default.
This commit is contained in:
17
Zend/tests/catch_static.phpt
Normal file
17
Zend/tests/catch_static.phpt
Normal file
@@ -0,0 +1,17 @@
|
||||
--TEST--
|
||||
Cannot catch "static"
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
// This could in principle be supported, but isn't right now.
|
||||
class Test {
|
||||
public function method() {
|
||||
try {
|
||||
foo();
|
||||
} catch (static $e) {}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Bad class name in the catch statement in %s on line %d
|
||||
12
Zend/tests/class_uses_static.phpt
Normal file
12
Zend/tests/class_uses_static.phpt
Normal file
@@ -0,0 +1,12 @@
|
||||
--TEST--
|
||||
Class cannot use static as a trait, as it is reserved
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Test {
|
||||
use static;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot use 'static' as trait name as it is reserved in %s on line %d
|
||||
@@ -9,4 +9,4 @@ class test extends self {
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot use 'self' as class name as it is reserved in %s on line %d
|
||||
Fatal error: Cannot use 'self' as class name, as it is reserved in %s on line %d
|
||||
|
||||
@@ -9,4 +9,4 @@ class test extends parent {
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot use 'parent' as class name as it is reserved in %s on line %d
|
||||
Fatal error: Cannot use 'parent' as class name, as it is reserved in %s on line %d
|
||||
|
||||
@@ -9,4 +9,4 @@ class test implements self {
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot use 'self' as interface name as it is reserved in %s on line %d
|
||||
Fatal error: Cannot use 'self' as interface name, as it is reserved in %s on line %d
|
||||
|
||||
@@ -9,4 +9,4 @@ class test implements parent {
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot use 'parent' as interface name as it is reserved in %s on line %d
|
||||
Fatal error: Cannot use 'parent' as interface name, as it is reserved in %s on line %d
|
||||
|
||||
10
Zend/tests/interface_extends_static.phpt
Normal file
10
Zend/tests/interface_extends_static.phpt
Normal file
@@ -0,0 +1,10 @@
|
||||
--TEST--
|
||||
Interface cannot extend static, as it is reserved
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
interface Foo extends static {}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot use 'static' as interface name, as it is reserved in %s on line %d
|
||||
@@ -9,4 +9,4 @@ class Foo implements static {
|
||||
?>
|
||||
==DONE==
|
||||
--EXPECTF--
|
||||
Parse error: %s error,%sexpecting %s in %s on line %d
|
||||
Fatal error: Cannot use 'static' as interface name, as it is reserved in %s on line %d
|
||||
|
||||
18
Zend/tests/static_in_trait_insteadof_list.phpt
Normal file
18
Zend/tests/static_in_trait_insteadof_list.phpt
Normal file
@@ -0,0 +1,18 @@
|
||||
--TEST--
|
||||
Cannot use static in trait insteadof list
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
trait SomeTrait {
|
||||
public function foobar() {}
|
||||
}
|
||||
|
||||
class Test {
|
||||
use SomeTrait {
|
||||
SomeTrait::foobar insteadof static;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot use 'static' as trait name, as it is reserved in %s on line %d
|
||||
18
Zend/tests/static_in_trait_insteadof_reference.phpt
Normal file
18
Zend/tests/static_in_trait_insteadof_reference.phpt
Normal file
@@ -0,0 +1,18 @@
|
||||
--TEST--
|
||||
Cannot use static in trait insteadof method reference
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
trait SomeTrait {
|
||||
public function foobar() {}
|
||||
}
|
||||
|
||||
class Test {
|
||||
use SomeTrait {
|
||||
static::foobar insteadof SomeTrait;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot use 'static' as trait name, as it is reserved in %s on line %d
|
||||
@@ -1498,6 +1498,17 @@ static uint32_t zend_get_class_fetch_type_ast(zend_ast *name_ast) /* {{{ */
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_string *zend_resolve_const_class_name_reference(zend_ast *ast, const char *type)
|
||||
{
|
||||
zend_string *class_name = zend_ast_get_str(ast);
|
||||
if (ZEND_FETCH_CLASS_DEFAULT != zend_get_class_fetch_type_ast(ast)) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR,
|
||||
"Cannot use '%s' as %s, as it is reserved",
|
||||
ZSTR_VAL(class_name), type);
|
||||
}
|
||||
return zend_resolve_class_name(class_name, ast->attr);
|
||||
}
|
||||
|
||||
static void zend_ensure_valid_class_fetch_type(uint32_t fetch_type) /* {{{ */
|
||||
{
|
||||
if (fetch_type != ZEND_FETCH_CLASS_DEFAULT && zend_is_scope_known()) {
|
||||
@@ -6399,7 +6410,7 @@ static void zend_compile_method_ref(zend_ast *ast, zend_trait_method_reference *
|
||||
method_ref->method_name = zend_string_copy(zend_ast_get_str(method_ast));
|
||||
|
||||
if (class_ast) {
|
||||
method_ref->class_name = zend_resolve_class_name_ast(class_ast);
|
||||
method_ref->class_name = zend_resolve_const_class_name_reference(class_ast, "trait name");
|
||||
} else {
|
||||
method_ref->class_name = NULL;
|
||||
}
|
||||
@@ -6419,7 +6430,8 @@ static void zend_compile_trait_precedence(zend_ast *ast) /* {{{ */
|
||||
|
||||
for (i = 0; i < insteadof_list->children; ++i) {
|
||||
zend_ast *name_ast = insteadof_list->child[i];
|
||||
precedence->exclude_class_names[i] = zend_resolve_class_name_ast(name_ast);
|
||||
precedence->exclude_class_names[i] =
|
||||
zend_resolve_const_class_name_reference(name_ast, "trait name");
|
||||
}
|
||||
|
||||
zend_add_to_list(&CG(active_class_entry)->trait_precedences, precedence);
|
||||
@@ -6513,15 +6525,8 @@ void zend_compile_implements(zend_ast *ast) /* {{{ */
|
||||
|
||||
for (i = 0; i < list->children; ++i) {
|
||||
zend_ast *class_ast = list->child[i];
|
||||
zend_string *name = zend_ast_get_str(class_ast);
|
||||
|
||||
if (!zend_is_const_default_class_ref(class_ast)) {
|
||||
efree(interface_names);
|
||||
zend_error_noreturn(E_COMPILE_ERROR,
|
||||
"Cannot use '%s' as interface name as it is reserved", ZSTR_VAL(name));
|
||||
}
|
||||
|
||||
interface_names[i].name = zend_resolve_class_name_ast(class_ast);
|
||||
interface_names[i].name =
|
||||
zend_resolve_const_class_name_reference(class_ast, "interface name");
|
||||
interface_names[i].lc_name = zend_string_tolower(interface_names[i].name);
|
||||
}
|
||||
|
||||
@@ -6605,23 +6610,8 @@ zend_op *zend_compile_class_decl(zend_ast *ast, zend_bool toplevel) /* {{{ */
|
||||
}
|
||||
|
||||
if (extends_ast) {
|
||||
znode extends_node;
|
||||
zend_string *extends_name;
|
||||
|
||||
if (!zend_is_const_default_class_ref(extends_ast)) {
|
||||
extends_name = zend_ast_get_str(extends_ast);
|
||||
zend_error_noreturn(E_COMPILE_ERROR,
|
||||
"Cannot use '%s' as class name as it is reserved", ZSTR_VAL(extends_name));
|
||||
}
|
||||
|
||||
zend_compile_expr(&extends_node, extends_ast);
|
||||
if (extends_node.op_type != IS_CONST || Z_TYPE(extends_node.u.constant) != IS_STRING) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Illegal class name");
|
||||
}
|
||||
extends_name = Z_STR(extends_node.u.constant);
|
||||
ce->parent_name = zend_resolve_class_name(extends_name,
|
||||
extends_ast->kind == ZEND_AST_ZVAL ? extends_ast->attr : ZEND_NAME_FQ);
|
||||
zend_string_release_ex(extends_name, 0);
|
||||
ce->parent_name =
|
||||
zend_resolve_const_class_name_reference(extends_ast, "class name");
|
||||
ce->ce_flags |= ZEND_ACC_INHERITED;
|
||||
}
|
||||
|
||||
|
||||
@@ -249,7 +249,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
|
||||
%type <ast> echo_expr_list unset_variables catch_name_list catch_list parameter_list class_statement_list
|
||||
%type <ast> implements_list case_list if_stmt_without_else
|
||||
%type <ast> non_empty_parameter_list argument_list non_empty_argument_list property_list
|
||||
%type <ast> class_const_list class_const_decl name_list trait_adaptations method_body non_empty_for_exprs
|
||||
%type <ast> class_const_list class_const_decl class_name_list trait_adaptations method_body non_empty_for_exprs
|
||||
%type <ast> ctor_arguments alt_if_stmt_without_else trait_adaptation_list lexical_vars
|
||||
%type <ast> lexical_var_list encaps_list
|
||||
%type <ast> array_pair non_empty_array_pair_list array_pair_list possible_array_pair
|
||||
@@ -469,8 +469,8 @@ catch_list:
|
||||
;
|
||||
|
||||
catch_name_list:
|
||||
name { $$ = zend_ast_create_list(1, ZEND_AST_NAME_LIST, $1); }
|
||||
| catch_name_list '|' name { $$ = zend_ast_list_add($1, $3); }
|
||||
class_name { $$ = zend_ast_create_list(1, ZEND_AST_NAME_LIST, $1); }
|
||||
| catch_name_list '|' class_name { $$ = zend_ast_list_add($1, $3); }
|
||||
;
|
||||
|
||||
finally_statement:
|
||||
@@ -542,13 +542,13 @@ extends_from:
|
||||
;
|
||||
|
||||
interface_extends_list:
|
||||
/* empty */ { $$ = NULL; }
|
||||
| T_EXTENDS name_list { $$ = $2; }
|
||||
/* empty */ { $$ = NULL; }
|
||||
| T_EXTENDS class_name_list { $$ = $2; }
|
||||
;
|
||||
|
||||
implements_list:
|
||||
/* empty */ { $$ = NULL; }
|
||||
| T_IMPLEMENTS name_list { $$ = $2; }
|
||||
/* empty */ { $$ = NULL; }
|
||||
| T_IMPLEMENTS class_name_list { $$ = $2; }
|
||||
;
|
||||
|
||||
foreach_variable:
|
||||
@@ -732,7 +732,7 @@ class_statement:
|
||||
$$->attr = $1; }
|
||||
| method_modifiers T_CONST class_const_list ';'
|
||||
{ $$ = $3; $$->attr = $1; }
|
||||
| T_USE name_list trait_adaptations
|
||||
| T_USE class_name_list trait_adaptations
|
||||
{ $$ = zend_ast_create(ZEND_AST_USE_TRAIT, $2, $3); }
|
||||
| method_modifiers function returns_ref identifier backup_doc_comment '(' parameter_list ')'
|
||||
return_type backup_fn_flags method_body backup_fn_flags
|
||||
@@ -740,9 +740,9 @@ class_statement:
|
||||
zend_ast_get_str($4), $7, NULL, $11, $9); CG(extra_fn_flags) = $10; }
|
||||
;
|
||||
|
||||
name_list:
|
||||
name { $$ = zend_ast_create_list(1, ZEND_AST_NAME_LIST, $1); }
|
||||
| name_list ',' name { $$ = zend_ast_list_add($1, $3); }
|
||||
class_name_list:
|
||||
class_name { $$ = zend_ast_create_list(1, ZEND_AST_NAME_LIST, $1); }
|
||||
| class_name_list ',' class_name { $$ = zend_ast_list_add($1, $3); }
|
||||
;
|
||||
|
||||
trait_adaptations:
|
||||
@@ -764,7 +764,7 @@ trait_adaptation:
|
||||
;
|
||||
|
||||
trait_precedence:
|
||||
absolute_trait_method_reference T_INSTEADOF name_list
|
||||
absolute_trait_method_reference T_INSTEADOF class_name_list
|
||||
{ $$ = zend_ast_create(ZEND_AST_TRAIT_PRECEDENCE, $1, $3); }
|
||||
;
|
||||
|
||||
@@ -786,7 +786,7 @@ trait_method_reference:
|
||||
;
|
||||
|
||||
absolute_trait_method_reference:
|
||||
name T_PAAMAYIM_NEKUDOTAYIM identifier
|
||||
class_name T_PAAMAYIM_NEKUDOTAYIM identifier
|
||||
{ $$ = zend_ast_create(ZEND_AST_METHOD_REFERENCE, $1, $3); }
|
||||
;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user