Skip to content

Reduce PHPStan baseline: fix generic object types and invalid array keys#3758

Open
Vondry wants to merge 2 commits into
bolt:6.1from
Vondry:phpstan-baseline-cleanup
Open

Reduce PHPStan baseline: fix generic object types and invalid array keys#3758
Vondry wants to merge 2 commits into
bolt:6.1from
Vondry:phpstan-baseline-cleanup

Conversation

@Vondry

@Vondry Vondry commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Summary

Reduces the PHPStan level-8 baseline by fixing the underlying issues instead of suppressing them. Removes 8 baselined errors across two focused, self-contained commits, with no behavior changes or signature changes.

Motivation

phpstan-baseline.php accumulates suppressed findings over time. This PR removes two cohesive, high-signal groups where the root causes were genuine type-safety issues (unverifiable method calls and invalid array key types) rather than annotation noise. Each change is small enough to review line by line.

Changes

1. Fix generic object types in the Field factory and discriminator

Instantiating classes via new $classname() / new $class() from a plain string produces a generic object, preventing PHPStan from verifying subsequent Field method calls.

  • FieldRepository::factory() — narrows the instantiated object to Field using an inline @var annotation.
  • FieldDiscriminatorListener::extractFieldType() — narrows the instantiated object to FieldInterface using an inline @var annotation.

Removes 7 baseline entries:

  • 6 × method.notFound
  • 1 × return.type

2. Fix invalid array key types (offsetAccess.invalidOffset)

Several array keys could previously be inferred as null or array, which PHPStan level 8 correctly rejects as potentially invalid offsets.

  • ContentValidator — skips relations whose target contentType is null. Those keys were never consumed downstream because validation keys only on real content-type names with allowExtraFields => true.
  • TranslationsManager and FieldExtension — cast getId() (?int) to int, matching the runtime guarantee that entities are already persisted in these code paths.
  • SelectQuery::getCheckboxFieldExpression() — casts the result of key(...) (int|string|null) to string, preserving existing runtime behaviour.
  • SelectQuery join maps — narrows Filter::getKey() (string|array) to string via an inline @var, matching how the value is already used (sprintf('%s', ...)).

Removes 1 additional baseline entry (array|string) and eliminates six non-baselined failures that appear on newer PHP versions.

Verification

  • vendor/bin/phpstan analyse (level 8) → [OK] No errors, with no analysis errors and no orphaned baseline entries.
  • Ran the affected test suite: FieldRepository::factory() remains covered and passes; overall test results are identical to master (pre-existing unrelated failures remain unchanged).
  • All modified methods are private except the two annotation-only changes, so there is no external API impact.

Notes for reviewers

  • The only intentional behavioural change is the continue in ContentValidator::relationsToMap(), which was verified to be functionally inert.
  • Type narrowing is implemented exclusively with inline /** @var ... */ annotations. No runtime constructs (such as assert()) were introduced.

Vondry added 2 commits July 23, 2026 21:18
new $classname() produced a bare object, so PHPStan could not verify the
Field method calls in FieldRepository::factory() and
FieldDiscriminatorListener::extractFieldType(). Narrow the instances to
Field / FieldInterface via inline @var, removing 7 baseline entries
(6 method.notFound, 1 return.type).
Several array keys could be null or array, which PHPStan level 8 rejects
as possibly-invalid offsets:

- Content::getContentType() (?string) in ContentValidator: skip null keys.
- Field/Content::getId() (?int) in TranslationsManager and FieldExtension:
  cast to int (entities are always persisted in these paths).
- key() (int|string|null) in SelectQuery::getCheckboxFieldExpression:
  cast to string.
- Filter::getKey() (string|array) in SelectQuery join maps: narrow the key
  to string via inline @var, matching how it is used elsewhere (sprintf '%s').

Removes the baselined array|string offsetAccess.invalidOffset entry and
clears the 6 non-baselined failures reported on newer PHP.
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.

1 participant