// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/// This file implements the AST of a Dart-like language suitable for testing
/// flow analysis.  Callers may use the top level methods in this file to create
/// AST nodes and then feed them to [Harness.run] to run them through flow
/// analysis testing.
import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
import 'package:test/test.dart';

const Expression nullLiteral = const _NullLiteral();

Statement assert_(Expression condition, [Expression? message]) =>
    new _Assert(condition, message);

Statement block(List<Statement> statements) => new _Block(statements);

Expression booleanLiteral(bool value) => _BooleanLiteral(value);

/// Wrapper allowing creation of a statement that can be used as the target of
/// `break` or `continue` statements.  [callback] will be invoked to create the
/// statement, and it will be passed a [BranchTargetPlaceholder] that can be
/// passed to [break_] or [continue_].
Statement branchTarget(Statement Function(BranchTargetPlaceholder) callback) {
  var branchTargetPlaceholder = BranchTargetPlaceholder._();
  var stmt = callback(branchTargetPlaceholder);
  branchTargetPlaceholder._target = stmt;
  return stmt;
}

Statement break_(BranchTargetPlaceholder branchTargetPlaceholder) =>
    new _Break(branchTargetPlaceholder);

SwitchCase case_(List<Statement> body, {bool hasLabel = false}) =>
    SwitchCase._(hasLabel, body);

CatchClause catch_(
        {Var? exception, Var? stackTrace, required List<Statement> body}) =>
    CatchClause._(body, exception, stackTrace);

/// Creates a pseudo-statement whose function is to verify that flow analysis
/// considers [variable]'s assigned state to be [expectedAssignedState].
Statement checkAssigned(Var variable, bool expectedAssignedState) =>
    new _CheckAssigned(variable, expectedAssignedState);

/// Creates a pseudo-statement whose function is to verify that flow analysis
/// considers [variable] to be un-promoted.
Statement checkNotPromoted(Var variable) => new _CheckPromoted(variable, null);

/// Creates a pseudo-statement whose function is to verify that flow analysis
/// considers [variable]'s assigned state to be promoted to [expectedTypeStr].
Statement checkPromoted(Var variable, String? expectedTypeStr) =>
    new _CheckPromoted(variable, expectedTypeStr);

/// Creates a pseudo-statement whose function is to verify that flow analysis
/// considers the current location's reachability state to be
/// [expectedReachable].
Statement checkReachable(bool expectedReachable) =>
    new _CheckReachable(expectedReachable);

/// Creates a pseudo-statement whose function is to verify that flow analysis
/// considers [variable]'s unassigned state to be [expectedUnassignedState].
Statement checkUnassigned(Var variable, bool expectedUnassignedState) =>
    new _CheckUnassigned(variable, expectedUnassignedState);

Statement continue_(BranchTargetPlaceholder branchTargetPlaceholder) =>
    new _Continue(branchTargetPlaceholder);

Statement declare(Var variable,
        {required bool initialized,
        bool isFinal = false,
        bool isLate = false}) =>
    new _Declare(variable, initialized ? expr(variable.type.type) : null,
        isFinal, isLate);

Statement declareInitialized(Var variable, Expression initializer,
        {bool isFinal = false, bool isLate = false}) =>
    new _Declare(variable, initializer, isFinal, isLate);

Statement do_(List<Statement> body, Expression condition) =>
    _Do(body, condition);

/// Creates a pseudo-expression having type [typeStr] that otherwise has no
/// effect on flow analysis.
Expression expr(String typeStr) =>
    new _PlaceholderExpression(new Type(typeStr));

/// Creates a conventional `for` statement.  Optional boolean [forCollection]
/// indicates that this `for` statement is actually a collection element, so
/// `null` should be passed to [for_bodyBegin].
Statement for_(Statement? initializer, Expression? condition,
        Expression? updater, List<Statement> body,
        {bool forCollection = false}) =>
    new _For(initializer, condition, updater, body, forCollection);

/// Creates a "for each" statement where the identifier being assigned to by the
/// iteration is not a local variable.
///
/// This models code like:
///     var x; // Top level variable
///     f(Iterable iterable) {
///       for (x in iterable) { ... }
///     }
Statement forEachWithNonVariable(Expression iterable, List<Statement> body) =>
    new _ForEach(null, iterable, body, false);

/// Creates a "for each" statement where the identifier being assigned to by the
/// iteration is a variable that is being declared by the "for each" statement.
///
/// This models code like:
///     f(Iterable iterable) {
///       for (var x in iterable) { ... }
///     }
Statement forEachWithVariableDecl(
    Var variable, Expression iterable, List<Statement> body) {
  // ignore: unnecessary_null_comparison
  assert(variable != null);
  return new _ForEach(variable, iterable, body, true);
}

/// Creates a "for each" statement where the identifier being assigned to by the
/// iteration is a local variable that is declared elsewhere in the function.
///
/// This models code like:
///     f(Iterable iterable) {
///       var x;
///       for (x in iterable) { ... }
///     }
Statement forEachWithVariableSet(
    Var variable, Expression iterable, List<Statement> body) {
  // ignore: unnecessary_null_comparison
  assert(variable != null);
  return new _ForEach(variable, iterable, body, false);
}

/// Creates a [Statement] that, when analyzed, will cause [callback] to be
/// passed an [SsaNodeHarness] allowing the test to examine the values of
/// variables' SSA nodes.
Statement getSsaNodes(void Function(SsaNodeHarness) callback) =>
    new _GetSsaNodes(callback);

