// Copyright (c) 2015, 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.

library dart2js.resolution.send_structure;

import '../common.dart';
import '../constants/expressions.dart';
import '../elements/resolution_types.dart';
import '../elements/elements.dart';
import '../resolution/tree_elements.dart' show TreeElements;
import '../tree/tree.dart';
import '../universe/call_structure.dart' show CallStructure;
import '../universe/selector.dart' show Selector;
import 'access_semantics.dart';
import 'operators.dart';
import 'semantic_visitor.dart';

/// Interface for the structure of the semantics of a [Send] or [NewExpression]
/// node.
abstract class SemanticSendStructure<R, A> {
  /// Calls the matching visit method on [visitor] with [node] and [arg].
  R dispatch(SemanticSendVisitor<R, A> visitor, Node node, A arg);
}

enum SendStructureKind {
  IF_NULL,
  LOGICAL_AND,
  LOGICAL_OR,
  IS,
  IS_NOT,
  AS,
  INVOKE,
  INCOMPATIBLE_INVOKE,
  GET,
  SET,
  NOT,
  UNARY,
  INVALID_UNARY,
  INDEX,
  EQUALS,
  NOT_EQUALS,
  BINARY,
  INVALID_BINARY,
  INDEX_SET,
  INDEX_PREFIX,
  INDEX_POSTFIX,
  COMPOUND,
  SET_IF_NULL,
  COMPOUND_INDEX_SET,
  INDEX_SET_IF_NULL,
  PREFIX,
  POSTFIX,
  DEFERRED_PREFIX,
}

/// Interface for the structure of the semantics of a [Send] node.
///
/// Subclasses handle each of the [Send] variations; `assert(e)`, `a && b`,
/// `a.b`, `a.b(c)`, etc.
abstract class SendStructure<R, A> extends SemanticSendStructure<R, A> {
  /// Calls the matching visit method on [visitor] with [send] and [arg].
  R dispatch(SemanticSendVisitor<R, A> visitor, Send send, A arg);

  SendStructureKind get kind;
}

/// The structure for a [Send] of the form `a ?? b`.
class IfNullStructure<R, A> implements SendStructure<R, A> {
  const IfNullStructure();

  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
    return visitor.visitIfNull(node, node.receiver, node.arguments.single, arg);
  }

  @override
  SendStructureKind get kind => SendStructureKind.IF_NULL;

  String toString() => '??';
}

/// The structure for a [Send] of the form `a && b`.
class LogicalAndStructure<R, A> implements SendStructure<R, A> {
  const LogicalAndStructure();

  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
    return visitor.visitLogicalAnd(
        node, node.receiver, node.arguments.single, arg);
  }

  @override
  SendStructureKind get kind => SendStructureKind.LOGICAL_AND;

  String toString() => '&&';
}

/// The structure for a [Send] of the form `a || b`.
class LogicalOrStructure<R, A> implements SendStructure<R, A> {
  const LogicalOrStructure();

  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
    return visitor.visitLogicalOr(
        node, node.receiver, node.arguments.single, arg);
  }

  @override
  SendStructureKind get kind => SendStructureKind.LOGICAL_OR;

  String toString() => '||';
}

/// The structure for a [Send] of the form `a is T`.
class IsStructure<R, A> implements SendStructure<R, A> {
  /// The type that the expression is tested against.
  final ResolutionDartType type;

  IsStructure(this.type);

  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
    return visitor.visitIs(node, node.receiver, type, arg);
  }

  @override
  SendStructureKind get kind => SendStructureKind.IS;

  String toString() => 'is $type';
}

/// The structure for a [Send] of the form `a is! T`.
class IsNotStructure<R, A> implements SendStructure<R, A> {
  /// The type that the expression is tested against.
  final ResolutionDartType type;

  IsNotStructure(this.type);

  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
    return visitor.visitIsNot(node, node.receiver, type, arg);
  }

  @override
  SendStructureKind get kind => SendStructureKind.IS_NOT;

  String toString() => 'is! $type';
}

/// The structure for a [Send] of the form `a as T`.
class AsStructure<R, A> implements SendStructure<R, A> {
  /// The type that the expression is cast to.
  final ResolutionDartType type;

  AsStructure(this.type);

  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
    return visitor.visitAs(node, node.receiver, type, arg);
  }

  @override
  SendStructureKind get kind => SendStructureKind.AS;

  String toString() => 'as $type';
}

/// The structure for a [Send] that is an invocation.
class InvokeStructure<R, A> implements SendStructure<R, A> {
  /// The target of the invocation.
  final AccessSemantics semantics;

  /// The [Selector] for the invocation.
  // TODO(johnniwinther): Store this only for dynamic invocations.
  final Selector selector;

  /// The [CallStructure] of the invocation.
  // TODO(johnniwinther): Store this directly for static invocations.
  CallStructure get callStructure => selector.callStructure;

  InvokeStructure(this.semantics, this.selector);

  @override
  SendStructureKind get kind => SendStructureKind.INVOKE;

  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
    switch (semantics.kind) {
      case AccessKind.CONDITIONAL_DYNAMIC_PROPERTY:
        return visitor.visitIfNotNullDynamicPropertyInvoke(
            node, node.receiver, node.argumentsNode, selector, arg);
      case AccessKind.DYNAMIC_PROPERTY:
        return visitor.visitDynamicPropertyInvoke(
            node, node.receiver, node.argumentsNode, selector, arg);
      case AccessKind.LOCAL_FUNCTION:
        return visitor.visitLocalFunctionInvoke(
            node,
            semantics.element,
            node.argumentsNode,
            // TODO(johnniwinther): Store the call selector instead of the
            // selector using the name of the function.
            callStructure,
            arg);
      case AccessKind.LOCAL_VARIABLE:
      case AccessKind.FINAL_LOCAL_VARIABLE:
        return visitor.visitLocalVariableInvoke(
            node,
            semantics.element,
            node.argumentsNode,
            // TODO(johnniwinther): Store the call selector instead of the
            // selector using the name of the variable.
            callStructure,
            arg);
      case AccessKind.PARAMETER:
      case AccessKind.FINAL_PARAMETER:
        return visitor.visitParameterInvoke(
            node,
            semantics.element,
            node.argumentsNode,
            // TODO(johnniwinther): Store the call selector instead of the
            // selector using the name of the parameter.
            callStructure,
            arg);
      case AccessKind.STATIC_FIELD:
      case AccessKind.FINAL_STATIC_FIELD:
        return visitor.visitStaticFieldInvoke(
            node, semantics.element, node.argumentsNode, callStructure, arg);
      case AccessKind.STATIC_METHOD:
        return visitor.visitStaticFunctionInvoke(
            node, semantics.element, node.argumentsNode, callStructure, arg);
      case AccessKind.STATIC_GETTER:
        return visitor.visitStaticGetterInvoke(
            node, semantics.element, node.argumentsNode, callStructure, arg);
      case AccessKind.STATIC_SETTER:
        return visitor.visitStaticSetterInvoke(
            node, semantics.element, node.argumentsNode, callStructure, arg);
      case AccessKind.TOPLEVEL_FIELD:
      case AccessKind.FINAL_TOPLEVEL_FIELD:
        return visitor.visitTopLevelFieldInvoke(
            node, semantics.element, node.argumentsNode, callStructure, arg);
      case AccessKind.TOPLEVEL_METHOD:
        return visitor.visitTopLevelFunctionInvoke(
            node, semantics.element, node.argumentsNode, callStructure, arg);
      case AccessKind.TOPLEVEL_GETTER:
        return visitor.visitTopLevelGetterInvoke(
            node, semantics.element, node.argumentsNode, callStructure, arg);
      case AccessKind.TOPLEVEL_SETTER:
        return visitor.visitTopLevelSetterInvoke(
            node, semantics.element, node.argumentsNode, callStructure, arg);
      case AccessKind.CLASS_TYPE_LITERAL:
        return visitor.visitClassTypeLiteralInvoke(
            node, semantics.constant, node.argumentsNode, callStructure, arg);
      case AccessKind.TYPEDEF_TYPE_LITERAL:
        return visitor.visitTypedefTypeLiteralInvoke(
            node, semantics.constant, node.argumentsNode, callStructure, arg);
      case AccessKind.DYNAMIC_TYPE_LITERAL:
        return visitor.visitDynamicTypeLiteralInvoke(
            node, semantics.constant, node.argumentsNode, callStructure, arg);
      case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
        return visitor.visitTypeVariableTypeLiteralInvoke(
            node, semantics.element, node.argumentsNode, callStructure, arg);
      case AccessKind.EXPRESSION:
        return visitor.visitExpressionInvoke(
            node, node.selector, node.argumentsNode, callStructure, arg);
      case AccessKind.THIS:
        return visitor.visitThisInvoke(
            node, node.argumentsNode, callStructure, arg);
      case AccessKind.THIS_PROPERTY:
        return visitor.visitThisPropertyInvoke(
            node, node.argumentsNode, selector, arg);
      case AccessKind.SUPER_FIELD:
      case AccessKind.SUPER_FINAL_FIELD:
        return visitor.visitSuperFieldInvoke(
            node, semantics.element, node.argumentsNode, callStructure, arg);
      case AccessKind.SUPER_METHOD:
        return visitor.visitSuperMethodInvoke(
            node, semantics.element, node.argumentsNode, callStructure, arg);
      case AccessKind.SUPER_GETTER:
        return visitor.visitSuperGetterInvoke(
            node, semantics.element, node.argumentsNode, callStructure, arg);
      case AccessKind.SUPER_SETTER:
        return visitor.visitSuperSetterInvoke(
            node, semantics.element, node.argumentsNode, callStructure, arg);
      case AccessKind.CONSTANT:
        return visitor.visitConstantInvoke(
            node, semantics.constant, node.argumentsNode, callStructure, arg);
      case AccessKind.UNRESOLVED:
        return visitor.visitUnresolvedInvoke(
            node, semantics.element, node.argumentsNode, selector, arg);
      case AccessKind.UNRESOLVED_SUPER:
        return visitor.visitUnresolvedSuperInvoke(
            node, semantics.element, node.argumentsNode, selector, arg);
      case AccessKind.INVALID:
        return visitor.errorInvalidInvoke(
            node, semantics.element, node.argumentsNode, selector, arg);
      case AccessKind.COMPOUND:
        // This is not a valid case.
        break;
    }
    throw new SpannableAssertionFailure(node, "Invalid invoke: ${semantics}");
  }

  String toString() => 'invoke($selector, $semantics)';
}

