registerExtensions method

void registerExtensions(
  1. String packageName,
  2. void body()
)

Registers a body callback that wires additional bridge state (e.g. registerRelaxers(), registerD4rtRuntimeExtensions(), registerD4rtInterfaceProxyOverrides()) after the main registerBridgedClass/registerBridgedEnum/etc. registrations for packageName have happened.

The body is not run immediately — the runner queues it and runs every queued body in registration order when finalizeBridges is called (or implicitly on the first execute*/executeBundle* call that follows). This replaces the comment-driven "must run AFTER bridges" rule (formerly enforced by code ordering inside FlutterD4rt._registerBridges) with an enforced mechanism: bridge packages declare their wiring up front, and the runner controls when it runs.

Idempotent on package name: a second call with the same packageName overwrites the previous body — the contract is one extension callback per bridge package. The body itself must internally tolerate being run more than once if the embedder constructs multiple D4rtRunner instances in the same process, since the D4 / BridgedClass registries it touches are static. (Step 5 made all the per-key D4 registries idempotent on factory identity, so this contract is satisfied for the standard register* calls.)

Throws StateError if finalizeBridges has already run on this runner — adding extensions after finalization is a misuse.

Implementation

void registerExtensions(String packageName, void Function() body) {
  if (_bridgesFinalized) {
    throw StateError(
      'Cannot registerExtensions("$packageName"): finalizeBridges() has '
      'already been called on this D4rtRunner. Register all extensions '
      'before the first execute*/executeBundle* call (or call '
      'finalizeBridges() explicitly after the last registerExtensions).',
    );
  }
  _extensionCallbacks[packageName] = body;
}