Skip to content

Flag Nova convention props as initialised (suppress PropertyNotSetInConstructor) - #7

Merged
alies-dev merged 1 commit into
mainfrom
feat/nova-property-not-set-stubs
Jul 13, 2026
Merged

Flag Nova convention props as initialised (suppress PropertyNotSetInConstructor)#7
alies-dev merged 1 commit into
mainfrom
feat/nova-property-not-set-stubs

Conversation

@alies-dev

@alies-dev alies-dev commented Jul 13, 2026

Copy link
Copy Markdown
Member

Problem

Nova base classes declare display/attribute properties via a @var docblock (or a native nullable) with no default:

  • Fields\Field: $name, $attribute, $resource
  • Actions\Action, Metrics\Metric, Filters\Filter, Lenses\Lens: $name
  • Metrics\TrendResult: $prefix, $suffix, $format

Nova assigns them through the constructor, a setter, or reflection — never at declaration — so every concrete subclass that does not redeclare them is reported PropertyNotSetInConstructor in the consuming project.

Fix

In afterCodebasePopulated, mark each such property as initialised on the class that declares it. ClassAnalyzer::checkPropertyInitialization reads that flag from the declaring class, so the report is silenced on every subclass that inherits the property, while a subclass's own uninitialised typed property still flags.

This is deliberately chosen over the two alternatives:

  • vs a stub default value (public $name = ''): the runtime value is never that — it would be fiction, and it also collapses union types / trips NonInvariantPropertyType on subclasses that legitimately redeclare public $name = 'Label'.
  • vs class-level issue suppression: PropertyNotSetInConstructor is emitted with the concrete class's suppression list, so suppressing would be all-or-nothing and would hide a subclass's genuine unset-property bugs.

The mutation is routed through a small helper taking the storage as a parameter so its side effect is visible to Psalm's purity analysis (mirrors the existing suppress() helper), avoiding a false MissingPureAnnotation.

Impact

Measured on IxDF-web (single-threaded cold runs, baseline ignored, before vs after): -47 PropertyNotSetInConstructor, 0 new issues. Covers Fields, Actions, Metrics, Filters, Lenses and TrendResult subclasses.

Local phpcs and psalm pass.

(Branch name feat/nova-property-not-set-stubs predates the final approach, which uses the handler rather than stubs.)

@alies-dev alies-dev changed the title feat(stubs): default convention props to fix PropertyNotSetInConstructor Default convention props to fix PropertyNotSetInConstructor Jul 13, 2026
@alies-dev alies-dev changed the title Default convention props to fix PropertyNotSetInConstructor Default convention props to fix PropertyNotSetInConstructor Jul 13, 2026
Nova base classes declare display/attribute props via a `@var` docblock
(or a native nullable) with no default: `$name` on Field/Action/Metric/
Filter/Lens, `$attribute`/`$resource` on Field, `$prefix`/`$suffix`/
`$format` on TrendResult. Nova assigns them through the constructor, a
setter or reflection, never at declaration, so every concrete subclass
that does not redeclare them is reported PropertyNotSetInConstructor.

In afterCodebasePopulated, mark each such property as initialised on the
class that declares it. ClassAnalyzer::checkPropertyInitialization reads
the flag from the declaring class, so the report is silenced on every
subclass that inherits the property, while a subclass's own uninitialised
typed property still flags. This is per-property precise: no stub with a
fictional default value (the runtime value is never that) and no
class-level issue suppression (which would hide a subclass's real bugs).

The mutation is routed through a helper taking the storage as a parameter
so its side effect is visible to Psalm's purity analysis (mirrors the
existing suppress() helper).

Fixes 47 PropertyNotSetInConstructor reports on the consuming project
with no new issues.
@alies-dev
alies-dev force-pushed the feat/nova-property-not-set-stubs branch from 6a3d729 to 01839f5 Compare July 13, 2026 22:59
@alies-dev alies-dev changed the title Default convention props to fix PropertyNotSetInConstructor fix(suppress): flag Nova convention props as initialised (PropertyNotSetInConstructor) Jul 13, 2026
@alies-dev alies-dev changed the title fix(suppress): flag Nova convention props as initialised (PropertyNotSetInConstructor) flag Nova convention props as initialised (PropertyNotSetInConstructor) Jul 13, 2026
@alies-dev alies-dev changed the title flag Nova convention props as initialised (PropertyNotSetInConstructor) Flag Nova convention props as initialised (suppress PropertyNotSetInConstructor) Jul 13, 2026
@alies-dev alies-dev self-assigned this Jul 13, 2026
@alies-dev
alies-dev merged commit c282c6b into main Jul 13, 2026
4 checks passed
@alies-dev
alies-dev deleted the feat/nova-property-not-set-stubs branch July 13, 2026 23:02
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