/// The structure for a [Send] that is an incompatible invocation, i.e. an
/// invocation of a known target where the call structure does not match.
class IncompatibleInvokeStructure<R, A> implements SendStructure<R, A> {
  /// The target of the invocation.
  final AccessSemantics semantics;

  /// The [Selector] for the invocation.
  // TODO(johnniwinther): Store this only for dynamic invocations.
  final Selector selector;

  /// The [CallStructure] of the invocation.
  // TODO(johnniwinther): Store this directly for static invocations.
  CallStructure get callStructure => selector.callStructure;

  IncompatibleInvokeStructure(this.semantics, this.selector);

  @override
  SendStructureKind get kind => SendStructureKind.INCOMPATIBLE_INVOKE;

  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
    switch (semantics.kind) {
      case AccessKind.STATIC_METHOD:
        return visitor.visitStaticFunctionIncompatibleInvoke(
            node, semantics.element, node.argumentsNode, callStructure, arg);
      case AccessKind.SUPER_METHOD:
        return visitor.visitSuperMethodIncompatibleInvoke(
            node, semantics.element, node.argumentsNode, callStructure, arg);
      case AccessKind.TOPLEVEL_METHOD:
        return visitor.visitTopLevelFunctionIncompatibleInvoke(
            node, semantics.element, node.argumentsNode, callStructure, arg);
      case AccessKind.LOCAL_FUNCTION:
        return visitor.visitLocalFunctionIncompatibleInvoke(
            node, semantics.element, node.argumentsNode, callStructure, arg);
      default:
        // TODO(johnniwinther): Support more variants of this invoke structure.
        break;
    }
    throw new SpannableAssertionFailure(
        node, "Invalid incompatible invoke: ${semantics}");
  }

  String toString() => 'incompatible-invoke($selector, $semantics)';
}

/// The structure for a [Send] that is a read access.
class GetStructure<R, A> implements SendStructure<R, A> {
  /// The target of the read access.
  final AccessSemantics semantics;

  GetStructure(this.semantics);

  @override
  SendStructureKind get kind => SendStructureKind.GET;

  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
    switch (semantics.kind) {
      case AccessKind.CONDITIONAL_DYNAMIC_PROPERTY:
        return visitor.visitIfNotNullDynamicPropertyGet(
            node, node.receiver, semantics.name, arg);
      case AccessKind.DYNAMIC_PROPERTY:
        return visitor.visitDynamicPropertyGet(
            node, node.receiver, semantics.name, arg);
      case AccessKind.LOCAL_FUNCTION:
        return visitor.visitLocalFunctionGet(node, semantics.element, arg);
      case AccessKind.LOCAL_VARIABLE:
      case AccessKind.FINAL_LOCAL_VARIABLE:
        return visitor.visitLocalVariableGet(node, semantics.element, arg);
      case AccessKind.PARAMETER:
      case AccessKind.FINAL_PARAMETER:
        return visitor.visitParameterGet(node, semantics.element, arg);
      case AccessKind.STATIC_FIELD:
      case AccessKind.FINAL_STATIC_FIELD:
        return visitor.visitStaticFieldGet(node, semantics.element, arg);
      case AccessKind.STATIC_METHOD:
        return visitor.visitStaticFunctionGet(node, semantics.element, arg);
      case AccessKind.STATIC_GETTER:
        return visitor.visitStaticGetterGet(node, semantics.element, arg);
      case AccessKind.STATIC_SETTER:
        return visitor.visitStaticSetterGet(node, semantics.element, arg);
      case AccessKind.TOPLEVEL_FIELD:
      case AccessKind.FINAL_TOPLEVEL_FIELD:
        return visitor.visitTopLevelFieldGet(node, semantics.element, arg);
      case AccessKind.TOPLEVEL_METHOD:
        return visitor.visitTopLevelFunctionGet(node, semantics.element, arg);
      case AccessKind.TOPLEVEL_GETTER:
        return visitor.visitTopLevelGetterGet(node, semantics.element, arg);
      case AccessKind.TOPLEVEL_SETTER:
        return visitor.visitTopLevelSetterGet(node, semantics.element, arg);
      case AccessKind.CLASS_TYPE_LITERAL:
        return visitor.visitClassTypeLiteralGet(node, semantics.constant, arg);
      case AccessKind.TYPEDEF_TYPE_LITERAL:
        return visitor.visitTypedefTypeLiteralGet(
            node, semantics.constant, arg);
      case AccessKind.DYNAMIC_TYPE_LITERAL:
        return visitor.visitDynamicTypeLiteralGet(
            node, semantics.constant, arg);
      case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
        return visitor.visitTypeVariableTypeLiteralGet(
            node, semantics.element, arg);
      case AccessKind.EXPRESSION:
        // This is not a valid case.
        break;
      case AccessKind.THIS:
        // TODO(johnniwinther): Handle this when `this` is a [Send].
        break;
      case AccessKind.THIS_PROPERTY:
        return visitor.visitThisPropertyGet(node, semantics.name, arg);
      case AccessKind.SUPER_FIELD:
      case AccessKind.SUPER_FINAL_FIELD:
        return visitor.visitSuperFieldGet(node, semantics.element, arg);
      case AccessKind.SUPER_METHOD:
        return visitor.visitSuperMethodGet(node, semantics.element, arg);
      case AccessKind.SUPER_GETTER:
        return visitor.visitSuperGetterGet(node, semantics.element, arg);
      case AccessKind.SUPER_SETTER:
        return visitor.visitSuperSetterGet(node, semantics.element, arg);
      case AccessKind.CONSTANT:
        return visitor.visitConstantGet(node, semantics.constant, arg);
      case AccessKind.UNRESOLVED:
        return visitor.visitUnresolvedGet(node, semantics.element, arg);
      case AccessKind.UNRESOLVED_SUPER:
        return visitor.visitUnresolvedSuperGet(node, semantics.element, arg);
      case AccessKind.INVALID:
        return visitor.errorInvalidGet(node, semantics.element, arg);
      case AccessKind.COMPOUND:
        // This is not a valid case.
        break;
    }
    throw new SpannableAssertionFailure(node, "Invalid getter: ${semantics}");
  }

  String toString() => 'get($semantics)';
}

/// The structure for a [Send] that is an assignment.
class SetStructure<R, A> implements SendStructure<R, A> {
  /// The target of the assignment.
  final AccessSemantics semantics;

  SetStructure(this.semantics);

