Skip to content

Pointcut expressiveness gaps for modern type/modifier system (union/DNF return types, readonly/private(set)/final) #604

Description

@lisachenko

Summary

Two pointcut components lag behind the modern PHP type/modifier system. Neither breaks weaving — matching is just silently impossible or wrong for these constructs. From the PHP 8.5 support audit (PR #597).

1. ReturnTypePointcut cannot match union / intersection / DNF types

src/Aop/Pointcut/ReturnTypePointcut.php:27-29 documents it:

This implementation currently doesn't support properly matching of complex types, thus union/intersection/DNF types are not supported yet here.

Matching is a string compare + wildcard on (string) $reflector->getReturnType() (line ~76), so execution(public **->*(*): Iterator) never matches Iterator|Generator, and member order (A&B vs B&A) defeats exact matches.

Proposed: normalize both sides into sorted member sets (split on | at depth 0, & inside parens), and let a single-type pattern match if any union member matches; document the semantics chosen.

2. ModifierPointcut has no predicates for modern modifiers

src/Aop/Pointcut/ModifierPointcut.php matches only the classic IS_PUBLIC/IS_PROTECTED/IS_PRIVATE/IS_STATIC/IS_FINAL/IS_ABSTRACT bitmask, and src/Aop/Pointcut/PointcutGrammar.php only accepts public|protected|private|final keywords. Not expressible today:

  • readonly properties/classes (8.1/8.2)
  • asymmetric visibility private(set) / protected(set) (8.4; static asymmetric visibility in 8.5)
  • hooked vs plain properties (8.4)
  • final properties (8.4)

Proposed: extend the grammar with readonly, private(set), protected(set) modifier tokens mapped onto the corresponding ReflectionProperty predicates (isReadOnly(), isPrivateSet(), isProtectedSet(), isFinal()), with the existing matcher-gate caveat that readonly/hooked/static properties are excluded from access() interception anyway (useful mainly for negative filters and class filters).

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