Idea: Expose array of E_COMPILE_WARNINGs encountered during parsing
TysonAndre opened this issue · 3 comments
Alternately, look into making it possible for user callbacks to handle E_COMPILE_WARNINGs in php 8.
It's possible to get the most recent error with error_clear_last()/error_get_last(), but it's not possible to get the full list of warnings.
- So if a user wants to suppress the last compile warning in the file in an application using php-ast, other compile warnings currently might get introduced unnoticed. This is hopefully a rare occurrence.
The global variable zend_error_cb
can be overridden by extensions. It should be able to add values to an output reference array, if one is provided (this functionality would also be nice for token_get_all()
to have in the future).
This idea will probably have issues if used in combination with PECL threading extensions.
- Before parsing the code, copy the old error handler and set the new error handler.
The new error handler will call the old error handler fortype != E_COMPILE_WARNING~, and append to the reference array for
type == E_COMPILE_WARNING` without calling the old error handler. - Parse the code
ext/soap/soap.c
586: zend_error_cb = old_error_handler;
791: old_error_handler = zend_error_cb;
792: zend_error_cb = soap_error_handler;
#define call_old_error_handler(error_num, error_filename, error_lineno, format, args) \
{ \
va_list copy; \
va_copy(copy, args); \
old_error_handler(error_num, error_filename, error_lineno, format, copy); \
va_end(copy); \
}
In php-src itself: I'm also fuzzy on why E_DEPRECATED can be emitted during parsing and will be handled by user callbacks, but E_COMPILE_WARNING is considered unsafe to use with user callbacks. Calling user callbacks (set_error_handler
) for both of these seem like they would be emitted during tokenization (in Zend/zend_language_scanner.l), which would be equally safe/unsafe.
var_export(ast\parse_code('<?php $x = (real)$y;', 70));
Deprecated: The (real) cast is deprecated, use (float) instead in string code on line 1
ast\Node::__set_state(array(
Also, this behavior was introduced in 2000, and there have been improvements to the engine (e.g. the Error
class) since then. php/php-src@b80b8381d4c#diff-b09edfedd835ebc4491e565c147190e7R559
I reported https://bugs.php.net/bug.php?id=78537 for the first proposal. I'm not sure which considerations are still an issue.
It doesn't seem like E_DEPRECATED getting emitted when parsing causes any obvious crashes if the user error handler throws
php > set_error_handler(function ($errno, $errstr) { echo "Will throw $errno $errstr\n"; throw new Exception("throwing $errstr"); });
php > token_get_all('<?php if (false) {$x = (real)(real)3;
php ' $y = (real)"2";}', TOKEN_PARSE);
Will throw 8192 The (real) cast is deprecated, use (float) instead
Warning: Uncaught Exception: throwing The (real) cast is deprecated, use (float) instead in php shell code:1
Stack trace:
#0 [internal function]: {closure}(8192, 'The (real) cast...', '', 1, Array)
#1 php shell code(2): token_get_all('<?php if (false...', 1)
#2 {main}
thrown in php shell code on line 1
The PR 4758 for php-src makes this obsolete.