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.
What is missing
PHP 8.4 property hooks and asymmetric visibility (
public private(set) int $x) do not fit the member model.Visibility. A property withprivate(set)is visible for read and not for write, and the model cannot say so.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
ClassInfofactories), one walk (MemberResolver), and predicates onMemberInfo. Adding a member kind is oneMemberKindcase 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.
MemberResolverapplies it in one place (isVisible).PropertyInfocarries visibility per operation. No consumer branches on it.Acceptance
TypeGraphParityTestcovers a hooked property and aprivate(set)property, with reflection as the oracle (ReflectionProperty::isPrivateSet()and friends).private(set)property; a read-position one does.src/branches onMemberKindor on the access operation outsideMemberResolverand the factories.KindBranchRulealready confinesMemberKind; the operation value is registered with it when it is added.When
After the last step of
docs/architecture/build-manifest.mdlands. Not before.This issue body was written by AI and has not been reviewed line by line by a human.