reassemble method

void reassemble()

Invokes State.reassemble on every live retained state and marks every live element dirty so the next buildScope re-runs its build().

This is hot reload's second step: reloadSources swaps method bodies but leaves the element tree untouched, so nothing re-executes an edited build() until something marks it dirty. No State is recreated and no initState re-runs — retained states get State.reassemble instead, in document order (parents before children) so a child re-derives against an already-refreshed parent. Every callback is attempted, the tree is marked whether or not any of them fail, and the first failure is rethrown once the pass is complete: a broken hook degrades the reload rather than aborting it.

Deliberate design decision: every registered element is marked, not only the root. Reconciliation currently has no identical-widget short-circuit, so marking the root alone would happen to cascade through the whole tree — but that is a property of reconciliation, not a guarantee this method should depend on. Marking directly keeps reassemble correct if such a short-circuit is ever added. scheduleBuild's generation-stamped reservations still collapse the marks with the parent cascade, so each element rebuilds exactly once.

Safe with nothing mounted, after dispose, and from inside a build(): an in-build call drains in a later batch of the same buildScope pass rather than re-entering it.

Implementation

void reassemble() {
  if (_disposed) {
    return;
  }
  // Snapshot first: `scheduleBuild` requests a frame through `_onFrame`, and
  // a host callback may mount elements before this loop finishes.
  final registered = _depths.keys.toList(growable: false);
  final failures = FirstErrorRecorder();
  for (final element in _reassembleTargets(registered)) {
    failures.attempt(element.state.reassemble);
  }
  for (final element in registered) {
    scheduleBuild(element);
  }
  failures.rethrowFirst();
}