Skip to content

Add Phpat usage provider#381

Merged
janedbal merged 3 commits into
masterfrom
phpat-support
Jun 24, 2026
Merged

Add Phpat usage provider#381
janedbal merged 3 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 janedbal marked this pull request as ready for review June 24, 2026 06:47
janedbal added 3 commits June 24, 2026 08:51
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
phpat/phpat is a hard require-dev pinned to ^0.12, so it is always
installed and prefer-lowest resolves 0.12.0 — the `>= 0.12` guard can
never skip. Unlike the symfony fixtures, whose constraints span multiple
majors, there is nothing to guard against here.

Co-Authored-By: Claude Code
Claude-Session: https://claude.ai/code/session_01WqA3SLHn3vQEytN5C1KCJj
@janedbal janedbal merged commit aa8c642 into master Jun 24, 2026
33 checks passed
@janedbal janedbal deleted the phpat-support branch June 24, 2026 06:58
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