  @override
  SendStructureKind get kind => SendStructureKind.SET;

  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
    switch (semantics.kind) {
      case AccessKind.CONDITIONAL_DYNAMIC_PROPERTY:
        return visitor.visitIfNotNullDynamicPropertySet(
            node, node.receiver, semantics.name, node.arguments.single, arg);
      case AccessKind.DYNAMIC_PROPERTY:
        return visitor.visitDynamicPropertySet(
            node, node.receiver, semantics.name, node.arguments.single, arg);
      case AccessKind.LOCAL_FUNCTION:
        return visitor.visitLocalFunctionSet(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.LOCAL_VARIABLE:
        return visitor.visitLocalVariableSet(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.FINAL_LOCAL_VARIABLE:
        return visitor.visitFinalLocalVariableSet(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.PARAMETER:
        return visitor.visitParameterSet(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.FINAL_PARAMETER:
        return visitor.visitFinalParameterSet(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.STATIC_FIELD:
        return visitor.visitStaticFieldSet(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.FINAL_STATIC_FIELD:
        return visitor.visitFinalStaticFieldSet(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.STATIC_METHOD:
        return visitor.visitStaticFunctionSet(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.STATIC_GETTER:
        return visitor.visitStaticGetterSet(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.STATIC_SETTER:
        return visitor.visitStaticSetterSet(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.TOPLEVEL_FIELD:
        return visitor.visitTopLevelFieldSet(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.FINAL_TOPLEVEL_FIELD:
        return visitor.visitFinalTopLevelFieldSet(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.TOPLEVEL_METHOD:
        return visitor.visitTopLevelFunctionSet(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.TOPLEVEL_GETTER:
        return visitor.visitTopLevelGetterSet(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.TOPLEVEL_SETTER:
        return visitor.visitTopLevelSetterSet(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.CLASS_TYPE_LITERAL:
        return visitor.visitClassTypeLiteralSet(
            node, semantics.constant, node.arguments.single, arg);
      case AccessKind.TYPEDEF_TYPE_LITERAL:
        return visitor.visitTypedefTypeLiteralSet(
            node, semantics.constant, node.arguments.single, arg);
      case AccessKind.DYNAMIC_TYPE_LITERAL:
        return visitor.visitDynamicTypeLiteralSet(
            node, semantics.constant, node.arguments.single, arg);
      case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
        return visitor.visitTypeVariableTypeLiteralSet(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.EXPRESSION:
        // This is not a valid case.
        break;
      case AccessKind.THIS:
        // This is not a valid case.
        break;
      case AccessKind.THIS_PROPERTY:
        return visitor.visitThisPropertySet(
            node, semantics.name, node.arguments.single, arg);
      case AccessKind.SUPER_FIELD:
        return visitor.visitSuperFieldSet(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.SUPER_FINAL_FIELD:
        return visitor.visitFinalSuperFieldSet(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.SUPER_METHOD:
        return visitor.visitSuperMethodSet(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.SUPER_GETTER:
        return visitor.visitSuperGetterSet(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.SUPER_SETTER:
        return visitor.visitSuperSetterSet(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.CONSTANT:
        // TODO(johnniwinther): Should this be a valid case?
        break;
      case AccessKind.UNRESOLVED_SUPER:
        return visitor.visitUnresolvedSuperSet(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.UNRESOLVED:
        return visitor.visitUnresolvedSet(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.INVALID:
        return visitor.errorInvalidSet(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.COMPOUND:
        // This is not a valid case.
        break;
    }
    throw new SpannableAssertionFailure(node, "Invalid setter: ${semantics}");
  }

  String toString() => 'set($semantics)';
}

/// The structure for a [Send] that is a negation, i.e. of the form `!e`.
class NotStructure<R, A> implements SendStructure<R, A> {
  const NotStructure();

  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
    return visitor.visitNot(node, node.receiver, arg);
  }

  @override
  SendStructureKind get kind => SendStructureKind.NOT;

  String toString() => 'not()';
}

/// The structure for a [Send] that is an invocation of a user definable unary
/// operator.
class UnaryStructure<R, A> implements SendStructure<R, A> {
  /// The target of the unary operation.
  final AccessSemantics semantics;

  /// The user definable unary operator.
  final UnaryOperator operator;

  UnaryStructure(this.semantics, this.operator);

  @override
  SendStructureKind get kind => SendStructureKind.UNARY;

  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
    switch (semantics.kind) {
      case AccessKind.EXPRESSION:
        return visitor.visitUnary(node, operator, node.receiver, arg);
      case AccessKind.SUPER_METHOD:
        return visitor.visitSuperUnary(node, operator, semantics.element, arg);
      case AccessKind.UNRESOLVED_SUPER:
        return visitor.visitUnresolvedSuperUnary(
            node, operator, semantics.element, arg);
      case AccessKind.INVALID:
        return visitor.errorInvalidUnary(
            node, operator, semantics.element, arg);
      default:
        // This is not a valid case.
        break;
    }
    throw new SpannableAssertionFailure(node, "Invalid setter: ${semantics}");
  }

  String toString() => 'unary($operator,$semantics)';
}

/// The structure for a [Send] that is an invocation of a undefined unary
/// operator.
class InvalidUnaryStructure<R, A> implements SendStructure<R, A> {
  const InvalidUnaryStructure();

  @override
  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
    return visitor.errorUndefinedUnaryExpression(
        node, node.selector, node.receiver, arg);
  }

  @override
  SendStructureKind get kind => SendStructureKind.INVALID_UNARY;

  String toString() => 'invalid unary';
}

/// The structure for a [Send] that is an index expression, i.e. of the form
/// `a[b]`.
class IndexStructure<R, A> implements SendStructure<R, A> {
  /// The target of the left operand.
  final AccessSemantics semantics;

  IndexStructure(this.semantics);

  @override
  SendStructureKind get kind => SendStructureKind.INDEX;

  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
    switch (semantics.kind) {
      case AccessKind.EXPRESSION:
        return visitor.visitIndex(
            node, node.receiver, node.arguments.single, arg);
      case AccessKind.SUPER_METHOD:
        return visitor.visitSuperIndex(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.UNRESOLVED_SUPER:
        return visitor.visitUnresolvedSuperIndex(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.INVALID:
        return visitor.errorInvalidIndex(
            node, semantics.element, node.arguments.single, arg);
      default:
        // This is not a valid case.
        break;
    }
    throw new SpannableAssertionFailure(node, "Invalid index: ${semantics}");
  }
}

/// The structure for a [Send] that is an equals test, i.e. of the form
/// `a == b`.
class EqualsStructure<R, A> implements SendStructure<R, A> {
  /// The target of the left operand.
  final AccessSemantics semantics;

  EqualsStructure(this.semantics);

  @override
  SendStructureKind get kind => SendStructureKind.EQUALS;

  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
    switch (semantics.kind) {
      case AccessKind.EXPRESSION:
        return visitor.visitEquals(
            node, node.receiver, node.arguments.single, arg);
      case AccessKind.SUPER_METHOD:
        return visitor.visitSuperEquals(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.INVALID:
        return visitor.errorInvalidEquals(
            node, semantics.element, node.arguments.single, arg);
      default:
        // This is not a valid case.
        break;
    }
    throw new SpannableAssertionFailure(node, "Invalid equals: ${semantics}");
  }

  String toString() => '==($semantics)';
}

/// The structure for a [Send] that is a not-equals test, i.e. of the form
/// `a != b`.
class NotEqualsStructure<R, A> implements SendStructure<R, A> {
  /// The target of the left operand.
  final AccessSemantics semantics;

  NotEqualsStructure(this.semantics);

  @override
  SendStructureKind get kind => SendStructureKind.NOT_EQUALS;

  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
    switch (semantics.kind) {
      case AccessKind.EXPRESSION:
        return visitor.visitNotEquals(
            node, node.receiver, node.arguments.single, arg);
      case AccessKind.SUPER_METHOD:
        return visitor.visitSuperNotEquals(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.INVALID:
        return visitor.errorInvalidNotEquals(
            node, semantics.element, node.arguments.single, arg);
      default:
        // This is not a valid case.
        break;
    }
    throw new SpannableAssertionFailure(
        node, "Invalid not equals: ${semantics}");
  }

  String toString() => '!=($semantics)';
}

/// The structure for a [Send] that is an invocation of a user-definable binary
/// operator.
class BinaryStructure<R, A> implements SendStructure<R, A> {
  /// The target of the left operand.
  final AccessSemantics semantics;

  /// The user definable binary operator.
  final BinaryOperator operator;

  BinaryStructure(this.semantics, this.operator);

  @override
  SendStructureKind get kind => SendStructureKind.BINARY;

  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
    switch (semantics.kind) {
      case AccessKind.EXPRESSION:
        return visitor.visitBinary(
            node, node.receiver, operator, node.arguments.single, arg);
      case AccessKind.SUPER_METHOD:
        return visitor.visitSuperBinary(
            node, semantics.element, operator, node.arguments.single, arg);
      case AccessKind.UNRESOLVED_SUPER:
        return visitor.visitUnresolvedSuperBinary(
            node, semantics.element, operator, node.arguments.single, arg);
      case AccessKind.INVALID:
        return visitor.errorInvalidBinary(
            node, semantics.element, operator, node.arguments.single, arg);
      default:
        // This is not a valid case.
        break;
    }
    throw new SpannableAssertionFailure(node, "Invalid binary: ${semantics}");
  }

  String toString() => 'binary($operator,$semantics)';
}

/// The structure for a [Send] that is an invocation of a undefined binary
/// operator.
class InvalidBinaryStructure<R, A> implements SendStructure<R, A> {
  const InvalidBinaryStructure();

  @override
  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
    return visitor.errorUndefinedBinaryExpression(
        node, node.receiver, node.selector, node.arguments.single, arg);
  }

  @override
  SendStructureKind get kind => SendStructureKind.INVALID_BINARY;

  String toString() => 'invalid binary';
}

/// The structure for a [Send] that is of the form `a[b] = c`.
class IndexSetStructure<R, A> implements SendStructure<R, A> {
  /// The target of the index set operation.
  final AccessSemantics semantics;

  IndexSetStructure(this.semantics);

  @override
  SendStructureKind get kind => SendStructureKind.INDEX_SET;

  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
    switch (semantics.kind) {
      case AccessKind.EXPRESSION:
        return visitor.visitIndexSet(node, node.receiver, node.arguments.first,
            node.arguments.tail.head, arg);
      case AccessKind.SUPER_METHOD:
        return visitor.visitSuperIndexSet(node, semantics.element,
            node.arguments.first, node.arguments.tail.head, arg);
      case AccessKind.UNRESOLVED_SUPER:
      case AccessKind.UNRESOLVED:
        return visitor.visitUnresolvedSuperIndexSet(node, semantics.element,
            node.arguments.first, node.arguments.tail.head, arg);
      case AccessKind.INVALID:
        return visitor.errorInvalidIndexSet(node, semantics.element,
            node.arguments.first, node.arguments.tail.head, arg);
      default:
        // This is not a valid case.
        break;
    }
    throw new SpannableAssertionFailure(
        node, "Invalid index set: ${semantics}");
  }

  String toString() => '[]=($semantics)';
}

/// The structure for a [Send] that is an prefix operation on an index
/// expression, i.e. of the form `--a[b]`.
class IndexPrefixStructure<R, A> implements SendStructure<R, A> {
  /// The target of the left operand.
  final AccessSemantics semantics;

  /// The `++` or `--` operator used in the operation.
  final IncDecOperator operator;

  IndexPrefixStructure(this.semantics, this.operator);

  @override
  SendStructureKind get kind => SendStructureKind.INDEX_PREFIX;

  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
    switch (semantics.kind) {
      case AccessKind.EXPRESSION:
        return visitor.visitIndexPrefix(
            node, node.receiver, node.arguments.single, operator, arg);
      case AccessKind.UNRESOLVED_SUPER:
        return visitor.visitUnresolvedSuperIndexPrefix(
            node, semantics.element, node.arguments.single, operator, arg);
      case AccessKind.INVALID:
        return visitor.errorInvalidIndexPrefix(
            node, semantics.element, node.arguments.single, operator, arg);
      case AccessKind.COMPOUND:
        CompoundAccessSemantics compoundSemantics = semantics;
        switch (compoundSemantics.compoundAccessKind) {
          case CompoundAccessKind.SUPER_GETTER_SETTER:
            return visitor.visitSuperIndexPrefix(node, compoundSemantics.getter,
                compoundSemantics.setter, node.arguments.single, operator, arg);
          case CompoundAccessKind.UNRESOLVED_SUPER_GETTER:
            return visitor.visitUnresolvedSuperGetterIndexPrefix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                node.arguments.single,
                operator,
                arg);
          case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
            return visitor.visitUnresolvedSuperSetterIndexPrefix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                node.arguments.single,
                operator,
                arg);
          default:
            // This is not a valid case.
            break;
        }
        break;
      default:
        // This is not a valid case.
        break;
    }
    throw new SpannableAssertionFailure(
        node, "Invalid index prefix: ${semantics}");
  }
}

/// The structure for a [Send] that is an postfix operation on an index
/// expression, i.e. of the form `a[b]++`.
class IndexPostfixStructure<R, A> implements SendStructure<R, A> {
  /// The target of the left operand.
  final AccessSemantics semantics;

  /// The `++` or `--` operator used in the operation.
  final IncDecOperator operator;

  IndexPostfixStructure(this.semantics, this.operator);

  @override
  SendStructureKind get kind => SendStructureKind.INDEX_POSTFIX;

  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
    switch (semantics.kind) {
      case AccessKind.EXPRESSION:
        return visitor.visitIndexPostfix(
            node, node.receiver, node.arguments.single, operator, arg);
      case AccessKind.UNRESOLVED_SUPER:
        return visitor.visitUnresolvedSuperIndexPostfix(
            node, semantics.element, node.arguments.single, operator, arg);
      case AccessKind.INVALID:
        return visitor.errorInvalidIndexPostfix(
            node, semantics.element, node.arguments.single, operator, arg);
      case AccessKind.COMPOUND:
        CompoundAccessSemantics compoundSemantics = semantics;
        switch (compoundSemantics.compoundAccessKind) {
          case CompoundAccessKind.SUPER_GETTER_SETTER:
            return visitor.visitSuperIndexPostfix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                node.arguments.single,
                operator,
                arg);
          case CompoundAccessKind.UNRESOLVED_SUPER_GETTER:
            return visitor.visitUnresolvedSuperGetterIndexPostfix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                node.arguments.single,
                operator,
                arg);
          case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
            return visitor.visitUnresolvedSuperSetterIndexPostfix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                node.arguments.single,
                operator,
                arg);
          default:
            // This is not a valid case.
            break;
        }
        break;
      default:
        // This is not a valid case.
        break;
    }
    throw new SpannableAssertionFailure(
        node, "Invalid index postfix: ${semantics}");
  }
}

/// The structure for a [Send] that is a compound assignment. For instance
/// `a += b`.
class CompoundStructure<R, A> implements SendStructure<R, A> {
  /// The target of the compound assignment, i.e. the left-hand side.
  final AccessSemantics semantics;

  /// The assignment operator used in the compound assignment.
  final AssignmentOperator operator;

  CompoundStructure(this.semantics, this.operator);

  @override
  SendStructureKind get kind => SendStructureKind.COMPOUND;

  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
    switch (semantics.kind) {
      case AccessKind.CONDITIONAL_DYNAMIC_PROPERTY:
        return visitor.visitIfNotNullDynamicPropertyCompound(
            node,
            node.receiver,
            semantics.name,
            operator,
            node.arguments.single,
            arg);
      case AccessKind.DYNAMIC_PROPERTY:
        return visitor.visitDynamicPropertyCompound(node, node.receiver,
            semantics.name, operator, node.arguments.single, arg);
      case AccessKind.LOCAL_FUNCTION:
        return visitor.visitLocalFunctionCompound(
            node, semantics.element, operator, node.arguments.single, arg);
      case AccessKind.LOCAL_VARIABLE:
        return visitor.visitLocalVariableCompound(
            node, semantics.element, operator, node.arguments.single, arg);
      case AccessKind.FINAL_LOCAL_VARIABLE:
        return visitor.visitFinalLocalVariableCompound(
            node, semantics.element, operator, node.arguments.single, arg);
      case AccessKind.PARAMETER:
        return visitor.visitParameterCompound(
            node, semantics.element, operator, node.arguments.single, arg);
      case AccessKind.FINAL_PARAMETER:
        return visitor.visitFinalParameterCompound(
            node, semantics.element, operator, node.arguments.single, arg);
      case AccessKind.STATIC_FIELD:
        return visitor.visitStaticFieldCompound(
            node, semantics.element, operator, node.arguments.single, arg);
      case AccessKind.FINAL_STATIC_FIELD:
        return visitor.visitFinalStaticFieldCompound(
            node, semantics.element, operator, node.arguments.single, arg);
      case AccessKind.STATIC_METHOD:
        return visitor.visitStaticMethodCompound(
            node, semantics.element, operator, node.arguments.single, arg);
      case AccessKind.STATIC_GETTER:
        // This is not a valid case.
        break;
      case AccessKind.STATIC_SETTER:
        // This is not a valid case.
        break;
      case AccessKind.TOPLEVEL_FIELD:
        return visitor.visitTopLevelFieldCompound(
            node, semantics.element, operator, node.arguments.single, arg);
      case AccessKind.FINAL_TOPLEVEL_FIELD:
        return visitor.visitFinalTopLevelFieldCompound(
            node, semantics.element, operator, node.arguments.single, arg);
      case AccessKind.TOPLEVEL_METHOD:
        return visitor.visitTopLevelMethodCompound(
            node, semantics.element, operator, node.arguments.single, arg);
      case AccessKind.TOPLEVEL_GETTER:
        // This is not a valid case.
        break;
      case AccessKind.TOPLEVEL_SETTER:
        // This is not a valid case.
        break;
      case AccessKind.CLASS_TYPE_LITERAL:
        return visitor.visitClassTypeLiteralCompound(
            node, semantics.constant, operator, node.arguments.single, arg);
      case AccessKind.TYPEDEF_TYPE_LITERAL:
        return visitor.visitTypedefTypeLiteralCompound(
            node, semantics.constant, operator, node.arguments.single, arg);
      case AccessKind.DYNAMIC_TYPE_LITERAL:
        return visitor.visitDynamicTypeLiteralCompound(
            node, semantics.constant, operator, node.arguments.single, arg);
      case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
        return visitor.visitTypeVariableTypeLiteralCompound(
            node, semantics.element, operator, node.arguments.single, arg);
      case AccessKind.EXPRESSION:
        // This is not a valid case.
        break;
      case AccessKind.THIS:
        // This is not a valid case.
        break;
      case AccessKind.THIS_PROPERTY:
        return visitor.visitThisPropertyCompound(
            node, semantics.name, operator, node.arguments.single, arg);
      case AccessKind.SUPER_FIELD:
        return visitor.visitSuperFieldCompound(
            node, semantics.element, operator, node.arguments.single, arg);
      case AccessKind.SUPER_FINAL_FIELD:
        return visitor.visitFinalSuperFieldCompound(
            node, semantics.element, operator, node.arguments.single, arg);
      case AccessKind.SUPER_METHOD:
        return visitor.visitSuperMethodCompound(
            node, semantics.element, operator, node.arguments.single, arg);
      case AccessKind.SUPER_GETTER:
        // This is not a valid case.
        break;
      case AccessKind.SUPER_SETTER:
        // This is not a valid case.
        break;
      case AccessKind.CONSTANT:
        // TODO(johnniwinther): Should this be a valid case?
        break;
      case AccessKind.UNRESOLVED_SUPER:
        return visitor.visitUnresolvedSuperCompound(
            node, semantics.element, operator, node.arguments.single, arg);
      case AccessKind.UNRESOLVED:
        return visitor.visitUnresolvedCompound(
            node, semantics.element, operator, node.arguments.single, arg);
      case AccessKind.INVALID:
        return visitor.errorInvalidCompound(
            node, semantics.element, operator, node.arguments.single, arg);
      case AccessKind.COMPOUND:
        CompoundAccessSemantics compoundSemantics = semantics;
        switch (compoundSemantics.compoundAccessKind) {
          case CompoundAccessKind.STATIC_GETTER_SETTER:
            return visitor.visitStaticGetterSetterCompound(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                node.arguments.single,
                arg);
          case CompoundAccessKind.STATIC_METHOD_SETTER:
            return visitor.visitStaticMethodSetterCompound(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                node.arguments.single,
                arg);
          case CompoundAccessKind.UNRESOLVED_STATIC_GETTER:
            return visitor.visitUnresolvedStaticGetterCompound(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                node.arguments.single,
                arg);
          case CompoundAccessKind.UNRESOLVED_STATIC_SETTER:
            return visitor.visitUnresolvedStaticSetterCompound(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                node.arguments.single,
                arg);
          case CompoundAccessKind.TOPLEVEL_GETTER_SETTER:
            return visitor.visitTopLevelGetterSetterCompound(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                node.arguments.single,
                arg);
          case CompoundAccessKind.TOPLEVEL_METHOD_SETTER:
            return visitor.visitTopLevelMethodSetterCompound(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                node.arguments.single,
                arg);
          case CompoundAccessKind.UNRESOLVED_TOPLEVEL_GETTER:
            return visitor.visitUnresolvedTopLevelGetterCompound(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                node.arguments.single,
                arg);
          case CompoundAccessKind.UNRESOLVED_TOPLEVEL_SETTER:
            return visitor.visitUnresolvedTopLevelSetterCompound(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                node.arguments.single,
                arg);
          case CompoundAccessKind.SUPER_FIELD_FIELD:
            return visitor.visitSuperFieldFieldCompound(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                node.arguments.single,
                arg);
          case CompoundAccessKind.SUPER_GETTER_SETTER:
            return visitor.visitSuperGetterSetterCompound(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                node.arguments.single,
                arg);
          case CompoundAccessKind.SUPER_GETTER_FIELD:
            return visitor.visitSuperGetterFieldCompound(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                node.arguments.single,
                arg);
          case CompoundAccessKind.SUPER_METHOD_SETTER:
            return visitor.visitSuperMethodSetterCompound(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                node.arguments.single,
                arg);
          case CompoundAccessKind.SUPER_FIELD_SETTER:
            return visitor.visitSuperFieldSetterCompound(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                node.arguments.single,
                arg);
          case CompoundAccessKind.UNRESOLVED_SUPER_GETTER:
            return visitor.visitUnresolvedSuperGetterCompound(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                node.arguments.single,
                arg);
          case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
            return visitor.visitUnresolvedSuperSetterCompound(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                node.arguments.single,
                arg);
        }
        break;
    }
    throw new SpannableAssertionFailure(
        node, "Invalid compound assigment: ${semantics}");
  }

  String toString() => 'compound($operator,$semantics)';
}

/// The structure for a [Send] that is an if-null assignment. For instance
/// `a ??= b`.
class SetIfNullStructure<R, A> implements SendStructure<R, A> {
  /// The target of the if-null assignment, i.e. the left-hand side.
  final AccessSemantics semantics;

  SetIfNullStructure(this.semantics);

  @override
  SendStructureKind get kind => SendStructureKind.SET_IF_NULL;

  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
    switch (semantics.kind) {
      case AccessKind.CONDITIONAL_DYNAMIC_PROPERTY:
        return visitor.visitIfNotNullDynamicPropertySetIfNull(
            node, node.receiver, semantics.name, node.arguments.single, arg);
      case AccessKind.DYNAMIC_PROPERTY:
        return visitor.visitDynamicPropertySetIfNull(
            node, node.receiver, semantics.name, node.arguments.single, arg);
      case AccessKind.LOCAL_FUNCTION:
        return visitor.visitLocalFunctionSetIfNull(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.LOCAL_VARIABLE:
        return visitor.visitLocalVariableSetIfNull(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.FINAL_LOCAL_VARIABLE:
        return visitor.visitFinalLocalVariableSetIfNull(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.PARAMETER:
        return visitor.visitParameterSetIfNull(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.FINAL_PARAMETER:
        return visitor.visitFinalParameterSetIfNull(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.STATIC_FIELD:
        return visitor.visitStaticFieldSetIfNull(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.FINAL_STATIC_FIELD:
        return visitor.visitFinalStaticFieldSetIfNull(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.STATIC_METHOD:
        return visitor.visitStaticMethodSetIfNull(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.STATIC_GETTER:
        // This is not a valid case.
        break;
      case AccessKind.STATIC_SETTER:
        // This is not a valid case.
        break;
      case AccessKind.TOPLEVEL_FIELD:
        return visitor.visitTopLevelFieldSetIfNull(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.FINAL_TOPLEVEL_FIELD:
        return visitor.visitFinalTopLevelFieldSetIfNull(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.TOPLEVEL_METHOD:
        return visitor.visitTopLevelMethodSetIfNull(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.TOPLEVEL_GETTER:
        // This is not a valid case.
        break;
      case AccessKind.TOPLEVEL_SETTER:
        // This is not a valid case.
        break;
      case AccessKind.CLASS_TYPE_LITERAL:
        return visitor.visitClassTypeLiteralSetIfNull(
            node, semantics.constant, node.arguments.single, arg);
      case AccessKind.TYPEDEF_TYPE_LITERAL:
        return visitor.visitTypedefTypeLiteralSetIfNull(
            node, semantics.constant, node.arguments.single, arg);
      case AccessKind.DYNAMIC_TYPE_LITERAL:
        return visitor.visitDynamicTypeLiteralSetIfNull(
            node, semantics.constant, node.arguments.single, arg);
      case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
        return visitor.visitTypeVariableTypeLiteralSetIfNull(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.EXPRESSION:
        // This is not a valid case.
        break;
      case AccessKind.THIS:
        // This is not a valid case.
        break;
      case AccessKind.THIS_PROPERTY:
        return visitor.visitThisPropertySetIfNull(
            node, semantics.name, node.arguments.single, arg);
      case AccessKind.SUPER_FIELD:
        return visitor.visitSuperFieldSetIfNull(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.SUPER_FINAL_FIELD:
        return visitor.visitFinalSuperFieldSetIfNull(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.SUPER_METHOD:
        return visitor.visitSuperMethodSetIfNull(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.SUPER_GETTER:
        // This is not a valid case.
        break;
      case AccessKind.SUPER_SETTER:
        // This is not a valid case.
        break;
      case AccessKind.CONSTANT:
        // TODO(johnniwinther): Should this be a valid case?
        break;
      case AccessKind.UNRESOLVED_SUPER:
        return visitor.visitUnresolvedSuperSetIfNull(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.UNRESOLVED:
        return visitor.visitUnresolvedSetIfNull(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.INVALID:
        return visitor.errorInvalidSetIfNull(
            node, semantics.element, node.arguments.single, arg);
      case AccessKind.COMPOUND:
        CompoundAccessSemantics compoundSemantics = semantics;
        switch (compoundSemantics.compoundAccessKind) {
          case CompoundAccessKind.STATIC_GETTER_SETTER:
            return visitor.visitStaticGetterSetterSetIfNull(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                node.arguments.single,
                arg);
          case CompoundAccessKind.STATIC_METHOD_SETTER:
            return visitor.visitStaticMethodSetterSetIfNull(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                node.arguments.single,
                arg);
          case CompoundAccessKind.UNRESOLVED_STATIC_GETTER:
            return visitor.visitUnresolvedStaticGetterSetIfNull(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                node.arguments.single,
                arg);
          case CompoundAccessKind.UNRESOLVED_STATIC_SETTER:
            return visitor.visitUnresolvedStaticSetterSetIfNull(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                node.arguments.single,
                arg);
          case CompoundAccessKind.TOPLEVEL_GETTER_SETTER:
            return visitor.visitTopLevelGetterSetterSetIfNull(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                node.arguments.single,
                arg);
          case CompoundAccessKind.TOPLEVEL_METHOD_SETTER:
            return visitor.visitTopLevelMethodSetterSetIfNull(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                node.arguments.single,
                arg);
          case CompoundAccessKind.UNRESOLVED_TOPLEVEL_GETTER:
            return visitor.visitUnresolvedTopLevelGetterSetIfNull(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                node.arguments.single,
                arg);
          case CompoundAccessKind.UNRESOLVED_TOPLEVEL_SETTER:
            return visitor.visitUnresolvedTopLevelSetterSetIfNull(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                node.arguments.single,
                arg);
          case CompoundAccessKind.SUPER_FIELD_FIELD:
            return visitor.visitSuperFieldFieldSetIfNull(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                node.arguments.single,
                arg);
          case CompoundAccessKind.SUPER_GETTER_SETTER:
            return visitor.visitSuperGetterSetterSetIfNull(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                node.arguments.single,
                arg);
          case CompoundAccessKind.SUPER_GETTER_FIELD:
            return visitor.visitSuperGetterFieldSetIfNull(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                node.arguments.single,
                arg);
          case CompoundAccessKind.SUPER_METHOD_SETTER:
            return visitor.visitSuperMethodSetterSetIfNull(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                node.arguments.single,
                arg);
          case CompoundAccessKind.SUPER_FIELD_SETTER:
            return visitor.visitSuperFieldSetterSetIfNull(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                node.arguments.single,
                arg);
          case CompoundAccessKind.UNRESOLVED_SUPER_GETTER:
            return visitor.visitUnresolvedSuperGetterSetIfNull(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                node.arguments.single,
                arg);
          case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
            return visitor.visitUnresolvedSuperSetterSetIfNull(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                node.arguments.single,
                arg);
        }
        break;
    }
    throw new SpannableAssertionFailure(
        node, "Invalid if-null assigment: ${semantics}");
  }

  String toString() => 'ifNull($semantics)';
}

/// The structure for a [Send] that is a compound assignment on the index
/// operator. For instance `a[b] += c`.
class CompoundIndexSetStructure<R, A> implements SendStructure<R, A> {
  /// The target of the index operations.
  final AccessSemantics semantics;

  /// The assignment operator used in the compound assignment.
  final AssignmentOperator operator;

  CompoundIndexSetStructure(this.semantics, this.operator);

  @override
  SendStructureKind get kind => SendStructureKind.COMPOUND_INDEX_SET;

  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
    switch (semantics.kind) {
      case AccessKind.EXPRESSION:
        return visitor.visitCompoundIndexSet(node, node.receiver,
            node.arguments.first, operator, node.arguments.tail.head, arg);
      case AccessKind.UNRESOLVED_SUPER:
        return visitor.visitUnresolvedSuperCompoundIndexSet(
            node,
            semantics.element,
            node.arguments.first,
            operator,
            node.arguments.tail.head,
            arg);
      case AccessKind.INVALID:
        return visitor.errorInvalidCompoundIndexSet(node, semantics.element,
            node.arguments.first, operator, node.arguments.tail.head, arg);
      case AccessKind.COMPOUND:
        CompoundAccessSemantics compoundSemantics = semantics;
        switch (compoundSemantics.compoundAccessKind) {
          case CompoundAccessKind.SUPER_GETTER_SETTER:
            return visitor.visitSuperCompoundIndexSet(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                node.arguments.first,
                operator,
                node.arguments.tail.head,
                arg);
          case CompoundAccessKind.UNRESOLVED_SUPER_GETTER:
            return visitor.visitUnresolvedSuperGetterCompoundIndexSet(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                node.arguments.first,
                operator,
                node.arguments.tail.head,
                arg);
          case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
            return visitor.visitUnresolvedSuperSetterCompoundIndexSet(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                node.arguments.first,
                operator,
                node.arguments.tail.head,
                arg);
          default:
            // This is not a valid case.
            break;
        }
        break;
      default:
        // This is not a valid case.
        break;
    }
    throw new SpannableAssertionFailure(
        node, "Invalid compound index set: ${semantics}");
  }

  String toString() => 'compound []=($operator,$semantics)';
}

/// The structure for a [Send] that is a if-null assignment on the index
/// operator. For instance `a[b] ??= c`.
class IndexSetIfNullStructure<R, A> implements SendStructure<R, A> {
  /// The target of the index operations.
  final AccessSemantics semantics;

  IndexSetIfNullStructure(this.semantics);

  @override
  SendStructureKind get kind => SendStructureKind.INDEX_SET_IF_NULL;

  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
    switch (semantics.kind) {
      case AccessKind.EXPRESSION:
        return visitor.visitIndexSetIfNull(node, node.receiver,
            node.arguments.first, node.arguments.tail.head, arg);
      case AccessKind.UNRESOLVED_SUPER:
        return visitor.visitUnresolvedSuperIndexSetIfNull(
            node,
            semantics.element,
            node.arguments.first,
            node.arguments.tail.head,
            arg);
      case AccessKind.INVALID:
        return visitor.errorInvalidIndexSetIfNull(node, semantics.element,
            node.arguments.first, node.arguments.tail.head, arg);
      case AccessKind.COMPOUND:
        CompoundAccessSemantics compoundSemantics = semantics;
        switch (compoundSemantics.compoundAccessKind) {
          case CompoundAccessKind.SUPER_GETTER_SETTER:
            return visitor.visitSuperIndexSetIfNull(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                node.arguments.first,
                node.arguments.tail.head,
                arg);
          case CompoundAccessKind.UNRESOLVED_SUPER_GETTER:
            return visitor.visitUnresolvedSuperGetterIndexSetIfNull(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                node.arguments.first,
                node.arguments.tail.head,
                arg);
          case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
            return visitor.visitUnresolvedSuperSetterIndexSetIfNull(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                node.arguments.first,
                node.arguments.tail.head,
                arg);
          default:
            // This is not a valid case.
            break;
        }
        break;
      default:
        // This is not a valid case.
        break;
    }
    throw new SpannableAssertionFailure(
        node, "Invalid index set if-null: ${semantics}");
  }

  String toString() => 'index set if-null []??=($semantics)';
}

/// The structure for a [Send] that is a prefix operations. For instance
/// `++a`.
class PrefixStructure<R, A> implements SendStructure<R, A> {
  /// The target of the prefix operation.
  final AccessSemantics semantics;

  /// The `++` or `--` operator used in the operation.
  final IncDecOperator operator;

  PrefixStructure(this.semantics, this.operator);

  @override
  SendStructureKind get kind => SendStructureKind.PREFIX;

  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
    switch (semantics.kind) {
      case AccessKind.CONDITIONAL_DYNAMIC_PROPERTY:
        return visitor.visitIfNotNullDynamicPropertyPrefix(
            node, node.receiver, semantics.name, operator, arg);
      case AccessKind.DYNAMIC_PROPERTY:
        return visitor.visitDynamicPropertyPrefix(
            node, node.receiver, semantics.name, operator, arg);
      case AccessKind.LOCAL_FUNCTION:
        return visitor.visitLocalFunctionPrefix(
            node, semantics.element, operator, arg);
      case AccessKind.LOCAL_VARIABLE:
        return visitor.visitLocalVariablePrefix(
            node, semantics.element, operator, arg);
      case AccessKind.FINAL_LOCAL_VARIABLE:
        return visitor.visitFinalLocalVariablePrefix(
            node, semantics.element, operator, arg);
      case AccessKind.PARAMETER:
        return visitor.visitParameterPrefix(
            node, semantics.element, operator, arg);
      case AccessKind.FINAL_PARAMETER:
        return visitor.visitFinalParameterPrefix(
            node, semantics.element, operator, arg);
      case AccessKind.STATIC_FIELD:
        return visitor.visitStaticFieldPrefix(
            node, semantics.element, operator, arg);
      case AccessKind.FINAL_STATIC_FIELD:
        return visitor.visitFinalStaticFieldPrefix(
            node, semantics.element, operator, arg);
      case AccessKind.STATIC_METHOD:
        return visitor.visitStaticMethodPrefix(
            node, semantics.element, operator, arg);
      case AccessKind.STATIC_GETTER:
        // This is not a valid case.
        break;
      case AccessKind.STATIC_SETTER:
        // This is not a valid case.
        break;
      case AccessKind.TOPLEVEL_FIELD:
        return visitor.visitTopLevelFieldPrefix(
            node, semantics.element, operator, arg);
      case AccessKind.FINAL_TOPLEVEL_FIELD:
        return visitor.visitFinalTopLevelFieldPrefix(
            node, semantics.element, operator, arg);
      case AccessKind.TOPLEVEL_METHOD:
        return visitor.visitTopLevelMethodPrefix(
            node, semantics.element, operator, arg);
      case AccessKind.TOPLEVEL_GETTER:
        // This is not a valid case.
        break;
      case AccessKind.TOPLEVEL_SETTER:
        // This is not a valid case.
        break;
      case AccessKind.CLASS_TYPE_LITERAL:
        return visitor.visitClassTypeLiteralPrefix(
            node, semantics.constant, operator, arg);
      case AccessKind.TYPEDEF_TYPE_LITERAL:
        return visitor.visitTypedefTypeLiteralPrefix(
            node, semantics.constant, operator, arg);
      case AccessKind.DYNAMIC_TYPE_LITERAL:
        return visitor.visitDynamicTypeLiteralPrefix(
            node, semantics.constant, operator, arg);
      case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
        return visitor.visitTypeVariableTypeLiteralPrefix(
            node, semantics.element, operator, arg);
      case AccessKind.EXPRESSION:
        // This is not a valid case.
        break;
      case AccessKind.THIS:
        // This is not a valid case.
        break;
      case AccessKind.THIS_PROPERTY:
        return visitor.visitThisPropertyPrefix(
            node, semantics.name, operator, arg);
      case AccessKind.SUPER_FIELD:
        return visitor.visitSuperFieldPrefix(
            node, semantics.element, operator, arg);
      case AccessKind.SUPER_FINAL_FIELD:
        return visitor.visitFinalSuperFieldPrefix(
            node, semantics.element, operator, arg);
      case AccessKind.SUPER_METHOD:
        return visitor.visitSuperMethodPrefix(
            node, semantics.element, operator, arg);
      case AccessKind.SUPER_GETTER:
        // This is not a valid case.
        break;
      case AccessKind.SUPER_SETTER:
        // This is not a valid case.
        break;
      case AccessKind.CONSTANT:
        // TODO(johnniwinther): Should this be a valid case?
        break;
      case AccessKind.UNRESOLVED_SUPER:
        return visitor.visitUnresolvedSuperPrefix(
            node, semantics.element, operator, arg);
      case AccessKind.UNRESOLVED:
        return visitor.visitUnresolvedPrefix(
            node, semantics.element, operator, arg);
      case AccessKind.INVALID:
        return visitor.errorInvalidPrefix(
            node, semantics.element, operator, arg);
      case AccessKind.COMPOUND:
        CompoundAccessSemantics compoundSemantics = semantics;
        switch (compoundSemantics.compoundAccessKind) {
          case CompoundAccessKind.STATIC_GETTER_SETTER:
            return visitor.visitStaticGetterSetterPrefix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                arg);
          case CompoundAccessKind.STATIC_METHOD_SETTER:
            return visitor.visitStaticMethodSetterPrefix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                arg);
          case CompoundAccessKind.UNRESOLVED_STATIC_GETTER:
            return visitor.visitUnresolvedStaticGetterPrefix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                arg);
          case CompoundAccessKind.UNRESOLVED_STATIC_SETTER:
            return visitor.visitUnresolvedStaticSetterPrefix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                arg);
          case CompoundAccessKind.STATIC_METHOD_SETTER:
            return visitor.visitStaticMethodSetterPrefix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                arg);
          case CompoundAccessKind.TOPLEVEL_GETTER_SETTER:
            return visitor.visitTopLevelGetterSetterPrefix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                arg);
          case CompoundAccessKind.TOPLEVEL_METHOD_SETTER:
            return visitor.visitTopLevelMethodSetterPrefix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                arg);
          case CompoundAccessKind.UNRESOLVED_TOPLEVEL_GETTER:
            return visitor.visitUnresolvedTopLevelGetterPrefix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                arg);
          case CompoundAccessKind.UNRESOLVED_TOPLEVEL_SETTER:
            return visitor.visitUnresolvedTopLevelSetterPrefix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                arg);
          case CompoundAccessKind.SUPER_FIELD_FIELD:
            return visitor.visitSuperFieldFieldPrefix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                arg);
          case CompoundAccessKind.SUPER_GETTER_SETTER:
            return visitor.visitSuperGetterSetterPrefix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                arg);
          case CompoundAccessKind.SUPER_GETTER_FIELD:
            return visitor.visitSuperGetterFieldPrefix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                arg);
          case CompoundAccessKind.SUPER_METHOD_SETTER:
            return visitor.visitSuperMethodSetterPrefix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                arg);
          case CompoundAccessKind.SUPER_FIELD_SETTER:
            return visitor.visitSuperFieldSetterPrefix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                arg);
          case CompoundAccessKind.UNRESOLVED_SUPER_GETTER:
            return visitor.visitUnresolvedSuperGetterPrefix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                arg);
          case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
            return visitor.visitUnresolvedSuperSetterPrefix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                arg);
        }
    }
    throw new SpannableAssertionFailure(
        node, "Invalid compound assigment: ${semantics}");
  }

  String toString() => 'prefix($operator,$semantics)';
}

/// The structure for a [Send] that is a postfix operations. For instance
/// `a++`.
class PostfixStructure<R, A> implements SendStructure<R, A> {
  /// The target of the postfix operation.
  final AccessSemantics semantics;

  /// The `++` or `--` operator used in the operation.
  final IncDecOperator operator;

  PostfixStructure(this.semantics, this.operator);

  @override
  SendStructureKind get kind => SendStructureKind.POSTFIX;

  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
    switch (semantics.kind) {
      case AccessKind.CONDITIONAL_DYNAMIC_PROPERTY:
        return visitor.visitIfNotNullDynamicPropertyPostfix(
            node, node.receiver, semantics.name, operator, arg);
      case AccessKind.DYNAMIC_PROPERTY:
        return visitor.visitDynamicPropertyPostfix(
            node, node.receiver, semantics.name, operator, arg);
      case AccessKind.LOCAL_FUNCTION:
        return visitor.visitLocalFunctionPostfix(
            node, semantics.element, operator, arg);
      case AccessKind.LOCAL_VARIABLE:
        return visitor.visitLocalVariablePostfix(
            node, semantics.element, operator, arg);
      case AccessKind.FINAL_LOCAL_VARIABLE:
        return visitor.visitFinalLocalVariablePostfix(
            node, semantics.element, operator, arg);
      case AccessKind.PARAMETER:
        return visitor.visitParameterPostfix(
            node, semantics.element, operator, arg);
      case AccessKind.FINAL_PARAMETER:
        return visitor.visitFinalParameterPostfix(
            node, semantics.element, operator, arg);
      case AccessKind.STATIC_FIELD:
        return visitor.visitStaticFieldPostfix(
            node, semantics.element, operator, arg);
      case AccessKind.FINAL_STATIC_FIELD:
        return visitor.visitFinalStaticFieldPostfix(
            node, semantics.element, operator, arg);
      case AccessKind.STATIC_METHOD:
        return visitor.visitStaticMethodPostfix(
            node, semantics.element, operator, arg);
      case AccessKind.STATIC_GETTER:
        // This is not a valid case.
        break;
      case AccessKind.STATIC_SETTER:
        // This is not a valid case.
        break;
      case AccessKind.TOPLEVEL_FIELD:
        return visitor.visitTopLevelFieldPostfix(
            node, semantics.element, operator, arg);
      case AccessKind.FINAL_TOPLEVEL_FIELD:
        return visitor.visitFinalTopLevelFieldPostfix(
            node, semantics.element, operator, arg);
      case AccessKind.TOPLEVEL_METHOD:
        return visitor.visitTopLevelMethodPostfix(
            node, semantics.element, operator, arg);
      case AccessKind.TOPLEVEL_GETTER:
        // This is not a valid case.
        break;
      case AccessKind.TOPLEVEL_SETTER:
        // This is not a valid case.
        break;
      case AccessKind.CLASS_TYPE_LITERAL:
        return visitor.visitClassTypeLiteralPostfix(
            node, semantics.constant, operator, arg);
      case AccessKind.TYPEDEF_TYPE_LITERAL:
        return visitor.visitTypedefTypeLiteralPostfix(
            node, semantics.constant, operator, arg);
      case AccessKind.DYNAMIC_TYPE_LITERAL:
        return visitor.visitDynamicTypeLiteralPostfix(
            node, semantics.constant, operator, arg);
      case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
        return visitor.visitTypeVariableTypeLiteralPostfix(
            node, semantics.element, operator, arg);
      case AccessKind.EXPRESSION:
        // This is not a valid case.
        break;
      case AccessKind.THIS:
        // This is not a valid case.
        break;
      case AccessKind.THIS_PROPERTY:
        return visitor.visitThisPropertyPostfix(
            node, semantics.name, operator, arg);
      case AccessKind.SUPER_FIELD:
        return visitor.visitSuperFieldPostfix(
            node, semantics.element, operator, arg);
      case AccessKind.SUPER_FINAL_FIELD:
        return visitor.visitFinalSuperFieldPostfix(
            node, semantics.element, operator, arg);
      case AccessKind.SUPER_METHOD:
        return visitor.visitSuperMethodPostfix(
            node, semantics.element, operator, arg);
      case AccessKind.SUPER_GETTER:
        // This is not a valid case.
        break;
      case AccessKind.SUPER_SETTER:
        // This is not a valid case.
        break;
      case AccessKind.CONSTANT:
        // TODO(johnniwinther): Should this be a valid case?
        break;
      case AccessKind.UNRESOLVED_SUPER:
        return visitor.visitUnresolvedSuperPostfix(
            node, semantics.element, operator, arg);
      case AccessKind.UNRESOLVED:
        return visitor.visitUnresolvedPostfix(
            node, semantics.element, operator, arg);
      case AccessKind.INVALID:
        return visitor.errorInvalidPostfix(
            node, semantics.element, operator, arg);
      case AccessKind.COMPOUND:
        CompoundAccessSemantics compoundSemantics = semantics;
        switch (compoundSemantics.compoundAccessKind) {
          case CompoundAccessKind.STATIC_GETTER_SETTER:
            return visitor.visitStaticGetterSetterPostfix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                arg);
          case CompoundAccessKind.UNRESOLVED_STATIC_GETTER:
            return visitor.visitUnresolvedStaticGetterPostfix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                arg);
          case CompoundAccessKind.UNRESOLVED_STATIC_SETTER:
            return visitor.visitUnresolvedStaticSetterPostfix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                arg);
          case CompoundAccessKind.STATIC_METHOD_SETTER:
            return visitor.visitStaticMethodSetterPostfix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                arg);
          case CompoundAccessKind.TOPLEVEL_GETTER_SETTER:
            return visitor.visitTopLevelGetterSetterPostfix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                arg);
          case CompoundAccessKind.TOPLEVEL_METHOD_SETTER:
            return visitor.visitTopLevelMethodSetterPostfix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                arg);
          case CompoundAccessKind.UNRESOLVED_TOPLEVEL_GETTER:
            return visitor.visitUnresolvedTopLevelGetterPostfix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                arg);
          case CompoundAccessKind.UNRESOLVED_TOPLEVEL_SETTER:
            return visitor.visitUnresolvedTopLevelSetterPostfix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                arg);
          case CompoundAccessKind.SUPER_FIELD_FIELD:
            return visitor.visitSuperFieldFieldPostfix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                arg);
          case CompoundAccessKind.SUPER_GETTER_SETTER:
            return visitor.visitSuperGetterSetterPostfix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                arg);
          case CompoundAccessKind.SUPER_GETTER_FIELD:
            return visitor.visitSuperGetterFieldPostfix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                arg);
          case CompoundAccessKind.SUPER_METHOD_SETTER:
            return visitor.visitSuperMethodSetterPostfix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                arg);
          case CompoundAccessKind.SUPER_FIELD_SETTER:
            return visitor.visitSuperFieldSetterPostfix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                arg);
          case CompoundAccessKind.UNRESOLVED_SUPER_GETTER:
            return visitor.visitUnresolvedSuperGetterPostfix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                arg);
          case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
            return visitor.visitUnresolvedSuperSetterPostfix(
                node,
                compoundSemantics.getter,
                compoundSemantics.setter,
                operator,
                arg);
        }
    }
    throw new SpannableAssertionFailure(
        node, "Invalid compound assigment: ${semantics}");
  }

  String toString() => 'postfix($operator,$semantics)';
}

