Mago 1.3.0
This release comes with significant performance improvements, bug fixes addressing false positives, and new formatter options. A massive thank you to everyone who reported issues and contributed!
✨ Features
Formatter
always-next-linebrace style: Newalways-next-linevalue for brace style options (method-brace-style,function-brace-style,closure-brace-style,classlike-brace-style,control-brace-style) that always places the opening brace on the next line, even for multiline signatures (#897)- Drupal preset: Add Drupal coding standards preset (#905) by @klausi
⚡ Performance
This release includes substantial performance optimizations:
- Reduced lock contention: Optimize empty atom handling to reduce lock contention (#956) by @dotdash
- Faster lexer/parser: Reduce allocations in lexer and parser for faster parsing
- Optimized clause lookups: Use
AtomSetinstead ofVecfor clause key lookups - Template type improvements: Remove template_types clone and use
HashMapfor bounds - Algebra optimizations: Use index-based tracking to avoid expensive clause cloning
- Faster context cloning: Use
AtomMapandControlActionSetbitfield for faster block context cloning - Type combination thresholds: Add literal type combination thresholds to prevent O(n²) complexity (#939, #940)
- HashMap for constants: Use
HashMapinstead ofIndexMapfor constants and enum_cases where ordering is not required - Deterministic method resolution: Use
IndexMapforoverridden_method_idsto ensure deterministic ordering (#907)
🐛 Bug Fixes
Analyzer
- Static return type resolution: Resolve
staticreturn types correctly in method chains across inheritance (#880, #949, #964) - Docblock inheritance: Prevent incorrect docblock inheritance when child class narrows return type (#960, #962)
- Unused method false positives: Skip trait-overriding methods in unused method check (#945)
- Unused property false positives: Skip non-private overridden properties in unused property check (#941, #943)
- Type narrowing for mixed arrays: Preserve type narrowing for array elements when base type is
mixed(#946, #947) - Nested isset narrowing: Handle nested array access in
isset()type narrowing (#900) - defined()/function_exists() assertions: Propagate assertions through
&&operator (#912) - Anonymous class constructors: Validate anonymous class constructor arguments (#958)
- Callable parameter inference: Make callable parameter type inference order-independent
- Never to string cast: Allow casting
neverto string - Combiner thresholds: Use user-configured combiner thresholds instead of defaults
Formatter
- Pint preset accuracy: Update Pint preset to match actual Pint formatting (#920)
CLI
- NO_COLOR support: Respect
NO_COLORenvironment variable and--colors neverflag globally across all output (#922) - Baseline fix filtering: Filter out baseline issues before applying fixes (#910)
Docblock
- By-reference parameters: Allow by-reference parameter syntax (
&$param) in@paramtags (#955)
Prelude (Type Stubs)
- sprintf family: Allow
nullandboolvalues insprintf,printf,sscanf, andfscanffunctions (#953) - $_FILES superglobal: Mark
$_FILESsuperglobal as potentially empty (#954)
🏗️ Internal
- Migrate template types from
VectoIndexMapwithGenericTemplatestruct for cleaner code - Replace block context boolean flags with
u32bitflags - Skip path separator normalization on non-Windows platforms
- Drop support for powerpc* and s390x tier 2 targets
- Update toolchain and dependencies
🙏 Thank You
Contributors
A huge thank you to everyone who contributed code to this release:
Issue Reporters
Thank you to everyone who reported issues that were fixed in this release:
- @bendavies — #955, #958, #960, #962
- @Bleksak — #880, #957
- @ddanielou — #953, #954
- @demonege — #910
- @Dima-369 — #912, #939, #940
- @dotdash — #946, #947
- @dragosprotung — #941, #945
- @dynasource — #943
- @kzmshx — #967
- @llaville — #922
- @MartkCz — #897
- @mytskine — #949
- @Nadyita — #964
- @Noojuno — #907
- @oleg-st — #900
- @poisa — #920
Full Changelog: 1.2.2...1.3.0