Statement if_(Expression condition, List<Statement> ifTrue,
        [List<Statement>? ifFalse]) =>
    new _If(condition, ifTrue, ifFalse);

Statement labeled(Statement body) => new _LabeledStatement(body);

Statement localFunction(List<Statement> body) => _LocalFunction(body);

Statement return_() => new _Return();

Statement switch_(Expression expression, List<SwitchCase> cases,
        {required bool isExhaustive}) =>
    new _Switch(expression, cases, isExhaustive);

Expression throw_(Expression operand) => new _Throw(operand);

Statement tryCatch(List<Statement> body, List<CatchClause> catches) =>
    new _TryCatch(body, catches);

Statement tryFinally(List<Statement> body, List<Statement> finally_) =>
    new _TryFinally(body, finally_);

Statement while_(Expression condition, List<Statement> body) =>
    new _While(condition, body);

/// Placeholder used by [branchTarget] to tie `break` and `continue` statements
/// to their branch targets.
class BranchTargetPlaceholder {
  late Statement _target;

  BranchTargetPlaceholder._();
}

/// Representation of a single catch clause in a try/catch statement.  Use
/// [catch_] to create instances of this class.
class CatchClause implements _Visitable<void> {
  final List<Statement> _body;
  final Var? _exception;
  final Var? _stackTrace;

  CatchClause._(this._body, this._exception, this._stackTrace);

  String toString() {
    String initialPart;
    if (_stackTrace != null) {
      initialPart = 'catch (${_exception!.name}, ${_stackTrace!.name})';
    } else if (_exception != null) {
      initialPart = 'catch (${_exception!.name})';
    } else {
      initialPart = 'on ...';
    }
    return '$initialPart ${block(_body)}';
  }

  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
    _body._preVisit(assignedVariables);
  }

  void _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    flow.tryCatchStatement_catchBegin(_exception, _stackTrace);
    _body._visit(h, flow);
    flow.tryCatchStatement_catchEnd();
  }
}

/// Representation of an expression in the pseudo-Dart language used for flow
/// analysis testing.  Methods in this class may be used to create more complex
/// expressions based on this one.
abstract class Expression extends Node implements _Visitable<Type> {
  const Expression() : super._();

  /// If `this` is an expression `x`, creates the expression `x!`.
  Expression get nonNullAssert => new _NonNullAssert(this);

  /// If `this` is an expression `x`, creates the expression `!x`.
  Expression get not => new _Not(this);

  /// If `this` is an expression `x`, creates the expression `(x)`.
  Expression get parenthesized => new _ParenthesizedExpression(this);

  /// If `this` is an expression `x`, creates the statement `x;`.
  Statement get stmt => new _ExpressionStatement(this);

  /// If `this` is an expression `x`, creates the expression `x && other`.
  Expression and(Expression other) => new _Logical(this, other, isAnd: true);

  /// If `this` is an expression `x`, creates the expression `x as typeStr`.
  Expression as_(String typeStr) => new _As(this, Type(typeStr));

  /// If `this` is an expression `x`, creates the expression
  /// `x ? ifTrue : ifFalse`.
  Expression conditional(Expression ifTrue, Expression ifFalse) =>
      new _Conditional(this, ifTrue, ifFalse);

  /// If `this` is an expression `x`, creates the expression `x == other`.
  Expression eq(Expression other) => new _Equal(this, other, false);

  /// Creates an [Expression] that, when analyzed, will behave the same as
  /// `this`, but after visiting it, will cause [callback] to be passed the
  /// [ExpressionInfo] associated with it.  If the expression has no flow
  /// analysis information associated with it, `null` will be passed to
  /// [callback].
  Expression getExpressionInfo(
          void Function(ExpressionInfo<Var, Type>?) callback) =>
      new _GetExpressionInfo(this, callback);

  /// If `this` is an expression `x`, creates the expression `x ?? other`.
  Expression ifNull(Expression other) => new _IfNull(this, other);

  /// If `this` is an expression `x`, creates the expression `x is typeStr`.
  ///
  /// With [isInverted] set to `true`, creates the expression `x is! typeStr`.
  Expression is_(String typeStr, {bool isInverted = false}) =>
      new _Is(this, Type(typeStr), isInverted);

  /// If `this` is an expression `x`, creates the expression `x is! typeStr`.
  Expression isNot(String typeStr) => _Is(this, Type(typeStr), true);

  /// If `this` is an expression `x`, creates the expression `x != other`.
  Expression notEq(Expression other) => _Equal(this, other, true);

  /// If `this` is an expression `x`, creates the expression `x?.other`.
  ///
  /// Note that in the real Dart language, the RHS of a null aware access isn't
  /// strictly speaking an expression.  However for flow analysis it suffices to
  /// model it as an expression.
  Expression nullAwareAccess(Expression other, {bool isCascaded = false}) =>
      _NullAwareAccess(this, other, isCascaded);

  /// If `this` is an expression `x`, creates the expression `x || other`.
  Expression or(Expression other) => new _Logical(this, other, isAnd: false);

  /// If `this` is an expression `x`, creates a pseudo-expression that models
  /// evaluation of `x` followed by execution of [stmt].  This can be used to
  /// test that flow analysis is in the correct state after an expression is
  /// visited.
  Expression thenStmt(Statement stmt) =>
      new _WrappedExpression(null, this, stmt);
}

