visitForOf method

  1. @override
dynamic visitForOf(
  1. ForOfStatement node
)

Implementation

@override
visitForOf(ForOfStatement node) {
  final String? loopLabel = _nextStatementLabel;
  _nextStatementLabel = null;
  final dynamic right = getValueFromNode(node.right);
  final List<dynamic> values = _toForOfValues(right, node);
  final _ForLoopBinding binding = _forLoopBinding(node.left, node);

  if (binding.kind == 'var') {
    binding.declaration?.visitBy(this);
  }

  for (final value in values) {
    _LexicalContext? iterationContext;
    if (binding.kind == 'assignment' && binding.binding is Expression) {
      _assignPattern(binding.binding as Expression, value, node.line ?? 1);
    } else if (binding.kind != 'var') {
      iterationContext = _LexicalContext();
      for (final name in _bindingNames(binding.binding)) {
        iterationContext.declare(name.value,
            mutable: binding.kind != 'const');
      }
      _lexicalContexts.add(iterationContext);
      _bindPattern(binding.binding, value,
          lexical: true,
          mutable: binding.kind != 'const',
          line: node.line ?? 1);
    } else {
      _bindPattern(binding.binding, value,
          lexical: false, mutable: true, line: node.line ?? 1);
    }

    try {
      node.body.visitBy(this);
    } on ControlFlowBreakException catch (e) {
      if (iterationContext != null) {
        _lexicalContexts.removeLast();
      }
      if (e.label == loopLabel) break;
      if (e.label != null) rethrow;
      break;
    } on ControlFlowContinueException catch (e) {
      if (e.label == loopLabel) {
        // Continue with the next iterable value.
      } else if (e.label != null) {
        rethrow;
      }
    } finally {
      if (iterationContext != null &&
          _lexicalContexts.isNotEmpty &&
          identical(_lexicalContexts.last, iterationContext)) {
        _lexicalContexts.removeLast();
      }
    }
  }
}