/// The structure for a [Send] whose prefix is a prefix for a deferred library.
/// For instance `deferred.a` where `deferred` is a deferred prefix.
class DeferredPrefixStructure<R, A> implements SendStructure<R, A> {
  /// The deferred prefix element.
  final PrefixElement prefix;

  /// The send structure for the whole [Send] node. For instance a
  /// [GetStructure] for `deferred.a` where `a` is a top level member of the
  /// deferred library.
  final SendStructure sendStructure;

  DeferredPrefixStructure(this.prefix, this.sendStructure) {
    assert(sendStructure != null);
  }

  @override
  SendStructureKind get kind => SendStructureKind.DEFERRED_PREFIX;

  @override
  R dispatch(SemanticSendVisitor<R, A> visitor, Send send, A arg) {
    visitor.previsitDeferredAccess(send, prefix, arg);
    return sendStructure.dispatch(visitor, send, arg);
  }
}

enum NewStructureKind {
  NEW_INVOKE,
  CONST_INVOKE,
  LATE_CONST,
}

/// The structure for a [NewExpression] of a new invocation.
abstract class NewStructure<R, A> implements SemanticSendStructure<R, A> {
  /// Calls the matching visit method on [visitor] with [node] and [arg].
  R dispatch(SemanticSendVisitor<R, A> visitor, NewExpression node, A arg);