/// Test harness for creating flow analysis tests.  This class implements all
/// the [TypeOperations] needed by flow analysis, as well as other methods
/// needed for testing.
class Harness extends TypeOperations<Var, Type> {
  static const Map<String, bool> _coreSubtypes = const {
    'bool <: int': false,
    'bool <: Object': true,
    'double <: Object': true,
    'double <: num': true,
    'double <: num?': true,
    'double <: int': false,
    'double <: int?': false,
    'int <: double': false,
    'int <: int?': true,
    'int <: Iterable': false,
    'int <: List': false,
    'int <: Null': false,
    'int <: num': true,
    'int <: num?': true,
    'int <: num*': true,
    'int <: Never?': false,
    'int <: Object': true,
    'int <: Object?': true,
    'int <: String': false,
    'int? <: int': false,
    'int? <: Null': false,
    'int? <: num': false,
    'int? <: num?': true,
    'int? <: Object': false,
    'int? <: Object?': true,
    'Null <: int': false,
    'Null <: Object': false,
    'num <: int': false,
    'num <: Iterable': false,
    'num <: List': false,
    'num <: num?': true,
    'num <: num*': true,
    'num <: Object': true,
    'num <: Object?': true,
    'num? <: int?': false,
    'num? <: num': false,
    'num? <: num*': true,
    'num? <: Object': false,
    'num? <: Object?': true,
    'num* <: num': true,
    'num* <: num?': true,
    'num* <: Object': true,
    'num* <: Object?': true,
    'Iterable <: int': false,
    'Iterable <: num': false,
    'Iterable <: Object': true,
    'Iterable <: Object?': true,
    'List <: int': false,
    'List <: Iterable': true,
    'List <: Object': true,
    'Never <: int': true,
    'Never <: int?': true,
    'Never <: Null': true,
    'Never? <: int': false,
    'Never? <: int?': true,
    'Never? <: num?': true,
    'Never? <: Object?': true,
    'Null <: int?': true,
    'Object <: int': false,
    'Object <: int?': false,
    'Object <: List': false,
    'Object <: num': false,
    'Object <: num?': false,
    'Object <: Object?': true,
    'Object <: String': false,
    'Object? <: Object': false,
    'Object? <: int': false,
    'Object? <: int?': false,
    'String <: int': false,
    'String <: int?': false,
    'String <: num?': false,
    'String <: Object': true,
    'String <: Object?': true,
  };

  static final Map<String, Type> _coreFactors = {
    'Object? - int': Type('Object?'),
    'Object? - int?': Type('Object'),
    'Object? - num?': Type('Object'),
    'Object? - Object?': Type('Never?'),
    'Object? - String': Type('Object?'),
    'Object - bool': Type('Object'),
    'Object - int': Type('Object'),
    'Object - String': Type('Object'),
    'int - Object': Type('Never'),
    'int - String': Type('int'),
    'int - int': Type('Never'),
    'int - int?': Type('Never'),
    'int? - int': Type('Never?'),
    'int? - int?': Type('Never'),
    'int? - String': Type('int?'),
    'Null - int': Type('Null'),
    'num - int': Type('num'),
    'num? - num': Type('Never?'),
    'num? - int': Type('num?'),
    'num? - int?': Type('num'),
    'num? - Object': Type('Never?'),
    'num? - String': Type('num?'),
    'Object - int?': Type('Object'),
    'Object - num': Type('Object'),
    'Object - num?': Type('Object'),
    'Object - num*': Type('Object'),
    'Object - Iterable': Type('Object'),
    'Object? - Object': Type('Never?'),
    'Object? - Iterable': Type('Object?'),
    'Object? - num': Type('Object?'),
    'Iterable - List': Type('Iterable'),
    'num* - Object': Type('Never'),
  };

  final bool allowLocalBooleanVarsToPromote;

  final bool legacy;

  final Map<String, bool> _subtypes = Map.of(_coreSubtypes);

  final Map<String, Type> _factorResults = Map.of(_coreFactors);

  Node? _currentSwitch;

  Map<String, Map<String, String>> _promotionExceptions = {};

  Harness({this.allowLocalBooleanVarsToPromote = false, this.legacy = false});

  /// Updates the harness so that when a [factor] query is invoked on types
  /// [from] and [what], [result] will be returned.
  void addFactor(String from, String what, String result) {
    var query = '$from - $what';
    _factorResults[query] = Type(result);
  }

  void addPromotionException(String from, String to, String result) {
    (_promotionExceptions[from] ??= {})[to] = result;
  }

  /// Updates the harness so that when an [isSubtypeOf] query is invoked on
  /// types [leftType] and [rightType], [isSubtype] will be returned.
  void addSubtype(String leftType, String rightType, bool isSubtype) {
    var query = '$leftType <: $rightType';
    _subtypes[query] = isSubtype;
  }

  @override
  TypeClassification classifyType(Type type) {
    if (isSubtypeOf(type, Type('Object'))) {
      return TypeClassification.nonNullable;
    } else if (isSubtypeOf(type, Type('Null'))) {
      return TypeClassification.nullOrEquivalent;
    } else {
      return TypeClassification.potentiallyNullable;
    }
  }

  @override
  Type factor(Type from, Type what) {
    var query = '$from - $what';
    return _factorResults[query] ?? fail('Unknown factor query: $query');
  }

  @override
  bool isNever(Type type) {
    return type.type == 'Never';
  }

