Skip to content

Commit bb17d66

Browse files
committed
Drop :mixed return type on 7.4
Signed-off-by: Bob Weinand <bob.weinand@datadoghq.com>
1 parent 8fd2dca commit bb17d66

File tree

1 file changed

+42
-0
lines changed

1 file changed

+42
-0
lines changed

ext/autoload_php_files.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,41 @@ 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+
}
206+
}
207+
208+
zend_ast_process_t dd_prev_ast_process = NULL;
209+
void dd_remove_mixed_return(zend_ast *ast) {
210+
dd_walk_ast_top_stmt(ast);
211+
if (dd_prev_ast_process) {
212+
dd_prev_ast_process(ast);
213+
}
214+
}
215+
#endif
216+
182217
// We have, at this place, the luxury of knowing that we'll always be called before composers autoloader.
183218
// Note that this code will also be called during opcache.preload, allowing us to not consider that scenario separately.
184219
// The first time the autoloader gets invoked for ddtrace\\, we load the API
@@ -213,7 +248,14 @@ static zend_class_entry *dd_perform_autoload(zend_string *class_name, zend_strin
213248

214249
if ((get_DD_TRACE_OTEL_ENABLED() || get_DD_METRICS_OTEL_ENABLED()) && zend_string_starts_with_literal(lc_name, "opentelemetry\\") && !DDTRACE_G(otel_is_loaded)) {
215250
DDTRACE_G(otel_is_loaded) = 1;
251+
#if PHP_VERSION_ID >= 70400 && PHP_VERSION_ID < 80000
252+
dd_prev_ast_process = zend_ast_process;
253+
zend_ast_process = dd_remove_mixed_return;
216254
dd_load_files("opentelemetry");
255+
zend_ast_process = dd_prev_ast_process;
256+
#else
257+
dd_load_files("opentelemetry");
258+
#endif
217259
if ((ce = zend_hash_find_ptr(EG(class_table), lc_name))) {
218260
return ce;
219261
}

0 commit comments

Comments
 (0)