KEMBAR78
Missing property hooks checks · Issue #12336 · phpstan/phpstan · GitHub
Skip to content

Missing property hooks checks #12336

@ondrejmirtes

Description

@ondrejmirtes

Feature request

After phpstan/phpstan-src#3746 there is still ground left that could be covered with static analysis. The following lists consist of ~30 todos that could be implemented for robust checks around property hooks.

PHP RFC

Fatal declarations

These situations make PHP fatal-error immediately during the class loading. This is easy low hanging fruit.

  • Hooked properties cannot be readonly
  • Readonly classes cannot have hooked properties
  • Final property before 8.4
  • Static properties cannot be hooked
  • Virtual property cannot have default value
  • hooked properties cannot be unset()
  • Returning by reference from a void function is deprecated - &set
  • Check parameters in get and set hooks, count, no default values, no byRef, no variadic, no promoted
  • If a trait and a class where it is used both declare the same property with hooks, an error is issued.
  • Abstract property from interface/abstract class should be implemented in non-abstract class
  • Interface prescribes whether implemented property should be publicly readable and writable. This can be accomplished in many ways, with virtual or non-virtual properties, with or without hooks.
  • A get hook in an interface may be satisfied by either a get or &get hook in a class. An interface may alternatively specify a &get hook in its definition, in which case an implementing class must also use a &get hook. This behavior is identical to how methods in interfaces already work.
  • Of note, an interface property that only requires get may be satisfied by a public readonly property, as the restrictions of readonly only apply on write. However, an interface property that requires set is incompatible with a readonly property, as public-write would be disallowed.
  • With abstract properties (on an interface or abstract class) or virtual properties, it is possible to declare a property that has only a get or set operation. As a result, abstract properties or virtual properties that have only a get operation required MAY be covariant. Similarly, an abstract property or virtual property that has only a set operation required MAY be contravariant. Once a property has both a get and set operation, however, it is no longer covariant or contravariant for further extension. That is, it is now invariant (as all properties are in 8.3 and earlier).
  • A readonly property with a get or set hook is disallowed and will throw a compile error. That also means that a child class may not redeclare and add hooks to a readonly property, either.
  • Check overriden hook from parent - final hook cannot be overriden, check set hook contravariance, maybe more checks
  • Detect hook duplicates - multiple get, get and &get etc.
  • Abstract private not allowed
  • Final private not allowed
  • Cross-check same properties inherited from multiple interfaces in a single class

Property hook body checks

  • Unused set hook parameter
  • Disallow magic access like $this->{‘haha’} inside hooks for virtual properties
  • Hook calls a method, method tries to access the same hooked property - PHP errors, PHPStan should detect it.

Behaviour checks & changes

  • Accessing parent hooks check parent::$propName::get(), MutatingScope::resolveType support
  • processAssignVar: with $isAssignOp true both get hooks and set hooks throw points should be considered
  • __PROPERTY__ exists only on 8.4+
  • Ability to mark get hooks as pure or impure
  • phpstan-deprecation-rules rule for invoking deprecated set/get hook
  • Writing array index to hooked property not always allowed, depends on a table described in the RFC
  • the presence of a set hook must necessarily also disallow acquiring a reference to a property
  • A caller may only obtain a reference to a property that has declared &get. Attempting to get a reference on a get property will trigger an error.
  • Casting object to array - skip virtual properties
  • the #[\Override] attribute can be applied to a hook, and it will treat the parent property's hook as its parent and behave accordingly.
  • Support for stub files - @param above set hook. This might already work thanks to createUserlandMethodReflection but needs to be tested.

Did PHPStan help you today? Did it make you happy in any way?

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions