Skip to content

Releases: carthage-software/mago

Mago 1.0.0-rc.3

16 Nov 00:04
ed0c848

Choose a tag to compare

Mago 1.0.0-rc.3

🤩 Features

💻 CLI

  • --retain-code option: Filter reported issues by specific codes (e.g., --retain-code semantics --retain-code invalid-argument). Unlike --only in lint, this runs all checks but filters the
    output

✨ Formatter

  • Method sorting: Add option to sort class methods based on name, visibility, and other modifiers

🐛 Bug Fixes

🎯 Type System

  • Variance-aware inheritdoc: Respect contravariance for parameters (allow child to widen types) and covariance for return types (allow child to narrow types) when inheriting docblock types (closes
    #629)
  • Better type narrowing: Narrow mixed to array types after isset() checks on nested array access
  • Nullsafe operator: Propagate nullsafe operator short-circuit through entire expression chains
  • Promoted properties: Parse inline @var docblocks on promoted constructor properties
  • Trait self types: Support self parameter types in closures defined in trait methods
  • Array operations: Preserve non-empty flag in array addition and array_merge() type inference
  • Type expansion: Correct type expansion logic for specialized type parameters

🔧 Linter

  • str-contains rule: Add support for negation pattern (strpos === false!str_contains). Only provide fixes for strict equality (=== and !==) to prevent unsafe replacements. Report warnings for loose equality (==, !=, <>) due to strpos returning 0 at position 0 (closes #494)

📚 Prelude

  • mbstring functions : Correct return types for encoding functions (closes #628)

🎨 Improvements

📁 Database

  • Path handling: Prioritize includes over paths, and add support for path and include patterns (closes #327)

Full Changelog: 1.0.0-rc.2...1.0.0-rc.3

Mago 1.0.0-rc.2

14 Nov 05:45
4b30882

Choose a tag to compare

Bug Fixes

  • Type alias imports: Fixed false positive "class not found" errors when importing type aliases from classes that haven't been populated yet #624
  • Self-imported type aliases: Fixed stack overflow when a class imports type aliases from itself - now skips self-imports with a helpful message #624
  • Empty containers: Fixed false positive error when passing new ArrayIterator([]) or similar empty containers to typed iterable parameters #626

Full Changelog: 1.0.0-rc.1...1.0.0-rc.2

Mago 1.0.0-rc.1

12 Nov 08:00
d6a6097

Choose a tag to compare

Mago 1.0.0-rc.1 🎉

We're excited to announce Mago 1.0.0-rc.1, a major milestone toward the 1.0.0 release! This release candidate includes significant performance improvements, comprehensive type system enhancements, and numerous bug fixes based on community feedback.

📊 Release Highlights

  • 🚀 Watch Mode with Incremental Analysis - Real-time analysis with intelligent re-analysis of only changed files
  • 📝 Full Type Alias Support - Complete implementation of @type, @psalm-type, and @phpstan-type
  • ✅ Comprehensive Inheritance Validation - 20+ new issue codes for class hierarchy validation
  • 📤 SARIF Format Support - Better integration with security and analysis tools
  • ⚙️ Configuration Enhancements - JSON schema support, YAML/JSON configuration files
  • 💰 67 GitHub issues closed in this release
  • 🤝 12 merged pull requests from community contributors

🎉 New Features

🧬 Type System Enhancements

Full Type Alias Support

Mago now has complete support for type aliases in docblocks:

/**
 * @type UserId = positive-int
 * @psalm-type UserData = array{id: UserId, name: string}
 */
class User {
    /** @param UserData $data */
    public function __construct(private array $data) {}
}

/**
 * @import-type UserData from User
 */
class UserService {
    /** @param !User::UserData $data */  // Reference without importing
    public function process(array $data): void {}
}

Features:

  • Define type aliases with @type, @psalm-type, and @phpstan-type tags
  • Import type aliases with @import-type (with as keyword support for renaming)
  • Reference without importing using !ClassName::AliasName syntax
  • Support for self and static references
  • Type aliases can reference other aliases, creating dependency chains

Index Access Type Support

Added support for T[K] (index access) type syntax for more precise array typing.

Literal-Int Type Support

Added support for literal-int type to distinguish between literal integer values (e.g., 42) and general integer types.

@inheritDoc Support

Full support for @inheritDoc tag in docblocks, including inline {@inheritDoc} syntax.

🔍 Static Analysis Improvements

Comprehensive Inheritance Validation

Mago now validates class inheritance, interface implementation, and trait composition following PHP's type system rules and the Liskov Substitution Principle.

Validates:

  • Property type compatibility (covariance/contravariance)
  • Method signature compatibility
  • Constant type and value compatibility
  • Visibility rules (cannot make members more restrictive)
  • Access modifiers (static, readonly, final)
  • Parameter counts and defaults

New Issue Codes (20+):

  • IncompatibleConstantAccess, IncompatibleConstantOverride, IncompatibleConstantType
  • IncompatibleParameterCount, IncompatibleParameterName, IncompatibleParameterType
  • IncompatiblePropertyAccess, IncompatiblePropertyDefault, IncompatiblePropertyOverride, IncompatiblePropertyType
  • IncompatibleReturnType, IncompatibleVisibility
  • MissingOverrideAttribute
  • And more...

Trait Constant Override Validation

Validates trait constant override rules - prevents classes from overriding trait constants with different values.

Auto-Fix Support for Redundancy Issues

The analyzer can now automatically fix various redundancy issues with mago analyze --fix --fmt.

Conditional Return Type for json_encode()

Special handler recognizes the JSON_THROW_ON_ERROR flag and returns string instead of string|false.

🎯 Special Function Handlers

array_merge and Psl\Dict\merge

Special type inference for array_merge and PSL's Psl\Dict\merge with proper key/value tracking.

array_filter with Callback Assertion

Better type narrowing when using array_filter with callback assertions like is_int(...).

compact() Handler

Preserves type information when using compact() - knows the exact keys and their types.

🧹 Linter Rules

New Rules

  1. no-self-assignment - Detects assignments where a variable is assigned to itself ($x = $x;)
  2. prefer-early-continue - Encourages early returns to reduce nesting
  3. prefer-static-closure - Performance optimization for closures that don't use $this

Previously Disabled Rules Now Enabled

The following rules are now enabled by default:

  • no-redundant-use - Detects unused imports
  • no-variable-variable - Warns about variable variables
  • no-redundant-readonly - Detects redundant readonly modifiers
  • sensitive-parameter - Validates sensitive parameter handling

📊 Reporting & Output

SARIF Format Support

Added support for SARIF (Static Analysis Results Interchange Format) for integration with GitHub Code Scanning, security dashboards, and CI/CD pipelines.

mago analyze --reporting-format sarif > results.sarif

Baseline Improvements

Major improvements to baseline management:

  • Cross-platform path normalization - Works correctly on Windows and Unix
  • Detailed statistics - Dead/removed issues, filtered counts, severity levels
  • Stricter baseline checking - New fail_on_out_of_sync_baseline parameter
  • Better API - Moved to mago-reporting crate for reusability

Enhanced Annotations for CI/CD

Annotation messages now included in GitHub, GitLab, and Checkstyle formats with column information and detailed context.

⚙️ Configuration

JSON Schema Support

Generate JSON schema for configuration validation with IDE autocomplete:

mago config --schema > mago-schema.json

YAML and JSON Configuration Support

Configuration files can now be written in YAML or JSON in addition to TOML.

Search Order: workspace directory → XDG_CONFIG_HOME → home directory
Format Priority: TOML > YAML > JSON

🖥️ CLI Enhancements

Shell Completions

Generate shell completions for Bash, Zsh, Fish, and PowerShell:

mago generate-completions bash > /etc/bash_completion.d/mago

Install Specific Versions

Installation script now supports version selection:

curl -sSL https://mago.sh/install | bash -s -- --version=1.0.0-rc.1

⚡ Performance

Watch Mode

New --watch flag for continuous analysis during development:

mago analyze --watch

Watches your filesystem and automatically re-analyzes only the files that changed and their dependencies. Powered by intelligent incremental analysis internally - dramatically faster than re-analyzing the entire codebase!

Type Pre-allocation Optimization

Re-use pre-allocated types for better memory usage and performance.

🔧 Breaking Changes

Configuration File Behavior Change

⚠️ BREAKING CHANGE: Configuration files are no longer merged from multiple locations.

What Changed:

  • Only ONE configuration file is loaded (first found in search order)
  • No merging between global and workspace configs

Migration: Consolidate your configuration into a single file if you previously relied on merging.

Previously Disabled Rules Now Enabled

Several linter rules are now enabled by default. You may see new warnings/errors for:

  • Unused imports
  • Variable variables
  • Redundant readonly modifiers
  • Sensitive parameter handling

Comprehensive Inheritance Validation

The new strict inheritance validation may report issues in class hierarchies that were previously undetected.

🐛 Bug Fixes

🧬 Type System & Analysis

  • Array key access in union types - Corrected error reporting
  • False positives - Fixed multiple issues to improve accuracy
  • Null coalesce type narrowing - Fixed when right-hand side is never type
  • isset() false positives - Fixed several issues with union array types and type checks after isset()
  • Nullability preservation - Preserve nullability when merging docblock types with real types

🔤 Syntax & Parser

  • Reserved keywords in string interpolation - Now accepts reserved keywords in array access ("$array[class]")
  • Static in constant expressions - Correctly disallows static in constant expressions (matches PHP behavior)

🎨 Formatter

  • String interpolation alignment - Preserve alignment for braced expressions
  • Echo tags recognition - No longer flagged as useless code
  • Empty single-line comments - Allow empty comments in blocks

🧹 Linter

  • --only flag - Fixed flag being ignored when linting
  • Only filter warning - Warn when filter doesn't match any rule
  • Unfulfilled expectations - Don't report on non-active rules

💥 Other Fixes

  • Extreme values - Prevent panics on extreme numeric values
  • Try statement return detection - Fixed detection when calling functions returning never

🏗️ Internal Changes

Orchestrator Crate

Major architectural refactoring introducing the orchestrator crate - separates CLI from core analysis engine.

Rust 1.91 Update

Updated to Rust 1.91 for latest language features and performance improvements.

SPL Stubs

Improved SPL (Standard PHP Library) stubs with better type definitions.

⚠️ Migration Notes

Upgrading from Previous Versions

  1. 📁 Configuration Files - Consolidate multiple configs into a single file (no more merging)
  2. 🧹 Linter Rules - Review new warnings from previously disabled rules
  3. 🔍 Inheritance Validation - Review and fix newly reported incompatibilities
  4. 🎨 JSON Schema - Generate schema for IDE autocomplete: mago config --schema > mago-schema.json
  5. ⌨️ Shell Completions - Install completions for better CLI experience

🙏 Acknowledgments

Thank you to all contri...

Read more

Mago 1.0.0-beta.34

19 Oct 07:04
1a29b3a

Choose a tag to compare

Mago 1.0.0-beta.34

This is a focused patch release that addresses a key correctness issue in the analyzer's handling of generic types, particularly when working with ::class strings.

🐞 Analyzer Fix

The analyzer's type comparator has been improved to be smarter about generic types.

Previously, comparing a "raw" generic class (e.g., BoxImpl) against a version with explicit type parameters (e.g., BoxImpl<mixed>) would fail. This commonly caused false positive errors when passing a literal class string like BoxImpl::class to a function expecting class-string<BoxImpl<mixed>>.

The analyzer now correctly understands that when type parameters are missing from a generic class, they should be treated as their default template constraints (which is usually mixed). This makes the comparison logic more robust and aligns it with developer expectations.


Full Changelog: 1.0.0-beta.33...1.0.0-beta.34

Mago 1.0.0-beta.33

19 Oct 06:10
74b081b

Choose a tag to compare

Mago 1.0.0-beta.33

This release introduces a powerful and highly-requested set of new analysis features for detecting missing type hints. We've also made the analyzer significantly smarter at handling superglobals and boolean comparisons, landed a raft of critical bug fixes that improve type-narrowing, and shipped a major performance optimization for large projects.

✨ New: Missing Type Hint Detection

The analyzer can now detect and report missing type hints for constants, properties, parameters, and return types, helping you improve the strictness and reliability of your codebase. This new analyzer-based feature is more powerful and accurate than the old linter rules it replaces.

  • Comprehensive Checking: The analyzer will report missing-constant-type, missing-property-type, missing-parameter-type, and missing-return-type issues.
  • Highly Configurable: You have fine-grained control via new settings in your mago.toml:
    • check-missing-type-hints: The main switch to enable/disable this feature.
    • check-closure-missing-type-hints: Toggles checks specifically for closures.
    • check-arrow-function-missing-type-hints: Toggles checks specifically for arrow functions.
  • Intelligent & Low-Noise: The analyzer is smart enough to avoid common false positives. It automatically ignores:
    • Methods/properties that override a parent that also lacks a type hint.
    • Parameters prefixed with $_ (a common convention for unused variables).
    • Constructors (__construct) and destructors (__destruct) for return type checks.

⚡️ Major Performance Gains for Large Projects

A significant performance bottleneck in the type reconciliation logic for sealed classes has been eliminated. The impact of this optimization is most dramatic on very large projects that make extensive use of sealed type hierarchies with many instanceof checks.

When analyzing a large codebase like the Symfony framework, this release is over 6x faster than the previous version.

Symfony Benchmarks:

Benchmark 1: mago-32 analyze --reporting-format count
  Time (mean ± σ):      8.894 s ±  0.326 s    [User: 11.398 s, System: 4.137 s]
  Range (min … max):    8.509 s …  9.508 s    10 runs
 
  Warning: Ignoring non-zero exit code.
 
Benchmark 2: mago-33 analyze --reporting-format count
  Time (mean ± σ):      1.455 s ±  0.071 s    [User: 7.138 s, System: 1.680 s]
  Range (min … max):    1.351 s …  1.536 s    10 runs
 
  Warning: Ignoring non-zero exit code.
 
Summary
  mago-33 analyze --reporting-format count ran
    6.11 ± 0.37 times faster than mago-32 analyze --reporting-format count

For smaller projects or codebases that do not heavily rely on this specific pattern (like PSL or WordPress), the performance will remain similar to the already fast previous versions. This targeted optimization ensures that Mago scales efficiently, even for the most complex architectural patterns, without introducing regressions elsewhere.

Psl Benchmarks:

Benchmark 1: mago-32 --config config/mago.toml analyze
  Time (mean ± σ):     233.6 ms ±  13.4 ms    [User: 612.0 ms, System: 400.4 ms]
  Range (min … max):   224.4 ms … 271.2 ms    10 runs
 
  Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.
 
Benchmark 2: mago-33 --config config/mago.toml analyze
  Time (mean ± σ):     224.4 ms ±   8.4 ms    [User: 631.4 ms, System: 402.6 ms]
  Range (min … max):   214.0 ms … 237.2 ms    10 runs
 
Summary
  mago-33 --config config/mago.toml analyze ran
    1.04 ± 0.07 times faster than mago-32 --config config/mago.toml analyze

WordPress Benchmarks:

Benchmark 1: mago-32 analyze --reporting-format count
  Time (mean ± σ):      3.853 s ±  0.147 s    [User: 15.298 s, System: 0.752 s]
  Range (min … max):    3.467 s …  3.946 s    10 runs
 
  Warning: Ignoring non-zero exit code.
  Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.
 
Benchmark 2: mago-33 analyze --reporting-format count
  Time (mean ± σ):      3.832 s ±  0.200 s    [User: 16.264 s, System: 0.758 s]
  Range (min … max):    3.488 s …  3.991 s    10 runs
 
  Warning: Ignoring non-zero exit code.
 
Summary
  mago-33 analyze --reporting-format count ran
    1.01 ± 0.07 times faster than mago-32 analyze --reporting-format count

🚀 Major Analyzer Improvements

Smarter Superglobal Handling

The analyzer is now much smarter about superglobals ($_GET, $_SERVER, etc.). They are now pre-registered in all scopes by default, which resolves a major pain point where type narrowing on superglobal array keys (e.g., in if (isset($_GET['user']))) would fail. You can control this with the new register-super-globals setting.

Upgraded: Type-Aware Boolean Comparison

The no-boolean-literal-comparison check has been moved from the linter to the analyzer. Because the analyzer is type-aware, it can now avoid false positives by understanding the context. For example, it will correctly allow a check like $foo === false if the type of $foo is a union that includes false (e.g., false|string).

🐞 Other Bug Fixes

  • Critical Analysis Fixes:
    • Resolved several bugs related to correctly resolving static return types, detecting callables in ::class strings, and handling chained null checks. (#511, #549, #577)
    • Corrected object type subtraction logic for non-sealed class hierarchies, improving type narrowing.
    • Fixed a bug where isset() was not correctly narrowing a nullable array key to non-null within a conditional block. (#573)

⚠️ Deprecations

The following linter rules are now deprecated in favor of the more powerful analyzer-based checks. They will be removed in a future release.

  • constant-type
  • parameter-type
  • property-type
  • return-type
  • no-boolean-literal-comparison

🤝 New Contributors

Closed Issues


Full Changelog: 1.0.0-beta.32...1.0.0-beta.33

Mago 1.0.0-beta.32

17 Oct 05:13
18c2f9a

Choose a tag to compare

Mago 1.0.0-beta.32

This is a massive stability and correctness release for the analyzer. We've significantly improved its ability to understand complex conditional logic and type hierarchies, leading to smarter type narrowing and the elimination of many false positives. As we get closer to the first release candidate, these foundational fixes are crucial for providing a reliable analysis experience.

A huge thank you to @baukevdw for their contribution to this release!

🚀 Smarter Conditional Type Analysis

The analyzer's ability to narrow types within if and match statements has been made much more powerful and correct.

  • Sealed Types (@psalm-inheritors) (#537): The analyzer now understands the @psalm-inheritors tag. When you check and negate an instanceof on a sealed interface or class, it will correctly infer the remaining possible types from the inheritor list. This is a huge improvement for codebases using algebraic data types.

  • Null Coalesce Assertions (??) (#531): The analyzer now correctly understands that a check like ($var ?? null) !== null guarantees that $var is both set and not null, eliminating false "possibly undefined" errors inside the if block.

  • Assignments in && Conditions (#538): Fixed a bug where a variable assigned on the right-hand side of an && in a condition was incorrectly reported as undefined.

  • Multiple isset() Assertions (#564): The analyzer now correctly processes all assertions in conditions with multiple isset() calls, like isset($a, $b) or isset($a) && isset($b).

🐞 Analyzer Soundness & Correctness

Several fundamental bugs in the type system and reconciler have been fixed to improve soundness.

  • !isset is null, not never (#570): A !isset() check now correctly reconciles the variable's type to null (or possibly_undefined), not never. This fixes a major bug that caused the analyzer to incorrectly mark valid code paths as unreachable.

  • Differentiated Null Array Access (#568): The analyzer now distinguishes between accessing an array on a variable that is definitely null (a NullArrayAccess error) versus one that is possibly null (a PossiblyNullArrayAccess warning). This provides more precise and appropriately severe feedback.

  • array vs Traversable (#563): A soundness issue was fixed where array was incorrectly treated as a subtype of Traversable. The type comparator now correctly distinguishes between them, fixing incorrect type narrowing for instanceof checks.

✨ New Configuration

  • New strict-list-index-checks Option (#565): A new configuration option, strict-list-index-checks (default: false), has been added. When enabled, it enforces that array list indices must be non-negative-int, providing stricter validation for users who want it.

🤝 New Contributors

Closed Issues


Full Changelog: 1.0.0-beta.31...1.0.0-beta.32

Mago 1.0.0-beta.31

16 Oct 05:44
acac89c

Choose a tag to compare

Mago 1.0.0-beta.31

This is a hotfix release that addresses a critical panic in the mago ast command, ensuring stability when processing files with multi-byte characters.

🐞 CLI Fix

A critical bug has been fixed that could cause the mago ast --tokens command to panic and crash when processing files containing multi-byte UTF-8 characters (e.g., emojis or CJK characters).

The crash occurred because the table-formatting logic was incorrectly truncating token values by byte length, which is unsafe for UTF-8 strings and can lead to a panic if a slice ends in the middle of a character.

The logic has been rewritten to be fully UTF-8 aware. It now correctly measures the visual width of characters and truncates strings on proper character boundaries. This not only resolves the panic but also ensures the token table aligns correctly for all character sets.

Closed Issues


Full Changelog: 1.0.0-beta.30...1.0.0-beta.31

Mago 1.0.0-beta.30

16 Oct 02:16
9338007

Choose a tag to compare

Mago 1.0.0-beta.30

This release introduces mago guard, a powerful new tool for enforcing architectural rules in your PHP projects. We've also added a new list-files utility command and landed several key correctness fixes for the analyzer and formatter as we get closer to our first release candidate.

A huge thank you to our community contributors for this release: @dotdash and @bendavies!

🛡️ New Feature: mago guard

We are thrilled to introduce mago guard, a high-performance tool for defining and enforcing architectural boundaries directly within your project. It combines the power of dependency validation (like deptrac) and structural rule-checking (like arkitect) into a single, cohesive command.

The goal of guard is to provide instant feedback on architectural violations, helping you maintain a clean and scalable codebase. Its concepts are designed to be intuitive, using a "Fortress" metaphor:

  • 🏰 The Fortress is your entire codebase.
  • 🧱 Perimeter Rules define your defensive layers. They control which namespaces can communicate, preventing illegal dependencies (e.g., ensuring your Domain layer never depends on your UI layer). A violation is a BoundaryBreach.
  • 🏛️ Structural Rules define the building codes inside the fortress. They ensure code within a namespace is built correctly (e.g., all Controllers are final, all Repositories implement an interface). A violation is a StructuralFlaw.

All rules are defined declaratively in your mago.toml file.

Read the full documentation for mago guard here.

✨ Other New Features

  • New list-files Command (#552): A new mago list-files command has been added. This utility prints a list of all files that would be processed by the lint, format, analyze, or guard commands, based on your configuration. It's an excellent tool for debugging your [source] paths and exclusion rules. (Thanks, @dotdash!)

🚀 Analyzer & Formatter Correctness

  • Analyzer: Fixed a critical soundness bug where accessing an explicitly optional array shape key (e.g., email in array{email?: string}) would not produce a nullable type. Accessing such a key now correctly results in a T|null type. (#557)
  • Analyzer: Fixed a bug where a negated isset() check on a possibly undefined array key was not correctly narrowing the type to null. (Thanks, @bendavies!)
  • Analyzer: The analyzer now correctly allows assigning a value to a string-keyed index on a list, which correctly converts the type to a keyed array. (#559)
  • Formatter: Fixed a bug where catch blocks with multiple exception types that exceeded the print width were not being correctly broken onto multiple lines. (#556)
  • Linter: The prefer-arrow-function rule will no longer suggest converting a closure to an arrow function if the closure imports variables by reference, which is unsafe. (#554)

Closed Issues


Full Changelog: 1.0.0-beta.28...1.0.0-beta.30

Mago 1.0.0-beta.28

12 Oct 02:48
4fda6c1

Choose a tag to compare

Mago 1.0.0-beta.28

This release is packed with significant correctness fixes for the analyzer, focusing on advanced type system features like enums, generics, and traits. The formatter also receives critical bug fixes for operator precedence and brace placement.

A massive thank you to our community for driving this release forward with their contributions: @bendavies, @yankewei, @dragosprotung, and @muro3r!

🚀 Analyzer Correctness Fixes

The analyzer's accuracy has been substantially improved with fixes for several fundamental type system and control flow bugs.

  • Enum Method Analysis (#546): The analyzer now synthetically generates full metadata for built-in enum methods (from, tryFrom, cases). This provides precise parameter and return types, enabling correct analysis of first-class callables like Category::from(...).

  • Template & Type System Correctness:

    • Inherited Templates (#535): Template types defined via extends or implements on an interface or class are now correctly resolved and applied.
    • enum_exists Narrowing (#541): Fixed a bug where intersecting a specific class with a generic type would incorrectly discard the more specific class information, improving type narrowing after checks like enum_exists().
    • count() Assertions (#540): Assertions from count() calls (e.g., if (count($arr) > 0)) are now correctly applied, allowing the analyzer to understand that an array is non-empty.
  • Flow PHP Types Support (#527): Added special handling for the flow-php/types library, including support for its type_structure() function. (Thanks, @bendavies!)

  • Imagick Support (#543): The analyzer now has stubs for Imagick class constants, improving type safety when working with the Imagick extension. (Thanks, @dragosprotung!)

💅 Formatter Fixes

  • Operator Precedence with clone (#536): Fixed a critical bug where the formatter would incorrectly remove parentheses from a ternary expression inside a clone() call, which would change the code's behavior. The logic is now more robust for other unary constructs as well.

  • Brace Placement (#545): Corrected an issue where the opening brace for functions or methods with long signatures but short parameter lists was being placed on the same line, violating the NextLine brace style.

✨ Linter Updates

  • yoda-conditions Rule Disabled by Default (#505): In response to community feedback, the yoda-conditions rule is now disabled by default. It was found to be too noisy for many projects, and its primary goal of preventing accidental assignments is already covered by the no-assign-in-condition rule. Teams that prefer this style can still enable it in their mago.toml.

  • New Rule: no-variable-variable: A new rule has been added to disallow the use of variable-variables (e.g., $$foo), which can make code difficult to understand and analyze.

  • no-redundant-use Improvements: This rule has been improved to understand Tempest view classes, reducing false positives in projects using this framework. (#532)

🤝 New Contributors


Full Changelog: 1.0.0-beta.27...1.0.0-beta.28

Mago 1.0.0-beta.27

07 Oct 16:15
3bee374

Choose a tag to compare

Mago 1.0.0-beta.27

This release is packed with community contributions, featuring powerful new linter rules, major analyzer correctness fixes, and expanded support for the PHP ecosystem.

We're thrilled to welcome several new contributors to the project! A huge thank you to @yigitcukuren, @rachidify, @thorsten, @dotdash, and @bendavies for their fantastic work on this release!

✨ New Linter Features (Community-Driven!)

The linter has received a huge upgrade, thanks to our community.

  • New Rule: no-redundant-use (#439): The highly-requested rule for detecting and removing unused use statements is here! It correctly handles symbols used in docblocks and comes with a powerful auto-fix. (Thanks, @rachidify!)

  • New Suggestions & Fixes for final & readonly (#530, #522, #529):

    • A new rule suggests using private instead of protected for members in final classes.
    • The linter can now detect and flag redundant readonly modifiers (no-redundant-readonly rule).
    • An auto-fix has been added for the no-redundant-final rule.
      (Thanks, @dotdash!)

🚀 Analyzer Improvements

  • Magic Constant Inference (#521): The analyzer now infers the exact literal value of magic constants like __DIR__, __FILE__, and __LINE__, leading to more precise path analysis.
  • Array Shape Correctness (#528, #523): The logic for comparing array shapes has been overhauled to be much stricter and more correct. This includes always reporting access to optional array keys, regardless of other settings.
  • Trait Visibility (#520): Fixed a critical bug where visibility changes on aliased trait methods (e.g., use Trait { method as private newName; }) were not being respected.
  • @method Parameter Casing (#507): The analyzer now correctly handles case-sensitivity for named arguments in magic methods defined with @method tags.

🐘 PHP Ecosystem Support

  • GD Extension (#509): Stubs for the GD graphics extension have been added. (Thanks, @yigitcukuren!)
  • phpMyFAQ (#518): We're excited to welcome phpMyFAQ to the list of projects using the tool! (Thanks, @thorsten!)

🤝 New Contributors

Closed Issues


Full Changelog: 1.0.0-beta.26...1.0.0-beta.27