Skip to content

feat(solid_generator): track foreign signal reads - #117

Merged
nank1ro merged 2 commits into
mainfrom
fix/foreign-signal-tracking
Sep 1, 2026
Merged

nank1ro merged 2 commits into
mainfrom
fix/foreign-signal-tracking

Conversation

@nank1ro

@nank1ro nank1ro commented Sep 1, 2026

Copy link
Copy Markdown
Owner

Reads of hand-written solidart signals (e.g. reached through @SolidEnvironment objects) now count as reactive dependencies, per SPEC §4.5/§5.1 — previously the reactivity analysis only counted generator-managed members, so a build() reading gate.complete.value got no SignalBuilder (silently non-reactive widget) and a @SolidState getter over a foreign signal was rejected with "has no reactive dependencies".

Found in production shape in fairtile_esg's pmi_app shell (Valutazione tab never appearing until a navigation-forced rebuild).

What's in here

  • _maybeRecordForeignSignalRead in value_rewriter.dart: records reads of receivers statically typed as solidart SignalBase subtypes, for .value / hasValue / previousValue / hasPreviousValue / state and the callable form (sig(), handled in visitFunctionExpressionInvocation — the analyzer rewrites zero-arg signal calls there, never MethodInvocation). A dedicated foreign-only getter set keeps the shared managed-member sets untouched (a machine.state read on a @SolidState field still lowers to machine.value.state — regression-tested).
  • Collision-proof key namespace (foreign: prefix, this.-stripped) so §7.5 wrap pruning can never conflate a foreign signal with a same-named managed member; symmetric offset guard.
  • .untracked chains are honored as an opt-out for build() wrap placement.
  • target_validator's resolved tier now uses isSolidartSignalType (solidart + flutter_solidart): the SPEC §3.6 rejection of @SolidEnvironment on SignalBase-typed fields previously could not fire in any real resolved build (anchored to the wrong declaring package).
  • New resolved-mode test infrastructure (real analyzer resolution via the workspace package config; Isolate.resolvePackageUri-anchored fixture) covering the validator rejection, alias tracking, and the opt-out.
  • Goldens: foreign_signal_value_read (incl. callable/probe/opt-out cases) and foreign_signal_name_collision; integration test asserting rebuild-on-flip through real generated output.
  • CHANGELOG scoped (pure-consumer files still pass through verbatim; @SolidQuery doesn't synthesize source: from foreign deps; .untracked scope; Resource.value deprecated → state covered). SPEC §5.1 corrected: SignalBase is declared in package:solidart.

Version: 3.0.0-dev.11.

Verification

dart test packages/solid_generator/ — 380 pass, from both repo root (CI form, -r github --fail-fast) and the package dir. Integration tests pass per-file. dart format clean; dart analyze --fatal-infos only the 2 pre-existing avoid_print infos.

Reads of hand-written solidart signals (e.g. via @SolidEnvironment
objects) now count as reactive dependencies: build() reads get a
SignalBuilder and @SolidState getters over them lower to Computed,
matching SPEC §4.5/§5.1 (the analysis previously only counted
generator-managed members, silently emitting non-reactive widgets).
Covers .value/hasValue/previousValue/hasPreviousValue/state and the
callable form via a foreign-only getter set; collision-proof
'foreign:' key namespace; target_validator's resolved tier now
actually rejects @SolidEnvironment on SignalBase fields (was anchored
to the wrong package); new resolved-mode test infrastructure.
3.0.0-dev.11.
@nank1ro
nank1ro merged commit c6a15d3 into main Sep 1, 2026
1 check passed
@nank1ro
nank1ro deleted the fix/foreign-signal-tracking branch September 1, 2026 18:01
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