mirror of
https://github.com/php/php-src.git
synced 2024-11-23 18:04:36 +08:00
Move zend_verify_abstract_class() into zend_inheritance.c
This commit is contained in:
parent
02eded868c
commit
ea9628936f
@ -304,7 +304,6 @@ ZEND_API void zend_unset_timeout(void);
|
||||
ZEND_API ZEND_NORETURN void zend_timeout(int dummy);
|
||||
ZEND_API zend_class_entry *zend_fetch_class(zend_string *class_name, int fetch_type);
|
||||
ZEND_API zend_class_entry *zend_fetch_class_by_name(zend_string *class_name, zend_string *lcname, int fetch_type);
|
||||
void zend_verify_abstract_class(zend_class_entry *ce);
|
||||
|
||||
ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function(zend_string *name);
|
||||
ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function_str(const char *name, size_t len);
|
||||
|
@ -1374,65 +1374,6 @@ zend_class_entry *zend_fetch_class_by_name(zend_string *class_name, zend_string
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#define MAX_ABSTRACT_INFO_CNT 3
|
||||
#define MAX_ABSTRACT_INFO_FMT "%s%s%s%s"
|
||||
#define DISPLAY_ABSTRACT_FN(idx) \
|
||||
ai.afn[idx] ? ZEND_FN_SCOPE_NAME(ai.afn[idx]) : "", \
|
||||
ai.afn[idx] ? "::" : "", \
|
||||
ai.afn[idx] ? ZSTR_VAL(ai.afn[idx]->common.function_name) : "", \
|
||||
ai.afn[idx] && ai.afn[idx + 1] ? ", " : (ai.afn[idx] && ai.cnt > MAX_ABSTRACT_INFO_CNT ? ", ..." : "")
|
||||
|
||||
typedef struct _zend_abstract_info {
|
||||
zend_function *afn[MAX_ABSTRACT_INFO_CNT + 1];
|
||||
int cnt;
|
||||
int ctor;
|
||||
} zend_abstract_info;
|
||||
|
||||
static void zend_verify_abstract_class_function(zend_function *fn, zend_abstract_info *ai) /* {{{ */
|
||||
{
|
||||
if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) {
|
||||
if (ai->cnt < MAX_ABSTRACT_INFO_CNT) {
|
||||
ai->afn[ai->cnt] = fn;
|
||||
}
|
||||
if (fn->common.fn_flags & ZEND_ACC_CTOR) {
|
||||
if (!ai->ctor) {
|
||||
ai->cnt++;
|
||||
ai->ctor = 1;
|
||||
} else {
|
||||
ai->afn[ai->cnt] = NULL;
|
||||
}
|
||||
} else {
|
||||
ai->cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
void zend_verify_abstract_class(zend_class_entry *ce) /* {{{ */
|
||||
{
|
||||
zend_function *func;
|
||||
zend_abstract_info ai;
|
||||
|
||||
if ((ce->ce_flags & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) && !(ce->ce_flags & (ZEND_ACC_TRAIT | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))) {
|
||||
memset(&ai, 0, sizeof(ai));
|
||||
|
||||
ZEND_HASH_FOREACH_PTR(&ce->function_table, func) {
|
||||
zend_verify_abstract_class_function(func, &ai);
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
if (ai.cnt) {
|
||||
zend_error_noreturn(E_ERROR, "Class %s contains %d abstract method%s and must therefore be declared abstract or implement the remaining methods (" MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT ")",
|
||||
ZSTR_VAL(ce->name), ai.cnt,
|
||||
ai.cnt > 1 ? "s" : "",
|
||||
DISPLAY_ABSTRACT_FN(0),
|
||||
DISPLAY_ABSTRACT_FN(1),
|
||||
DISPLAY_ABSTRACT_FN(2)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API int zend_delete_global_variable(zend_string *name) /* {{{ */
|
||||
{
|
||||
return zend_hash_del_ind(&EG(symbol_table), name);
|
||||
|
@ -1891,6 +1891,65 @@ void zend_check_deprecated_constructor(const zend_class_entry *ce) /* {{{ */
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#define MAX_ABSTRACT_INFO_CNT 3
|
||||
#define MAX_ABSTRACT_INFO_FMT "%s%s%s%s"
|
||||
#define DISPLAY_ABSTRACT_FN(idx) \
|
||||
ai.afn[idx] ? ZEND_FN_SCOPE_NAME(ai.afn[idx]) : "", \
|
||||
ai.afn[idx] ? "::" : "", \
|
||||
ai.afn[idx] ? ZSTR_VAL(ai.afn[idx]->common.function_name) : "", \
|
||||
ai.afn[idx] && ai.afn[idx + 1] ? ", " : (ai.afn[idx] && ai.cnt > MAX_ABSTRACT_INFO_CNT ? ", ..." : "")
|
||||
|
||||
typedef struct _zend_abstract_info {
|
||||
zend_function *afn[MAX_ABSTRACT_INFO_CNT + 1];
|
||||
int cnt;
|
||||
int ctor;
|
||||
} zend_abstract_info;
|
||||
|
||||
static void zend_verify_abstract_class_function(zend_function *fn, zend_abstract_info *ai) /* {{{ */
|
||||
{
|
||||
if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) {
|
||||
if (ai->cnt < MAX_ABSTRACT_INFO_CNT) {
|
||||
ai->afn[ai->cnt] = fn;
|
||||
}
|
||||
if (fn->common.fn_flags & ZEND_ACC_CTOR) {
|
||||
if (!ai->ctor) {
|
||||
ai->cnt++;
|
||||
ai->ctor = 1;
|
||||
} else {
|
||||
ai->afn[ai->cnt] = NULL;
|
||||
}
|
||||
} else {
|
||||
ai->cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
void zend_verify_abstract_class(zend_class_entry *ce) /* {{{ */
|
||||
{
|
||||
zend_function *func;
|
||||
zend_abstract_info ai;
|
||||
|
||||
if ((ce->ce_flags & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) && !(ce->ce_flags & (ZEND_ACC_TRAIT | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))) {
|
||||
memset(&ai, 0, sizeof(ai));
|
||||
|
||||
ZEND_HASH_FOREACH_PTR(&ce->function_table, func) {
|
||||
zend_verify_abstract_class_function(func, &ai);
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
if (ai.cnt) {
|
||||
zend_error_noreturn(E_ERROR, "Class %s contains %d abstract method%s and must therefore be declared abstract or implement the remaining methods (" MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT ")",
|
||||
ZSTR_VAL(ce->name), ai.cnt,
|
||||
ai.cnt > 1 ? "s" : "",
|
||||
DISPLAY_ABSTRACT_FN(0),
|
||||
DISPLAY_ABSTRACT_FN(1),
|
||||
DISPLAY_ABSTRACT_FN(2)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
|
@ -31,6 +31,7 @@ ZEND_API void zend_do_implement_interfaces(zend_class_entry *ce);
|
||||
|
||||
ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent_ce);
|
||||
|
||||
void zend_verify_abstract_class(zend_class_entry *ce);
|
||||
void zend_check_deprecated_constructor(const zend_class_entry *ce);
|
||||
|
||||
END_EXTERN_C()
|
||||
|
Loading…
Reference in New Issue
Block a user