  @override
  bool isSameType(Type type1, Type type2) {
    return type1.type == type2.type;
  }

  @override
  bool isSubtypeOf(Type leftType, Type rightType) {
    if (leftType.type == rightType.type) return true;
    var query = '$leftType <: $rightType';
    return _subtypes[query] ?? fail('Unknown subtype query: $query');
  }

  @override
  Type promoteToNonNull(Type type) {
    if (type.type.endsWith('?')) {
      return Type(type.type.substring(0, type.type.length - 1));
    } else if (type.type == 'Null') {
      return Type('Never');
    } else {
      return type;
    }
  }

  /// Runs the given [statements] through flow analysis, checking any assertions
  /// they contain.
  void run(List<Statement> statements) {
    var assignedVariables = AssignedVariables<Node, Var>();
    statements._preVisit(assignedVariables);
    var flow = legacy
        ? FlowAnalysis<Node, Statement, Expression, Var, Type>.legacy(
            this, assignedVariables)
        : FlowAnalysis<Node, Statement, Expression, Var, Type>(
            this, assignedVariables,
            allowLocalBooleanVarsToPromote: allowLocalBooleanVarsToPromote);
    statements._visit(this, flow);
    flow.finish();
  }

  @override
  Type? tryPromoteToType(Type to, Type from) {
    var exception = (_promotionExceptions[from.type] ?? {})[to.type];
    if (exception != null) {
      return Type(exception);
    }
    if (isSubtypeOf(to, from)) {
      return to;
    } else {
      return null;
    }
  }

  @override
  Type variableType(Var variable) {
    return variable.type;
  }

  Type _getIteratedType(Type iterableType) {
    var typeStr = iterableType.type;
    if (typeStr.startsWith('List<') && typeStr.endsWith('>')) {
      return Type(typeStr.substring(5, typeStr.length - 1));
    } else {
      throw UnimplementedError('TODO(paulberry): getIteratedType($typeStr)');
    }
  }

  Type _lub(Type type1, Type type2) {
    if (isSameType(type1, type2)) {
      return type1;
    } else if (isSameType(promoteToNonNull(type1), type2)) {
      return type1;
    } else if (isSameType(promoteToNonNull(type2), type1)) {
      return type2;
    } else if (type1.type == 'Null' &&
        !isSameType(promoteToNonNull(type2), type2)) {
      // type2 is already nullable
      return type2;
    } else if (type2.type == 'Null' &&
        !isSameType(promoteToNonNull(type1), type1)) {
      // type1 is already nullable
      return type1;
    } else if (type1.type == 'Never') {
      return type2;
    } else if (type2.type == 'Never') {
      return type1;
    } else {
      throw UnimplementedError(
          'TODO(paulberry): least upper bound of $type1 and $type2');
    }
  }
}

/// Representation of an expression or statement in the pseudo-Dart language
/// used for flow analysis testing.
class Node {
  const Node._();
}

/// Helper class allowing tests to examine the values of variables' SSA nodes.
class SsaNodeHarness {
  final FlowAnalysis<Node, Statement, Expression, Var, Type> _flow;

  SsaNodeHarness(this._flow);

  /// Gets the SSA node associated with [variable] at the current point in
  /// control flow, or `null` if the variable has been write captured.
  SsaNode<Var, Type>? operator [](Var variable) =>
      _flow.ssaNodeForTesting(variable);
}

/// Representation of a statement in the pseudo-Dart language used for flow
/// analysis testing.
abstract class Statement extends Node implements _Visitable<void> {
  Statement._() : super._();

  /// If `this` is a statement `x`, creates a pseudo-expression that models
  /// execution of `x` followed by evaluation of [expr].  This can be used to
  /// test that flow analysis is in the correct state before an expression is
  /// visited.
  Expression thenExpr(Expression expr) => _WrappedExpression(this, expr, null);
}

/// Representation of a single case clause in a switch statement.  Use [case_]
/// to create instances of this class.
class SwitchCase implements _Visitable<void> {
  final bool _hasLabel;
  final List<Statement> _body;

  SwitchCase._(this._hasLabel, this._body);

  String toString() =>
      [if (_hasLabel) '<label>:', 'case <value>:', ..._body].join(' ');

  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
    _body._preVisit(assignedVariables);
  }

  void _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    flow.switchStatement_beginCase(_hasLabel, h._currentSwitch!);
    _body._visit(h, flow);
  }
}

/// Representation of a type in the pseudo-Dart language used for flow analysis
/// testing.  This is essentially a thin wrapper around a string representation
/// of the type.
class Type {
  final String type;

  Type(this.type);

  @override
  bool operator ==(Object other) {
    // The flow analysis engine should not compare types using operator==.  It
    // should compare them using TypeOperations.
    fail('Unexpected use of operator== on types');
  }

  @override
  String toString() => type;
}

/// Representation of a local variable in the pseudo-Dart language used for flow
/// analysis testing.
class Var {
  final String name;
  final Type type;

  Var(this.name, String typeStr) : type = Type(typeStr);

  /// Creates an expression representing a read of this variable.
  Expression get read => new _VariableRead(this, null);

  /// Creates an expression representing a read of this variable, which as a
  /// side effect will call the given callback with the returned promoted type.
  Expression readAndCheckPromotedType(void Function(Type?) callback) =>
      new _VariableRead(this, callback);

  @override
  String toString() => '$type $name';

  /// Creates an expression representing a write to this variable.
  Expression write(Expression? value) => new _Write(this, value);
}

