Skip to content

Add Phpat usage provider#381

Draft
janedbal wants to merge 2 commits into
masterfrom
phpat-support
Draft

Add Phpat usage provider#381
janedbal wants to merge 2 commits into
masterfrom
phpat-support

Conversation

@janedbal

Copy link
Copy Markdown
Member

Resolves #378.

phpat registers architecture tests as services tagged phpat.test in the PHPStan DI container. At runtime it iterates those services and invokes their public methods that are either named test* or carry the #[TestRule] attribute (see PHPat\Test\TestParser and PHPat\Test\TestExtractor in phpat's source). Because these invocations are invisible in source code, the test methods were reported as dead — e.g. the Infection\Tests\Architecture\PHPat\... case from the issue.

What this does

PhpatUsageProvider resolves the services tagged phpat.test from the PHPStan container (getServicesByTag) and marks their test* / #[TestRule] public methods as used, mirroring phpat's own selection logic exactly.

  • Constructors of the test classes are not re-emitted here — they are registered DIC services, so PhpStanUsageProvider already covers them.
  • Autoenabled when phpat/phpat is installed (overridable via shipmonkDeadCode.usageProviders.phpat.enabled).

Notes / trade-offs

  • phpat/phpat is added as a dev dependency for the fixture/test. As with the other library providers, this couples our test matrix to phpat's supported PHPStan range — something to keep in mind for future PHPStan bumps.
  • Detection keys on the phpat.test service tag, which is resolved via getServicesByTag and therefore instantiates the tagged test services (this is what phpat itself does). findServiceNamesByType (used by PhpStanUsageProvider) is instantiation-free but is a by-type reverse lookup with no by-tag equivalent on the Container interface, so it can't be reused here.

janedbal added 2 commits June 22, 2026 09:59
phpat registers architecture tests as services tagged "phpat.test" in the
PHPStan DI container, and at runtime invokes their public methods that are
either named `test*` or carry the #[TestRule] attribute (see
PHPat\Test\TestParser / TestExtractor). These invocations are invisible in
source code, so the methods were reported as dead.

PhpatUsageProvider resolves the tagged services from the container and marks
those test methods as used. Constructors of the test classes are already
covered by PhpStanUsageProvider (they are registered DIC services), so this
provider only handles the invoked methods.

Autoenabled when phpat/phpat is installed.

Closes #378

Co-Authored-By: Claude Code
Claude-Session: https://claude.ai/code/session_01WqA3SLHn3vQEytN5C1KCJj
Replace the standalone PhpatUsageProviderTest with the conventional
integration fixture used by every other provider: a real
data/providers/phpat.php with a registered and an unregistered phpat
architecture test, driven through DeadCodeRuleTest.

The container mock now returns an instance of the registered test for the
"phpat.test" tag, mirroring phpat's getServicesByTag() lookup, so detection
is exercised end-to-end against the dead-code graph. testNoFatalError uses
require_once since the fixture classes are autoloaded during analysis.

Co-Authored-By: Claude Code
Claude-Session: https://claude.ai/code/session_01WqA3SLHn3vQEytN5C1KCJj
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

phpat archirtecture rules reported as dead code

1 participant