// This code was auto-generated, is not intended to be edited, and is subject to
// significant change. Please see the README file for more information.
library engine.constant;
import 'java_core.dart';
import 'source.dart' show Source;
import 'error.dart' show AnalysisError, ErrorCode, CompileTimeErrorCode;
import 'scanner.dart' show TokenType;
import 'ast.dart';
import 'element.dart';
import 'engine.dart' show AnalysisEngine;
/**
 * Instances of the class `ConstantEvaluator` evaluate constant expressions to produce their
 * compile-time value. According to the Dart Language Specification: <blockquote> A constant
 * expression is one of the following:
 *
 * * A literal number.
 * * A literal boolean.
 * * A literal string where any interpolated expression is a compile-time constant that evaluates
 * to a numeric, string or boolean value or to `null`.
 * * `null`.
 * * A reference to a static constant variable.
 * * An identifier expression that denotes a constant variable, a class or a type parameter.
 * * A constant constructor invocation.
 * * A constant list literal.
 * * A constant map literal.
 * * A simple or qualified identifier denoting a top-level function or a static method.
 * * A parenthesized expression `(e)` where `e` is a constant expression.
 * * An expression of one of the forms `identical(e1, e2)`, `e1 == e2`,
 * `e1 != e2` where `e1` and `e2` are constant expressions that evaluate to a
 * numeric, string or boolean value or to `null`.
 * * An expression of one of the forms `!e`, `e1 && e2` or `e1 || e2`, where
 * `e`, `e1` and `e2` are constant expressions that evaluate to a boolean value or
 * to `null`.
 * * An expression of one of the forms `~e`, `e1 ^ e2`, `e1 & e2`,
 * `e1 | e2`, `e1 >> e2` or `e1 << e2`, where `e`, `e1` and `e2`
 * are constant expressions that evaluate to an integer value or to `null`.
 * * An expression of one of the forms `-e`, `e1 + e2`, `e1 - e2`,
 * `e1 * e2`, `e1 / e2`, `e1 ~/ e2`, `e1 > e2`, `e1 < e2`,
 * `e1 >= e2`, `e1 <= e2` or `e1 % e2`, where `e`, `e1` and `e2`
 * are constant expressions that evaluate to a numeric value or to `null`.
 *
 * </blockquote> The values returned by instances of this class are therefore `null` and
 * instances of the classes `Boolean`, `BigInteger`, `Double`, `String`, and
 * `DartObject`.
 *
 * In addition, this class defines several values that can be returned to indicate various
 * conditions encountered during evaluation. These are documented with the static field that define
 * those values.
 */
class ConstantEvaluator {

  /**
   * The source containing the expression(s) that will be evaluated.
   */
  Source _source;

  /**
   * Initialize a newly created evaluator to evaluate expressions in the given source.
   *
   * @param source the source containing the expression(s) that will be evaluated
   */
  ConstantEvaluator(Source source) {
    this._source = source;
  }
  EvaluationResult evaluate(Expression expression) {
    EvaluationResultImpl result = expression.accept(new ConstantVisitor());
    if (result is ValidResult) {
      return EvaluationResult.forValue(((result as ValidResult)).value);
    }
    List<AnalysisError> errors = new List<AnalysisError>();
    for (ErrorResult_ErrorData data in ((result as ErrorResult)).errorData) {
      ASTNode node = data.node;
      errors.add(new AnalysisError.con2(_source, node.offset, node.length, data.errorCode, []));
    }
    return EvaluationResult.forErrors(new List.from(errors));
  }
}
/**
 * Instances of the class `EvaluationResult` represent the result of attempting to evaluate an
 * expression.
 */
class EvaluationResult {

  /**
   * Return an evaluation result representing the result of evaluating an expression that is not a
   * compile-time constant because of the given errors.
   *
   * @param errors the errors that should be reported for the expression(s) that were evaluated
   * @return the result of evaluating an expression that is not a compile-time constant
   */
  static EvaluationResult forErrors(List<AnalysisError> errors) => new EvaluationResult(null, errors);

  /**
   * Return an evaluation result representing the result of evaluating an expression that is a
   * compile-time constant that evaluates to the given value.
   *
   * @param value the value of the expression
   * @return the result of evaluating an expression that is a compile-time constant
   */
  static EvaluationResult forValue(Object value) => new EvaluationResult(value, null);

  /**
   * The value of the expression.
   */
  Object value;

  /**
   * The errors that should be reported for the expression(s) that were evaluated.
   */
  List<AnalysisError> _errors;

  /**
   * Initialize a newly created result object with the given state. Clients should use one of the
   * factory methods: [forErrors] and [forValue].
   *
   * @param value the value of the expression
   * @param errors the errors that should be reported for the expression(s) that were evaluated
   */
  EvaluationResult(Object value, List<AnalysisError> errors) {
    this.value = value;
    this._errors = errors;
  }

  /**
   * Return an array containing the errors that should be reported for the expression(s) that were
   * evaluated. If there are no such errors, the array will be empty. The array can be empty even if
   * the expression is not a valid compile time constant if the errors would have been reported by
   * other parts of the analysis engine.
   */
  List<AnalysisError> get errors => _errors == null ? AnalysisError.NO_ERRORS : _errors;

  /**
   * Return `true` if the expression is a compile-time constant expression that would not
   * throw an exception when evaluated.
   *
   * @return `true` if the expression is a valid compile-time constant expression
   */
  bool get isValid => _errors == null;
}
/**
 * Instances of the class `ConstantFinder` are used to traverse the AST structures of all of
 * the compilation units being resolved and build a table mapping constant variable elements to the
 * declarations of those variables.
 */
class ConstantFinder extends RecursiveASTVisitor<Object> {

  /**
   * A table mapping constant variable elements to the declarations of those variables.
   */
  final Map<VariableElement, VariableDeclaration> variableMap = new Map<VariableElement, VariableDeclaration>();
  Object visitVariableDeclaration(VariableDeclaration node) {
    super.visitVariableDeclaration(node);
    Expression initializer = node.initializer;
    if (initializer != null && node.isConst) {
      VariableElement element = node.element;
      if (element != null) {
        variableMap[element] = node;
      }
    }
    return null;
  }
}
/**
 * Instances of the class `ConstantValueComputer` compute the values of constant variables in
 * one or more compilation units. The expected usage pattern is for the compilation units to be
 * added to this computer using the method [add] and then for the method
 * [computeValues] to invoked exactly once. Any use of an instance after invoking the
 * method [computeValues] will result in unpredictable behavior.
 */
class ConstantValueComputer {

  /**
   * The object used to find constant variables in the compilation units that were added.
   */
  ConstantFinder _constantFinder = new ConstantFinder();

  /**
   * A graph in which the nodes are the constant variables and the edges are from each variable to
   * the other constant variables that are referenced in the head's initializer.
   */
  DirectedGraph<VariableElement> _referenceGraph = new DirectedGraph<VariableElement>();

  /**
   * A table mapping constant variables to the declarations of those variables.
   */
  Map<VariableElement, VariableDeclaration> _declarationMap;

  /**
   * Add the constant variables in the given compilation unit to the list of constant variables
   * whose value needs to be computed.
   *
   * @param unit the compilation unit defining the constant variables to be added
   */
  void add(CompilationUnit unit) {
    unit.accept(_constantFinder);
  }

  /**
   * Compute values for all of the constant variables in the compilation units that were added.
   */
  void computeValues() {
    _declarationMap = _constantFinder.variableMap;
    for (MapEntry<VariableElement, VariableDeclaration> entry in getMapEntrySet(_declarationMap)) {
      VariableElement element = entry.getKey();
      ReferenceFinder referenceFinder = new ReferenceFinder(element, _referenceGraph);
      _referenceGraph.addNode(element);
      entry.getValue().initializer.accept(referenceFinder);
    }
    while (!_referenceGraph.isEmpty) {
      VariableElement element = _referenceGraph.removeSink();
      while (element != null) {
        computeValueFor(element);
        element = _referenceGraph.removeSink();
      }
      if (!_referenceGraph.isEmpty) {
        List<VariableElement> variablesInCycle = _referenceGraph.findCycle();
        if (variablesInCycle == null) {
          AnalysisEngine.instance.logger.logError("Exiting constant value computer with ${_referenceGraph.nodeCount} variables that are neither sinks no in a cycle");
          return;
        }
        for (VariableElement variable in variablesInCycle) {
          generateCycleError(variablesInCycle, variable);
        }
        _referenceGraph.removeAllNodes(variablesInCycle);
      }
    }
  }