  NewStructureKind get kind;
}

/// The structure for a [NewExpression] of a new invocation. For instance
/// `new C()`.
class NewInvokeStructure<R, A> extends NewStructure<R, A> {
  final ConstructorAccessSemantics semantics;
  final Selector selector;

  NewInvokeStructure(this.semantics, this.selector);

  @override
  NewStructureKind get kind => NewStructureKind.NEW_INVOKE;

  CallStructure get callStructure => selector.callStructure;

  R dispatch(SemanticSendVisitor<R, A> visitor, NewExpression node, A arg) {
    switch (semantics.kind) {
      case ConstructorAccessKind.GENERATIVE:
        ConstructorElement constructor = semantics.element;
        if (constructor.isRedirectingGenerative) {
          return visitor.visitRedirectingGenerativeConstructorInvoke(
              node,
              constructor,
              semantics.type,
              node.send.argumentsNode,
              callStructure,
              arg);
        }
        return visitor.visitGenerativeConstructorInvoke(node, constructor,
            semantics.type, node.send.argumentsNode, callStructure, arg);
      case ConstructorAccessKind.FACTORY:
        ConstructorElement constructor = semantics.element;
        if (constructor.isRedirectingFactory) {
          if (constructor.isEffectiveTargetMalformed) {
            return visitor.visitUnresolvedRedirectingFactoryConstructorInvoke(
                node,
                semantics.element,
                semantics.type,
                node.send.argumentsNode,
                callStructure,
                arg);
          }
          ConstructorElement effectiveTarget = constructor.effectiveTarget;
          ResolutionInterfaceType effectiveTargetType =
              constructor.computeEffectiveTargetType(semantics.type);
          if (callStructure.signatureApplies(effectiveTarget.type)) {
            return visitor.visitRedirectingFactoryConstructorInvoke(
                node,
                semantics.element,
                semantics.type,
                effectiveTarget,
                effectiveTargetType,
                node.send.argumentsNode,
                callStructure,
                arg);
          } else {
            return visitor.visitUnresolvedRedirectingFactoryConstructorInvoke(
                node,
                semantics.element,
                semantics.type,
                node.send.argumentsNode,
                callStructure,
                arg);
          }
        }
        if (callStructure.signatureApplies(constructor.type)) {
          return visitor.visitFactoryConstructorInvoke(node, constructor,
              semantics.type, node.send.argumentsNode, callStructure, arg);
        }
        return visitor.visitConstructorIncompatibleInvoke(node, constructor,
            semantics.type, node.send.argumentsNode, callStructure, arg);
      case ConstructorAccessKind.ABSTRACT:
        return visitor.visitAbstractClassConstructorInvoke(
            node,
            semantics.element,
            semantics.type,
            node.send.argumentsNode,
            callStructure,
            arg);
      case ConstructorAccessKind.UNRESOLVED_CONSTRUCTOR:
        return visitor.visitUnresolvedConstructorInvoke(node, semantics.element,
            semantics.type, node.send.argumentsNode, selector, arg);
      case ConstructorAccessKind.UNRESOLVED_TYPE:
        return visitor.visitUnresolvedClassConstructorInvoke(
            node,
            semantics.element,
            semantics.type,
            node.send.argumentsNode,
            selector,
            arg);
      case ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR:
        return visitor.errorNonConstantConstructorInvoke(
            node,
            semantics.element,
            semantics.type,
            node.send.argumentsNode,
            callStructure,
            arg);
      case ConstructorAccessKind.INCOMPATIBLE:
        return visitor.visitConstructorIncompatibleInvoke(
            node,
            semantics.element,
            semantics.type,
            node.send.argumentsNode,
            callStructure,
            arg);
    }
    throw new SpannableAssertionFailure(
        node, "Unhandled constructor invocation kind: ${semantics.kind}");
  }

