Mago 1.0.0-beta.5
- The Correctness Update
This is a landmark release focused entirely on the correctness and reliability of our expression parser and formatter. After extensive testing, we discovered that the root cause of many formatting bugs was not the formatter itself, but subtle inaccuracies in the parser's operator precedence rules. An incorrect Abstract Syntax Tree (AST) will always lead to incorrect formatting.
This version fundamentally addresses these issues, ensuring that Mago handles even the most complex PHP expressions with perfect accuracy. For end-users, this is a stability and bug-fix release.
🚀 Major Feature: Complete Parser and Formatter Overhaul
Note for library consumers: This release introduces breaking changes to the mago_syntax
AST, most notably the removal of BinaryOperator::Elvis
in favor of a unified Conditional
node. For end-users of the formatter tool, these changes manifest as critical bug fixes that make formatting safer and more reliable.
This release overhauls the entire expression parsing and formatting pipeline to be 100% compatible with nikic/php-parser
, the de-facto standard for PHP AST generation.
Key Improvements:
-
Parser Overhaul for PHP Compatibility: The operator precedence and associativity tables have been completely re-architected. This fixes dozens of bugs related to how logical operators (
and
,||
), assignment (=
,&=
), unary operators (@
,&
,++
), and ternaries interact. The parser now produces a semantically correct AST for all expressions. -
Unified Ternary/Elvis AST: The
?:
(Elvis) operator is no longer a unique binary operator in the AST. Both?:
and the full ternary (? :
) are now correctly represented by a singleConditional
node. This simplifies the AST, aligns our tooling with the broader PHP ecosystem, and makes analysis logic more robust. -
Smarter Parenthesis Formatting: With a guaranteed-correct AST, the formatter's parenthesis logic has been rewritten from the ground up. It now operates on two principles:
- Correctness: It surgically adds parentheses when they are semantically required to preserve the original code's logic.
- Clarity: It intelligently adds clarifying parentheses in complex expressions that mix different operator types (e.g., arithmetic inside logical statements, or different bitwise operators together). This improves readability and prevents subtle bugs, even when the parentheses are not strictly required by PHP's precedence rules.
All other truly redundant parentheses are confidently removed for the cleanest possible output.
-
Massive New Test Suite: To validate these foundational changes, we have integrated a new test suite of 100s of programmatically-generated expressions. We now verify our parser's output directly against
nikic/php-parser
's output, guaranteeing a 1:1 match in AST structure and ensuring these bugs will not return. -
Improved Inlining Logic: A subtle but important bug in how the formatter handles chains of inlined binary expressions has been fixed, resulting in cleaner and more consistent output.
This is the most significant step we have ever taken to guarantee the reliability of the formatter. You can now format your code with confidence, knowing that its behavior will not be altered.
Acknowledgements
A special thanks goes to @bendavies, who reported a critical bug on our Discord server. His report on an incorrect parenthesis issue with ($value = &$data[$field->getName()]) ?? null;
was the spark that initiated this deep investigation, ultimately leading to the discovery and resolution of dozens of underlying parser bugs.
We're incredibly grateful for community contributions like this that make Mago better. Join the conversation and help us find the next bug on Discord: https://discord.gg/mwyyjr27eu
Full Changelog: 1.0.0-beta.4...1.0.0-beta.5