--- /dev/null
+--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
--- /dev/null
+--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
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
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
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
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
--- /dev/null
+--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
?>
==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
--- /dev/null
+--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
--- /dev/null
+--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
}
/* }}} */
+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()) {
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;
}
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);
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);
}
}
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;
}
%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
;
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:
;
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:
$$->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
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:
;
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); }
;
;
absolute_trait_method_reference:
- name T_PAAMAYIM_NEKUDOTAYIM identifier
+ class_name T_PAAMAYIM_NEKUDOTAYIM identifier
{ $$ = zend_ast_create(ZEND_AST_METHOD_REFERENCE, $1, $3); }
;