Skip to content

fix(pointcut): follow the documented name wildcard and alternation rules - #775

Merged
lisachenko merged 1 commit into
masterfrom
feature/focused-brahmagupta-d8a6bz
Oct 22, 2026
Merged

lisachenko merged 1 commit into
masterfrom
feature/focused-brahmagupta-d8a6bz

Conversation

@lisachenko

Copy link
Copy Markdown
Member

What and why

Fixes #774, found while re-checking #327. Two name matching rules contradicted the "Names and wildcards" table in docs/pointcuts.md:

  • * needed at least one character. Sensor* skipped the class Sensor itself, get* skipped a method named get, and an Exc* return type pattern skipped the type Exc. * now stands for any characters of one name part, including none, and still never crosses a \. NamePointcut and ReturnTypePointcut agree on it.
  • | spanned the whole qualified name. Ns\Sensor|SensorValue meant Ns\Sensor or the global class SensorValue, and skipped Ns\SensorValue. The grammar already limits | to one name part, so NamePointcut now translates the pattern part by part and groups the alternatives of each part (which also keeps the anchors strict, see When i use the pattern that selects multiple values, all method are starting by one of values are matched #115).

Changes:

  • src/Aop/Pointcut/NamePointcut.php: new compilePattern(), one regex group per name part with alternatives.
  • src/Aop/Pointcut/ReturnTypePointcut.php: * is zero or more characters.
  • Tests: unit cases in NamePointcutTest, end-to-end cases through the parser in PointcutSemanticsTest (class and member names, global class, strict alternatives), two return type cases. Nine of them fail on the old code.
  • docs/pointcuts.md states both rules explicitly; CHANGELOG.md and UPGRADE-4.0.md list the behaviour change.

Behaviour change for existing pointcuts, listed as a BC break (4.0 is unreleased):

  • set* now also matches a method called set(), Foo* also matches Foo.
  • A pattern that listed classes of different namespaces in one expression (Foo\A|Bar\B) must be written as execution(public Foo\A->*(*)) || execution(public Bar\B->*(*)). No pointcut in the repository, demos or docs relied on either old rule.

The wildcard ** is unchanged.

Checklist

  • The title follows Conventional Commits (type(scope): summary)
  • Tests cover the change
  • composer check passes
  • User-facing or breaking changes are in CHANGELOG.md (and the upgrade guide for breaking changes)

Generated by Claude Code

Two name matching rules contradicted the "Names and wildcards" table of
docs/pointcuts.md:

- `*` was translated to "one or more characters", so `Sensor*` skipped
  the class `Sensor` itself, `get*` a method named `get` and an `Exc*`
  return type pattern the type `Exc`. It now stands for any characters of
  one name part, including none, and still never crosses a namespace
  separator. NamePointcut and ReturnTypePointcut agree on it.
- `|` was applied to the whole qualified name, so `Ns\Sensor|SensorValue`
  meant `Ns\Sensor` or the global class `SensorValue` and skipped
  `Ns\SensorValue`. The grammar already limits `|` to one name part;
  NamePointcut now translates the pattern part by part and groups the
  alternatives of each part, which also keeps the anchors strict (#115).

Both are listed as BC breaks in the changelog and the upgrade guide.

Fixes #774

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018dKKrvU4XVsKSfKRXPpwUS
@codecov

codecov Bot commented Oct 22, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.20%. Comparing base (ea73099) to head (745fb0e).

Additional details and impacted files
@@            Coverage Diff            @@
##             master     #775   +/-   ##
=========================================
  Coverage     98.19%   98.20%           
- Complexity     1910     1913    +3     
=========================================
  Files           113      113           
  Lines          4995     5000    +5     
=========================================
+ Hits           4905     4910    +5     
  Misses           90       90           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@lisachenko
lisachenko marked this pull request as ready for review October 22, 2026 00:30
@lisachenko
lisachenko merged commit 04e13a9 into master Oct 22, 2026
14 checks passed
@lisachenko
lisachenko deleted the feature/focused-brahmagupta-d8a6bz branch October 22, 2026 00:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

[Pointcut] * never matches an empty string and | alternation spans the whole qualified name

2 participants