Skip to content

Model member kind and access context as axes with one extension point each #443

Description

@Firehed

What is missing

PHP 8.4 property hooks and asymmetric visibility (public private(set) int $x) do not fit the member model.

  • A member has one Visibility. A property with private(set) is visible for read and not for write, and the model cannot say so.
  • A hook is a member shape that is neither a method nor a plain property.

Today the effect is small: a private(set) property is offered in a write position from outside its class, and a hooked property is read as a plain property.

The two axes

RFC 1 Appendix A names both as (target) rows. Each gets exactly one extension point. A change that touches a consumer (completion, hover, definition, signature help) to support either is the M×N shape this project forbids and is rejected in review.

Member kind. One extraction (the two ClassInfo factories), one walk (MemberResolver), and predicates on MemberInfo. Adding a member kind is one MemberKind case and one factory case. No consumer edit.

Access context. One value, built by the positional layer, that says who is asking and for what: the vantage class, the operation (read, write, call), and whether the access is static. MemberResolver applies it in one place (isVisible). PropertyInfo carries visibility per operation. No consumer branches on it.

Acceptance

  • TypeGraphParityTest covers a hooked property and a private(set) property, with reflection as the oracle (ReflectionProperty::isPrivateSet() and friends).
  • A write-position completion from outside the class does not offer a private(set) property; a read-position one does.
  • Hover, definition, and completion agree on every fixture that has a hook or asymmetric visibility (the feature-matrix grid, if it exists, is the check; otherwise one test per handler).
  • No file in src/ branches on MemberKind or on the access operation outside MemberResolver and the factories. KindBranchRule already confines MemberKind; the operation value is registered with it when it is added.

When

After the last step of docs/architecture/build-manifest.md lands. Not before.


This issue body was written by AI and has not been reviewed line by line by a human.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions