Skip to content

Commit 2b43c21

Browse files
committed
Drop :mixed return type on 7.4
Signed-off-by: Bob Weinand <[email protected]>
1 parent 8fd2dca commit 2b43c21

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

ext/autoload_php_files.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,43 @@ static void dd_load_files(const char *files_file) {
179179

180180
#define dd_load_files(file) EXPECTED(get_global_DD_AUTOLOAD_NO_COMPILE() == false) ? dd_load_file("bridge/_generated_" file) : dd_load_files("bridge/_files_" file)
181181

182+
// Remove mixed return types for PHP 7.4 support. OpenTelemetry v2 now requires ": mixed" and drops PHP 7.4, but we fixup the AST here so that OpenTelemetry v1 still works with PHP 7.4.
183+
#if PHP_VERSION_ID >= 70400 && PHP_VERSION_ID < 80000
184+
void dd_walk_ast_top_stmt(zend_ast *ast) {
185+
if (ast->kind == ZEND_AST_STMT_LIST) {
186+
zend_ast_list *list = zend_ast_get_list(ast);
187+
uint32_t i;
188+
for (i = 0; i < list->children; ++i) {
189+
dd_walk_ast_top_stmt(list->child[i]);
190+
}
191+
} else if (ast->kind == ZEND_AST_FUNC_DECL || ast->kind == ZEND_AST_METHOD) {
192+
zend_ast_decl *decl = (zend_ast_decl *) ast;
193+
zend_ast *return_type_ast = decl->child[3];
194+
if (return_type_ast && return_type_ast->kind != ZEND_AST_TYPE) {
195+
if (zend_string_equals_literal(zend_ast_get_str(return_type_ast), "mixed")) {
196+
decl->child[3] = NULL;
197+
zend_ast_destroy(return_type_ast);
198+
}
199+
}
200+
} else if (ast->kind == ZEND_AST_CLASS) {
201+
zend_ast_decl *decl = (zend_ast_decl *) ast;
202+
zend_ast *stmt_ast = decl->child[2];
203+
204+
dd_walk_ast_top_stmt(stmt_ast);
205+
} else if (ast->kind == ZEND_AST_NAMESPACE && ast->child[1]) {
206+
dd_walk_ast_top_stmt(ast->child[1]);
207+
}
208+
}
209+
210+
zend_ast_process_t dd_prev_ast_process = NULL;
211+
void dd_remove_mixed_return(zend_ast *ast) {
212+
dd_walk_ast_top_stmt(ast);
213+
if (dd_prev_ast_process) {
214+
dd_prev_ast_process(ast);
215+
}
216+
}
217+
#endif
218+
182219
// We have, at this place, the luxury of knowing that we'll always be called before composers autoloader.
183220
// Note that this code will also be called during opcache.preload, allowing us to not consider that scenario separately.
184221
// The first time the autoloader gets invoked for ddtrace\\, we load the API
@@ -213,7 +250,14 @@ static zend_class_entry *dd_perform_autoload(zend_string *class_name, zend_strin
213250

214251
if ((get_DD_TRACE_OTEL_ENABLED() || get_DD_METRICS_OTEL_ENABLED()) && zend_string_starts_with_literal(lc_name, "opentelemetry\\") && !DDTRACE_G(otel_is_loaded)) {
215252
DDTRACE_G(otel_is_loaded) = 1;
253+
#if PHP_VERSION_ID >= 70400 && PHP_VERSION_ID < 80000
254+
dd_prev_ast_process = zend_ast_process;
255+
zend_ast_process = dd_remove_mixed_return;
216256
dd_load_files("opentelemetry");
257+
zend_ast_process = dd_prev_ast_process;
258+
#else
259+
dd_load_files("opentelemetry");
260+
#endif
217261
if ((ce = zend_hash_find_ptr(EG(class_table), lc_name))) {
218262
return ce;
219263
}

0 commit comments

Comments
 (0)