Skip to content

Releases: carthage-software/mago

Mago 1.0.0-rc.11

07 Dec 09:33
46f0046

Choose a tag to compare

This release focuses on reducing false positives, improving type system accuracy, performance optimizations, and introducing new linter rules.

New Features

Linter

  • New property-name rule (#703)
    Added a new linter rule to enforce consistent property naming conventions across your codebase.

  • New use-specific-assertions rule
    Introduced a new rule that encourages using specific assertion methods (e.g., assertTrue, assertNull) instead of generic assertEquals/assertSame with literal values for better clarity and intent.

Analyzer

  • Type narrowing for symbol existence checks
    The analyzer now properly narrows types based on symbol and member existence checks like function_exists(), method_exists(), property_exists(), and defined(). This eliminates false positives when conditionally using symbols after checking their existence.

Bug Fixes

Analyzer

  • Fixed false positives for class-string comparisons and static variable initialization
    Resolved issues where the analyzer incorrectly flagged valid code involving class-string type comparisons and static variable initialization patterns.

  • Fixed false positive for count() comparison on non-empty-list
    The analyzer no longer incorrectly reports issues when comparing the count of a non-empty-list with integer values.

  • Fixed list type preservation when narrowing with is_array()
    Using is_array() on a union type containing a list no longer incorrectly loses the list type information.

  • Fixed interface method resolution for __callStatic
    The analyzer now only reports interface implementation issues when resolving actual methods, not when resolving magic __callStatic calls.

  • Fixed invalid array access assignment value checking
    Improved detection of invalid values being assigned through array access expressions.

Reconciler

  • Fixed list type narrowing preserving assertion element types
    Type narrowing on list types now correctly preserves the element type assertions, preventing false positives in generic list operations.

Docblock

  • Fixed @method tag with static return type
    The docblock parser now correctly handles @method tags that specify static as their return type.

Linter

  • Made strict-assertions rule less strict
    The strict-assertions rule has been adjusted to reduce noise while still catching problematic assertion patterns.

WASM

  • Matched analyzer default settings
    The WASM build now uses the same default analyzer settings as the native build for consistent behavior.

Reporting

  • Fixed duplicate issue collection
    Removed unnecessary duplicate checking when collecting issues, improving performance and correctness.

Performance Improvements

  • Optimized type combiner
    Significant performance improvements to the type combination logic, reducing analysis time for codebases with complex type operations.

  • Lowered analysis thresholds
    Adjusted internal thresholds for formula complexity and algebra operations to improve analysis speed on large codebases without sacrificing accuracy.

  • Early return optimization for pragma collection
    Added early return when no pragmas are present, avoiding unnecessary processing.

Build Improvements

  • Profile-Guided Optimization (PGO) for Tier 1 targets
    Release binaries for macOS and Windows are now built with PGO, resulting in 5-15% performance improvements.

Full Changelog: 1.0.0-rc.10...1.0.0-rc.11

Mago 1.0.0-rc.10

05 Dec 03:16
bbe08d2

Choose a tag to compare

Mago 1.0.0-rc.10

This release focuses on reducing false positives across multiple analysis scenarios, improving type system accuracy, and enhancing PHP compatibility.

Bug Fixes

Analyzer

  • Fixed impossible type assertion false positive when comparing interfaces - a class can implement multiple interfaces, so Foo can be Bar at runtime (#707)
  • Corrected template resolution regression affecting PSL and other libraries using generic parameters from class-strings
  • Fixed false positive when checking $value === [] on non-null or mixed types (#701)
  • Resolved false positive unimplemented-abstract-property-hook incorrectly reported on interfaces
  • Infer Iterator key/value types from key() and current() method return types
  • Support float and array-key in string concatenation with improved __toString trait detection
  • Fixed callable-to-array reconciliation and interface throwable checks in catch blocks
  • Added missing $_COOKIE superglobal

Codex

  • Resolved false positive redundant condition for integer range identity comparisons (#706)
  • Fixed trait self type resolution to use intersection with @require-implements/@require-extends constraints

Prelude

  • Fixed call_user_func and sprintf stubs with Stringable support

Improvements

Composer

  • Added PHP 8.5 and 8.6 as compatible versions (#699)

Full Changelog: 1.0.0-rc.9...1.0.0-rc.10

Mago 1.0.0-rc.9

04 Dec 07:21
94bdacd

Choose a tag to compare

Bug Fixes

  • Fixed stack overflow when analyzing projects with complex generic types - Analysis of certain codebases (including tempest-framework) would crash with a stack overflow due to infinite recursion in type expansion. Added cycle detection to prevent recursive expansion loops while preserving correct type resolution.

Full Changelog: 1.0.0-rc.8...1.0.0-rc.9

Mago 1.0.0-rc.8

04 Dec 05:43
f739ab1

Choose a tag to compare

Overview

This release brings significant analyzer enhancements including full property hooks support, unused template parameter detection, and improved type assertion analysis. The linter gains a new variable-name rule, and the prelude is updated with MongoDB, Redis, and URI extension stubs.

Features

Analyzer

  • Unused Template Parameter Detection: The analyzer now detects and reports unused template parameters on classes, interfaces, traits, functions, and methods
  • Impossible Type Assertion Detection: Added detection for impossible type assertions in @assert annotations, helping catch logical errors in assertion docblocks
  • Negation Operator Validation: The analyzer now validates operand types for the negation (-) operator, catching type errors early

Codex

  • Full Property Hooks Support: Complete implementation of PHP 8.4 property hooks, including type inference, visibility checks, and backed property reference validation
  • Full properties-of<T> Support: The properties-of<T> type is now fully implemented with proper visibility filtering (public-properties-of<T>, protected-properties-of<T>, private-properties-of<T>)

Linter

  • New variable-name Rule: Enforces consistent variable naming conventions (snake_case or camelCase) with configurable options for parameter checking and promoted property exclusion (#695)

Bug Fixes

Analyzer

  • Fixed handling of by-reference values in array literals
  • Prevented duplicate catch type errors by inlining the avoid-catching-error heuristic check (#696)
  • Redundant negated type assertions (e.g., !is_string() on an int) are now reported as warnings instead of impossible errors
  • Removed incorrect assertion from fclose() stub

Linter

  • The literal-named-argument rule now skips the first argument by default, as it's typically self-explanatory. A new check-first-argument option preserves the original behavior (#694)

Playground

  • Fixed an issue where shared playground URLs would immediately lose their state upon loading

Documentation

  • Replaced outdated PSR-12 references with PER Coding Style (PER-CS) (#698)

Prelude Updates

  • New Extension Stubs: Added stubs for MongoDB, Redis, and URI extensions
  • Updated Stubs: Synced DOM, Intl, Reflection, and Standard extension stubs with phpstorm-stubs

Full Changelog: 1.0.0-rc.7...1.0.0-rc.8

Mago 1.0.0-rc.7

02 Dec 19:54
b8fbffa

Choose a tag to compare

Features

Type System

  • Added support for int-mask<1, 2, 3> and int-mask-of<Foo::*> types
  • Added support for literal-float type

Analyzer

  • Added support for exception filtering

Playground

Bug Fixes

Formatter

  • Fixed indentation for flattened binary chains with trailing comments
  • Fixed idempotence issue with elvis operator in arrow function bodies

Analyzer

  • Fixed template constraint resolution to use inferred types instead of declared constraints (#676)
  • Fixed type assertions for mixed variables in if statements
  • Fixed yoda style handling in assertion scrapper

Codex

  • Fixed expansion state not being reset after expanding

Linter

  • Fixed literal-named-argument rule to ignore variadic functions

Prelude

  • Fixed multiple PHP stub docblocks
  • Added return type to ReflectionNamedType::getName method (#673)

CLI

  • Updated init command to match the latest configuration schema

WASM

  • Fixed duplicate issues reported by both linter and analyzer
  • Fixed timing being enabled in wasm builds

Improvements

Performance

  • Improved type expander and comparator performance
  • Improved metadata populator performance
  • Refactored codex to use bitflags for TUnion properties

CLI

  • Standardized exit codes

Full Changelog: 1.0.0-rc.6...1.0.0-rc.7

Mago 1.0.0-rc.6

26 Nov 21:44
d7fe3d0

Choose a tag to compare

Bug Fixes

Analyzer

  • Use constant REQUEST_TIME for $_SERVER to ensure deterministic error messages for baseline matching (#669)
  • Consider template constraints when checking int/float disjointness (#659)
  • Mark $_SESSION superglobal as possibly undefined (#670)
  • Allow array destructuring on ArrayAccess implementations (#671)
  • Consider possibly_undefined when checking redundant nullsafe operator (#672)
  • Resolve array access type using only matching keys from union index type (#666)
  • Check parent classes for pseudo methods to prevent false positive missing-magic-method (#667)

Codex

  • Sort docblock inheritance by hierarchy depth to ensure parents are processed first (#663)
  • Resolve templates when inheriting assertions from parent methods (#660)
  • Infer arithmetic operations as int|float instead of mixed (#664)
  • Treat arrays with required keys as non-empty in containment check (#665)

Semantics & Formatter

  • Require arrow functions on RHS of |> to be parenthesized (#662)

Improvements

Baseline

  • Introduced a new loose baseline variant as the default format, which is more resilient to code changes. The loose format matches issues by (file, code, message) tuple with occurrence counts, making baselines stable even when line numbers shift. The previous strict format (exact line matching) remains available via configuration. (#492)

Full Changelog: 1.0.0-rc.5...1.0.0-rc.6

Mago 1.0.0-rc.5

25 Nov 02:11
09b1f6e

Choose a tag to compare

Bug Fixes

Syntax

  • Fixed parsing of integers prefixed with 0 to correctly interpret them as octal numbers

Analyzer

  • Fixed type narrowing for in_array and Psl\Iter\contains (#658)
  • Fixed assertion scrapping for in_array and Psl\Iter\contains
  • Fixed int/float disjointness handling in conditional type narrowing (#656)

Codex

  • Fixed child native return types to take precedence over parent docblock types (#657)

Improvements

PHP 8.5 Support

  • Semicolon as a switch case separator is now deprecated for PHP >= 8.5

CLI

  • Removed deprecated --no-color flag (use --colors never instead)

Internal

  • Refactored codex populator into modular subcomponents

Full Changelog: 1.0.0-rc.4...1.0.0-rc.5

Mago 1.0.0-rc.4

24 Nov 00:50

Choose a tag to compare

Features

Partial Function Application (RFC)

Mago now fully supports PHP 8.6's Partial Function Application RFC, enabling first-class callable creation using placeholder syntax. You can use positional (?), named (name: ?), and variadic (...) placeholders to create closures from existing functions and methods, with full type inference and validation to ensure type safety across your partial applications.

PHP Version Support

  • Added support for PHP 8.5, which was released just days ago
  • Switched minimum supported PHP version from 7.4 to 8.0

Looking Ahead to PHP 8.6

This release demonstrates Mago's unique capability to stay ahead of the PHP ecosystem. While PHP 8.6 won't be released for another year and the Partial Function Application RFC hasn't even been merged into PHP yet, Mago already provides full support for this feature. By controlling our entire stack, from parser to analyzer, we can implement and validate upcoming PHP features much faster than traditional tools, giving developers early access to write future-proof code with confidence.

Linter

  • New no-redundant-yield-from rule to identify unnecessary yield from expressions that can be simplified

Bug Fixes

Analyzer

  • Fixed incorrect parameter type mapping when using named placeholders that reorder parameters in partial function application
  • Corrected false positives when real methods are documented with @method annotations in child classes for return type refinement
  • Fixed variable invalidation logic to properly invalidate descendant variables when passed by reference
  • Resolved trait constant access issues when using self, static, and $this keywords
  • Suppressed redundant unused statement issues in test contexts
  • Disabled reporting of #[Override] attribute issues before PHP 8.3
  • Corrected impossible condition detection when comparing numeric and array-key types
  • Eliminated invalid and redundant auto-fix suggestions
  • Fixed array_merge() result computation when using empty arrays as arguments

Codex

  • Improved docblock inheritance logic to respect explicit return types in child classes instead of inheriting parent types
  • Enhanced overall docblock inheritance handling with better resolution rules

Database

  • Corrected path normalization for Windows systems during test execution
  • Improved pattern specificity resolution for path and include conflicts
  • Fixed file logical name usage when updating files during watch mode

Linter

  • Prevented false positives in no-redundant-math rule for float division operations
  • Disabled sensitive-parameter rule for PHP versions below 8.2
  • Fixed incorrect static closure suggestions when nested closures reference $this

Formatter

  • Preserved parentheses around constant access expressions in instanceof binary operations

Docblock

  • Added support for multiple spaces after colons in callable type annotations

Collector

  • Disabled reporting of unfulfilled expectations during incremental analysis to reduce noise

Installation

  • Fixed installation script incorrectly exiting successfully when the download server is unavailable

Improvements

Syntax

  • Tagged Expression, Statement, and Node enums as #[non_exhaustive] for future compatibility

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

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