  /**
   * Compute a value for the given variable.
   *
   * @param variable the variable for which a value is to be computed
   */
  void computeValueFor(VariableElement variable) {
    VariableDeclaration declaration = _declarationMap[variable];
    if (declaration == null) {
      return;
    }
    EvaluationResultImpl result = declaration.initializer.accept(new ConstantVisitor());
    ((variable as VariableElementImpl)).evaluationResult = result;
    if (result is ErrorResult) {
      List<AnalysisError> errors = new List<AnalysisError>();
      for (ErrorResult_ErrorData data in ((result as ErrorResult)).errorData) {
        ASTNode node = data.node;
        Source source = variable.getAncestor(CompilationUnitElement).source;
        errors.add(new AnalysisError.con2(source, node.offset, node.length, data.errorCode, []));
      }
    }
  }

  /**
   * Generate an error indicating that the given variable is not a valid compile-time constant
   * because it references at least one of the variables in the given cycle, each of which directly
   * or indirectly references the variable.
   *
   * @param variablesInCycle the variables in the cycle that includes the given variable
   * @param variable the variable that is not a valid compile-time constant
   */
  void generateCycleError(List<VariableElement> variablesInCycle, VariableElement variable) {
  }
}
/**
 * Instances of the class `ConstantVisitor` evaluate constant expressions to produce their
 * compile-time value. According to the Dart Language Specification: <blockquote> A constant
 * expression is one of the following:
 *
 * * A literal number.
 * * A literal boolean.
 * * A literal string where any interpolated expression is a compile-time constant that evaluates
 * to a numeric, string or boolean value or to `null`.
 * * `null`.
 * * A reference to a static constant variable.
 * * An identifier expression that denotes a constant variable, a class or a type parameter.
 * * A constant constructor invocation.
 * * A constant list literal.
 * * A constant map literal.
 * * A simple or qualified identifier denoting a top-level function or a static method.
 * * A parenthesized expression `(e)` where `e` is a constant expression.
 * * An expression of one of the forms `identical(e1, e2)`, `e1 == e2`,
 * `e1 != e2` where `e1` and `e2` are constant expressions that evaluate to a
 * numeric, string or boolean value or to `null`.
 * * An expression of one of the forms `!e`, `e1 && e2` or `e1 || e2`, where
 * `e`, `e1` and `e2` are constant expressions that evaluate to a boolean value or
 * to `null`.
 * * An expression of one of the forms `~e`, `e1 ^ e2`, `e1 & e2`,
 * `e1 | e2`, `e1 >> e2` or `e1 << e2`, where `e`, `e1` and `e2`
 * are constant expressions that evaluate to an integer value or to `null`.
 * * An expression of one of the forms `-e`, `e1 + e2`, `e1 - e2`,
 * `e1 * e2`, `e1 / e2`, `e1 ~/ e2`, `e1 > e2`, `e1 < e2`,
 * `e1 >= e2`, `e1 <= e2` or `e1 % e2`, where `e`, `e1` and `e2`
 * are constant expressions that evaluate to a numeric value or to `null`.
 *
 * </blockquote>
 */
