github carthage-software/mago 1.10.0
Mago 1.10.0

9 hours ago

Mago 1.10.0

This release introduces wildcard pragma suppression (@mago-ignore all), auto-fix for unused pragmas, a new just-in-time binary download for Composer, and a large number of bug fixes across the analyzer, linter, formatter, and type system.

✨ Features

Collector (Pragma System)

  • @mago-ignore all / @mago-expect all wildcard pragmas: You can now use all as the issue code in suppress pragmas to suppress all issues within a category (e.g., @mago-ignore lint:all) or across all categories (e.g., @mago-ignore all). This is especially useful for legacy code where listing individual codes is impractical (#1034)
  • Auto-fix suggestions for unused pragmas: When running mago lint --fix or mago analyze --fix, unused @mago-ignore and unfulfilled @mago-expect directives are now automatically stripped. The fixer handles three cases: removing a single code from a comma-separated list, removing a directive line from a multi-line comment, or deleting the entire comment when all pragmas are unused (#1187)

Linter

  • check-functions option for prefer-first-class-callable: The rule now supports a check-functions config option (default: false). When disabled, the rule only suggests first-class callable conversion for method and static method calls, avoiding false positives with internal PHP functions that throw ArgumentCountError on extra arguments (#1147, #1160)
  • exclude-setters-and-constructors option for no-boolean-flag-parameter: The rule now supports excluding setter methods and constructors from boolean flag parameter detection, reducing noise for legitimate boolean setter patterns (#1155)

Composer

  • Just-in-time binary download: The Composer plugin has been replaced with a lightweight wrapper script that detects the platform and downloads the correct Mago binary on first run. This eliminates the need to allow a Composer plugin and supports multi-platform environments (e.g., Docker on macOS with mounted volumes) (#1141, #1159)

CLI

  • Fully resolved formatter settings in config output: The mago config --show formatter command now displays all resolved formatter settings flattened alongside excludes, matching the TOML configuration structure. The --schema output has also been updated to reflect the flat structure. Previously, only {"excludes": []} was shown (#1180)

🐛 Bug Fixes

Analyzer

  • False positive redundant-condition for is_float() on int|float union: The int ⊂ float containment rule is now guarded by assertion context, preventing incorrect redundant-condition and redundant-type-comparison diagnostics when is_float() or is_double() is called on int|float variables (#1186)
  • Bogus diagnostic when writing an unknown array index: Fixed false undefined-string-array-index errors when writing to (not reading from) unknown array keys with allow-possibly-undefined-array-keys set to false (#1168, #1171)
  • Class names reported as written instead of normalized: The catch-type-not-throwable diagnostic now shows class names in their original casing instead of all-lowercase (#1185)
  • Multiple incremental analysis bugs in watch mode: Fixed several issues where editing one file would clear diagnostics in other files, and body-only changes would lose existing errors. The populator now correctly clears invalid_dependencies during class-like metadata re-population, and the incremental analysis service properly tracks per-file issues (#1176, #1178)
  • False positive missing-magic-method with trait @property/@method: Real inherited properties and methods from parent classes now correctly override trait pseudo @property and @method annotations, preventing false positives when a trait declares magic accessors that shadow real parent members (#1184)
  • Mixin types inherited from parent classes: Mixin types declared via @mixin on parent classes are now correctly inherited by child classes during method and property resolution (#1169)

Linter

  • prefer-arrow-function disabled inside constant expressions: Arrow function suggestions are no longer emitted inside constant expressions (e.g., class constant initializers) where closures are the only valid syntax (#1166)

Formatter

  • Pint preset: method-chain-semicolon-on-next-line disabled by default: The Pint preset now correctly defaults this setting to false, matching Pint's actual behavior (#1164)

Syntax

  • yield expression detected inside return statement: The parser now correctly identifies yield expressions when used as a return value (e.g., return yield $value), preventing incorrect diagnostics on generator functions (#1167)

Prelude (Type Stubs)

  • dir() second argument marked as optional: The second parameter of dir() is now correctly annotated as optional, fixing false too-few-arguments errors when calling dir() with a single argument (#1163)

Reporter

  • Writer buffer flushed in watch mode: The JSON reporter now flushes its writer buffer after each report, preventing incomplete JSON output when piped to external tools like VS Code extensions (#1170)

Atom (Case Folding)

  • Case folding matches PHP's behavior for non-ASCII characters: Fixed a bug where non-ASCII characters were incorrectly lowercased using full Unicode rules instead of ASCII-only folding, matching PHP's actual strtolower() behavior. This could cause mago to fail to detect errors resulting from case differences in non-ASCII class names (#1161)

Playground

  • file-name rule disabled by default: The file-name lint rule is now disabled in the Mago playground to reduce noise for single-file examples (#1162)

🙏 Thank You

Contributors

A huge thank you to everyone who contributed code to this release:

Issue Reporters

Thank you to everyone who reported issues and requested features that shaped this release:


Full Changelog: 1.9.1...1.10.0

Don't miss a new mago release

NewReleases is sending notifications on new releases.