Mago 1.56.0 continues the performance and memory work, strengthens incremental analysis, and fixes closure types, constant defaults, and formatter stability. It also adds Rust APIs for editor tools and updates the analyzer extension protocol to MANA 2.0.
Note
Support Mago
Does your company use Mago? Please consider sponsoring its development so we can keep fixing bugs and shipping releases.
Sponsor Mago ❤️
✨ Features
Formatter
- Range formatting: adds a Rust API to format selected statements, members, and import groups. (6ae7935)
Syntax
- Incomplete input: adds opt-in parser recovery for unfinished bodies and lists in editor tools. (86b81a9)
Analyzer
- Variable records: exposes compact variable-type records for editor tools. (162e4a6)
Codex
- Trait metadata: exposes directly declared trait names through the Rust API. (7934662)
Pipeline
- Declaration scans: adds a Rust API mode that updates declarations without analyzing bodies or running plugins. (3c23baf)
Database
- Directory symlinks: adds a loading API that returns discovered directory symlinks. (9c4d564)
🐛 Bug Fixes
Analyzer
- Implicit Stringable: recognizes interfaces that declare
__toString()asStringable. (#2450, 51befd3) - Constant defaults: resolves cross-file constant defaults before choosing conditional return types. (#2456, 5dcc33a)
- Stable getters: keeps mutation-free method narrowing across
&&operands and the following body. (#2454, e7707be) - Reference captures: widens closure captures that can change between calls, including empty arrays. (#2453, 398abb9)
- Nullable receivers: keeps declared method return types while retaining null-access warnings. (#2457, #2458, 3cb2e5c)
- Static closures: keeps
$thisout of static closure scopes. (5af4c93) - Closure scope: resolves closure types in their defining class. (36acc1b)
- Partial calls: keeps reduced signatures and captured argument constraints. (fa8dd4b)
- Template names: keeps template parameters separate from namespace imports. (173c0a4)
- Trait aliases: keeps multiple aliases and resolves adaptations through the source method. (27ef789, 10b5ed2)
- Final trait methods: enforces final aliases through inheritance. (7e85417)
- Callable unions: keeps distinct callable origins when combining types. (dfc377f)
- SimpleXML checks: allows
SimpleXMLElementandSimpleXMLIteratorto be falsy. (#2452, 27b0d2a)
Linter
- Import fixes: includes required imports in each fix and applies shared edits only once. (bf446f7)
Formatter
- Nested chains: stops repeated formatting from alternating between layouts. (#2449, 45f3a18)
- PHP 8.3 chains: keeps required parentheses around
newin property and nullsafe-property chains. (#2455, 779b8c5)
Incremental Analysis
- Inherited members: refreshes constants, members, and mixins after parent edits. (0dfc73c, 3f5ccf6, 14a157a)
- Inherited types: refreshes template data and thrown types after parent edits. (4f6d6b7, 249e597)
- Dependent types: refreshes vendor descendants and closure types after declaration changes. (9429d38, 034e9a9)
- Missing classes: tracks unresolved class and attribute dependencies for later updates. (97beca9, 6ea673d)
- Reference updates: replaces stale references and keeps shared and inherited origins. (0596b77, 0361be5, 3d8e983)
- Dependency merges: normalizes class references and makes merges independent of order. (0c46bee, 7392f75)
- Class aliases: rebuilds analysis after alias bindings change. (45d94a6)
- Removed files: clears analysis state when the last source file is removed. (1aed241)
- Failed analysis: discards stale state and failed analysis results. (3139aa8)
Database
- File updates: matches full source patterns and keeps membership through symlink paths. (5117cbc, 1e01300)
Editor Data
- Receiver records: keeps cached targets, variable types, and receiver uncertainty. (3d4d85d, 63f0f67, bf60635)
- Callable records: keeps literal targets, reduced partial signatures, and bound closure types. (bd2a000, 7e4d80d, c3b107e)
- Callable keys: uses consistent keys for callable records. (ffaca3f)
- Type displays: keeps declared casing, absolute names, and readable template bounds. (692d96b, 0a234fc, fa963a4)
🏗️ Internal
Analyzer
- Analysis allocations: cuts temporary allocations and drops completed expression types in one-shot analysis. (fab264a, c777d0a)
Codex
- Union hashing: makes union hashes match type equality. (d099407)
- Type allocations: cuts type and reference allocations and renders owned type text without interning. (4fe3d31, dd7e58c)
- Metadata capacity: reuses signature and descendant storage and avoids growth on duplicate references. (7e8889b, b0411ca, 477f2a2)
Pipeline
- Cached analysis: shares issue collections and skips unused incremental cleanup. (69f2018, 513282f)
- Scan storage: moves metadata into the codebase and avoids duplicate reference graphs. (c1be090, b5ec0c7)
- Rebuild memory: releases scan data and skip sets after use. (6981e77, e0e3533)
- Worker memory: releases unused analysis data and large worker arenas. (8f2f9bd)
Reporting
- Issue storage: borrows issues for ignore checks and trims annotation and note storage. (fce3ecd, 9972acf)
Tests
🧩 Extension Protocol
Analyzer extensions now use MANA 2.0. Update the PHP SDK to 1.56.0; other SDKs must support callable parameter out-types. MANA 1.x is no longer accepted. MEXT remains at 1.0.
- Callable out-types: preserves by-reference output types in callable snapshots and signature responses. (a307a94)
🙏 Thank You
Contributors
Thank you to everyone who contributed to this release:
Issue Reporters
Thank you to everyone who reported issues that shaped this release:
Full Changelog: 1.55.0...1.56.0