}
/* }}} */
+static uint32_t zend_get_class_fetch_type_ast(zend_ast *name_ast) /* {{{ */
+{
+ /* Fully qualified names are always default refs */
+ if (name_ast->attr == ZEND_NAME_FQ) {
+ return ZEND_FETCH_CLASS_DEFAULT;
+ }
+
+ return zend_get_class_fetch_type(zend_ast_get_str(name_ast));
+}
+/* }}} */
+
+void zend_ensure_valid_class_fetch_type(uint32_t fetch_type) /* {{{ */
+{
+ if (fetch_type != ZEND_FETCH_CLASS_DEFAULT && !CG(active_class_entry)) {
+ zend_error_noreturn(E_COMPILE_ERROR, "Cannot use \"%s\" when no class scope is active",
+ fetch_type == ZEND_FETCH_CLASS_SELF ? "self" :
+ fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static");
+ }
+}
+/* }}} */
+
ZEND_API zend_string *zend_get_compiled_variable_name(const zend_op_array *op_array, uint32_t var) /* {{{ */
{
return op_array->vars[EX_VAR_TO_NUM(var)];
static inline zend_bool zend_is_const_default_class_ref(zend_ast *name_ast) /* {{{ */
{
- zend_string *name;
-
if (name_ast->kind != ZEND_AST_ZVAL) {
return 0;
}
- /* Fully qualified names are always default refs */
- if (!name_ast->attr) {
- return 1;
- }
-
- name = zend_ast_get_str(name_ast);
- return ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type(name);
+ return ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type_ast(name_ast);
}
/* }}} */
opline->op2_type = IS_CONST;
opline->op2.constant = zend_add_class_name_literal(CG(active_op_array),
zend_resolve_class_name(name, type));
+ } else {
+ zend_ensure_valid_class_fetch_type(fetch_type);
}
zend_string_release(name);
}
/* }}} */
-void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, zend_bool is_method) /* {{{ */
+void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */
{
zend_ast_list *list = zend_ast_get_list(ast);
uint32_t i;
if (type != 0) {
arg_infos->type_hint = type;
} else {
- if (zend_is_const_default_class_ref(return_type_ast)) {
+ uint32_t fetch_type = zend_get_class_fetch_type_ast(return_type_ast);
+ if (fetch_type == ZEND_FETCH_CLASS_DEFAULT) {
class_name = zend_resolve_class_name_ast(return_type_ast);
zend_assert_valid_class_name(class_name);
} else {
+ zend_ensure_valid_class_fetch_type(fetch_type);
zend_string_addref(class_name);
- if (!is_method) {
- zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare a return type of %s outside of a class scope", class_name->val);
- return;
- }
}
arg_infos->type_hint = IS_OBJECT;
if (type != 0) {
arg_info->type_hint = type;
} else {
- if (zend_is_const_default_class_ref(type_ast)) {
+ uint32_t fetch_type = zend_get_class_fetch_type_ast(type_ast);
+ if (fetch_type == ZEND_FETCH_CLASS_DEFAULT) {
class_name = zend_resolve_class_name_ast(type_ast);
zend_assert_valid_class_name(class_name);
} else {
+ zend_ensure_valid_class_fetch_type(fetch_type);
zend_string_addref(class_name);
}
zend_stack_push(&CG(loop_var_stack), (void *) &dummy_var);
}
- zend_compile_params(params_ast, return_type_ast, is_method);
+ zend_compile_params(params_ast, return_type_ast);
if (uses_ast) {
zend_compile_closure_uses(uses_ast);
}
{
zend_ast *name_ast = ast->child[0];
uint32_t fetch_type = zend_get_class_fetch_type(zend_ast_get_str(name_ast));
+ zend_ensure_valid_class_fetch_type(fetch_type);
switch (fetch_type) {
case ZEND_FETCH_CLASS_SELF:
- if (!CG(active_class_entry)) {
- zend_error_noreturn(E_COMPILE_ERROR,
- "Cannot access self::class when no class scope is active");
- }
if (CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) {
zval class_str_zv;
zend_ast *class_str_ast, *class_const_ast;
break;
case ZEND_FETCH_CLASS_STATIC:
case ZEND_FETCH_CLASS_PARENT:
- if (!CG(active_class_entry)) {
- zend_error_noreturn(E_COMPILE_ERROR,
- "Cannot access %s::class when no class scope is active",
- fetch_type == ZEND_FETCH_CLASS_STATIC ? "static" : "parent");
- } else {
+ {
zval class_str_zv;
zend_ast *class_str_ast, *class_const_ast;
{
zend_ast *ast = *ast_ptr;
zend_ast *name_ast = ast->child[0];
- uint32_t fetch_type = zend_get_class_fetch_type(zend_ast_get_str(name_ast));
zval result;
+ uint32_t fetch_type = zend_get_class_fetch_type(zend_ast_get_str(name_ast));
+ zend_ensure_valid_class_fetch_type(fetch_type);
switch (fetch_type) {
case ZEND_FETCH_CLASS_SELF:
- if (!CG(active_class_entry)) {
- zend_error_noreturn(E_COMPILE_ERROR,
- "Cannot access self::class when no class scope is active");
- }
ZVAL_STR_COPY(&result, CG(active_class_entry)->name);
break;
case ZEND_FETCH_CLASS_STATIC: