github vimeo/psalm 7.6.0

one hour ago

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 @mixin lookup 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

New Contributors

Full Changelog: 7.5.0...7.6.0

Don't miss a new psalm release

NewReleases is sending notifications on new releases.