class ConstantVisitor extends GeneralizingASTVisitor<EvaluationResultImpl> {
  EvaluationResultImpl visitAdjacentStrings(AdjacentStrings node) {
    EvaluationResultImpl result = null;
    for (StringLiteral string in node.strings) {
      if (result == null) {
        result = string.accept(this);
      } else {
        result = result.concatenate(node, string.accept(this));
      }
    }
    return result;
  }
  EvaluationResultImpl visitBinaryExpression(BinaryExpression node) {
    EvaluationResultImpl leftResult = node.leftOperand.accept(this);
    EvaluationResultImpl rightResult = node.rightOperand.accept(this);
    TokenType operatorType = node.operator.type;
    if (operatorType != TokenType.BANG_EQ && operatorType != TokenType.EQ_EQ) {
      if (leftResult is ValidResult && ((leftResult as ValidResult)).isNull || rightResult is ValidResult && ((rightResult as ValidResult)).isNull) {
        return error(node, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
      }
    }
    while (true) {
      if (operatorType == TokenType.AMPERSAND) {
        return leftResult.bitAnd(node, rightResult);
      } else if (operatorType == TokenType.AMPERSAND_AMPERSAND) {
        return leftResult.logicalAnd(node, rightResult);
      } else if (operatorType == TokenType.BANG_EQ) {
        return leftResult.notEqual(node, rightResult);
      } else if (operatorType == TokenType.BAR) {
        return leftResult.bitOr(node, rightResult);
      } else if (operatorType == TokenType.BAR_BAR) {
        return leftResult.logicalOr(node, rightResult);
      } else if (operatorType == TokenType.CARET) {
        return leftResult.bitXor(node, rightResult);
      } else if (operatorType == TokenType.EQ_EQ) {
        return leftResult.equalEqual(node, rightResult);
      } else if (operatorType == TokenType.GT) {
        return leftResult.greaterThan(node, rightResult);
      } else if (operatorType == TokenType.GT_EQ) {
        return leftResult.greaterThanOrEqual(node, rightResult);
      } else if (operatorType == TokenType.GT_GT) {
        return leftResult.shiftRight(node, rightResult);
      } else if (operatorType == TokenType.LT) {
        return leftResult.lessThan(node, rightResult);
      } else if (operatorType == TokenType.LT_EQ) {
        return leftResult.lessThanOrEqual(node, rightResult);
      } else if (operatorType == TokenType.LT_LT) {
        return leftResult.shiftLeft(node, rightResult);
      } else if (operatorType == TokenType.MINUS) {
        return leftResult.minus(node, rightResult);
      } else if (operatorType == TokenType.PERCENT) {
        return leftResult.remainder(node, rightResult);
      } else if (operatorType == TokenType.PLUS) {
        return leftResult.add(node, rightResult);
      } else if (operatorType == TokenType.STAR) {
        return leftResult.times(node, rightResult);
      } else if (operatorType == TokenType.SLASH) {
        return leftResult.divide(node, rightResult);
      } else if (operatorType == TokenType.TILDE_SLASH) {
        return leftResult.integerDivide(node, rightResult);
      }
      break;
    }
    return error(node, null);
  }
  EvaluationResultImpl visitBooleanLiteral(BooleanLiteral node) => node.value ? ValidResult.RESULT_TRUE : ValidResult.RESULT_FALSE;
  EvaluationResultImpl visitConditionalExpression(ConditionalExpression node) {
    Expression condition = node.condition;
    EvaluationResultImpl conditionResult = condition.accept(this);
    conditionResult = conditionResult.applyBooleanConversion(condition);
    if (conditionResult is ErrorResult) {
      return conditionResult;
    }
    EvaluationResultImpl thenResult = node.thenExpression.accept(this);
    if (thenResult is ErrorResult) {
      return thenResult;
    }
    EvaluationResultImpl elseResult = node.elseExpression.accept(this);
    if (elseResult is ErrorResult) {
      return elseResult;
    }
    return (identical(conditionResult, ValidResult.RESULT_TRUE)) ? thenResult : elseResult;
  }
  EvaluationResultImpl visitDoubleLiteral(DoubleLiteral node) => new ValidResult(node.value);
  EvaluationResultImpl visitInstanceCreationExpression(InstanceCreationExpression node) {
    if (!node.isConst) {
      return error(node, null);
    }
    ConstructorElement constructor = node.staticElement;
    if (constructor != null && constructor.isConst) {
      node.argumentList.accept(this);
      return ValidResult.RESULT_OBJECT;
    }
    return error(node, null);
  }
  EvaluationResultImpl visitIntegerLiteral(IntegerLiteral node) => new ValidResult(node.value);
  EvaluationResultImpl visitInterpolationExpression(InterpolationExpression node) {
    EvaluationResultImpl result = node.expression.accept(this);
    return result.performToString(node);
  }
  EvaluationResultImpl visitInterpolationString(InterpolationString node) => new ValidResult(node.value);
  EvaluationResultImpl visitListLiteral(ListLiteral node) {
    if (node.constKeyword == null) {
      return new ErrorResult.con1(node, CompileTimeErrorCode.MISSING_CONST_IN_LIST_LITERAL);
    }
    ErrorResult result = null;
    for (Expression element in node.elements) {
      result = union(result, element.accept(this));
    }
    if (result != null) {
      return result;
    }
    return ValidResult.RESULT_OBJECT;
  }
  EvaluationResultImpl visitMapLiteral(MapLiteral node) {
    if (node.constKeyword == null) {
      return new ErrorResult.con1(node, CompileTimeErrorCode.MISSING_CONST_IN_MAP_LITERAL);
    }
    ErrorResult result = null;
    for (MapLiteralEntry entry in node.entries) {
      result = union(result, entry.key.accept(this));
      result = union(result, entry.value.accept(this));
    }
    if (result != null) {
      return result;
    }
    return ValidResult.RESULT_OBJECT;
  }
  EvaluationResultImpl visitMethodInvocation(MethodInvocation node) {
    Element element = node.methodName.staticElement;
    if (element is FunctionElement) {
      FunctionElement function = element as FunctionElement;
      if (function.name == "identical") {
        NodeList<Expression> arguments = node.argumentList.arguments;
        if (arguments.length == 2) {
          Element enclosingElement = function.enclosingElement;
          if (enclosingElement is CompilationUnitElement) {
            LibraryElement library = ((enclosingElement as CompilationUnitElement)).library;
            if (library.isDartCore) {
              EvaluationResultImpl leftArgument = arguments[0].accept(this);
              EvaluationResultImpl rightArgument = arguments[1].accept(this);
              return leftArgument.equalEqual(node, rightArgument);
            }
          }
        }
      }
    }
    return error(node, null);
  }
  EvaluationResultImpl visitNamedExpression(NamedExpression node) => node.expression.accept(this);
  EvaluationResultImpl visitNode(ASTNode node) => error(node, null);
  EvaluationResultImpl visitNullLiteral(NullLiteral node) => ValidResult.RESULT_NULL;
  EvaluationResultImpl visitParenthesizedExpression(ParenthesizedExpression node) => node.expression.accept(this);
  EvaluationResultImpl visitPrefixedIdentifier(PrefixedIdentifier node) {
    SimpleIdentifier prefixNode = node.prefix;
    Element prefixElement = prefixNode.staticElement;
    if (prefixElement is! PrefixElement) {
      EvaluationResultImpl prefixResult = prefixNode.accept(this);
      if (prefixResult is! ValidResult) {
        return error(node, null);
      }
    }
    return getConstantValue(node, node.staticElement);
  }
  EvaluationResultImpl visitPrefixExpression(PrefixExpression node) {
    EvaluationResultImpl operand = node.operand.accept(this);
    if (operand is ValidResult && ((operand as ValidResult)).isNull) {
      return error(node, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
    }
    while (true) {
      if (node.operator.type == TokenType.BANG) {
        return operand.logicalNot(node);
      } else if (node.operator.type == TokenType.TILDE) {
        return operand.bitNot(node);
      } else if (node.operator.type == TokenType.MINUS) {
        return operand.negated(node);
      }
      break;
    }
    return error(node, null);
  }
  EvaluationResultImpl visitPropertyAccess(PropertyAccess node) => getConstantValue(node, node.propertyName.staticElement);
  EvaluationResultImpl visitSimpleIdentifier(SimpleIdentifier node) => getConstantValue(node, node.staticElement);
  EvaluationResultImpl visitSimpleStringLiteral(SimpleStringLiteral node) => new ValidResult(node.value);
  EvaluationResultImpl visitStringInterpolation(StringInterpolation node) {
    EvaluationResultImpl result = null;
    for (InterpolationElement element in node.elements) {
      if (result == null) {
        result = element.accept(this);
      } else {
        result = result.concatenate(node, element.accept(this));
      }
    }
    return result;
  }

  /**
   * Return a result object representing an error associated with the given node.
   *
   * @param node the AST node associated with the error
   * @param code the error code indicating the nature of the error
   * @return a result object representing an error associated with the given node
   */
  ErrorResult error(ASTNode node, ErrorCode code) => new ErrorResult.con1(node, code == null ? CompileTimeErrorCode.INVALID_CONSTANT : code);

  /**
   * Return the constant value of the static constant represented by the given element.
   *
   * @param node the node to be used if an error needs to be reported
   * @param element the element whose value is to be returned
   * @return the constant value of the static constant
   */
  EvaluationResultImpl getConstantValue(ASTNode node, Element element) {
    if (element is PropertyAccessorElement) {
      element = ((element as PropertyAccessorElement)).variable;
    }
    if (element is VariableElementImpl) {
      VariableElementImpl variableElementImpl = element as VariableElementImpl;
      EvaluationResultImpl value = variableElementImpl.evaluationResult;
      if (variableElementImpl.isConst && value != null) {
        return value;
      }
    } else if (element is ExecutableElement) {
      if (((element as ExecutableElement)).isStatic) {
        return new ValidResult(element);
      }
    } else if (element is ClassElement) {
      return ValidResult.RESULT_OBJECT;
    }
    return error(node, null);
  }

  /**
   * Return the union of the errors encoded in the given results.
   *
   * @param leftResult the first set of errors, or `null` if there was no previous collection
   *          of errors
   * @param rightResult the errors to be added to the collection, or a valid result if there are no
   *          errors to be added
   * @return the union of the errors encoded in the given results
   */
  ErrorResult union(ErrorResult leftResult, EvaluationResultImpl rightResult) {
    if (rightResult is ErrorResult) {
      if (leftResult != null) {
        return new ErrorResult.con2(leftResult, rightResult as ErrorResult);
      } else {
        return rightResult as ErrorResult;
      }
    }
    return leftResult;
  }
}
/**
 * Instances of the class `DirectedGraph` implement a directed graph in which the nodes are
 * arbitrary (client provided) objects and edges are represented implicitly. The graph will allow an
 * edge from any node to any other node, including itself, but will not represent multiple edges
 * between the same pair of nodes.
 *
 * @param N the type of the nodes in the graph
 */
class DirectedGraph<N> {

  /**
   * The table encoding the edges in the graph. An edge is represented by an entry mapping the head
   * to a set of tails. Nodes that are not the head of any edge are represented by an entry mapping
   * the node to an empty set of tails.
   */
  Map<N, Set<N>> _edges = new Map<N, Set<N>>();

  /**
   * Add an edge from the given head node to the given tail node. Both nodes will be a part of the
   * graph after this method is invoked, whether or not they were before.
   *
   * @param head the node at the head of the edge
   * @param tail the node at the tail of the edge
   */
  void addEdge(N head, N tail) {
    Set<N> tails = _edges[tail];
    if (tails == null) {
      _edges[tail] = new Set<N>();
    }
    tails = _edges[head];
    if (tails == null) {
      tails = new Set<N>();
      _edges[head] = tails;
    }
    javaSetAdd(tails, tail);
  }

  /**
   * Add the given node to the set of nodes in the graph.
   *
   * @param node the node to be added
   */
  void addNode(N node) {
    Set<N> tails = _edges[node];
    if (tails == null) {
      _edges[node] = new Set<N>();
    }
  }

  /**
   * Return a list of nodes that form a cycle, or `null` if there are no cycles in this graph.
   *
   * @return a list of nodes that form a cycle
   */
  List<N> findCycle() => null;

  /**
   * Return the number of nodes in this graph.
   *
   * @return the number of nodes in this graph
   */
  int get nodeCount => _edges.length;

  /**
   * Return a set containing the tails of edges that have the given node as their head. The set will
   * be empty if there are no such edges or if the node is not part of the graph. Clients must not
   * modify the returned set.
   *
   * @param head the node at the head of all of the edges whose tails are to be returned
   * @return a set containing the tails of edges that have the given node as their head
   */
  Set<N> getTails(N head) {
    Set<N> tails = _edges[head];
    if (tails == null) {
      return new Set<N>();
    }
    return tails;
  }

  /**
   * Return `true` if this graph is empty.
   *
   * @return `true` if this graph is empty
   */
  bool get isEmpty => _edges.isEmpty;

  /**
   * Remove all of the given nodes from this graph. As a consequence, any edges for which those
   * nodes were either a head or a tail will also be removed.
   *
   * @param nodes the nodes to be removed
   */
  void removeAllNodes(List<N> nodes) {
    for (N node in nodes) {
      removeNode(node);
    }
  }

  /**
   * Remove the edge from the given head node to the given tail node. If there was no such edge then
   * the graph will be unmodified: the number of edges will be the same and the set of nodes will be
   * the same (neither node will either be added or removed).
   *
   * @param head the node at the head of the edge
   * @param tail the node at the tail of the edge
   * @return `true` if the graph was modified as a result of this operation
   */
  void removeEdge(N head, N tail) {
    Set<N> tails = _edges[head];
    if (tails != null) {
      tails.remove(tail);
    }
  }

  /**
   * Remove the given node from this graph. As a consequence, any edges for which that node was
   * either a head or a tail will also be removed.
   *
   * @param node the node to be removed
   */
  void removeNode(N node) {
    _edges.remove(node);
    for (Set<N> tails in _edges.values) {
      tails.remove(node);
    }
  }

  /**
   * Find one node (referred to as a sink node) that has no outgoing edges (that is, for which there
   * are no edges that have that node as the head of the edge) and remove it from this graph. Return
   * the node that was removed, or `null` if there are no such nodes either because the graph
   * is empty or because every node in the graph has at least one outgoing edge. As a consequence of
   * removing the node from the graph any edges for which that node was a tail will also be removed.
   *
   * @return the sink node that was removed
   */
  N removeSink() {
    N sink = findSink();
    if (sink == null) {
      return null;
    }
    removeNode(sink);
    return sink;
  }

  /**
   * Return one node that has no outgoing edges (that is, for which there are no edges that have
   * that node as the head of the edge), or `null` if there are no such nodes.
   *
   * @return a sink node
   */
  N findSink() {
    for (N key in _edges.keys) {
      if (_edges[key].isEmpty) return key;
    }
    return null;
  }
}
/**
 * Instances of the class `ErrorResult` represent the result of evaluating an expression that
 * is not a valid compile time constant.
 */
class ErrorResult extends EvaluationResultImpl {

  /**
   * The errors that prevent the expression from being a valid compile time constant.
   */
  final List<ErrorResult_ErrorData> errorData = new List<ErrorResult_ErrorData>();

  /**
   * Initialize a newly created result representing the error with the given code reported against
   * the given node.
   *
   * @param node the node against which the error should be reported
   * @param errorCode the error code for the error to be generated
   */
  ErrorResult.con1(ASTNode node, ErrorCode errorCode) {
    errorData.add(new ErrorResult_ErrorData(node, errorCode));
  }

  /**
   * Initialize a newly created result to represent the union of the errors in the given result
   * objects.
   *
   * @param firstResult the first set of results being merged
   * @param secondResult the second set of results being merged
   */
  ErrorResult.con2(ErrorResult firstResult, ErrorResult secondResult) {
    errorData.addAll(firstResult.errorData);
    errorData.addAll(secondResult.errorData);
  }
  EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.addToError(node, this);
  EvaluationResultImpl applyBooleanConversion(ASTNode node) => this;
  EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitAndError(node, this);
  EvaluationResultImpl bitNot(Expression node) => this;
  EvaluationResultImpl bitOr(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitOrError(node, this);
  EvaluationResultImpl bitXor(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitXorError(node, this);
  EvaluationResultImpl concatenate(Expression node, EvaluationResultImpl rightOperand) => rightOperand.concatenateError(node, this);
  EvaluationResultImpl divide(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.divideError(node, this);
  EvaluationResultImpl equalEqual(Expression node, EvaluationResultImpl rightOperand) => rightOperand.equalEqualError(node, this);
  bool equalValues(EvaluationResultImpl result) => false;
  EvaluationResultImpl greaterThan(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanError(node, this);
  EvaluationResultImpl greaterThanOrEqual(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanOrEqualError(node, this);
  EvaluationResultImpl integerDivide(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.integerDivideError(node, this);
  EvaluationResultImpl integerDivideValid(BinaryExpression node, ValidResult leftOperand) => this;
  EvaluationResultImpl lessThan(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanError(node, this);
  EvaluationResultImpl lessThanOrEqual(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanOrEqualError(node, this);
  EvaluationResultImpl logicalAnd(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalAndError(node, this);
  EvaluationResultImpl logicalNot(Expression node) => this;
  EvaluationResultImpl logicalOr(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalOrError(node, this);
  EvaluationResultImpl minus(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.minusError(node, this);
  EvaluationResultImpl negated(Expression node) => this;
  EvaluationResultImpl notEqual(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.notEqualError(node, this);
  EvaluationResultImpl performToString(ASTNode node) => this;
  EvaluationResultImpl remainder(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.remainderError(node, this);
  EvaluationResultImpl shiftLeft(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.shiftLeftError(node, this);
  EvaluationResultImpl shiftRight(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.shiftRightError(node, this);
  EvaluationResultImpl times(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.timesError(node, this);
  EvaluationResultImpl addToError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
  EvaluationResultImpl addToValid(BinaryExpression node, ValidResult leftOperand) => this;
  EvaluationResultImpl bitAndError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
  EvaluationResultImpl bitAndValid(BinaryExpression node, ValidResult leftOperand) => this;
  EvaluationResultImpl bitOrError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
  EvaluationResultImpl bitOrValid(BinaryExpression node, ValidResult leftOperand) => this;
  EvaluationResultImpl bitXorError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
  EvaluationResultImpl bitXorValid(BinaryExpression node, ValidResult leftOperand) => this;
  EvaluationResultImpl concatenateError(Expression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
  EvaluationResultImpl concatenateValid(Expression node, ValidResult leftOperand) => this;
  EvaluationResultImpl divideError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
  EvaluationResultImpl divideValid(BinaryExpression node, ValidResult leftOperand) => this;
  EvaluationResultImpl equalEqualError(Expression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
  EvaluationResultImpl equalEqualValid(Expression node, ValidResult leftOperand) => this;
  EvaluationResultImpl greaterThanError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
  EvaluationResultImpl greaterThanOrEqualError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
  EvaluationResultImpl greaterThanOrEqualValid(BinaryExpression node, ValidResult leftOperand) => this;
  EvaluationResultImpl greaterThanValid(BinaryExpression node, ValidResult leftOperand) => this;
  EvaluationResultImpl integerDivideError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
  EvaluationResultImpl lessThanError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
  EvaluationResultImpl lessThanOrEqualError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
  EvaluationResultImpl lessThanOrEqualValid(BinaryExpression node, ValidResult leftOperand) => this;
  EvaluationResultImpl lessThanValid(BinaryExpression node, ValidResult leftOperand) => this;
  EvaluationResultImpl logicalAndError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
  EvaluationResultImpl logicalAndValid(BinaryExpression node, ValidResult leftOperand) => this;
  EvaluationResultImpl logicalOrError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
  EvaluationResultImpl logicalOrValid(BinaryExpression node, ValidResult leftOperand) => this;
  EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
  EvaluationResultImpl minusValid(BinaryExpression node, ValidResult leftOperand) => this;
  EvaluationResultImpl notEqualError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
  EvaluationResultImpl notEqualValid(BinaryExpression node, ValidResult leftOperand) => this;
  EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
  EvaluationResultImpl remainderValid(BinaryExpression node, ValidResult leftOperand) => this;
  EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
  EvaluationResultImpl shiftLeftValid(BinaryExpression node, ValidResult leftOperand) => this;
  EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
  EvaluationResultImpl shiftRightValid(BinaryExpression node, ValidResult leftOperand) => this;
  EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
  EvaluationResultImpl timesValid(BinaryExpression node, ValidResult leftOperand) => this;
}
class ErrorResult_ErrorData {

  /**
   * The node against which the error should be reported.
   */
  ASTNode node;

  /**
   * The error code for the error to be generated.
   */
  ErrorCode errorCode;

  /**
   * Initialize a newly created data holder to represent the error with the given code reported
   * against the given node.
   *
   * @param node the node against which the error should be reported
   * @param errorCode the error code for the error to be generated
   */
  ErrorResult_ErrorData(ASTNode node, ErrorCode errorCode) {
    this.node = node;
    this.errorCode = errorCode;
  }
}
/**
 * Instances of the class `InternalResult` represent the result of attempting to evaluate a
 * expression.
 */
abstract class EvaluationResultImpl {
  EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOperand);

  /**
   * Return the result of applying boolean conversion to this result.
   *
   * @param node the node against which errors should be reported
   * @return the result of applying boolean conversion to the given value
   */
  EvaluationResultImpl applyBooleanConversion(ASTNode node);
  EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightOperand);
  EvaluationResultImpl bitNot(Expression node);
  EvaluationResultImpl bitOr(BinaryExpression node, EvaluationResultImpl rightOperand);
  EvaluationResultImpl bitXor(BinaryExpression node, EvaluationResultImpl rightOperand);
  EvaluationResultImpl concatenate(Expression node, EvaluationResultImpl rightOperand);
  EvaluationResultImpl divide(BinaryExpression node, EvaluationResultImpl rightOperand);
  EvaluationResultImpl equalEqual(Expression node, EvaluationResultImpl rightOperand);
  bool equalValues(EvaluationResultImpl result);
  EvaluationResultImpl greaterThan(BinaryExpression node, EvaluationResultImpl rightOperand);
  EvaluationResultImpl greaterThanOrEqual(BinaryExpression node, EvaluationResultImpl rightOperand);
  EvaluationResultImpl integerDivide(BinaryExpression node, EvaluationResultImpl rightOperand);
  EvaluationResultImpl lessThan(BinaryExpression node, EvaluationResultImpl rightOperand);
  EvaluationResultImpl lessThanOrEqual(BinaryExpression node, EvaluationResultImpl rightOperand);
  EvaluationResultImpl logicalAnd(BinaryExpression node, EvaluationResultImpl rightOperand);
  EvaluationResultImpl logicalNot(Expression node);
  EvaluationResultImpl logicalOr(BinaryExpression node, EvaluationResultImpl rightOperand);
  EvaluationResultImpl minus(BinaryExpression node, EvaluationResultImpl rightOperand);
  EvaluationResultImpl negated(Expression node);
  EvaluationResultImpl notEqual(BinaryExpression node, EvaluationResultImpl rightOperand);
  EvaluationResultImpl performToString(ASTNode node);
  EvaluationResultImpl remainder(BinaryExpression node, EvaluationResultImpl rightOperand);
  EvaluationResultImpl shiftLeft(BinaryExpression node, EvaluationResultImpl rightOperand);
  EvaluationResultImpl shiftRight(BinaryExpression node, EvaluationResultImpl rightOperand);
  EvaluationResultImpl times(BinaryExpression node, EvaluationResultImpl rightOperand);
  EvaluationResultImpl addToError(BinaryExpression node, ErrorResult leftOperand);
  EvaluationResultImpl addToValid(BinaryExpression node, ValidResult leftOperand);
  EvaluationResultImpl bitAndError(BinaryExpression node, ErrorResult leftOperand);
  EvaluationResultImpl bitAndValid(BinaryExpression node, ValidResult leftOperand);
  EvaluationResultImpl bitOrError(BinaryExpression node, ErrorResult leftOperand);
  EvaluationResultImpl bitOrValid(BinaryExpression node, ValidResult leftOperand);
  EvaluationResultImpl bitXorError(BinaryExpression node, ErrorResult leftOperand);
  EvaluationResultImpl bitXorValid(BinaryExpression node, ValidResult leftOperand);
  EvaluationResultImpl concatenateError(Expression node, ErrorResult leftOperand);
  EvaluationResultImpl concatenateValid(Expression node, ValidResult leftOperand);
  EvaluationResultImpl divideError(BinaryExpression node, ErrorResult leftOperand);
  EvaluationResultImpl divideValid(BinaryExpression node, ValidResult leftOperand);
  EvaluationResultImpl equalEqualError(Expression node, ErrorResult leftOperand);
  EvaluationResultImpl equalEqualValid(Expression node, ValidResult leftOperand);
  EvaluationResultImpl greaterThanError(BinaryExpression node, ErrorResult leftOperand);
  EvaluationResultImpl greaterThanOrEqualError(BinaryExpression node, ErrorResult leftOperand);
  EvaluationResultImpl greaterThanOrEqualValid(BinaryExpression node, ValidResult leftOperand);
  EvaluationResultImpl greaterThanValid(BinaryExpression node, ValidResult leftOperand);
  EvaluationResultImpl integerDivideError(BinaryExpression node, ErrorResult leftOperand);
  EvaluationResultImpl integerDivideValid(BinaryExpression node, ValidResult leftOperand);
  EvaluationResultImpl lessThanError(BinaryExpression node, ErrorResult leftOperand);
  EvaluationResultImpl lessThanOrEqualError(BinaryExpression node, ErrorResult leftOperand);
  EvaluationResultImpl lessThanOrEqualValid(BinaryExpression node, ValidResult leftOperand);
  EvaluationResultImpl lessThanValid(BinaryExpression node, ValidResult leftOperand);
  EvaluationResultImpl logicalAndError(BinaryExpression node, ErrorResult leftOperand);
  EvaluationResultImpl logicalAndValid(BinaryExpression node, ValidResult leftOperand);
  EvaluationResultImpl logicalOrError(BinaryExpression node, ErrorResult leftOperand);
  EvaluationResultImpl logicalOrValid(BinaryExpression node, ValidResult leftOperand);
  EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand);
  EvaluationResultImpl minusValid(BinaryExpression node, ValidResult leftOperand);
  EvaluationResultImpl notEqualError(BinaryExpression node, ErrorResult leftOperand);
  EvaluationResultImpl notEqualValid(BinaryExpression node, ValidResult leftOperand);
  EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOperand);
  EvaluationResultImpl remainderValid(BinaryExpression node, ValidResult leftOperand);
  EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOperand);
  EvaluationResultImpl shiftLeftValid(BinaryExpression node, ValidResult leftOperand);
  EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOperand);
  EvaluationResultImpl shiftRightValid(BinaryExpression node, ValidResult leftOperand);
  EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand);
  EvaluationResultImpl timesValid(BinaryExpression node, ValidResult leftOperand);
}
/**
 * Instances of the class `ReferenceFinder` add reference information for a given variable to
 * the bi-directional mapping used to order the evaluation of constants.
 */
class ReferenceFinder extends RecursiveASTVisitor<Object> {

  /**
   * The element representing the variable whose initializer will be visited.
   */
  VariableElement _source;

  /**
   * A graph in which the nodes are the constant variables and the edges are from each variable to
   * the other constant variables that are referenced in the head's initializer.
   */
  DirectedGraph<VariableElement> _referenceGraph;

  /**
   * Initialize a newly created reference finder to find references from the given variable to other
   * variables and to add those references to the given graph.
   *
   * @param source the element representing the variable whose initializer will be visited
   * @param referenceGraph a graph recording which variables (heads) reference which other variables
   *          (tails) in their initializers
   */
  ReferenceFinder(VariableElement source, DirectedGraph<VariableElement> referenceGraph) {
    this._source = source;
    this._referenceGraph = referenceGraph;
  }
  Object visitSimpleIdentifier(SimpleIdentifier node) {
    Element element = node.staticElement;
    if (element is PropertyAccessorElement) {
      element = ((element as PropertyAccessorElement)).variable;
    }
    if (element is VariableElement) {
      VariableElement variable = element as VariableElement;
      if (variable.isConst) {
        _referenceGraph.addEdge(_source, variable);
      }
    }
    return null;
  }
}
/**
 * Instances of the class `ValidResult` represent the result of attempting to evaluate a valid
 * compile time constant expression.
 */
class ValidResult extends EvaluationResultImpl {

  /**
   * A result object representing the value 'false'.
   */
  static ValidResult RESULT_FALSE = new ValidResult(false);

  /**
   * A result object representing the an object without specific type on which no further operations
   * can be performed.
   */
  static ValidResult RESULT_DYNAMIC = new ValidResult(null);

  /**
   * A result object representing the an arbitrary integer on which no further operations can be
   * performed.
   */
  static ValidResult RESULT_INT = new ValidResult(null);

  /**
   * A result object representing the `null` value.
   */
  static ValidResult RESULT_NULL = new ValidResult(null);

  /**
   * A result object representing the an arbitrary numeric on which no further operations can be
   * performed.
   */
  static ValidResult RESULT_NUM = new ValidResult(null);

  /**
   * A result object representing the an arbitrary boolean on which no further operations can be
   * performed.
   */
  static ValidResult RESULT_BOOL = new ValidResult(null);

  /**
   * A result object representing the an arbitrary object on which no further operations can be
   * performed.
   */
  static ValidResult RESULT_OBJECT = new ValidResult(new Object());

  /**
   * A result object representing the an arbitrary string on which no further operations can be
   * performed.
   */
  static ValidResult RESULT_STRING = new ValidResult("<string>");

  /**
   * A result object representing the value 'true'.
   */
  static ValidResult RESULT_TRUE = new ValidResult(true);

  /**
   * The value of the expression.
   */
  Object value;

  /**
   * Initialize a newly created result to represent the given value.
   *
   * @param value the value of the expression
   */
  ValidResult(Object value) {
    this.value = value;
  }
  EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.addToValid(node, this);

  /**
   * Return the result of applying boolean conversion to this result.
   *
   * @param node the node against which errors should be reported
   * @return the result of applying boolean conversion to the given value
   */
  EvaluationResultImpl applyBooleanConversion(ASTNode node) => booleanConversion(node, value);
  EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitAndValid(node, this);
  EvaluationResultImpl bitNot(Expression node) {
    if (isSomeInt) {
      return RESULT_INT;
    }
    if (value == null) {
      return error(node);
    } else if (value is int) {
      return valueOf(~((value as int)));
    }
    return error(node);
  }
  EvaluationResultImpl bitOr(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitOrValid(node, this);
  EvaluationResultImpl bitXor(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitXorValid(node, this);
  EvaluationResultImpl concatenate(Expression node, EvaluationResultImpl rightOperand) => rightOperand.concatenateValid(node, this);
  EvaluationResultImpl divide(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.divideValid(node, this);
  EvaluationResultImpl equalEqual(Expression node, EvaluationResultImpl rightOperand) => rightOperand.equalEqualValid(node, this);
  bool equalValues(EvaluationResultImpl result) => identical(equalEqual(null, result), RESULT_TRUE);
  EvaluationResultImpl greaterThan(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanValid(node, this);
  EvaluationResultImpl greaterThanOrEqual(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanOrEqualValid(node, this);
  EvaluationResultImpl integerDivide(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.integerDivideValid(node, this);
  EvaluationResultImpl lessThan(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanValid(node, this);
  EvaluationResultImpl lessThanOrEqual(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanOrEqualValid(node, this);
  EvaluationResultImpl logicalAnd(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalAndValid(node, this);
  EvaluationResultImpl logicalNot(Expression node) {
    if (isSomeBool) {
      return RESULT_BOOL;
    }
    if (value == null) {
      return RESULT_TRUE;
    } else if (value is bool) {
      return ((value as bool)) ? RESULT_FALSE : RESULT_TRUE;
    }
    return error(node);
  }
  EvaluationResultImpl logicalOr(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalOrValid(node, this);
  EvaluationResultImpl minus(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.minusValid(node, this);
  EvaluationResultImpl negated(Expression node) {
    if (isSomeNum) {
      return RESULT_INT;
    }
    if (value == null) {
      return error(node);
    } else if (value is int) {
      return valueOf(-((value as int)));
    } else if (value is double) {
      return valueOf3(-((value as double)));
    }
    return error(node);
  }
  EvaluationResultImpl notEqual(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.notEqualValid(node, this);
  EvaluationResultImpl performToString(ASTNode node) {
    if (value == null) {
      return valueOf4("null");
    } else if (value is bool) {
      return valueOf4(((value as bool)).toString());
    } else if (value is int) {
      return valueOf4(((value as int)).toString());
    } else if (value is double) {
      return valueOf4(((value as double)).toString());
    } else if (value is String) {
      return this;
    }
    return error(node);
  }
  EvaluationResultImpl remainder(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.remainderValid(node, this);
  EvaluationResultImpl shiftLeft(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.shiftLeftValid(node, this);
  EvaluationResultImpl shiftRight(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.shiftRightValid(node, this);
  EvaluationResultImpl times(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.timesValid(node, this);
  String toString() {
    if (value == null) {
      return "null";
    }
    return value.toString();
  }
  EvaluationResultImpl addToError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
  EvaluationResultImpl addToValid(BinaryExpression node, ValidResult leftOperand) {
    if (!isAnyNum || !leftOperand.isAnyNum) {
      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
    }
    if (isSomeInt || leftOperand.isSomeInt) {
      return RESULT_INT;
    } else if (isSomeNum || leftOperand.isSomeNum) {
      return RESULT_NUM;
    }
    Object leftValue = leftOperand.value;
    if (leftValue == null) {
      return error(node.leftOperand);
    } else if (value == null) {
      return error(node.rightOperand);
    } else if (leftValue is int) {
      if (value is int) {
        return valueOf(((leftValue as int)) + (value as int));
      } else if (value is double) {
        return valueOf3(((leftValue as int)).toDouble() + ((value as double)));
      }
    } else if (leftValue is double) {
      if (value is int) {
        return valueOf3(((leftValue as double)) + ((value as int)).toDouble());
      } else if (value is double) {
        return valueOf3(((leftValue as double)) + ((value as double)));
      }
    } else if (leftValue is String) {
      if (value is String) {
        return valueOf4("${((leftValue as String))}${((value as String))}");
      }
    }
    return error(node);
  }
  EvaluationResultImpl bitAndError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
  EvaluationResultImpl bitAndValid(BinaryExpression node, ValidResult leftOperand) {
    if (!isAnyInt || !leftOperand.isAnyInt) {
      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
    }
    if (isSomeInt || leftOperand.isSomeInt) {
      return RESULT_INT;
    }
    Object leftValue = leftOperand.value;
    if (leftValue == null) {
      return error(node.leftOperand);
    } else if (value == null) {
      return error(node.rightOperand);
    } else if (leftValue is int) {
      if (value is int) {
        return valueOf(((leftValue as int)) & (value as int));
      }
      return error(node.leftOperand);
    }
    if (value is int) {
      return error(node.rightOperand);
    }
    return union(error(node.leftOperand), error(node.rightOperand));
  }
  EvaluationResultImpl bitOrError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
  EvaluationResultImpl bitOrValid(BinaryExpression node, ValidResult leftOperand) {
    if (!isAnyInt || !leftOperand.isAnyInt) {
      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
    }
    if (isSomeInt || leftOperand.isSomeInt) {
      return RESULT_INT;
    }
    Object leftValue = leftOperand.value;
    if (leftValue == null) {
      return error(node.leftOperand);
    } else if (value == null) {
      return error(node.rightOperand);
    } else if (leftValue is int) {
      if (value is int) {
        return valueOf(((leftValue as int)) | (value as int));
      }
      return error(node.leftOperand);
    }
    if (value is int) {
      return error(node.rightOperand);
    }
    return union(error(node.leftOperand), error(node.rightOperand));
  }
  EvaluationResultImpl bitXorError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
  EvaluationResultImpl bitXorValid(BinaryExpression node, ValidResult leftOperand) {
    if (!isAnyInt || !leftOperand.isAnyInt) {
      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
    }
    if (isSomeInt || leftOperand.isSomeInt) {
      return RESULT_INT;
    }
    Object leftValue = leftOperand.value;
    if (leftValue == null) {
      return error(node.leftOperand);
    } else if (value == null) {
      return error(node.rightOperand);
    } else if (leftValue is int) {
      if (value is int) {
        return valueOf(((leftValue as int)) ^ (value as int));
      }
      return error(node.leftOperand);
    }
    if (value is int) {
      return error(node.rightOperand);
    }
    return union(error(node.leftOperand), error(node.rightOperand));
  }
  EvaluationResultImpl concatenateError(Expression node, ErrorResult leftOperand) => leftOperand;
  EvaluationResultImpl concatenateValid(Expression node, ValidResult leftOperand) {
    Object leftValue = leftOperand.value;
    if (leftValue is String && value is String) {
      return valueOf4("${((leftValue as String))}${((value as String))}");
    }
    return error(node);
  }
  EvaluationResultImpl divideError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
  EvaluationResultImpl divideValid(BinaryExpression node, ValidResult leftOperand) {
    if (!isAnyNum || !leftOperand.isAnyNum) {
      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
    }
    if (isSomeNum || leftOperand.isSomeNum) {
      return RESULT_NUM;
    }
    Object leftValue = leftOperand.value;
    if (leftValue == null) {
      return error(node.leftOperand);
    } else if (value == null) {
      return error(node.rightOperand);
    } else if (leftValue is int) {
      if (value is int) {
        if (((value as int)) == 0) {
          return valueOf3(((leftValue as int)).toDouble() / ((value as int)).toDouble());
        }
        return valueOf(((leftValue as int)) ~/ (value as int));
      } else if (value is double) {
        return valueOf3(((leftValue as int)).toDouble() / ((value as double)));
      }
    } else if (leftValue is double) {
      if (value is int) {
        return valueOf3(((leftValue as double)) / ((value as int)).toDouble());
      } else if (value is double) {
        return valueOf3(((leftValue as double)) / ((value as double)));
      }
    }
    return error(node);
  }
  EvaluationResultImpl equalEqualError(Expression node, ErrorResult leftOperand) => leftOperand;
  EvaluationResultImpl equalEqualValid(Expression node, ValidResult leftOperand) {
    if (node is BinaryExpression) {
      if (!isAnyNullBoolNumString || !leftOperand.isAnyNullBoolNumString) {
        return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING);
      }
    }
    Object leftValue = leftOperand.value;
    if (leftValue == null) {
      return valueOf2(value == null);
    } else if (leftValue is bool) {
      if (value is bool) {
        return valueOf2(identical(leftValue as bool, value as bool));
      }
      return RESULT_FALSE;
    } else if (leftValue is int) {
      if (value is int) {
        return valueOf2(((leftValue as int)) == value);
      } else if (value is double) {
        return valueOf2(toDouble(leftValue as int) == value);
      }
      return RESULT_FALSE;
    } else if (leftValue is double) {
      if (value is int) {
        return valueOf2(((leftValue as double)) == toDouble(value as int));
      } else if (value is double) {
        return valueOf2(((leftValue as double)) == value);
      }
      return RESULT_FALSE;
    } else if (leftValue is String) {
      if (value is String) {
        return valueOf2(((leftValue as String)) == value);
      }
      return RESULT_FALSE;
    }
    return RESULT_FALSE;
  }
  EvaluationResultImpl greaterThanError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
  EvaluationResultImpl greaterThanOrEqualError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
  EvaluationResultImpl greaterThanOrEqualValid(BinaryExpression node, ValidResult leftOperand) {
    if (!isAnyNum || !leftOperand.isAnyNum) {
      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
    }
    if (isSomeNum || leftOperand.isSomeNum) {
      return RESULT_BOOL;
    }
    Object leftValue = leftOperand.value;
    if (leftValue == null) {
      return error(node.leftOperand);
    } else if (value == null) {
      return error(node.rightOperand);
    } else if (leftValue is int) {
      if (value is int) {
        return valueOf2(((leftValue as int)).compareTo(value as int) >= 0);
      } else if (value is double) {
        return valueOf2(((leftValue as int)).toDouble() >= ((value as double)));
      }
    } else if (leftValue is double) {
      if (value is int) {
        return valueOf2(((leftValue as double)) >= ((value as int)).toDouble());
      } else if (value is double) {
        return valueOf2(((leftValue as double)) >= ((value as double)));
      }
    }
    return error(node);
  }
  EvaluationResultImpl greaterThanValid(BinaryExpression node, ValidResult leftOperand) {
    if (!isAnyNum || !leftOperand.isAnyNum) {
      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
    }
    if (isSomeNum || leftOperand.isSomeNum) {
      return RESULT_BOOL;
    }
    Object leftValue = leftOperand.value;
    if (leftValue == null) {
      return error(node.leftOperand);
    } else if (value == null) {
      return error(node.rightOperand);
    } else if (leftValue is int) {
      if (value is int) {
        return valueOf2(((leftValue as int)).compareTo(value as int) > 0);
      } else if (value is double) {
        return valueOf2(((leftValue as int)).toDouble() > ((value as double)));
      }
    } else if (leftValue is double) {
      if (value is int) {
        return valueOf2(((leftValue as double)) > ((value as int)).toDouble());
      } else if (value is double) {
        return valueOf2(((leftValue as double)) > ((value as double)));
      }
    }
    return error(node);
  }
  EvaluationResultImpl integerDivideError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
  EvaluationResultImpl integerDivideValid(BinaryExpression node, ValidResult leftOperand) {
    if (!isAnyNum || !leftOperand.isAnyNum) {
      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
    }
    if (isSomeNum || leftOperand.isSomeNum) {
      return RESULT_INT;
    }
    Object leftValue = leftOperand.value;
    if (leftValue == null) {
      return error(node.leftOperand);
    } else if (value == null) {
      return error(node.rightOperand);
    } else if (leftValue is int) {
      if (value is int) {
        if (((value as int)) == 0) {
          return error2(node, CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE);
        }
        return valueOf(((leftValue as int)) ~/ (value as int));
      } else if (value is double) {
        double result = ((leftValue as int)).toDouble() / ((value as double));
        return valueOf(result.toInt());
      }
    } else if (leftValue is double) {
      if (value is int) {
        double result = ((leftValue as double)) / ((value as int)).toDouble();
        return valueOf(result.toInt());
      } else if (value is double) {
        double result = ((leftValue as double)) / ((value as double));
        return valueOf(result.toInt());
      }
    }
    return error(node);
  }
  EvaluationResultImpl lessThanError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
  EvaluationResultImpl lessThanOrEqualError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
  EvaluationResultImpl lessThanOrEqualValid(BinaryExpression node, ValidResult leftOperand) {
    if (!isAnyNum || !leftOperand.isAnyNum) {
      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
    }
    if (isSomeNum || leftOperand.isSomeNum) {
      return RESULT_BOOL;
    }
    Object leftValue = leftOperand.value;
    if (leftValue == null) {
      return error(node.leftOperand);
    } else if (value == null) {
      return error(node.rightOperand);
    } else if (leftValue is int) {
      if (value is int) {
        return valueOf2(((leftValue as int)).compareTo(value as int) <= 0);
      } else if (value is double) {
        return valueOf2(((leftValue as int)).toDouble() <= ((value as double)));
      }
    } else if (leftValue is double) {
      if (value is int) {
        return valueOf2(((leftValue as double)) <= ((value as int)).toDouble());
      } else if (value is double) {
        return valueOf2(((leftValue as double)) <= ((value as double)));
      }
    }
    return error(node);
  }
  EvaluationResultImpl lessThanValid(BinaryExpression node, ValidResult leftOperand) {
    if (!isAnyNum || !leftOperand.isAnyNum) {
      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
    }
    if (isSomeNum || leftOperand.isSomeNum) {
      return RESULT_BOOL;
    }
    Object leftValue = leftOperand.value;
    if (leftValue == null) {
      return error(node.leftOperand);
    } else if (value == null) {
      return error(node.rightOperand);
    } else if (leftValue is int) {
      if (value is int) {
        return valueOf2(((leftValue as int)).compareTo(value as int) < 0);
      } else if (value is double) {
        return valueOf2(((leftValue as int)).toDouble() < ((value as double)));
      }
    } else if (leftValue is double) {
      if (value is int) {
        return valueOf2(((leftValue as double)) < ((value as int)).toDouble());
      } else if (value is double) {
        return valueOf2(((leftValue as double)) < ((value as double)));
      }
    }
    return error(node);
  }
  EvaluationResultImpl logicalAndError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
  EvaluationResultImpl logicalAndValid(BinaryExpression node, ValidResult leftOperand) {
    if (!isAnyBool || !leftOperand.isAnyBool) {
      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL);
    }
    if (isSomeBool || leftOperand.isSomeBool) {
      return RESULT_BOOL;
    }
    Object leftValue = leftOperand.value;
    if (leftValue is bool) {
      if (((leftValue as bool))) {
        return booleanConversion(node.rightOperand, value);
      }
      return RESULT_FALSE;
    }
    return error(node);
  }
  EvaluationResultImpl logicalOrError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
  EvaluationResultImpl logicalOrValid(BinaryExpression node, ValidResult leftOperand) {
    if (!isAnyBool || !leftOperand.isAnyBool) {
      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL);
    }
    if (isSomeBool || leftOperand.isSomeBool) {
      return RESULT_BOOL;
    }
    Object leftValue = leftOperand.value;
    if (leftValue is bool && ((leftValue as bool))) {
      return RESULT_TRUE;
    }
    return booleanConversion(node.rightOperand, value);
  }
  EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
  EvaluationResultImpl minusValid(BinaryExpression node, ValidResult leftOperand) {
    if (!isAnyNum || !leftOperand.isAnyNum) {
      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
    }
    if (isSomeInt || leftOperand.isSomeInt) {
      return RESULT_INT;
    } else if (isSomeNum || leftOperand.isSomeNum) {
      return RESULT_NUM;
    }
    Object leftValue = leftOperand.value;
    if (leftValue == null) {
      return error(node.leftOperand);
    } else if (value == null) {
      return error(node.rightOperand);
    } else if (leftValue is int) {
      if (value is int) {
        return valueOf(((leftValue as int)) - (value as int));
      } else if (value is double) {
        return valueOf3(((leftValue as int)).toDouble() - ((value as double)));
      }
    } else if (leftValue is double) {
      if (value is int) {
        return valueOf3(((leftValue as double)) - ((value as int)).toDouble());
      } else if (value is double) {
        return valueOf3(((leftValue as double)) - ((value as double)));
      }
    }
    return error(node);
  }
  EvaluationResultImpl notEqualError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
  EvaluationResultImpl notEqualValid(BinaryExpression node, ValidResult leftOperand) {
    if (!isAnyNullBoolNumString || !leftOperand.isAnyNullBoolNumString) {
      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING);
    }
    Object leftValue = leftOperand.value;
    if (leftValue == null) {
      return valueOf2(value != null);
    } else if (leftValue is bool) {
      if (value is bool) {
        return valueOf2(((leftValue as bool)) != ((value as bool)));
      }
      return RESULT_TRUE;
    } else if (leftValue is int) {
      if (value is int) {
        return valueOf2(((leftValue as int)) != value);
      } else if (value is double) {
        return valueOf2(toDouble(leftValue as int) != value);
      }
      return RESULT_TRUE;
    } else if (leftValue is double) {
      if (value is int) {
        return valueOf2(((leftValue as double)) != toDouble(value as int));
      } else if (value is double) {
        return valueOf2(((leftValue as double)) != value);
      }
      return RESULT_TRUE;
    } else if (leftValue is String) {
      if (value is String) {
        return valueOf2(((leftValue as String)) != value);
      }
      return RESULT_TRUE;
    }
    return RESULT_TRUE;
  }
  EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
  EvaluationResultImpl remainderValid(BinaryExpression node, ValidResult leftOperand) {
    if (!isAnyNum || !leftOperand.isAnyNum) {
      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
    }
    if (isSomeInt || leftOperand.isSomeInt) {
      return RESULT_INT;
    } else if (isSomeNum || leftOperand.isSomeNum) {
      return RESULT_NUM;
    }
    Object leftValue = leftOperand.value;
    if (leftValue == null) {
      return error(node.leftOperand);
    } else if (value == null) {
      return error(node.rightOperand);
    } else if (leftValue is int) {
      if (value is int) {
        if (((value as int)) == 0) {
          return valueOf3(((leftValue as int)).toDouble() % ((value as int)).toDouble());
        }
        return valueOf(((leftValue as int)).remainder(value as int));
      } else if (value is double) {
        return valueOf3(((leftValue as int)).toDouble() % ((value as double)));
      }
    } else if (leftValue is double) {
      if (value is int) {
        return valueOf3(((leftValue as double)) % ((value as int)).toDouble());
      } else if (value is double) {
        return valueOf3(((leftValue as double)) % ((value as double)));
      }
    }
    return error(node);
  }
  EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
  EvaluationResultImpl shiftLeftValid(BinaryExpression node, ValidResult leftOperand) {
    if (!isAnyInt || !leftOperand.isAnyInt) {
      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
    }
    if (isSomeInt || leftOperand.isSomeInt) {
      return RESULT_INT;
    }
    Object leftValue = leftOperand.value;
    if (leftValue == null) {
      return error(node.leftOperand);
    } else if (value == null) {
      return error(node.rightOperand);
    } else if (leftValue is int) {
      if (value is int) {
        return valueOf(((leftValue as int)) << ((value as int)));
      }
      return error(node.rightOperand);
    }
    if (value is int) {
      return error(node.leftOperand);
    }
    return union(error(node.leftOperand), error(node.rightOperand));
  }
  EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
  EvaluationResultImpl shiftRightValid(BinaryExpression node, ValidResult leftOperand) {
    if (!isAnyInt || !leftOperand.isAnyInt) {
      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
    }
    if (isSomeInt || leftOperand.isSomeInt) {
      return RESULT_INT;
    }
    Object leftValue = leftOperand.value;
    if (leftValue == null) {
      return error(node.leftOperand);
    } else if (value == null) {
      return error(node.rightOperand);
    } else if (leftValue is int) {
      if (value is int) {
        return valueOf(((leftValue as int)) >> ((value as int)));
      }
      return error(node.rightOperand);
    }
    if (value is int) {
      return error(node.leftOperand);
    }
    return union(error(node.leftOperand), error(node.rightOperand));
  }
  EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
  EvaluationResultImpl timesValid(BinaryExpression node, ValidResult leftOperand) {
    if (!isAnyNum || !leftOperand.isAnyNum) {
      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
    }
    if (isSomeInt || leftOperand.isSomeInt) {
      return RESULT_INT;
    } else if (isSomeNum || leftOperand.isSomeNum) {
      return RESULT_NUM;
    }
    Object leftValue = leftOperand.value;
    if (leftValue == null) {
      return error(node.leftOperand);
    } else if (value == null) {
      return error(node.rightOperand);
    } else if (leftValue is int) {
      if (value is int) {
        return valueOf(((leftValue as int)) * (value as int));
      } else if (value is double) {
        return valueOf3(((leftValue as int)).toDouble() * ((value as double)));
      }
    } else if (leftValue is double) {
      if (value is int) {
        return valueOf3(((leftValue as double)) * ((value as int)).toDouble());
      } else if (value is double) {
        return valueOf3(((leftValue as double)) * ((value as double)));
      }
    }
    return error(node);
  }
  bool get isNull => identical(this, RESULT_NULL);

  /**
   * Return the result of applying boolean conversion to the given value.
   *
   * @param node the node against which errors should be reported
   * @param value the value to be converted to a boolean
   * @return the result of applying boolean conversion to the given value
   */
  EvaluationResultImpl booleanConversion(ASTNode node, Object value) {
    if (value is bool) {
      if (((value as bool))) {
        return RESULT_TRUE;
      } else {
        return RESULT_FALSE;
      }
    }
    return error(node);
  }
  ErrorResult error(ASTNode node) => error2(node, CompileTimeErrorCode.INVALID_CONSTANT);

  /**
   * Return a result object representing an error associated with the given node.
   *
   * @param node the AST node associated with the error
   * @param code the error code indicating the nature of the error
   * @return a result object representing an error associated with the given node
   */
  ErrorResult error2(ASTNode node, ErrorCode code) => new ErrorResult.con1(node, code);

  /**
   * Checks if this result has type "bool", with known or unknown value.
   */
  bool get isAnyBool => isSomeBool || identical(this, RESULT_TRUE) || identical(this, RESULT_FALSE);

  /**
   * Checks if this result has type "int", with known or unknown value.
   */
  bool get isAnyInt => identical(this, RESULT_INT) || value is int;

  /**
   * Checks if this result has one of the types - "bool", "num" or "string"; or may be `null`.
   */
  bool get isAnyNullBoolNumString => isNull || isAnyBool || isAnyNum || value is String;

  /**
   * Checks if this result has type "num", with known or unknown value.
   */
  bool get isAnyNum => isSomeNum || value is num;

  /**
   * Checks if this result has type "bool", exact value of which we don't know.
   */
  bool get isSomeBool => identical(this, RESULT_BOOL);

  /**
   * Checks if this result has type "int", exact value of which we don't know.
   */
  bool get isSomeInt => identical(this, RESULT_INT);

  /**
   * Checks if this result has type "num" (or "int"), exact value of which we don't know.
   */
  bool get isSomeNum => identical(this, RESULT_DYNAMIC) || identical(this, RESULT_INT) || identical(this, RESULT_NUM);
  double toDouble(int value) => value.toDouble();

  /**
   * Return an error result that is the union of the two given error results.
   *
   * @param firstError the first error to be combined
   * @param secondError the second error to be combined
   * @return an error result that is the union of the two given error results
   */
  ErrorResult union(ErrorResult firstError, ErrorResult secondError) => new ErrorResult.con2(firstError, secondError);

  /**
   * Return a result object representing the given value.
   *
   * @param value the value to be represented as a result object
   * @return a result object representing the given value
   */
  ValidResult valueOf(int value) => new ValidResult(value);

  /**
   * Return a result object representing the given value.
   *
   * @param value the value to be represented as a result object
   * @return a result object representing the given value
   */
  ValidResult valueOf2(bool value) => value ? RESULT_TRUE : RESULT_FALSE;

  /**
   * Return a result object representing the given value.
   *
   * @param value the value to be represented as a result object
   * @return a result object representing the given value
   */
  ValidResult valueOf3(double value) => new ValidResult(value);

  /**
   * Return a result object representing the given value.
   *
   * @param value the value to be represented as a result object
   * @return a result object representing the given value
   */
  ValidResult valueOf4(String value) => new ValidResult(value);
}