Repository navigation
What's Changed
Features
- Make allowStringToStandInForClass consistent across class-string usages by @orklah in #13702
- Add
Codebase::addReportableFiles()to report issues in files Psalm doesn't analyze by @alies-dev in #13725 - Narrow array_filter() results with first-class callable callbacks by @kamil-tekiela in #12524
- Narrow a string to empty or non-empty from strlen() compared with 0 or 1 by @jirkace in #12597
- Report a float that loses its fraction as an operand of a bitwise or modulo operation by @jirkace in #12623
Fixes
- fix(algebra): an operand of an || that can never be true is paradoxical by @jirkace in #13689
- fix(reconciler): a lowercase or literal string can be asserted to be the name of a class or a callable by @jirkace in #13685
- fix(reconciler): !is_iterable() drops the objects that are Traversable by @jirkace in #13686
- Fix false positive null array access diagnostics in unset() by @orklah in #13663
- Fix dynamic method call reachability in unused code analysis by @orklah in #13668
- fix(algebra): a not-null check after isset() of the same variable is redundant by @jirkace in #13692
- fix(scope): a switch default that falls through without returning does not end the function by @jirkace in #13684
- fix(unused): a read in a try body after an assignment does not use the values the assignment overwrote by @jirkace in #13704
- fix(reconciler): array_key_exists() of a string in an array of int keys narrows it to the keys as strings by @jirkace in #13690
- fix(properties): a class extending a universal object crate keeps the properties it declares by @jirkace in #13703
- fix(reconciler): a negated isset of a possibly undefined variable is null by @jirkace in #13706
- Fix
@mixinlookup order: own, traits, parents; first declared wins by @alies-dev in #13694 - Print exact types in argument, return type and signature mismatch messages by @alies-dev in #13717
- Fix crash when Psalm is used as a library without a check method (nullable
$project_files) by @alies-dev in #13719 - Fix stubs that redeclare properties of builtin or already stubbed classes by @alies-dev in #13720
- Don't report an || operand reading a variable the condition assigns by @orklah in #13724
- Fix overly broad invalidation of memoized getters after unrelated object mutations by @orklah in #13662
- fix(context): a block that forgot a variable leaves its type as it was before the block by @jirkace in #13705
- Fix: an inaccessible method hides the mixin method reached through
__call()by @alies-dev in #13727 - Keep the key and value types of a negated iterable assertion on Traversable by @orklah in #13732
- Treat the bound of a template a receiver leaves out as a stand-in by @orklah in #13733
- Resolve static::$p to its property when it is passed by reference by @orklah in #13730
- Report a stringable object in the index column of array_column since PHP 8 by @orklah in #13731
- Keep the invariance check of a template nested in a generic param by @orklah in #13729
- Remember a property of an interface that a shape or a mixin gives by @orklah in #13734
- Nullsafe call compared to a bool literal no longer narrows its receiver to null by @0xABCD01 in #13602
- fix(algebra): four unsound simplifications of simplifyCNF() #13736 by @jirkace in #13745
- fix(algebra): two clauses of one condition that are not reconcilable do not share a hash #13737 by @jirkace in #13747
- fix(foreach): a key that isset() added to the item in a foreach by reference is not written back by @jirkace in #13691
- A sealed array shape with optional keys can be a list (#11905) by @jirkace in #12763
- fix(stubs): DateTime::createFromFormat() reports its false return like DateTimeImmutable's by @jirkace in #13350
- Fix: Report an unparsable @method return type instead of crashing by @yvo-niedrich in #13608
- fix(cli): don't crash when clearing a cache directory another process writes to by @jirkace in #13418
- Inherit the parent's @var type for a redeclared property without one by @alies-dev in #13746
- extract() with EXTR_SKIP defines a possibly undefined variable by @orklah in #13761
- Report a possibly undefined variable at the use() of a closure and in an arrow function by @orklah in #13760
- Fix --alter for a variable defined by a previous loop iteration by @orklah in #13759
- Let stubs refine property types listed in PropertyMap by @alies-dev in #13755
- A possibly undefined variable reads and reconciles as null when undefined by @orklah in #13762
- Evaluate the keys of an array item before the value by @orklah in #13758
- fix(algebra): a native symbol guard of function_exists() is no PHP_VERSION_ID check #13736 by @jirkace in #13764
- fix(types): do not crash on a type alias imported from a class that is not scanned yet by @jirkace in #13192
- fix(property): honour @Property on assignment without __set #5092 by @jirkace in #13711
- fix(call): do not crash on a method call on a variable typed with an unresolvable static by @jirkace in #13191
- fix(isset): isset() on a typed property of a class without a constructor is not redundant #10252 by @jirkace in #13286
- fix(loops): a variable the loop condition always assigns is defined after the loop #7072 by @jirkace in #13266
- Fix wrong-case property names in PropertyMap by @alies-dev in #13771
- Keep the type of a possibly undefined variable defined in some branches by @orklah in #13751
- fix(unused-code): don't report params of a method whose body isn't analysed as unused by @jirkace in #13384
- Don't crash on a docblock return or assertion type that is empty by @jirkace in #12719
- fix(conditions): keep what an elseif or else writes after the first branch updated the variable #10328 by @jirkace in #13281
- fix(algebra): the clauses of an if or a switch case about a variable its condition assigns are dropped #13739 by @jirkace in #13770
- fix(array): appending to a nested element of a sealed keyed array no longer asserts by @jirkace in #13029
- fix(int-mask): two bit sets compared for equality are no ambiguous comparison by @jirkace in #13713
- Keep self-contradicting conditions for the reconciler #13736 by @orklah in #13754
- fix(docblock): an int-mask accepts a global constant used from a namespace by @jirkace in #13200
Docs
- Document calling
addReportableFiles()in the plugin entry point by @alies-dev in #13728 - Document the conditional default of findUnusedVariablesAndParams by @roxblnfk in #13750
- Document how library authors help Psalm understand their package by @alies-dev in #13773
Internal changes
- Drop unneeded suppressions from invalid-code test cases by @orklah in #13715
- Drop ignored_issues entries that valid-code test cases never need by @orklah in #13716
- Split PsalmEndToEndTest so ParaTest runs its tests in parallel by @orklah in #13722
- Require psalm/psalm-plugin-api 0.4.5 by @alies-dev in #13735
- Remove redundant branches and statements repeated in every branch by @orklah in #13749
- Disable CircleCI by @orklah in #13752
Other changes
- Find references to a method also where its return value is used by @shu-chen-dot-ca in #13667
New Contributors
- @0xABCD01 made their first contribution in #13602
- @yvo-niedrich made their first contribution in #13608
Full Changelog: 7.5.0...7.6.0