class _As extends Expression {
  final Expression target;
  final Type type;

  _As(this.target, this.type);

  @override
  String toString() => '$target as $type';

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
    target._preVisit(assignedVariables);
  }

  @override
  Type _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    target._visit(h, flow);
    flow.asExpression_end(target, type);
    return type;
  }
}

class _Assert extends Statement {
  final Expression condition;
  final Expression? message;

  _Assert(this.condition, this.message) : super._();

  @override
  String toString() =>
      'assert($condition${message == null ? '' : ', $message'});';

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
    condition._preVisit(assignedVariables);
    message?._preVisit(assignedVariables);
  }

  @override
  void _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    flow.assert_begin();
    flow.assert_afterCondition(condition.._visit(h, flow));
    message?._visit(h, flow);
    flow.assert_end();
  }
}

class _Block extends Statement {
  final List<Statement> statements;

  _Block(this.statements) : super._();

  @override
  String toString() =>
      statements.isEmpty ? '{}' : '{ ${statements.join(' ')} }';

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
    statements._preVisit(assignedVariables);
  }

  @override
  void _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    statements._visit(h, flow);
  }
}

class _BooleanLiteral extends Expression {
  final bool value;

  _BooleanLiteral(this.value);

  @override
  String toString() => '$value';

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}

  @override
  Type _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    flow.booleanLiteral(this, value);
    return Type('bool');
  }
}

class _Break extends Statement {
  final BranchTargetPlaceholder branchTargetPlaceholder;

  _Break(this.branchTargetPlaceholder) : super._();

  @override
  String toString() => 'break;';

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}

  @override
  void _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    // ignore: unnecessary_null_comparison
    assert(branchTargetPlaceholder._target != null);
    flow.handleBreak(branchTargetPlaceholder._target);
  }
}

class _CheckAssigned extends Statement {
  final Var variable;
  final bool expectedAssignedState;

  _CheckAssigned(this.variable, this.expectedAssignedState) : super._();

  @override
  String toString() {
    var verb = expectedAssignedState ? 'is' : 'is not';
    return 'check $variable $verb definitely assigned;';
  }

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}

  @override
  void _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    expect(flow.isAssigned(variable), expectedAssignedState);
  }
}

class _CheckPromoted extends Statement {
  final Var variable;
  final String? expectedTypeStr;

  _CheckPromoted(this.variable, this.expectedTypeStr) : super._();

  @override
  String toString() {
    var predicate = expectedTypeStr == null
        ? 'not promoted'
        : 'promoted to $expectedTypeStr';
    return 'check $variable $predicate;';
  }

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}

  @override
  void _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    var promotedType = flow.promotedType(variable);
    if (expectedTypeStr == null) {
      expect(promotedType, isNull);
    } else {
      expect(promotedType?.type, expectedTypeStr);
    }
  }
}

class _CheckReachable extends Statement {
  final bool expectedReachable;

  _CheckReachable(this.expectedReachable) : super._();

  @override
  String toString() => 'check reachable;';

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}

  @override
  void _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    expect(flow.isReachable, expectedReachable);
  }
}

class _CheckUnassigned extends Statement {
  final Var variable;
  final bool expectedUnassignedState;

  _CheckUnassigned(this.variable, this.expectedUnassignedState) : super._();

  @override
  String toString() {
    var verb = expectedUnassignedState ? 'is' : 'is not';
    return 'check $variable $verb definitely unassigned;';
  }

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}

  @override
  void _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    expect(flow.isUnassigned(variable), expectedUnassignedState);
  }
}

class _Conditional extends Expression {
  final Expression condition;
  final Expression ifTrue;
  final Expression ifFalse;

  _Conditional(this.condition, this.ifTrue, this.ifFalse);

  @override
  String toString() => '$condition ? $ifTrue : $ifFalse';

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
    condition._preVisit(assignedVariables);
    assignedVariables.beginNode();
    ifTrue._preVisit(assignedVariables);
    assignedVariables.endNode(this);
    ifFalse._preVisit(assignedVariables);
  }

  @override
  Type _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    flow.conditional_conditionBegin();
    flow.conditional_thenBegin(condition.._visit(h, flow), this);
    var ifTrueType = ifTrue._visit(h, flow);
    flow.conditional_elseBegin(ifTrue);
    var ifFalseType = ifFalse._visit(h, flow);
    flow.conditional_end(this, ifFalse);
    return h._lub(ifTrueType, ifFalseType);
  }
}

class _Continue extends Statement {
  final BranchTargetPlaceholder branchTargetPlaceholder;

  _Continue(this.branchTargetPlaceholder) : super._();

  @override
  String toString() => 'continue;';

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}

  @override
  void _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    // ignore: unnecessary_null_comparison
    assert(branchTargetPlaceholder._target != null);
    flow.handleContinue(branchTargetPlaceholder._target);
  }
}

class _Declare extends Statement {
  final Var variable;
  final Expression? initializer;
  final bool isFinal;
  final bool isLate;

  _Declare(this.variable, this.initializer, this.isFinal, this.isLate)
      : super._();

  @override
  String toString() {
    var latePart = isLate ? 'late ' : '';
    var finalPart = isFinal ? 'final ' : '';
    var initializerPart = initializer != null ? ' = $initializer' : '';
    return '$latePart$finalPart$variable${initializerPart};';
  }

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
    initializer?._preVisit(assignedVariables);
  }

  @override
  void _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    var initializer = this.initializer;
    if (initializer == null) {
      flow.declare(variable, false);
    } else {
      var initializerType = initializer._visit(h, flow);
      flow.declare(variable, true);
      flow.initialize(variable, initializerType, initializer,
          isFinal: isFinal, isLate: isLate);
    }
  }
}