  String toString() => 'new($semantics,$selector)';
}

enum ConstantInvokeKind {
  CONSTRUCTED,
  BOOL_FROM_ENVIRONMENT,
  INT_FROM_ENVIRONMENT,
  STRING_FROM_ENVIRONMENT,
}

/// The structure for a [NewExpression] of a constant invocation. For instance
/// `const C()`.
class ConstInvokeStructure<R, A> extends NewStructure<R, A> {
  final ConstantInvokeKind constantInvokeKind;
  final ConstantExpression constant;

  ConstInvokeStructure(this.constantInvokeKind, this.constant);

  @override
  NewStructureKind get kind => NewStructureKind.CONST_INVOKE;

  R dispatch(SemanticSendVisitor<R, A> visitor, NewExpression node, A arg) {
    switch (constantInvokeKind) {
      case ConstantInvokeKind.CONSTRUCTED:
        return visitor.visitConstConstructorInvoke(node, constant, arg);
      case ConstantInvokeKind.BOOL_FROM_ENVIRONMENT:
        return visitor.visitBoolFromEnvironmentConstructorInvoke(
            node, constant, arg);
      case ConstantInvokeKind.INT_FROM_ENVIRONMENT:
        return visitor.visitIntFromEnvironmentConstructorInvoke(
            node, constant, arg);
      case ConstantInvokeKind.STRING_FROM_ENVIRONMENT:
        return visitor.visitStringFromEnvironmentConstructorInvoke(
            node, constant, arg);
    }
  }
}

