Mago 1.14.0
Mago 1.14.0 is a feature-packed release that brings full parent type hint support across the analyzer and codex, two new linter rules, PER-CS 3.0 compliance for the formatter's opening tag placement, a new parameter-attribute-on-new-line formatter setting, authenticated GitHub API requests for self-update, and a batch of bug fixes across the analyzer, formatter, syntax, and prelude.
✨ Features
Analyzer
- Full
parenttype hint support: Theparenttype hint is now fully supported across the codex, analyzer, scanner, builder, and expander — including return types, parameter types, properties, generics, arrays, and nested types (#1249) - Type provider for
Psl\Type\int_range: Added type narrowing support forPsl\Type\int_range(#1329)
Linter
- New
switch-continue-to-breakrule: Detectscontinueinside switch cases and suggests usingbreakinstead, sincecontinuein a switch behaves identically tobreakin PHP and can mislead readers (#1314) - New
no-redundant-binary-string-prefixrule: Flags redundantborBprefixes on string literals that don't contain any bytes outside the ASCII range (#1324)
Formatter
opening-tag-on-own-lineoption for PER-CS 3.0 compliance: Ensures<?phpis placed on its own line in pure PHP files by default, per PER-CS 3.0 Section 3. The setting defaults totruebut can be set tofalseto preserve the previous behavior. Template files are unaffected (#1293)parameter_attribute_on_new_linesetting: When enabled (default, PER-CS 12.2 compliant), parameter attributes are placed on their own line before the parameter (#1298)
CLI
- Authenticated GitHub API requests for self-update:
mago self-updatenow uses GitHub tokens (fromGITHUB_TOKEN, orGH_TOKEN) for authenticated API requests, avoiding rate-limit failures (#1284)
Docker
- Alpine base image: The Docker image now uses
alpine:3instead ofscratch, providing a shell (/bin/sh) so CI runners like GitLab CI can execute commands correctly (#1285)
🐛 Bug Fixes
Analyzer
- Fixed false positive
possibly-null-property-accesswith null-coalesce in short-circuit evaluation: The reconciler now correctly narrows types when($x ?? null) === nullis used in short-circuit||expressions (#1278) - Fixed false positive
redundant-null-coalesceon uninitialized typed properties: Typed properties without default values are now correctly marked as possibly-undefined, preventing false redundant-null-coalesce diagnostics when using??=(#1286) - Fixed protected method resolution through
@require-extendstraits: Protected methods from traits used by a@require-extendsclass are now correctly resolved as accessible (#1287) - Fixed sealed keyed arrays with disjoint keys merged incorrectly in unions: Sealed keyed arrays with disjoint keys are now kept as separate union members instead of being merged into a single array with all keys made optional (#1291)
Linter
- Narrowed annotation spans: Cyclomatic-complexity and kan-defect diagnostics now highlight minimal code regions instead of entire class bodies (#1282)
- Fixed
else ifflagged byblock-statementrule: The block-statement rule no longer incorrectly flagselse if(two keywords) as missing a block body (#1299)
Formatter
- Fixed compact inline array alignment:
align-assignment-likeno longer pads compact inline arrays into columns (#1321) - Fixed parentheses stripped from unbounded constructs in member access chains: Parentheses around
require,include,include_once,require_once, andprintare now preserved when used as the base of a member access chain (#1322) - Fixed brace placement for preserved single-parameter lists: Restored correct opening brace placement for functions/methods with a single parameter when
preserve_breaking_parameter_listis enabled (#1290) - Fixed trailing comment drift in try-catch-finally chains: Trailing comments on try/catch/finally closing braces no longer cause idempotency issues (#1303)
Syntax
- Fixed lexer panic on invalid octal array keys in docblocks: The lexer no longer panics when encountering invalid octal literals in docblock types (#1295)
- Added support for
bstring prefix: ThebandBbinary string prefixes are now correctly parsed (#1301) - Fixed braced interpolation in heredoc after escaped backslash:
\\{$var}in heredoc and shell-execute strings is now correctly parsed as an escaped backslash followed by braced interpolation (#1300)
Prelude
- Corrected OpenSSL stubs: Fixed incorrect function signatures in the OpenSSL stubs (#1327)
- Updated zstd stubs: Fixed incorrect function signatures in the zstd stubs (#1328)
🏗️ Internal
- Updated to Rust 1.94.0 (#1326)
- Updated sponsors list
🙏 Thank You
Contributors
A huge thank you to everyone who contributed code to this release:
- @Bleksak — #1296
- @dotdash — #1282
- @kzmshx — #1292, #1298, #1303, #1322
- @ostark — #1314
- @psihius — #1321
Issue Reporters
Thank you to everyone who reported issues that shaped this release:
- @bendavies — #1286, #1287, #1290, #1291
- @BafS — #1301
- @czim — #1280
- @edsrzf — #1295
- @Fan2Shrek — #1249
- @HeySora — #1279, #1293
- @JonasBuerger — #1300
- @karoun — #1284, #1299
- @marcovmun — #1285
- @veewee — #1329
- @zip-fa — #1278
Full Changelog: 1.13.3...1.14.0