detach static method

  1. @experimental
bool detach(
  1. ContextToken token, [
  2. Zone? zone
])

Detaches the Context associated with the given ContextToken from their associated Zone.

Returns true if the given ContextToken is associated with the latest, expected, attached Context, false otherwise.

If the ContextToken is not found in the latest stack, detach will walk up the Zone tree attempting to find and detach the associated Context.

Regardless of whether the Context is found, if the given ContextToken is not expected, a warning will be logged.

Implementation

@experimental
static bool detach(ContextToken token, [Zone? zone]) {
  final stack = _currentContextStack(zone ?? Zone.current);

  final index = stack.indexWhere((c) => c.token == token);

  // the expected context to detach is the latest entry of the latest stack
  final match = index != -1 && index == stack.length - 1;
  if (!match) {
    _log.warning('unexpected (mismatched) token given to detach');
  }

  if (index != -1) {
    // context found in the latest stack, possibly the latest entry
    stack.removeAt(index);
    return match;
  }

  // at this point, the token was not in the latest stack, but it might be in a
  // stack held by a parent zone

  // walk up the zone tree checking for the token in each zone's context stack
  zone ??= Zone.current;
  do {
    final stack = _stacks[zone!];
    final index = stack?.indexWhere((c) => c.token == token);
    if (index != null && index != -1) {
      // token found, remove it, but return false since it wasn't expected
      stack!.removeAt(index);
      return false;
    }
    zone = zone.parent;
  } while (zone != null);

  // the token was nowhere to be found, a context was not detached
  _log.warning('failed to detach context');
  return false;
}