Ignore missing legacy hook BC attributes (LegacyHook, LegacyRequirementsHook, LegacyModuleImplementsAlter) - #967
Merged
Conversation
LegacyHook, LegacyRequirementsHook, and LegacyModuleImplementsAlter were added across different Drupal minor versions and LegacyHook is being removed in Drupal 12. Without stubs, PHPStan reports "class not found" errors against Drupal versions where these attributes don't exist, and "unused ignore" errors against versions where they do. Providing stubs makes these classes always available to PHPStan regardless of the installed Drupal version. Closes #945 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The test would pass even without the stubs because the fixture classes in tests/fixtures/drupal/ are always present, and TypeInferenceTestCase does not surface unknown class errors. StubTest already validates stub well-formedness; integration coverage comes from the build_integration CI jobs running against real Drupal installations. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a fixture PHP file using LegacyHook, LegacyRequirementsHook, and LegacyModuleImplementsAlter, and scans it in both build_integration jobs across all Drupal version matrix entries. Against Drupal 10.4 these classes don't exist in the installed package, so this verifies the stubs make them available regardless of Drupal version. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy the fixture into the Drupal directory before analysing rather than passing an absolute workspace path to PHPStan, which failed to resolve it. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
PHPStan stubs only override type information for existing classes; they cannot make missing classes available for attribute validation. The integration tests confirmed this — attribute class errors still fired on Drupal 10.4 where the classes don't exist. Instead, add ignoreErrors entries with reportUnmatched: false so the suppression is silent on Drupal versions where the classes do exist, avoiding the "unused ignore" problem the issue describes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Scope each ignore to the attribute.notFound identifier as well as the message, and document why unmatched ignores are expected. Rename the integration step and fixture docblock, which still described the stub approach this PR moved away from, and type the fixture's arrays so it passes at any level. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #945
Drupal added
LegacyHook,LegacyRequirementsHook, andLegacyModuleImplementsAlteras BC-bridge attributes across different minor versions, and Drupal 12 removes them again (LegacyModuleImplementsAlteris already gone from coremain). No supported core version has all three, which puts module maintainers in a bind:@phpstan-ignoreto suppress that, PHPStan reports "Unused ignore" on versions where the class does existThis adds
ignoreErrorsentries toextension.neon, pinned to theattribute.notFoundidentifier and the exact message, withreportUnmatched: false. The error is suppressed where the class is missing, and there is no unmatched-ignore noise where it exists. Because this lives in the extension, it also covers upgrade_status and anything else that runs phpstan-drupal.PHPStan stubs don't work here: stubs only override type information for classes that already exist, they can't make a missing class visible to attribute validation.
Test plan
php vendor/bin/phpstan analyzepassesphp vendor/bin/phpunitpassesreportUnmatchedIgnoredErrors: true, both with all three classes present and withLegacyHookandLegacyModuleImplementsAlterremovedtests/fixtures/integration/legacy-hook-attributes.phpagainst ^10.4 (none of the classes exist), ~11.3.0, ~11.4.0, and 11.x-dev🤖 Generated with Claude Code