Tags: mglaman/phpstan-drupal
Tags
Fix never type for dynamic container service IDs (#1014) fix(type): avoid never type for dynamic container service IDs Container get()/has() built their return type by unioning the types of each constant string argument. A variable service ID has none, so the union of zero types collapsed to never — a subtype of everything — triggering entityStoragePropertyAssignment on core-generated proxy classes. Fall back to the declared return type instead. Closes #1012 Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Fix never type for dynamic container service IDs (#1014) fix(type): avoid never type for dynamic container service IDs Container get()/has() built their return type by unioning the types of each constant string argument. A variable service ID has none, so the union of zero types collapsed to never — a subtype of everything — triggering entityStoragePropertyAssignment on core-generated proxy classes. Fall back to the declared return type instead. Closes #1012 Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Make containerHasAlwaysTrue false by default (#1005) ContainerInterface::has() now returns bool instead of always-true for known services, so conditional service guards survive analysis. The strict behavior shipped in bleedingEdge.neon and graduates to the default; set containerHasAlwaysTrue: true to restore the old inference. Fixes #1004 Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Config::get return type extension (#993) * Config::get return type extension * Address feedback * fix phpstan issue * Address review feedback on config schema support - Parse schema files lazily on first query instead of eagerly in the bootstrap. The bootstrap only collects schema directories; parsing happens when configGetReturnType or configGetUnknownKeyRule actually queries the data, so disabled features no longer pay the memory cost. - Verify the receiver when resolving config names: static calls must be on \Drupal, and $this->config() must come from ConfigFormBaseTrait. Same-named helpers on other classes no longer produce false positives. - Treat keys beneath dynamic type references like mailer_dsn.options.[%parent.scheme] as unverifiable instead of reporting them as unknown. - Stop narrowing when any key in a union of constant strings is unresolvable, instead of silently dropping the mixed branch. - Use TypeCombinator::union() so overlapping union members do not crash. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Gate system.mail asserts on schema content system.mail is not FullyValidatable in Drupal ^10.4, so its type asserts fail there. Move them to a separate fixture that only runs when the installed core's schema actually has the constraint, keyed off the schema file content rather than a version compare. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Document config schema-based checks in README Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Matt Glaman <nmd.matt@gmail.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Bump actions/cache from 5 to 6 (#997) Bumps [actions/cache](https://github.com/actions/cache) from 5 to 6. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](actions/cache@v5...v6) --- updated-dependencies: - dependency-name: actions/cache dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Add rules to detect missing CacheableMetadata parameter in entity ope… …ration methods and hooks (#979) * Add rule to detect missing CacheableMetadata parameter in EntityListBuilder subclasses Closes #930 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Use version_compare for Drupal version gate Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Add rules for hook_entity_operation and hook_entity_operation_alter cacheability parameter Covers both OOP (#[Hook] attribute) and procedural hook implementations. Procedural rule uses version_compare rather than ReflectionProvider since api.php files are not loaded by default. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Use entityListBuilderOperationsCacheabilityRule flag for all three rules Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Fix tests to handle Drupal version matrix in CI The CI tests against Drupal ~11.2.0 where the version gate causes rules to return no errors. Make expected errors conditional on the running Drupal version so tests pass across the full version matrix. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Rename entityListBuilderOperationsCacheabilityRule to entityOperationsCacheabilityRule * Validate CacheableMetadata parameter type and nullability in entity operation rules * Include = NULL in suggested signatures for entity operation cacheability rules * phpcs * Refactor cacheability parameter validation to use PHPStan isNull() and simplify helper signature * phpcs * Extract shared ParamHelper for reusable param type validation Replace duplicated isValidCacheabilityParam() in three rules with a general-purpose ParamHelper::isValidParam() that accepts any expected FQCN and nullable constraint. Callers now own bounds checking via count(). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Remove Drupal 12 upper version gate from hook cacheability rules Hooks have no shared interface contract, so PHPStan native method-signature checking cannot catch missing cacheability params in Drupal 12+. Keep the rule firing for any Drupal >= 11.3. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix $offset type in ItemList::offsetExists (#914) * TKey * Fix ListInterface extends to define TKey * Add offsetExists stub to ItemList and regression test for #914 The TKey template resolution through ArrayAccess caused PHPStan to treat TKey as a class name (Drupal\Core\TypedData\Plugin\DataType\TKey) when analyzing ComputedItemListTrait::offsetExists in context of implementing classes. Adding an explicit offsetExists stub with @param int $offset anchors the type without violating contravariance (mixed PHP type). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Matt Glaman <nmd.matt@gmail.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Add TodoCommentWithIssueUrlRule to flag @todo comments referencing th… …e current issue (#953) * Add TodoCommentWithIssueUrlRule to detect @todo comments referencing the current issue Adds a new opt-in rule for Drupal contrib CI pipelines that reports an error when a @todo comment references the same drupal.org issue NID as the current merge request. This prevents TODOs added during issue work from being merged without resolution. The rule auto-detects the issue NID from GitLab CI environment variables (CI_MERGE_REQUEST_SOURCE_BRANCH_NAME or CI_MERGE_REQUEST_SOURCE_PROJECT_PATH) and is silent when neither is set. It is not registered by default. Closes #952 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Document TodoCommentWithIssueUrlRule in README Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Shorten TodoCommentWithIssueUrlRule error message Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Address Copilot review feedback Guard against non-Node array elements in traverseNodes() — some PHP-Parser subnodes are scalar arrays (e.g. Name::$parts is string[]), which would cause a fatal error without the instanceof check. Also fix test style to match existing rule tests: remove trailing commas after line numbers and the extra blank line before the closing brace. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace ~11.0.0 and ~11.1.0 with ~11.2.0 and ~11.3.0 in CI matrix (#943) * Replace ~11.1.0 with ~11.2.0 in CI matrix to fix broken dependency drupal/core-dev 11.1.x has a broken dependency: it requires both composer/composer ^2.8.1 (resolves to 2.9.x) and justinrainbow/json-schema ^5.2, but composer/composer 2.9.x requires justinrainbow/json-schema ^6.x. drupal/core-dev 11.2.x fixes this. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Update PHP version and Drupal dependencies in workflow --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
PreviousNext