Mago 1.40.0
Mago 1.40.0
A big release driven by community reports: three new formatter settings, a new suspicious-explode-arguments linter rule and a final-controller auto-fix, an inspect-baseline CLI command, a Composer-shipped editor schema, and a long list of analyzer, codex, prelude, and PHP-parity syntax fixes. Under the hood, the 2.0 groundwork landed on main: a new high-level IR, a unified mago-phpdoc-syntax, and new mago-allocator/mago-flags crates.
✨ Features
Analyzer
array_filtertruthiness: a callback-lessarray_filter()narrows values to their truthy form. (#1990, bc9bede)
Formatter
- Breaking binary expressions:
preserve_breaking_binary_expressionkeeps author line breaks in such chains. (#1853, 5aacc7d) - Sort uses by length: optional sorting of
usestatements by length. (#1942, 0688859) - Tag +
declare: optionally combine the opening tag anddeclare(strict_types=1)onto one line. (#1959, 2ff4cf5)
Linter
suspicious-explode-arguments: warns whenexplode's short literal looks swapped into the string position. (#1998, 577d40a)final-controllerfix: offers an auto-fix that insertsfinalbefore any modifier. (#2006, 82017a0)sensitive-parameter: skips boolean-like parameters. (#1949, 2333626)
Type System
CLI
Composer
- Editor schema: ships a version-matched
schema.jsonundervendor/carthage-software/mago/. (#1899, 38b78d0)
Nix
🐛 Bug Fixes
Analyzer
- Named args + optional params:
too-few-argumentsfires when a named arg fills only an optional param. (#2004, c5ec4ef) - Conditional array shapes: double-quoted array-access keys reconcile like single-quoted ones. (#2005, 095badf)
- Shadowed overrides: no false
incompatible-return-typeagainst an ancestor hidden by an intermediate override. (#1996, 431ff97) $thiscalls: a property keeps its declared type instead of widening tomixed. (#1994, 5eef024)- Readonly narrowing: readonly property narrowings survive a call passing an object argument. (#1993, 5cbbe91)
foreachover unions: corrected always-entered inference, fixing a falseimpossible-condition. (#1986, 22951bd)- Compound conditions: avoid duplicate diagnostics in compound conditions. (#1961, 1ea5ba2)
@propertytraits: trait property conflicts are no longer reported against@propertytags. (#1964, a5f3823)
Codex
- Self-cased display:
self/static/parentresolve to the original-cased class name in diagnostics. (#1995, b544222) - Closure
instanceof: closures are treated as instances ofClosure. (#1956, 6fe1bbd) - Callable variance:
nullis no longer ignored in contravariant callable parameter checks. (#1966, 3f94734)
Linter
- String-concat chains: a whole chain collapses into one
no-redundant-string-concatissue and fix. (#2003, f8a31f8) no-dead-store: flags stores overwritten across a conditional branch. (#1999, a315465)no-boolean-flag: only flags boolean parameters actually used as flags. (#1988, 50cdd11)prefer-early-continue: the auto-fix preserves comments and indentation. (#1946, 495f639)
Syntax
- Operator precedence: corrected
clone/cast/unary precedence and boundprint/yieldaboveand/xor/or. (1ac37b0, 4d01d2d) - String interpolation: distinguishes
${label}/${ expr }and$a[offset]forms in the lexer. (b56a704, f3198c8) - Reference operands: relational stays above equality when a reference assignment is an operand. (ea6cbce)
- Unicode escapes:
\u{...}decodes to UTF-8 bytes to match Zend. (b19386c)
HIR
- Integer literals: lowered with PHP long semantics, overflowing to
float. (9014c33, 79a7600) - Anonymous classes: anonymous-class modifiers are now lowered. (797358f)
Docblock
Prelude
phpversion():$extensionis optional. (#1950, 5aed5bf)array_splice: preserves the element type in its return. (#1982, af4e647)- PCRE/mbstring stubs: corrected
preg_match_all/preg_replace_callback_arrayandmb_ordstubs. (#1980, 958a4b7; #1981, dd0b80c) - Default values: added to
ZipArchive::addEmptyDir,xml_parser_create,ini_get_all, and more. (#1967, 6c640d9; #1969, 054651d) - Precise types:
base64_encodereturnsnon-empty-string; tighter stdlib types. (#1974, c2c37f5; #1975, c7e595f) - Falsable returns:
mb_chr/mb_ordandReflectionClass::getReflectionConstant. (578e427, 327778a)
📖 Documentation
🏗️ Internal
Architecture
- High-level IR: new
mago-hircrate lowering the CST to a high-level IR (2.0 groundwork). (ca15f9d, e32d0d8, afefad6) - PHPDoc unification: codex/analyzer/linter scan docblocks via
mago-phpdoc-syntax, retiring two crates. (#1932, #1972, 70179ec) - New crates:
mago-allocator(+CopyInto) andmago-flags. (#1957, 0adfdc0, 9a4cd06) - Lexer heredoc: heredoc/nowdoc resolved in the lexer with indentation as trivia. (0e4c0e6)
ast→cst: renamed AST to CST across the workspace. (#1933, b7d64b6)
Dependencies
- Slimmer deps:
serdeis now optional/off-by-default; droppedcruet,ustr,shell-words. (1751bae, 184c493, ec8e092)
CI / Tooling
- Toolchain: routine pinned-nightly bumps. (#2002, #2000, #1997)
- Miri & fuzzing: skip deep-nesting overflow tests under Miri; fix fuzz-target
Arenaimport. (676e1a4, #1984, 92d29cd)
🙏 Thank You
Contributors
A huge thank you to everyone who contributed code to this release:
- @Soean: #1951, #1967, #1969, #1980, #1981, #1983, #1984, #1987
- @mvanhorn: #1962, #1977
- @dotdash: #1961, #1964
- @SpectralFlame: #1955
- @nhedger: #1953
- @Zuruuh: #1974
- @gsteel: #1975
- @Ocramius: #1970
- @vjsai: #1991
Issue Reporters
Thank you to everyone who reported issues that shaped this release:
- @bendavies: #1982, #1994, #1995, #1996
- @UweOhse: #1986, #1998, #1999
- @datahari: #2004, #2005
- @theofidry: #1899, #1900
- @Ocramius: #1966, #1968
- @simbig: #1853
- @SpectralFlame: #1942
- @josephkerkhof: #1946
- @adnweedon: #1949
- @Soean: #1950
- @ADmad: #1956
- @still-dreaming-1: #1959
- @massimilianobraglia: #1963
- @charjr: #1988
- @shadowhand: #1990
- @BafS: #1993
- @HeySora: #2003
Full Changelog: 1.30.0...1.40.0