This release brings significant improvements including method call assertions, a new parser configuration section, fault-tolerant parsing, new linter fixers, and numerous bug fixes addressing false positives in the analyzer. A massive thank you to everyone who contributed!
✨ Features
Analyzer
- Method call assertions: Support for
@assert-if-trueand@assert-if-falsedocblock assertions on method calls, enabling type narrowing based on method return values (#763) - Unreachable else detection: Detect unreachable else clauses when all enum cases are already handled in if-elseif chains (#356)
Linter
- Fixer for
no-redundant-string-concat: Automatically fix redundant string concatenations (#1018) by @dotdash - Fixer for
no-trailing-space: Automatically remove trailing whitespace (#1017) by @dotdash - Fixer for
braced-string-interpolation: Automatically add braces around interpolated variables (#1013) by @dotdash - Configurable early-continue threshold: New
max-statements-before-early-continueoption to control when theearly-continuerule recommends refactoring (#979, #975) by @dotdash
Parser
- New
[parser]configuration section: Configure parser-level settings including the ability to disable short opening tag recognition viaenable-short-tags = false(#841) - Fault-tolerant parsing: Major parser rewrite introducing fault-tolerant parsing, a foundational step towards LSP support. The parser now recovers from syntax errors and continues analysis, providing better diagnostics for files with minor issues (#988) by @azjezz
CLI
FORCE_COLORenvironment variable: Force colored output even when piping to files or other commands, taking precedence overNO_COLOR(#1012)
⚡ Performance
- Parser rewrite: Complete rewrite of the parser resulting in ~3x faster parsing and ~2x faster type parsing (#988) by @azjezz
- MiMalloc allocator: Use MiMalloc on GNU targets for improved memory allocation performance (#999) by @dotdash
- Atom optimizations: Improve performance of
ascii_lowercase_atomfor common cases
🐛 Bug Fixes
Analyzer
- False positive with references in closures: Skip undefined variable errors for reference captures in closure use clauses (#1003, #982) by @kzmshx
- False positive with intersection types: Resolve properties on intersection types from instanceof checks (#996)
- False positive in intersection type ordering: Flatten nested intersection types during scanning to resolve method lookup (#1002, #1004)
- False positive with asymmetric visibility: Allow inheritance of properties with
private(set)in child classes (#985) - False positive with nullsafe chains: Clear nullsafe_null flag when null is removed during type narrowing (#998)
- False positive with redundant comparisons in loops: Suppress redundant comparison warnings inside loops where values change (#1006)
- False positive with dynamic array access: Mark list access with non-literal index as possibly undefined (#1005)
- False positive with empty() on optional keys: Narrow possibly-undefined array keys after
!empty()check (#973) - False positive with array building in loops: Convert never-typed array elements to empty arrays inside loops (#976, #968)
$_SERVERarray shape typo: Fixarvctypo toargcin$_SERVERarray shape (#990, #972) by @kzmshx
Formatter
- Comments not moving with sorted methods: When
sort-class-methodsis enabled, comments now move with their associated methods instead of stacking on the first method (#994) - Preset override bug: User-specified values that match framework defaults are no longer incorrectly overwritten by preset values (#1010)
- Pint preset accuracy: Set
space-around-assignment-in-declaretofalsein Pint preset to match actual Pint behavior (#1011, #974) by @kzmshx
Linter
- False positive with aliased imports: Handle aliases correctly in same-namespace import redundancy check (#989, #983) by @kzmshx
- False positive with reference captures: Skip
inline-variable-returnwhen closure has reference capture (#997, #981) by @kzmshx
Docblock
- UTF-8 boundary panic: Fix panic on multi-byte UTF-8 whitespace in docblock parsing (#971, #967) by @kzmshx
Prelude (Type Stubs)
- Array pointer functions: Improve signatures of
end,prev,next,resetwith@param-outannotations to preserve array type after by-reference calls (#980, #984) array_unshiftsignature: Preserve list type in@param-outannotation (#970)
Codex
- Constant references in defaults: Resolve constant references in function default parameter values, fixing issues with functions like
pathinfo()where the second argument is optional (#969) - Internal interfaces: Hide internal interfaces from public API (#1000)
🏗️ Internal
- Update
.gitattributesto exclude more files from export (#1008) by @shyim - Add
conststo typos dictionary
🙏 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 — #356, #981, #982, #983
- @Bleksak — #984, #1000, #1002, #1004, #1006
- @bronek89 — #998, #1005
- @ddanielou — #969, #972
- @Dima-369 — #968, #973, #977
- @dotdash — #975
- @dynasource — #980
- @innocenzi — #841
- @klunejko — #994
- @KorvinSzanto — #985, #996
- @kzmshx — #1010
- @Nadyita — #970
- @norberttech — #763
- @scop — #1012
- @valpuia — #974
Full Changelog: 1.3.0...1.4.0