class _Do extends Statement {
  final List<Statement> body;
  final Expression condition;

  _Do(this.body, this.condition) : super._();

  @override
  String toString() => 'do ${block(body)} while ($condition);';

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
    assignedVariables.beginNode();
    body._preVisit(assignedVariables);
    condition._preVisit(assignedVariables);
    assignedVariables.endNode(this);
  }

  @override
  void _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    flow.doStatement_bodyBegin(this);
    body._visit(h, flow);
    flow.doStatement_conditionBegin();
    condition._visit(h, flow);
    flow.doStatement_end(condition);
  }
}

class _Equal extends Expression {
  final Expression lhs;
  final Expression rhs;
  final bool isInverted;

  _Equal(this.lhs, this.rhs, this.isInverted);

  @override
  String toString() => '$lhs ${isInverted ? '!=' : '=='} $rhs';

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
    lhs._preVisit(assignedVariables);
    rhs._preVisit(assignedVariables);
  }

  @override
  Type _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    var lhsType = lhs._visit(h, flow);
    flow.equalityOp_rightBegin(lhs, lhsType);
    var rhsType = rhs._visit(h, flow);
    flow.equalityOp_end(this, rhs, rhsType, notEqual: isInverted);
    return Type('bool');
  }
}

class _ExpressionStatement extends Statement {
  final Expression expr;

  _ExpressionStatement(this.expr) : super._();

  @override
  String toString() => '$expr;';

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
    expr._preVisit(assignedVariables);
  }

  @override
  void _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    expr._visit(h, flow);
  }
}

class _For extends Statement {
  final Statement? initializer;
  final Expression? condition;
  final Expression? updater;
  final List<Statement> body;
  final bool forCollection;

  _For(this.initializer, this.condition, this.updater, this.body,
      this.forCollection)
      : super._();

  @override
  String toString() {
    var buffer = StringBuffer('for (');
    if (initializer == null) {
      buffer.write(';');
    } else {
      buffer.write(initializer);
    }
    if (condition == null) {
      buffer.write(';');
    } else {
      buffer.write(' $condition;');
    }
    if (updater != null) {
      buffer.write(' $updater');
    }
    buffer.write(') ${block(body)}');
    return buffer.toString();
  }

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
    initializer?._preVisit(assignedVariables);
    assignedVariables.beginNode();
    condition?._preVisit(assignedVariables);
    body._preVisit(assignedVariables);
    updater?._preVisit(assignedVariables);
    assignedVariables.endNode(this);
  }

  @override
  void _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    initializer?._visit(h, flow);
    flow.for_conditionBegin(this);
    condition?._visit(h, flow);
    flow.for_bodyBegin(forCollection ? null : this, condition);
    body._visit(h, flow);
    flow.for_updaterBegin();
    updater?._visit(h, flow);
    flow.for_end();
  }
}

class _ForEach extends Statement {
  final Var? variable;
  final Expression iterable;
  final List<Statement> body;
  final bool declaresVariable;

  _ForEach(this.variable, this.iterable, this.body, this.declaresVariable)
      : super._();

  @override
  String toString() {
    String declarationPart;
    if (variable == null) {
      declarationPart = '<identifier>';
    } else if (declaresVariable) {
      declarationPart = variable.toString();
    } else {
      declarationPart = variable!.name;
    }
    return 'for ($declarationPart in $iterable) ${block(body)}';
  }

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
    iterable._preVisit(assignedVariables);
    if (variable != null) {
      if (declaresVariable) {
        assignedVariables.declare(variable!);
      } else {
        assignedVariables.write(variable!);
      }
    }
    assignedVariables.beginNode();
    body._preVisit(assignedVariables);
    assignedVariables.endNode(this);
  }

  @override
  void _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    var iteratedType = h._getIteratedType(iterable._visit(h, flow));
    flow.forEach_bodyBegin(this, variable, iteratedType);
    body._visit(h, flow);
    flow.forEach_end();
  }
}

class _GetExpressionInfo extends Expression {
  final Expression target;

  final void Function(ExpressionInfo<Var, Type>?) callback;

  _GetExpressionInfo(this.target, this.callback);

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
    target._preVisit(assignedVariables);
  }

  @override
  Type _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    var type = target._visit(h, flow);
    flow.forwardExpression(this, target);
    callback(flow.expressionInfoForTesting(this));
    return type;
  }
}

class _GetSsaNodes extends Statement {
  final void Function(SsaNodeHarness) callback;

  _GetSsaNodes(this.callback) : super._();

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}

  @override
  void _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    callback(SsaNodeHarness(flow));
  }
}

class _If extends Statement {
  final Expression condition;
  final List<Statement> ifTrue;
  final List<Statement>? ifFalse;

  _If(this.condition, this.ifTrue, this.ifFalse) : super._();

