diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2020-02-06 11:13:13 +0100 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2020-02-17 12:21:33 +0100 |
commit | 72bd55902d1908857f47555ad69458861e1acd94 (patch) | |
tree | 3e54bf617776657ae9a7ae9a8b357798dfab2cb0 /Zend/zend_compile.c | |
parent | 43443857b74503246ee4ca25859b302ed0ebc078 (diff) | |
download | php-git-72bd55902d1908857f47555ad69458861e1acd94.tar.gz |
Improve generated names for anonymous classes
In order of preference, the generated name will be:
new class extends ParentClass {};
// -> ParentClass@anonymous
new class implements FirstInterface, SecondInterface {};
// -> FirstInterface@anonymous
new class {};
// -> class@anonymous
This is intended to display a more useful class name in error messages
and stack traces, and thus make debugging easier.
Closes GH-5153.
Diffstat (limited to 'Zend/zend_compile.c')
-rw-r--r-- | Zend/zend_compile.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 58fb3377d2..bc0a7dfdae 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -6569,14 +6569,25 @@ void zend_compile_implements(zend_ast *ast) /* {{{ */ } /* }}} */ -static zend_string *zend_generate_anon_class_name(uint32_t start_lineno) /* {{{ */ +static zend_string *zend_generate_anon_class_name(zend_ast_decl *decl) { zend_string *filename = CG(active_op_array)->filename; - zend_string *result = zend_strpprintf(0, "class@anonymous%c%s:%" PRIu32 "$%" PRIx32, - '\0', ZSTR_VAL(filename), start_lineno, CG(rtd_key_counter)++); + uint32_t start_lineno = decl->start_lineno; + + /* Use parent or first interface as prefix. */ + zend_string *prefix = ZSTR_KNOWN(ZEND_STR_CLASS); + if (decl->child[0]) { + prefix = zend_resolve_const_class_name_reference(decl->child[0], "class name"); + } else if (decl->child[1]) { + zend_ast_list *list = zend_ast_get_list(decl->child[1]); + prefix = zend_resolve_const_class_name_reference(list->child[0], "interface name"); + } + + zend_string *result = zend_strpprintf(0, "%s@anonymous%c%s:%" PRIu32 "$%" PRIx32, + ZSTR_VAL(prefix), '\0', ZSTR_VAL(filename), start_lineno, CG(rtd_key_counter)++); + zend_string_release(prefix); return zend_new_interned_string(result); } -/* }}} */ zend_op *zend_compile_class_decl(zend_ast *ast, zend_bool toplevel) /* {{{ */ { @@ -6613,7 +6624,7 @@ zend_op *zend_compile_class_decl(zend_ast *ast, zend_bool toplevel) /* {{{ */ zend_register_seen_symbol(lcname, ZEND_SYMBOL_CLASS); } else { - name = zend_generate_anon_class_name(decl->start_lineno); + name = zend_generate_anon_class_name(decl); lcname = zend_string_tolower(name); } lcname = zend_new_interned_string(lcname); |