visitLabeledStatement method

  1. @override
Object? visitLabeledStatement(
  1. SLabeledStatement node
)
override

Implementation

@override
Object? visitLabeledStatement(SLabeledStatement node) {
  final labelNames = node.labels.map((l) => l.label!.name).toSet();
  // A statement written `a: b: ...` may arrive as nested labelled
  // statements; the statement they wrap answers to every one of them.
  if (identical(node, _labelledStatement)) {
    labelNames.addAll(_labelledStatementLabels);
  }
  final previousStatement = _labelledStatement;
  final previousLabels = _labelledStatementLabels;
  _labelledStatement = node.statement;
  _labelledStatementLabels = labelNames;
  Logger.debug("[SLabeledStatement] Entering with labels: $labelNames");

  try {
    return node.statement!.accept<Object?>(this);
  } on BreakException catch (e) {
    if (e.label != null && labelNames.contains(e.label)) {
      // A labelled break naming this statement leaves it — the only way to
      // leave a labelled block, and harmless for a loop, which consumed its
      // own labelled break already.
      Logger.debug(
        "[SLabeledStatement] Consuming labeled break: '${e.label}'.",
      );
      return null;
    }
    rethrow;
  }
  // A labelled continue is caught by the loop the label is written on.
  finally {
    Logger.debug("[SLabeledStatement] Exiting labels: $labelNames");
    _labelledStatement = previousStatement;
    _labelledStatementLabels = previousLabels;
  }
}