  @override
  String toString() =>
      'if ($condition) ${block(ifTrue)}' +
      (ifFalse == null ? '' : 'else ${block(ifFalse!)}');

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
    condition._preVisit(assignedVariables);
    assignedVariables.beginNode();
    ifTrue._preVisit(assignedVariables);
    assignedVariables.endNode(this);
    ifFalse?._preVisit(assignedVariables);
  }

  @override
  void _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    flow.ifStatement_conditionBegin();
    flow.ifStatement_thenBegin(condition.._visit(h, flow), this);
    ifTrue._visit(h, flow);
    if (ifFalse == null) {
      flow.ifStatement_end(false);
    } else {
      flow.ifStatement_elseBegin();
      ifFalse!._visit(h, flow);
      flow.ifStatement_end(true);
    }
  }
}

class _IfNull extends Expression {
  final Expression lhs;
  final Expression rhs;

  _IfNull(this.lhs, this.rhs);

  @override
  String toString() => '$lhs ?? $rhs';

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
    lhs._preVisit(assignedVariables);
    rhs._preVisit(assignedVariables);
  }

  @override
  Type _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    var lhsType = lhs._visit(h, flow);
    flow.ifNullExpression_rightBegin(lhs, lhsType);
    var rhsType = rhs._visit(h, flow);
    flow.ifNullExpression_end();
    return h._lub(h.promoteToNonNull(lhsType), rhsType);
  }
}

class _Is extends Expression {
  final Expression target;
  final Type type;
  final bool isInverted;

  _Is(this.target, this.type, this.isInverted);

  @override
  String toString() => '$target is${isInverted ? '!' : ''} $type';

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
    target._preVisit(assignedVariables);
  }

  @override
  Type _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    flow.isExpression_end(this, target.._visit(h, flow), isInverted, type);
    return Type('bool');
  }
}

class _LabeledStatement extends Statement {
  final Statement body;

  _LabeledStatement(this.body) : super._();

  @override
  String toString() => 'labeled: $body';

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
    body._preVisit(assignedVariables);
  }

  @override
  void _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    flow.labeledStatement_begin(this);
    body._visit(h, flow);
    flow.labeledStatement_end();
  }
}

class _LocalFunction extends Statement {
  final List<Statement> body;

  _LocalFunction(this.body) : super._();

  @override
  String toString() => '() ${block(body)}';

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
    assignedVariables.beginNode();
    body._preVisit(assignedVariables);
    assignedVariables.endNode(this, isClosureOrLateVariableInitializer: true);
  }

  @override
  void _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    flow.functionExpression_begin(this);
    body._visit(h, flow);
    flow.functionExpression_end();
  }
}

class _Logical extends Expression {
  final Expression lhs;
  final Expression rhs;
  final bool isAnd;

  _Logical(this.lhs, this.rhs, {required this.isAnd});

  @override
  String toString() => '$lhs ${isAnd ? '&&' : '||'} $rhs';

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
    lhs._preVisit(assignedVariables);
    assignedVariables.beginNode();
    rhs._preVisit(assignedVariables);
    assignedVariables.endNode(this);
  }

  @override
  Type _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    flow.logicalBinaryOp_begin();
    flow.logicalBinaryOp_rightBegin(lhs.._visit(h, flow), this, isAnd: isAnd);
    flow.logicalBinaryOp_end(this, rhs.._visit(h, flow), isAnd: isAnd);
    return Type('bool');
  }
}

class _NonNullAssert extends Expression {
  final Expression operand;

  _NonNullAssert(this.operand);

  @override
  String toString() => '$operand!';

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
    operand._preVisit(assignedVariables);
  }

  @override
  Type _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    var type = operand._visit(h, flow);
    flow.nonNullAssert_end(operand);
    return h.promoteToNonNull(type);
  }
}

class _Not extends Expression {
  final Expression operand;

  _Not(this.operand);

  @override
  String toString() => '!$operand';

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
    operand._preVisit(assignedVariables);
  }

  @override
  Type _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    flow.logicalNot_end(this, operand.._visit(h, flow));
    return Type('bool');
  }
}

class _NullAwareAccess extends Expression {
  final Expression lhs;
  final Expression rhs;
  final bool isCascaded;

  _NullAwareAccess(this.lhs, this.rhs, this.isCascaded);

  @override
  String toString() => '$lhs?.${isCascaded ? '.' : ''}($rhs)';

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
    lhs._preVisit(assignedVariables);
    rhs._preVisit(assignedVariables);
  }

  @override
  Type _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    var lhsType = lhs._visit(h, flow);
    flow.nullAwareAccess_rightBegin(isCascaded ? null : lhs, lhsType);
    var rhsType = rhs._visit(h, flow);
    flow.nullAwareAccess_end();
    return h._lub(rhsType, Type('Null'));
  }
}

class _NullLiteral extends Expression {
  const _NullLiteral();

  @override
  String toString() => 'null';

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}

  @override
  Type _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    flow.nullLiteral(this);
    return Type('Null');
  }
}

class _ParenthesizedExpression extends Expression {
  final Expression expr;

  _ParenthesizedExpression(this.expr);

  @override
  String toString() => '($expr)';

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
    expr._preVisit(assignedVariables);
  }

  @override
  Type _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    var type = expr._visit(h, flow);
    flow.parenthesizedExpression(this, expr);
    return type;
  }
}

class _PlaceholderExpression extends Expression {
  final Type type;

  _PlaceholderExpression(this.type);

  @override
  String toString() => '(expr with type $type)';

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}

  @override
  Type _visit(Harness h,
          FlowAnalysis<Node, Statement, Expression, Var, Type> flow) =>
      type;
}

class _Return extends Statement {
  _Return() : super._();

  @override
  String toString() => 'return;';

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}

  @override
  void _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    flow.handleExit();
  }
}