/// A constant constructor invocation that couldn't be determined fully during
/// resolution.
// TODO(johnniwinther): Remove this when all constants are computed during
// resolution.
class LateConstInvokeStructure<R, A> extends NewStructure<R, A> {
  final TreeElements elements;

  LateConstInvokeStructure(this.elements);

  @override
  NewStructureKind get kind => NewStructureKind.LATE_CONST;

  /// Convert this new structure into a regular new structure using the data
  /// available in [elements].
  NewStructure resolve(NewExpression node) {
    Element element = elements[node.send];
    Selector selector = elements.getSelector(node.send);
    ResolutionDartType type = elements.getType(node);
    ConstantExpression constant = elements.getConstant(node);
    if (element.isMalformed ||
        constant == null ||
        constant.kind == ConstantExpressionKind.ERRONEOUS) {
      // This is a non-constant constant constructor invocation, like
      // `const Const(method())`.
      return new NewInvokeStructure(
          new ConstructorAccessSemantics(
              ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR, element, type),
          selector);
    } else {
      ConstantInvokeKind kind;
      switch (constant.kind) {
        case ConstantExpressionKind.CONSTRUCTED:
          kind = ConstantInvokeKind.CONSTRUCTED;
          break;
        case ConstantExpressionKind.BOOL_FROM_ENVIRONMENT:
          kind = ConstantInvokeKind.BOOL_FROM_ENVIRONMENT;
          break;
        case ConstantExpressionKind.INT_FROM_ENVIRONMENT:
          kind = ConstantInvokeKind.INT_FROM_ENVIRONMENT;
          break;
        case ConstantExpressionKind.STRING_FROM_ENVIRONMENT:
          kind = ConstantInvokeKind.STRING_FROM_ENVIRONMENT;
          break;
        default:
          throw new SpannableAssertionFailure(
              node, "Unexpected constant kind $kind: ${constant.toDartText()}");
      }
      return new ConstInvokeStructure(kind, constant);
    }
  }

