Skip to content

feat(core)!: enable function and initialization interception from registered pointcuts - #767

Merged
lisachenko merged 5 commits into
masterfrom
feature/peaceful-johnson-8hibba
Oct 15, 2026
Merged

lisachenko merged 5 commits into
masterfrom
feature/peaceful-johnson-8hibba

Conversation

@lisachenko

Copy link
Copy Markdown
Member

What and why

Users no longer set Features::INTERCEPT_FUNCTIONS or Features::INTERCEPT_INITIALIZATIONS. The framework now works out from the registered pointcuts what it has to enable, and both flags are removed (BC break, same treatment as PARAMETER_WIDENING).

  • Function interception: the flag only short-circuited AdviceMatcher::getAdvicesForFunctions(). That method already skips every advisor without a KIND_FUNCTION pointcut, so an execution(Namespace\function(*)) pointcut now weaves without a flag, and with no such pointcut it still costs nothing.
  • Initialization interception: ConstructorExecutionTransformer is now always registered. Its getSourceMarkers() returns [] (rule off) unless an advisor with a KIND_INIT pointcut is registered. SyntaxTreeRewriter already drops a prefiltered rule that has no matching marker, so a file needing no rule is still never walked. PrefilteredNodeRewriter documents that an empty list turns a rule off.
  • Lazy aspects: the new internal Go\Core\AdvisorIndex loads the aspects that are not loaded yet on the first query, the same way WeavingTransformer does on a cache miss. It keeps the union of the advisors' pointcut kinds and collects it again whenever the container's cached getServicesByInterface(Advisor::class) array changes, which happens after any registration. An aspect registered or loaded later is therefore picked up. Warm-cache requests never build any of this.
  • Passing bit 1 or 2 in features fails with an InvalidConfigurationException that tells the user to drop the flag.
  • INTERCEPT_INCLUDES (legacy include routing, not driven by pointcuts) and PREBUILT_CACHE are unchanged.

Behaviour change worth noting: an initialization(...) pointcut without the flag used to weave __initialization() but never run its advice. The fixture project's InitializationAspect was in exactly that state. It now intercepts new, and a new functional test checks this. With the gate deliberately broken, that test fails.

Transformation performance (composer test:performance:transformation, base and head alternated 3×, JIT disabled), average ratios:

Case Base Head
default rules 0.102 0.098
all rules 1.319 1.315
WeavingTransformer 0.282 0.282

Checklist

  • The title follows Conventional Commits (type(scope): summary)
  • Tests cover the change (new AdvisorIndexTest, rule on/off cases in ConstructorExecutionTransformerTest, removed-flag cases in AspectKernelTest, functional ClassWeavingTest::testInitializationAdviceRunsOnNewInWovenCode)
  • composer check passes (cs, phpstan level 10, 3116 tests)
  • User-facing or breaking changes are in CHANGELOG.md (and the upgrade guide for breaking changes)

🤖 Generated with Claude Code

https://claude.ai/code/session_01Hhj7Aqnac5xDA6L31WeJs8


Generated by Claude Code

…istered pointcuts

Features::INTERCEPT_FUNCTIONS and Features::INTERCEPT_INITIALIZATIONS made users
switch on machinery that the registered pointcuts already describe. Both are removed:

- execution(Namespace\function(*)) pointcuts weave function proxies without a flag;
  AdviceMatcher already skips every advisor without a KIND_FUNCTION pointcut.
- ConstructorExecutionTransformer is always registered and turns itself on only while
  an advisor with a KIND_INIT pointcut is registered. The new internal AdvisorIndex
  loads the aspects that are not loaded yet (lazy aspects included) and collects the
  pointcut kinds again after every registration in the container.

Before, an initialization(...) pointcut without the flag wove __initialization() but
never ran its advice. Passing one of the removed bits now fails with a hint to drop it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Hhj7Aqnac5xDA6L31WeJs8
…nly API

expectExceptionMessageIsOrContains() is missing on the lowest supported PHPUnit,
and expectExceptionMessage() is deprecated on the newest one.

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

codecov Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.82%. Comparing base (02b9a4c) to head (b2816cd).
⚠️ Report is 6 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff            @@
##             master     #767   +/-   ##
=========================================
  Coverage     97.81%   97.82%           
- Complexity     1841     1847    +6     
=========================================
  Files           104      105    +1     
  Lines          4849     4867   +18     
=========================================
+ Hits           4743     4761   +18     
  Misses          106      106           

☔ 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.

AdvisorIndex now loads the aspects before the weaver runs in the default pipeline,
so the weaver's own loading path (kept for kernels that override the transformer
services) lost its indirect coverage.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Hhj7Aqnac5xDA6L31WeJs8
Comment thread src/Core/AspectKernel.php Outdated
Comment thread src/Core/AspectKernel.php Outdated
Comment thread UPGRADE-4.0.md Outdated
Feature bit values are internal: bits 1 and 2 are rejected by the generic
unknown-feature validation like any other undefined bit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Hhj7Aqnac5xDA6L31WeJs8
@lisachenko
lisachenko marked this pull request as ready for review October 15, 2026 21:57
@lisachenko
lisachenko merged commit 02cbe01 into master Oct 15, 2026
13 checks passed
@lisachenko
lisachenko deleted the feature/peaceful-johnson-8hibba branch October 15, 2026 21:57
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.

2 participants