// 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';

Expression get nullLiteral => new _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 implicitThis_whyNotPromoted(String staticType,
        void Function(Map<Type, NonPromotionReason>) callback) =>
    new _WhyNotPromoted_ImplicitThis(Type(staticType), callback);

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 this_(String type) => new _This(Type(type));

Expression thisOrSuperPropertyGet(String name, {String type = 'Object?'}) =>
    new _ThisOrSuperPropertyGet(name, Type(type));

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> {
  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 the expression `x.name`.
  Expression propertyGet(String name, {String type = 'Object?'}) =>
      new _PropertyGet(this, name, Type(type));

  /// 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);

  /// Creates an [Expression] that, when analyzed, will behave the same as
  /// `this`, but after visiting it, will cause [callback] to be passed the
  /// non-promotion info associated with it.  If the expression has no
  /// non-promotion info, an empty map will be passed to [callback].
  Expression whyNotPromoted(
          void Function(Map<Type, NonPromotionReason>) callback) =>
      new _WhyNotPromoted(this, callback);
}

/// 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,
    'Never <: Object?': true,
    'Null <: int': false,
    'Null <: Object': false,
    'Null <: Object?': true,
    '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 <: Null': false,
    'Object <: num': false,
    'Object <: num?': false,
    'Object <: Object?': true,
    'Object <: String': false,
    'Object? <: Object': false,
    'Object? <: int': false,
    'Object? <: int?': false,
    'Object? <: Null': 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? - Never': Type('Object?'),
    'Object? - Null': 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 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.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);
    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 {
  static int _nextId = 0;

  final int id;

  Node._() : id = _nextId++;

  String toString() => 'Node#$id';
}

/// 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 {
  static bool _allowComparisons = false;

  final String type;

  Type(this.type);

  @override
  int get hashCode {
    if (!_allowComparisons) {
      // The flow analysis engine should not hash types using hashCode.  It
      // should compare them using TypeOperations.
      fail('Unexpected use of operator== on types');
    }
    return type.hashCode;
  }

  @override
  bool operator ==(Object other) {
    if (!_allowComparisons) {
      // The flow analysis engine should not compare types using operator==.  It
      // should compare them using TypeOperations.
      fail('Unexpected use of operator== on types');
    }
    return other is Type && this.type == other.type;
  }

  @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 {
  _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 _PropertyGet extends Expression {
  final Expression target;

  final String propertyName;

  final Type type;

  _PropertyGet(this.target, this.propertyName, this.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.propertyGet(this, target, propertyName, type);
    return 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 _This extends Expression {
  final Type type;

  _This(this.type);

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

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

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

class _ThisOrSuperPropertyGet extends Expression {
  final String propertyName;

  final Type type;

  _ThisOrSuperPropertyGet(this.propertyName, this.type);

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

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

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._();

  _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);
    finally_._preVisit(assignedVariables);
  }

  @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();
  }
}

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 _WhyNotPromoted extends Expression {
  final Expression target;

  final void Function(Map<Type, NonPromotionReason>) callback;

  _WhyNotPromoted(this.target, this.callback);

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

  @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);
    assert(!Type._allowComparisons);
    Type._allowComparisons = true;
    try {
      callback(flow.whyNotPromoted(this));
    } finally {
      Type._allowComparisons = false;
    }
    return type;
  }
}

class _WhyNotPromoted_ImplicitThis extends Statement {
  final Type staticType;

  final void Function(Map<Type, NonPromotionReason>) callback;

  _WhyNotPromoted_ImplicitThis(this.staticType, this.callback) : super._();

  @override
  String toString() => 'implicit this (whyNotPromoted)';

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

  @override
  void _visit(
      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
    assert(!Type._allowComparisons);
    Type._allowComparisons = true;
    try {
      callback(flow.whyNotPromotedImplicitThis(staticType));
    } finally {
      Type._allowComparisons = false;
    }
  }
}

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(this, 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);
    }
  }
}