class _Switch extends Statement {
  final Expression expression;
  final List<SwitchCase> cases;
  final bool isExhaustive;

  _Switch(this.expression, this.cases, this.isExhaustive) : super._();

  @override
  String toString() {
    var exhaustiveness = isExhaustive ? 'exhaustive' : 'non-exhaustive';
    String body;
    if (cases.isEmpty) {
      body = '{}';
    } else {
      var contents = cases.join(' ');
      body = '{ $contents }';
    }
    return 'switch<$exhaustiveness> ($expression) $body';
  }

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
    expression._preVisit(assignedVariables);
    assignedVariables.beginNode();
    cases._preVisit(assignedVariables);
    assignedVariables.endNode(this);
  }

  @override
  void _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    expression._visit(h, flow);
    flow.switchStatement_expressionEnd(this);
    var oldSwitch = h._currentSwitch;
    h._currentSwitch = this;
    cases._visit(h, flow);
    h._currentSwitch = oldSwitch;
    flow.switchStatement_end(isExhaustive);
  }
}

class _Throw extends Expression {
  final Expression operand;

  _Throw(this.operand);

  @override
  String toString() => 'throw ...';

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
    operand._preVisit(assignedVariables);
  }

  @override
  Type _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    operand._visit(h, flow);
    flow.handleExit();
    return Type('Never');
  }
}

class _TryCatch extends Statement {
  final List<Statement> body;
  final List<CatchClause> catches;

  _TryCatch(this.body, this.catches) : super._();

  @override
  String toString() => 'try ${block(body)} ${catches.join(' ')}';

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
    assignedVariables.beginNode();
    body._preVisit(assignedVariables);
    assignedVariables.endNode(this);
    catches._preVisit(assignedVariables);
  }

  @override
  void _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    flow.tryCatchStatement_bodyBegin();
    body._visit(h, flow);
    flow.tryCatchStatement_bodyEnd(this);
    catches._visit(h, flow);
    flow.tryCatchStatement_end();
  }
}

class _TryFinally extends Statement {
  final List<Statement> body;
  final List<Statement> finally_;
  final Node _bodyNode = Node._();
  final Node _finallyNode = Node._();

  _TryFinally(this.body, this.finally_) : super._();

  @override
  String toString() => 'try ${block(body)} finally ${block(finally_)}';

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
    assignedVariables.beginNode();
    body._preVisit(assignedVariables);
    assignedVariables.endNode(_bodyNode);
    assignedVariables.beginNode();
    finally_._preVisit(assignedVariables);
    assignedVariables.endNode(_finallyNode);
  }

  @override
  void _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    flow.tryFinallyStatement_bodyBegin();
    body._visit(h, flow);
    flow.tryFinallyStatement_finallyBegin(_bodyNode);
    finally_._visit(h, flow);
    flow.tryFinallyStatement_end(_finallyNode);
  }
}

class _VariableRead extends Expression {
  final Var variable;

  final void Function(Type?)? callback;

  _VariableRead(this.variable, this.callback);

  @override
  String toString() => variable.name;

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
    assignedVariables.read(variable);
  }

  @override
  Type _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    var readResult = flow.variableRead(this, variable);
    callback?.call(readResult);
    return readResult ?? variable.type;
  }
}

abstract class _Visitable<T> {
  void _preVisit(AssignedVariables<Node, Var> assignedVariables);

  T _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow);
}

class _While extends Statement {
  final Expression condition;
  final List<Statement> body;

  _While(this.condition, this.body) : super._();

  @override
  String toString() => 'while ($condition) ${block(body)}';

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
    assignedVariables.beginNode();
    condition._preVisit(assignedVariables);
    body._preVisit(assignedVariables);
    assignedVariables.endNode(this);
  }

  @override
  void _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    flow.whileStatement_conditionBegin(this);
    condition._visit(h, flow);
    flow.whileStatement_bodyBegin(this, condition);
    body._visit(h, flow);
    flow.whileStatement_end();
  }
}

class _WrappedExpression extends Expression {
  final Statement? before;
  final Expression expr;
  final Statement? after;

  _WrappedExpression(this.before, this.expr, this.after);

  @override
  String toString() {
    var s = StringBuffer('(');
    if (before != null) {
      s.write('($before) ');
    }
    s.write(expr);
    if (after != null) {
      s.write(' ($after)');
    }
    s.write(')');
    return s.toString();
  }

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
    before?._preVisit(assignedVariables);
    expr._preVisit(assignedVariables);
    after?._preVisit(assignedVariables);
  }

  @override
  Type _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    before?._visit(h, flow);
    var type = expr._visit(h, flow);
    after?._visit(h, flow);
    flow.forwardExpression(this, expr);
    return type;
  }
}

class _Write extends Expression {
  final Var variable;
  final Expression? rhs;

  _Write(this.variable, this.rhs);

  @override
  String toString() => '${variable.name} = $rhs';

  @override
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
    assignedVariables.write(variable);
    rhs?._preVisit(assignedVariables);
  }

  @override
  Type _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    var rhs = this.rhs;
    var type = rhs == null ? variable.type : rhs._visit(h, flow);
    flow.write(variable, type, rhs);
    return type;
  }
}

extension on List<_Visitable<void>> {
  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
    for (var element in this) {
      element._preVisit(assignedVariables);
    }
  }

  void _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    for (var element in this) {
      element._visit(h, flow);
    }
  }
}
