buildAddresses method

void buildAddresses([
  1. OccurrenceAddress startAddr = OccurrenceAddress.root
])

Build hierarchical addresses for this occurrence and all descendants.

This performs a single O(n) tree traversal to assign OccurrenceAddress to every occurrence and signal in the tree. Call this once after tree construction to enable efficient address-based navigation.

Signal address ordering: ports (signals with a non-null SignalOccurrence.direction) are assigned indices first (0 .. portCount-1), followed by internal signals (portCount .. signals.length-1). Within each group the original list order is preserved.

This means a port's SignalOccurrence.portIndex always equals its signal address index, which consumers (e.g. schematic hyperedges) can rely on remaining stable across incremental expansion.

Example:

root.buildAddresses();  // Assign addresses to all occurrences/signals
final signalAddr = signals[0].address;  // Now available

Implementation

void buildAddresses([OccurrenceAddress startAddr = OccurrenceAddress.root]) {
  _address = startAddr;

  // Assign ports first, then internal signals, so that port indices
  // are stable across incremental hierarchy expansion.
  var idx = 0;
  for (final s in signals) {
    if (s.isPort) {
      s
        ..address = startAddr.signal(idx++)
        ..parent = this;
    }
  }
  for (final s in signals) {
    if (!s.isPort) {
      s
        ..address = startAddr.signal(idx++)
        ..parent = this;
    }
  }

  for (final (i, c) in children.indexed) {
    c
      .._parent = this
      ..buildAddresses(startAddr.child(i));
  }
}