  R dispatch(SemanticSendVisitor<R, A> visitor, NewExpression node, A arg) {
    Element element = elements[node.send];
    Selector selector = elements.getSelector(node.send);
    ResolutionDartType type = elements.getType(node);
    ConstantExpression constant = elements.getConstant(node);
    if (element.isMalformed ||
        constant == null ||
        constant.kind == ConstantExpressionKind.ERRONEOUS) {
      // This is a non-constant constant constructor invocation, like
      // `const Const(method())`.
      return visitor.errorNonConstantConstructorInvoke(node, element, type,
          node.send.argumentsNode, selector.callStructure, arg);
    } else {
      ConstantInvokeKind kind;
      switch (constant.kind) {
        case ConstantExpressionKind.CONSTRUCTED:
          return visitor.visitConstConstructorInvoke(node, constant, arg);
        case ConstantExpressionKind.BOOL_FROM_ENVIRONMENT:
          return visitor.visitBoolFromEnvironmentConstructorInvoke(
              node, constant, arg);
        case ConstantExpressionKind.INT_FROM_ENVIRONMENT:
          return visitor.visitIntFromEnvironmentConstructorInvoke(
              node, constant, arg);
        case ConstantExpressionKind.STRING_FROM_ENVIRONMENT:
          return visitor.visitStringFromEnvironmentConstructorInvoke(
              node, constant, arg);
        default:
          throw new SpannableAssertionFailure(
              node, "Unexpected constant kind $kind: ${constant.toDartText()}");
      }
    }
  }
}

/// The structure of a parameter declaration.
abstract class ParameterStructure<R, A> {
  final VariableDefinitions definitions;
  final Node node;
  final ParameterElement parameter;

  ParameterStructure(this.definitions, this.node, this.parameter);

  /// Calls the matching visit method on [visitor] with [definitions] and [arg].
  R dispatch(SemanticDeclarationVisitor<R, A> visitor, A arg);
}

/// The structure of a required parameter declaration.
class RequiredParameterStructure<R, A> extends ParameterStructure<R, A> {
  final int index;

  RequiredParameterStructure(VariableDefinitions definitions, Node node,
      ParameterElement parameter, this.index)
      : super(definitions, node, parameter);

  @override
  R dispatch(SemanticDeclarationVisitor<R, A> visitor, A arg) {
    if (parameter.isInitializingFormal) {
      return visitor.visitInitializingFormalDeclaration(
          definitions, node, parameter, index, arg);
    } else {
      return visitor.visitParameterDeclaration(
          definitions, node, parameter, index, arg);
    }
  }
}

/// The structure of a optional positional parameter declaration.
class OptionalParameterStructure<R, A> extends ParameterStructure<R, A> {
  final ConstantExpression defaultValue;
  final int index;

  OptionalParameterStructure(VariableDefinitions definitions, Node node,
      ParameterElement parameter, this.defaultValue, this.index)
      : super(definitions, node, parameter);

  @override
  R dispatch(SemanticDeclarationVisitor<R, A> visitor, A arg) {
    if (parameter.isInitializingFormal) {
      return visitor.visitOptionalInitializingFormalDeclaration(
          definitions, node, parameter, defaultValue, index, arg);
    } else {
      return visitor.visitOptionalParameterDeclaration(
          definitions, node, parameter, defaultValue, index, arg);
    }
  }
}

/// The structure of a optional named parameter declaration.
class NamedParameterStructure<R, A> extends ParameterStructure<R, A> {
  final ConstantExpression defaultValue;

  NamedParameterStructure(VariableDefinitions definitions, Node node,
      ParameterElement parameter, this.defaultValue)
      : super(definitions, node, parameter);

  @override
  R dispatch(SemanticDeclarationVisitor<R, A> visitor, A arg) {
    if (parameter.isInitializingFormal) {
      return visitor.visitNamedInitializingFormalDeclaration(
          definitions, node, parameter, defaultValue, arg);
    } else {
      return visitor.visitNamedParameterDeclaration(
          definitions, node, parameter, defaultValue, arg);
    }
  }
}

enum VariableKind {
  TOP_LEVEL_FIELD,
  STATIC_FIELD,
  INSTANCE_FIELD,
  LOCAL_VARIABLE,
}

abstract class VariableStructure<R, A> {
  final VariableKind kind;
  final Node node;
  final VariableElement variable;

  VariableStructure(this.kind, this.node, this.variable);

  R dispatch(SemanticDeclarationVisitor<R, A> visitor,
      VariableDefinitions definitions, A arg);
}

class NonConstantVariableStructure<R, A> extends VariableStructure<R, A> {
  NonConstantVariableStructure(
      VariableKind kind, Node node, VariableElement variable)
      : super(kind, node, variable);

  R dispatch(SemanticDeclarationVisitor<R, A> visitor,
      VariableDefinitions definitions, A arg) {
    switch (kind) {
      case VariableKind.TOP_LEVEL_FIELD:
        return visitor.visitTopLevelFieldDeclaration(
            definitions, node, variable, variable.initializer, arg);
      case VariableKind.STATIC_FIELD:
        return visitor.visitStaticFieldDeclaration(
            definitions, node, variable, variable.initializer, arg);
      case VariableKind.INSTANCE_FIELD:
        return visitor.visitInstanceFieldDeclaration(
            definitions, node, variable, variable.initializer, arg);
      case VariableKind.LOCAL_VARIABLE:
        return visitor.visitLocalVariableDeclaration(
            definitions, node, variable, variable.initializer, arg);
    }
  }
}

class ConstantVariableStructure<R, A> extends VariableStructure<R, A> {
  final ConstantExpression constant;

  ConstantVariableStructure(
      VariableKind kind, Node node, VariableElement variable, this.constant)
      : super(kind, node, variable);

  R dispatch(SemanticDeclarationVisitor<R, A> visitor,
      VariableDefinitions definitions, A arg) {
    switch (kind) {
      case VariableKind.TOP_LEVEL_FIELD:
        return visitor.visitTopLevelConstantDeclaration(
            definitions, node, variable, constant, arg);
      case VariableKind.STATIC_FIELD:
        return visitor.visitStaticConstantDeclaration(
            definitions, node, variable, constant, arg);
      case VariableKind.LOCAL_VARIABLE:
        return visitor.visitLocalConstantDeclaration(
            definitions, node, variable, constant, arg);
      default:
    }
    throw new SpannableAssertionFailure(
        node, "Invalid constant variable: $variable");
  }
}

class InitializersStructure<R, A> {
  final List<InitializerStructure<R, A>> initializers;

  InitializersStructure(this.initializers);
}

abstract class InitializerStructure<R, A> {
  R dispatch(SemanticDeclarationVisitor<R, A> visitor, A arg);

  bool get isConstructorInvoke => false;
}

class FieldInitializerStructure<R, A> extends InitializerStructure<R, A> {
  final Send node;
  final FieldElement field;

  FieldInitializerStructure(this.node, this.field);

  R dispatch(SemanticDeclarationVisitor<R, A> visitor, A arg) {
    return visitor.visitFieldInitializer(
        node, field, node.arguments.single, arg);
  }
}

class SuperConstructorInvokeStructure<R, A> extends InitializerStructure<R, A> {
  final Send node;
  final ConstructorElement constructor;
  final ResolutionInterfaceType type;
  final CallStructure callStructure;

  SuperConstructorInvokeStructure(
      this.node, this.constructor, this.type, this.callStructure);

  R dispatch(SemanticDeclarationVisitor<R, A> visitor, A arg) {
    return visitor.visitSuperConstructorInvoke(
        node, constructor, type, node.argumentsNode, callStructure, arg);
  }

  bool get isConstructorInvoke => true;
}

class ImplicitSuperConstructorInvokeStructure<R, A>
    extends InitializerStructure<R, A> {
  final FunctionExpression node;
  final ConstructorElement constructor;
  final ResolutionInterfaceType type;

  ImplicitSuperConstructorInvokeStructure(
      this.node, this.constructor, this.type);

  R dispatch(SemanticDeclarationVisitor<R, A> visitor, A arg) {
    return visitor.visitImplicitSuperConstructorInvoke(
        node, constructor, type, arg);
  }

  bool get isConstructorInvoke => true;
}

class ThisConstructorInvokeStructure<R, A> extends InitializerStructure<R, A> {
  final Send node;
  final ConstructorElement constructor;
  final CallStructure callStructure;

  ThisConstructorInvokeStructure(
      this.node, this.constructor, this.callStructure);

  R dispatch(SemanticDeclarationVisitor<R, A> visitor, A arg) {
    return visitor.visitThisConstructorInvoke(
        node, constructor, node.argumentsNode, callStructure, arg);
  }

  bool get isConstructorInvoke => true;
}
