Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(116)

Unified Diff: pkg/analyzer/lib/src/generated/constant.dart

Issue 123763002: New analyzer snapshot. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/analyzer/lib/src/generated/constant.dart
diff --git a/pkg/analyzer/lib/src/generated/constant.dart b/pkg/analyzer/lib/src/generated/constant.dart
index 8fe9e12bb1e3814710710d820cc3c9b665b54448..43bc247d6ee9e4305db9bc6a3da1cab55a7c38a9 100644
--- a/pkg/analyzer/lib/src/generated/constant.dart
+++ b/pkg/analyzer/lib/src/generated/constant.dart
@@ -4,12 +4,15 @@
library engine.constant;
import 'java_core.dart';
+import 'java_engine.dart' show ObjectUtilities;
import 'source.dart' show Source;
import 'error.dart' show AnalysisError, ErrorCode, CompileTimeErrorCode;
-import 'scanner.dart' show TokenType;
+import 'scanner.dart' show Token, TokenType;
import 'ast.dart';
import 'element.dart';
+import 'resolver.dart' show TypeProvider;
import 'engine.dart' show AnalysisEngine;
+import 'utilities_dart.dart' show ParameterKind;
/**
* Instances of the class `ConstantEvaluator` evaluate constant expressions to produce their
@@ -19,36 +22,42 @@ import 'engine.dart' show AnalysisEngine;
* * 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.
+ * to a numeric, string or boolean value or to <b>null</b>.
+ * * A literal symbol.
+ * * <b>null</b>.
+ * * A qualified reference to a static constant variable.
+ * * An identifier expression that denotes a constant variable, class or type alias.
* * 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`.
+ * * A parenthesized expression <i>(e)</i> where <i>e</i> is a constant expression.
+ * * An expression of the form <i>identical(e<sub>1</sub>, e<sub>2</sub>)</i> where
+ * <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant expressions and <i>identical()</i> is
+ * statically bound to the predefined dart function <i>identical()</i> discussed above.
+ * * An expression of one of the forms <i>e<sub>1</sub> == e<sub>2</sub></i> or <i>e<sub>1</sub>
+ * != e<sub>2</sub></i> where <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant expressions
+ * that evaluate to a numeric, string or boolean value.
+ * * An expression of one of the forms <i>!e</i>, <i>e<sub>1</sub> &amp;&amp; e<sub>2</sub></i> or
+ * <i>e<sub>1</sub> || e<sub>2</sub></i>, where <i>e</i>, <i>e1</sub></i> and <i>e2</sub></i> are
+ * constant expressions that evaluate to a boolean value.
+ * * An expression of one of the forms <i>~e</i>, <i>e<sub>1</sub> ^ e<sub>2</sub></i>,
+ * <i>e<sub>1</sub> &amp; e<sub>2</sub></i>, <i>e<sub>1</sub> | e<sub>2</sub></i>, <i>e<sub>1</sub>
+ * &gt;&gt; e<sub>2</sub></i> or <i>e<sub>1</sub> &lt;&lt; e<sub>2</sub></i>, where <i>e</i>,
+ * <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant expressions that evaluate to an
+ * integer value or to <b>null</b>.
+ * * An expression of one of the forms <i>-e</i>, <i>e<sub>1</sub> + e<sub>2</sub></i>,
+ * <i>e<sub>1</sub> -e<sub>2</sub></i>, <i>e<sub>1</sub> * e<sub>2</sub></i>, <i>e<sub>1</sub> /
+ * e<sub>2</sub></i>, <i>e<sub>1</sub> ~/ e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;
+ * e<sub>2</sub></i>, <i>e<sub>1</sub> &lt; e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;=
+ * e<sub>2</sub></i>, <i>e<sub>1</sub> &lt;= e<sub>2</sub></i> or <i>e<sub>1</sub> %
+ * e<sub>2</sub></i>, where <i>e</i>, <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant
+ * expressions that evaluate to a numeric value or to <b>null</b>.
+ * * An expression of the form <i>e<sub>1</sub> ? e<sub>2</sub> : e<sub>3</sub></i> where
+ * <i>e<sub>1</sub></i>, <i>e<sub>2</sub></i> and <i>e<sub>3</sub></i> are constant expressions, and
+ * <i>e<sub>1</sub></i> evaluates to a boolean value.
*
- * </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.
+ * </blockquote>
*/
class ConstantEvaluator {
/**
@@ -57,16 +66,23 @@ class ConstantEvaluator {
Source _source;
/**
+ * The type provider used to access the known types.
+ */
+ TypeProvider _typeProvider;
+
+ /**
* Initialize a newly created evaluator to evaluate expressions in the given source.
*
* @param source the source containing the expression(s) that will be evaluated
+ * @param typeProvider the type provider used to access known types
*/
- ConstantEvaluator(Source source) {
+ ConstantEvaluator(Source source, TypeProvider typeProvider) {
this._source = source;
+ this._typeProvider = typeProvider;
}
EvaluationResult evaluate(Expression expression) {
- EvaluationResultImpl result = expression.accept(new ConstantVisitor());
+ EvaluationResultImpl result = expression.accept(new ConstantVisitor(_typeProvider));
if (result is ValidResult) {
return EvaluationResult.forValue((result as ValidResult).value);
}
@@ -80,6 +96,72 @@ class ConstantEvaluator {
}
/**
+ * The interface `DartObject` defines the behavior of objects that represent the state of a
+ * Dart object.
+ */
+abstract class DartObject {
+ /**
+ * Return the boolean value of this object, or `null` if either the value of this object is
+ * not known or this object is not of type 'bool'.
+ *
+ * @return the boolean value of this object
+ */
+ Object get boolValue;
+
+ /**
+ * Return the floating point value of this object, or `null` if either the value of this
+ * object is not known or this object is not of type 'double'.
+ *
+ * @return the floating point value of this object
+ */
+ double get doubleValue;
+
+ /**
+ * Return the integer value of this object, or `null` if either the value of this object is
+ * not known or this object is not of type 'int'.
+ *
+ * @return the integer value of this object
+ */
+ int get intValue;
+
+ /**
+ * Return the string value of this object, or `null` if either the value of this object is
+ * not known or this object is not of type 'String'.
+ *
+ * @return the string value of this object
+ */
+ String get stringValue;
+
+ /**
+ * Return the run-time type of this object.
+ *
+ * @return the run-time type of this object
+ */
+ InterfaceType get type;
+
+ /**
+ * Return `true` if this object represents the value 'false'.
+ *
+ * @return `true` if this object represents the value 'false'
+ */
+ bool get isFalse;
+
+ /**
+ * Return `true` if this object represents the value 'null'.
+ *
+ * @return `true` if this object represents the value 'null'
+ */
+ bool get isNull;
+
+ /**
+ * Return `true` if this object represents the value 'true'.
+ *
+ * @return `true` if this object represents the value 'true'
+ */
+ bool get isTrue;
+}
+
+/**
* Instances of the class `EvaluationResult` represent the result of attempting to evaluate an
* expression.
*/
@@ -100,12 +182,12 @@ class EvaluationResult {
* @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);
+ static EvaluationResult forValue(DartObject value) => new EvaluationResult(value, null);
/**
* The value of the expression.
*/
- final Object value;
+ final DartObject value;
/**
* The errors that should be reported for the expression(s) that were evaluated.
@@ -168,11 +250,16 @@ class ConstantFinder extends RecursiveASTVisitor<Object> {
* 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
+ * [computeValues] to be invoked exactly once. Any use of an instance after invoking the
* method [computeValues] will result in unpredictable behavior.
*/
class ConstantValueComputer {
/**
+ * The type provider used to access the known types.
+ */
+ TypeProvider _typeProvider;
+
+ /**
* The object used to find constant variables in the compilation units that were added.
*/
ConstantFinder _constantFinder = new ConstantFinder();
@@ -189,6 +276,15 @@ class ConstantValueComputer {
Map<VariableElement, VariableDeclaration> _declarationMap;
/**
+ * Initialize a newly created constant value computer.
+ *
+ * @param typeProvider the type provider used to access known types
+ */
+ ConstantValueComputer(TypeProvider typeProvider) {
+ this._typeProvider = typeProvider;
+ }
+
+ /**
* Add the constant variables in the given compilation unit to the list of constant variables
* whose value needs to be computed.
*
@@ -218,7 +314,7 @@ class ConstantValueComputer {
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");
+ AnalysisEngine.instance.logger.logError("Exiting constant value computer with ${_referenceGraph.nodeCount} variables that are neither sinks nor in a cycle");
return;
}
for (VariableElement variable in variablesInCycle) {
@@ -239,7 +335,7 @@ class ConstantValueComputer {
if (declaration == null) {
return;
}
- EvaluationResultImpl result = declaration.initializer.accept(new ConstantVisitor());
+ EvaluationResultImpl result = declaration.initializer.accept(new ConstantVisitor(_typeProvider));
(variable as VariableElementImpl).evaluationResult = result;
if (result is ErrorResult) {
List<AnalysisError> errors = new List<AnalysisError>();
@@ -271,39 +367,70 @@ class ConstantValueComputer {
* * 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.
+ * to a numeric, string or boolean value or to <b>null</b>.
+ * * A literal symbol.
+ * * <b>null</b>.
+ * * A qualified reference to a static constant variable.
+ * * An identifier expression that denotes a constant variable, class or type alias.
* * 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`.
+ * * A parenthesized expression <i>(e)</i> where <i>e</i> is a constant expression.
+ * * An expression of the form <i>identical(e<sub>1</sub>, e<sub>2</sub>)</i> where
+ * <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant expressions and <i>identical()</i> is
+ * statically bound to the predefined dart function <i>identical()</i> discussed above.
+ * * An expression of one of the forms <i>e<sub>1</sub> == e<sub>2</sub></i> or <i>e<sub>1</sub>
+ * != e<sub>2</sub></i> where <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant expressions
+ * that evaluate to a numeric, string or boolean value.
+ * * An expression of one of the forms <i>!e</i>, <i>e<sub>1</sub> &amp;&amp; e<sub>2</sub></i> or
+ * <i>e<sub>1</sub> || e<sub>2</sub></i>, where <i>e</i>, <i>e1</sub></i> and <i>e2</sub></i> are
+ * constant expressions that evaluate to a boolean value.
+ * * An expression of one of the forms <i>~e</i>, <i>e<sub>1</sub> ^ e<sub>2</sub></i>,
+ * <i>e<sub>1</sub> &amp; e<sub>2</sub></i>, <i>e<sub>1</sub> | e<sub>2</sub></i>, <i>e<sub>1</sub>
+ * &gt;&gt; e<sub>2</sub></i> or <i>e<sub>1</sub> &lt;&lt; e<sub>2</sub></i>, where <i>e</i>,
+ * <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant expressions that evaluate to an
+ * integer value or to <b>null</b>.
+ * * An expression of one of the forms <i>-e</i>, <i>e<sub>1</sub> + e<sub>2</sub></i>,
+ * <i>e<sub>1</sub> - e<sub>2</sub></i>, <i>e<sub>1</sub> * e<sub>2</sub></i>, <i>e<sub>1</sub> /
+ * e<sub>2</sub></i>, <i>e<sub>1</sub> ~/ e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;
+ * e<sub>2</sub></i>, <i>e<sub>1</sub> &lt; e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;=
+ * e<sub>2</sub></i>, <i>e<sub>1</sub> &lt;= e<sub>2</sub></i> or <i>e<sub>1</sub> %
+ * e<sub>2</sub></i>, where <i>e</i>, <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant
+ * expressions that evaluate to a numeric value or to <b>null</b>.
+ * * An expression of the form <i>e<sub>1</sub> ? e<sub>2</sub> : e<sub>3</sub></i> where
+ * <i>e<sub>1</sub></i>, <i>e<sub>2</sub></i> and <i>e<sub>3</sub></i> are constant expressions, and
+ * <i>e<sub>1</sub></i> evaluates to a boolean value.
*
* </blockquote>
*/
class ConstantVisitor extends UnifyingASTVisitor<EvaluationResultImpl> {
+ /**
+ * The type provider used to access the known types.
+ */
+ TypeProvider _typeProvider;
+
+ /**
+ * An shared object representing the value 'null'.
+ */
+ DartObjectImpl _nullObject;
+
+ /**
+ * Initialize a newly created constant visitor.
+ *
+ * @param typeProvider the type provider used to access known types
+ */
+ ConstantVisitor(TypeProvider typeProvider) {
+ this._typeProvider = typeProvider;
+ }
+
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));
+ result = result.concatenate(_typeProvider, node, string.accept(this));
}
}
return result;
@@ -320,70 +447,81 @@ class ConstantVisitor extends UnifyingASTVisitor<EvaluationResultImpl> {
}
while (true) {
if (operatorType == TokenType.AMPERSAND) {
- return leftResult.bitAnd(node, rightResult);
+ return leftResult.bitAnd(_typeProvider, node, rightResult);
} else if (operatorType == TokenType.AMPERSAND_AMPERSAND) {
- return leftResult.logicalAnd(node, rightResult);
+ return leftResult.logicalAnd(_typeProvider, node, rightResult);
} else if (operatorType == TokenType.BANG_EQ) {
- return leftResult.notEqual(node, rightResult);
+ return leftResult.notEqual(_typeProvider, node, rightResult);
} else if (operatorType == TokenType.BAR) {
- return leftResult.bitOr(node, rightResult);
+ return leftResult.bitOr(_typeProvider, node, rightResult);
} else if (operatorType == TokenType.BAR_BAR) {
- return leftResult.logicalOr(node, rightResult);
+ return leftResult.logicalOr(_typeProvider, node, rightResult);
} else if (operatorType == TokenType.CARET) {
- return leftResult.bitXor(node, rightResult);
+ return leftResult.bitXor(_typeProvider, node, rightResult);
} else if (operatorType == TokenType.EQ_EQ) {
- return leftResult.equalEqual(node, rightResult);
+ return leftResult.equalEqual(_typeProvider, node, rightResult);
} else if (operatorType == TokenType.GT) {
- return leftResult.greaterThan(node, rightResult);
+ return leftResult.greaterThan(_typeProvider, node, rightResult);
} else if (operatorType == TokenType.GT_EQ) {
- return leftResult.greaterThanOrEqual(node, rightResult);
+ return leftResult.greaterThanOrEqual(_typeProvider, node, rightResult);
} else if (operatorType == TokenType.GT_GT) {
- return leftResult.shiftRight(node, rightResult);
+ return leftResult.shiftRight(_typeProvider, node, rightResult);
} else if (operatorType == TokenType.LT) {
- return leftResult.lessThan(node, rightResult);
+ return leftResult.lessThan(_typeProvider, node, rightResult);
} else if (operatorType == TokenType.LT_EQ) {
- return leftResult.lessThanOrEqual(node, rightResult);
+ return leftResult.lessThanOrEqual(_typeProvider, node, rightResult);
} else if (operatorType == TokenType.LT_LT) {
- return leftResult.shiftLeft(node, rightResult);
+ return leftResult.shiftLeft(_typeProvider, node, rightResult);
} else if (operatorType == TokenType.MINUS) {
- return leftResult.minus(node, rightResult);
+ return leftResult.minus(_typeProvider, node, rightResult);
} else if (operatorType == TokenType.PERCENT) {
- return leftResult.remainder(node, rightResult);
+ return leftResult.remainder(_typeProvider, node, rightResult);
} else if (operatorType == TokenType.PLUS) {
- return leftResult.add(node, rightResult);
+ return leftResult.add(_typeProvider, node, rightResult);
} else if (operatorType == TokenType.STAR) {
- return leftResult.times(node, rightResult);
+ return leftResult.times(_typeProvider, node, rightResult);
} else if (operatorType == TokenType.SLASH) {
- return leftResult.divide(node, rightResult);
+ return leftResult.divide(_typeProvider, node, rightResult);
} else if (operatorType == TokenType.TILDE_SLASH) {
- return leftResult.integerDivide(node, rightResult);
+ return leftResult.integerDivide(_typeProvider, node, rightResult);
}
break;
}
return error(node, null);
}
- EvaluationResultImpl visitBooleanLiteral(BooleanLiteral node) => node.value ? ValidResult.RESULT_TRUE : ValidResult.RESULT_FALSE;
+ EvaluationResultImpl visitBooleanLiteral(BooleanLiteral node) => valid2(_typeProvider.boolType, BoolState.from(node.value));
EvaluationResultImpl visitConditionalExpression(ConditionalExpression node) {
Expression condition = node.condition;
EvaluationResultImpl conditionResult = condition.accept(this);
- conditionResult = conditionResult.applyBooleanConversion(condition);
+ EvaluationResultImpl thenResult = node.thenExpression.accept(this);
+ EvaluationResultImpl elseResult = node.elseExpression.accept(this);
+ if (conditionResult is ErrorResult) {
+ return union(union(conditionResult as ErrorResult, thenResult), elseResult);
+ } else if (!(conditionResult as ValidResult).isBool) {
+ return new ErrorResult.con1(condition, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL);
+ } else if (thenResult is ErrorResult) {
+ return union(thenResult as ErrorResult, elseResult);
+ } else if (elseResult is ErrorResult) {
+ return elseResult;
+ }
+ conditionResult = conditionResult.applyBooleanConversion(_typeProvider, condition);
if (conditionResult is ErrorResult) {
return conditionResult;
}
- EvaluationResultImpl thenResult = node.thenExpression.accept(this);
- if (thenResult is ErrorResult) {
+ ValidResult validResult = conditionResult as ValidResult;
+ if (validResult.isTrue) {
return thenResult;
- }
- EvaluationResultImpl elseResult = node.elseExpression.accept(this);
- if (elseResult is ErrorResult) {
+ } else if (validResult.isFalse) {
return elseResult;
}
- return (identical(conditionResult, ValidResult.RESULT_TRUE)) ? thenResult : elseResult;
+ InterfaceType thenType = (thenResult as ValidResult).value.type;
+ InterfaceType elseType = (elseResult as ValidResult).value.type;
+ return valid(thenType.getLeastUpperBound(elseType) as InterfaceType);
}
- EvaluationResultImpl visitDoubleLiteral(DoubleLiteral node) => new ValidResult(node.value);
+ EvaluationResultImpl visitDoubleLiteral(DoubleLiteral node) => valid2(_typeProvider.doubleType, new DoubleState(node.value));
EvaluationResultImpl visitInstanceCreationExpression(InstanceCreationExpression node) {
if (!node.isConst) {
@@ -391,33 +529,82 @@ class ConstantVisitor extends UnifyingASTVisitor<EvaluationResultImpl> {
}
ConstructorElement constructor = node.staticElement;
if (constructor != null && constructor.isConst) {
- node.argumentList.accept(this);
- return ValidResult.RESULT_OBJECT;
+ NodeList<Expression> arguments = node.argumentList.arguments;
+ int argumentCount = arguments.length;
+ List<DartObjectImpl> argumentValues = new List<DartObjectImpl>(argumentCount);
+ Map<String, DartObjectImpl> namedArgumentValues = new Map<String, DartObjectImpl>();
+ for (int i = 0; i < argumentCount; i++) {
+ Expression argument = arguments[i];
+ if (argument is NamedExpression) {
+ NamedExpression namedExpression = argument as NamedExpression;
+ String name = namedExpression.name.label.name;
+ namedArgumentValues[name] = valueOf(namedExpression.expression);
+ argumentValues[i] = null2;
+ } else {
+ argumentValues[i] = valueOf(argument);
+ }
+ }
+ InterfaceType definingClass = constructor.returnType as InterfaceType;
+ if (definingClass.element.library.isDartCore) {
+ String className = definingClass.name;
+ if (className == "Symbol" && argumentCount == 1) {
+ String argumentValue = argumentValues[0].stringValue;
+ if (argumentValue != null) {
+ return valid2(definingClass, new SymbolState(argumentValue));
+ }
+ }
+ }
+ Map<String, DartObjectImpl> fieldMap = new Map<String, DartObjectImpl>();
+ List<ParameterElement> parameters = constructor.parameters;
+ int parameterCount = parameters.length;
+ for (int i = 0; i < parameterCount; i++) {
+ ParameterElement parameter = parameters[i];
+ if (parameter.isInitializingFormal) {
+ String fieldName = (parameter as FieldFormalParameterElement).field.name;
+ if (identical(parameter.parameterKind, ParameterKind.NAMED)) {
+ DartObjectImpl argumentValue = namedArgumentValues[parameter.name];
+ if (argumentValue != null) {
+ fieldMap[fieldName] = argumentValue;
+ }
+ } else if (i < argumentCount) {
+ fieldMap[fieldName] = argumentValues[i];
+ }
+ }
+ }
+ return valid2(definingClass, new GenericState(fieldMap));
}
return error(node, null);
}
- EvaluationResultImpl visitIntegerLiteral(IntegerLiteral node) => new ValidResult(node.value);
+ EvaluationResultImpl visitIntegerLiteral(IntegerLiteral node) => valid2(_typeProvider.intType, new IntState(node.value));
EvaluationResultImpl visitInterpolationExpression(InterpolationExpression node) {
EvaluationResultImpl result = node.expression.accept(this);
- return result.performToString(node);
+ if (result is ValidResult && !(result as ValidResult).isBoolNumStringOrNull) {
+ return error(node, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING);
+ }
+ return result.performToString(_typeProvider, node);
}
- EvaluationResultImpl visitInterpolationString(InterpolationString node) => new ValidResult(node.value);
+ EvaluationResultImpl visitInterpolationString(InterpolationString node) => valid2(_typeProvider.stringType, new StringState(node.value));
EvaluationResultImpl visitListLiteral(ListLiteral node) {
if (node.constKeyword == null) {
return new ErrorResult.con1(node, CompileTimeErrorCode.MISSING_CONST_IN_LIST_LITERAL);
}
ErrorResult result = null;
+ List<DartObjectImpl> elements = new List<DartObjectImpl>();
for (Expression element in node.elements) {
- result = union(result, element.accept(this));
+ EvaluationResultImpl elementResult = element.accept(this);
+ result = union(result, elementResult);
+ if (elementResult is ValidResult) {
+ elements.add((elementResult as ValidResult).value);
+ }
}
if (result != null) {
return result;
}
- return ValidResult.RESULT_OBJECT;
+ return valid2(_typeProvider.listType, new ListState(new List.from(elements)));
}
EvaluationResultImpl visitMapLiteral(MapLiteral node) {
@@ -425,14 +612,20 @@ class ConstantVisitor extends UnifyingASTVisitor<EvaluationResultImpl> {
return new ErrorResult.con1(node, CompileTimeErrorCode.MISSING_CONST_IN_MAP_LITERAL);
}
ErrorResult result = null;
+ Map<DartObjectImpl, DartObjectImpl> map = new Map<DartObjectImpl, DartObjectImpl>();
for (MapLiteralEntry entry in node.entries) {
- result = union(result, entry.key.accept(this));
- result = union(result, entry.value.accept(this));
+ EvaluationResultImpl keyResult = entry.key.accept(this);
+ EvaluationResultImpl valueResult = entry.value.accept(this);
+ result = union(result, keyResult);
+ result = union(result, valueResult);
+ if (keyResult is ValidResult && valueResult is ValidResult) {
+ map[(keyResult as ValidResult).value] = (valueResult as ValidResult).value;
+ }
}
if (result != null) {
return result;
}
- return ValidResult.RESULT_OBJECT;
+ return valid2(_typeProvider.mapType, new MapState(map));
}
EvaluationResultImpl visitMethodInvocation(MethodInvocation node) {
@@ -448,7 +641,7 @@ class ConstantVisitor extends UnifyingASTVisitor<EvaluationResultImpl> {
if (library.isDartCore) {
EvaluationResultImpl leftArgument = arguments[0].accept(this);
EvaluationResultImpl rightArgument = arguments[1].accept(this);
- return leftArgument.equalEqual(node, rightArgument);
+ return leftArgument.equalEqual(_typeProvider, node, rightArgument);
}
}
}
@@ -461,7 +654,7 @@ class ConstantVisitor extends UnifyingASTVisitor<EvaluationResultImpl> {
EvaluationResultImpl visitNode(ASTNode node) => error(node, null);
- EvaluationResultImpl visitNullLiteral(NullLiteral node) => ValidResult.RESULT_NULL;
+ EvaluationResultImpl visitNullLiteral(NullLiteral node) => new ValidResult(null2);
EvaluationResultImpl visitParenthesizedExpression(ParenthesizedExpression node) => node.expression.accept(this);
@@ -484,11 +677,11 @@ class ConstantVisitor extends UnifyingASTVisitor<EvaluationResultImpl> {
}
while (true) {
if (node.operator.type == TokenType.BANG) {
- return operand.logicalNot(node);
+ return operand.logicalNot(_typeProvider, node);
} else if (node.operator.type == TokenType.TILDE) {
- return operand.bitNot(node);
+ return operand.bitNot(_typeProvider, node);
} else if (node.operator.type == TokenType.MINUS) {
- return operand.negated(node);
+ return operand.negated(_typeProvider, node);
}
break;
}
@@ -499,7 +692,7 @@ class ConstantVisitor extends UnifyingASTVisitor<EvaluationResultImpl> {
EvaluationResultImpl visitSimpleIdentifier(SimpleIdentifier node) => getConstantValue(node, node.staticElement);
- EvaluationResultImpl visitSimpleStringLiteral(SimpleStringLiteral node) => new ValidResult(node.value);
+ EvaluationResultImpl visitSimpleStringLiteral(SimpleStringLiteral node) => valid2(_typeProvider.stringType, new StringState(node.value));
EvaluationResultImpl visitStringInterpolation(StringInterpolation node) {
EvaluationResultImpl result = null;
@@ -507,13 +700,23 @@ class ConstantVisitor extends UnifyingASTVisitor<EvaluationResultImpl> {
if (result == null) {
result = element.accept(this);
} else {
- result = result.concatenate(node, element.accept(this));
+ result = result.concatenate(_typeProvider, node, element.accept(this));
}
}
return result;
}
- EvaluationResultImpl visitSymbolLiteral(SymbolLiteral node) => ValidResult.RESULT_SYMBOL;
+ EvaluationResultImpl visitSymbolLiteral(SymbolLiteral node) {
+ JavaStringBuilder builder = new JavaStringBuilder();
+ List<Token> components = node.components;
+ for (int i = 0; i < components.length; i++) {
+ if (i > 0) {
+ builder.appendChar(0x2E);
+ }
+ builder.append(components[i].lexeme);
+ }
+ return valid2(_typeProvider.symbolType, new SymbolState(builder.toString()));
+ }
/**
* Return a result object representing an error associated with the given node.
@@ -542,16 +745,29 @@ class ConstantVisitor extends UnifyingASTVisitor<EvaluationResultImpl> {
return value;
}
} else if (element is ExecutableElement) {
- if ((element as ExecutableElement).isStatic) {
- return new ValidResult(element);
+ ExecutableElement function = element as ExecutableElement;
+ if (function.isStatic) {
+ return valid2(_typeProvider.functionType, new FunctionState(function));
}
} else if (element is ClassElement || element is FunctionTypeAliasElement) {
- return ValidResult.RESULT_OBJECT;
+ return valid2(_typeProvider.typeType, new TypeState(element));
}
return error(node, null);
}
/**
+ * Return an object representing the value 'null'.
+ *
+ * @return an object representing the value 'null'
+ */
+ DartObjectImpl get null2 {
+ if (_nullObject == null) {
+ _nullObject = new DartObjectImpl(_typeProvider.nullType, NullState.NULL_STATE);
+ }
+ return _nullObject;
+ }
+
+ /**
* 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
@@ -570,6 +786,39 @@ class ConstantVisitor extends UnifyingASTVisitor<EvaluationResultImpl> {
}
return leftResult;
}
+
+ ValidResult valid(InterfaceType type) {
+ if (type.element.library.isDartCore) {
+ String typeName = type.name;
+ if (typeName == "bool") {
+ return valid2(type, BoolState.UNKNOWN_VALUE);
+ } else if (typeName == "double") {
+ return valid2(type, DoubleState.UNKNOWN_VALUE);
+ } else if (typeName == "int") {
+ return valid2(type, IntState.UNKNOWN_VALUE);
+ } else if (typeName == "String") {
+ return valid2(type, StringState.UNKNOWN_VALUE);
+ }
+ }
+ return valid2(type, GenericState.UNKNOWN_VALUE);
+ }
+
+ ValidResult valid2(InterfaceType type, InstanceState state) => new ValidResult(new DartObjectImpl(type, state));
+
+ /**
+ * Return the value of the given expression, or a representation of 'null' if the expression
+ * cannot be evaluated.
+ *
+ * @param expression the expression whose value is to be returned
+ * @return the value of the given expression
+ */
+ DartObjectImpl valueOf(Expression expression) {
+ EvaluationResultImpl expressionValue = expression.accept(this);
+ if (expressionValue is ValidResult) {
+ return (expressionValue as ValidResult).value;
+ }
+ return null2;
+ }
}
/**
@@ -763,97 +1012,97 @@ class ErrorResult extends EvaluationResultImpl {
_errors.addAll(secondResult._errors);
}
- EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.addToError(node, this);
+ EvaluationResultImpl add(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.addToError(node, this);
- EvaluationResultImpl applyBooleanConversion(ASTNode node) => this;
+ EvaluationResultImpl applyBooleanConversion(TypeProvider typeProvider, ASTNode node) => this;
- EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitAndError(node, this);
+ EvaluationResultImpl bitAnd(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitAndError(node, this);
- EvaluationResultImpl bitNot(Expression node) => this;
+ EvaluationResultImpl bitNot(TypeProvider typeProvider, Expression node) => this;
- EvaluationResultImpl bitOr(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitOrError(node, this);
+ EvaluationResultImpl bitOr(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitOrError(node, this);
- EvaluationResultImpl bitXor(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitXorError(node, this);
+ EvaluationResultImpl bitXor(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitXorError(node, this);
- EvaluationResultImpl concatenate(Expression node, EvaluationResultImpl rightOperand) => rightOperand.concatenateError(node, this);
+ EvaluationResultImpl concatenate(TypeProvider typeProvider, Expression node, EvaluationResultImpl rightOperand) => rightOperand.concatenateError(node, this);
- EvaluationResultImpl divide(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.divideError(node, this);
+ EvaluationResultImpl divide(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.divideError(node, this);
- EvaluationResultImpl equalEqual(Expression node, EvaluationResultImpl rightOperand) => rightOperand.equalEqualError(node, this);
+ EvaluationResultImpl equalEqual(TypeProvider typeProvider, Expression node, EvaluationResultImpl rightOperand) => rightOperand.equalEqualError(node, this);
- bool equalValues(EvaluationResultImpl result) => false;
+ bool equalValues(TypeProvider typeProvider, EvaluationResultImpl result) => false;
List<ErrorResult_ErrorData> get errorData => _errors;
- EvaluationResultImpl greaterThan(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanError(node, this);
+ EvaluationResultImpl greaterThan(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanError(node, this);
- EvaluationResultImpl greaterThanOrEqual(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanOrEqualError(node, this);
+ EvaluationResultImpl greaterThanOrEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanOrEqualError(node, this);
- EvaluationResultImpl integerDivide(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.integerDivideError(node, this);
+ EvaluationResultImpl integerDivide(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.integerDivideError(node, this);
- EvaluationResultImpl integerDivideValid(BinaryExpression node, ValidResult leftOperand) => this;
+ EvaluationResultImpl integerDivideValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
- EvaluationResultImpl lessThan(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanError(node, this);
+ EvaluationResultImpl lessThan(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanError(node, this);
- EvaluationResultImpl lessThanOrEqual(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanOrEqualError(node, this);
+ EvaluationResultImpl lessThanOrEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanOrEqualError(node, this);
- EvaluationResultImpl logicalAnd(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalAndError(node, this);
+ EvaluationResultImpl logicalAnd(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalAndError(node, this);
- EvaluationResultImpl logicalNot(Expression node) => this;
+ EvaluationResultImpl logicalNot(TypeProvider typeProvider, Expression node) => this;
- EvaluationResultImpl logicalOr(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalOrError(node, this);
+ EvaluationResultImpl logicalOr(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalOrError(node, this);
- EvaluationResultImpl minus(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.minusError(node, this);
+ EvaluationResultImpl minus(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.minusError(node, this);
- EvaluationResultImpl negated(Expression node) => this;
+ EvaluationResultImpl negated(TypeProvider typeProvider, Expression node) => this;
- EvaluationResultImpl notEqual(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.notEqualError(node, this);
+ EvaluationResultImpl notEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.notEqualError(node, this);
- EvaluationResultImpl performToString(ASTNode node) => this;
+ EvaluationResultImpl performToString(TypeProvider typeProvider, ASTNode node) => this;
- EvaluationResultImpl remainder(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.remainderError(node, this);
+ EvaluationResultImpl remainder(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.remainderError(node, this);
- EvaluationResultImpl shiftLeft(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.shiftLeftError(node, this);
+ EvaluationResultImpl shiftLeft(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.shiftLeftError(node, this);
- EvaluationResultImpl shiftRight(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.shiftRightError(node, this);
+ EvaluationResultImpl shiftRight(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.shiftRightError(node, this);
- EvaluationResultImpl times(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.timesError(node, this);
+ EvaluationResultImpl times(TypeProvider typeProvider, 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 addToValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
EvaluationResultImpl bitAndError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
- EvaluationResultImpl bitAndValid(BinaryExpression node, ValidResult leftOperand) => this;
+ EvaluationResultImpl bitAndValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
EvaluationResultImpl bitOrError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
- EvaluationResultImpl bitOrValid(BinaryExpression node, ValidResult leftOperand) => this;
+ EvaluationResultImpl bitOrValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
EvaluationResultImpl bitXorError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
- EvaluationResultImpl bitXorValid(BinaryExpression node, ValidResult leftOperand) => this;
+ EvaluationResultImpl bitXorValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
EvaluationResultImpl concatenateError(Expression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
- EvaluationResultImpl concatenateValid(Expression node, ValidResult leftOperand) => this;
+ EvaluationResultImpl concatenateValid(TypeProvider typeProvider, Expression node, ValidResult leftOperand) => this;
EvaluationResultImpl divideError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
- EvaluationResultImpl divideValid(BinaryExpression node, ValidResult leftOperand) => this;
+ EvaluationResultImpl divideValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
EvaluationResultImpl equalEqualError(Expression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
- EvaluationResultImpl equalEqualValid(Expression node, ValidResult leftOperand) => this;
+ EvaluationResultImpl equalEqualValid(TypeProvider typeProvider, 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 greaterThanOrEqualValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
- EvaluationResultImpl greaterThanValid(BinaryExpression node, ValidResult leftOperand) => this;
+ EvaluationResultImpl greaterThanValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
EvaluationResultImpl integerDivideError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
@@ -861,41 +1110,41 @@ class ErrorResult extends EvaluationResultImpl {
EvaluationResultImpl lessThanOrEqualError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
- EvaluationResultImpl lessThanOrEqualValid(BinaryExpression node, ValidResult leftOperand) => this;
+ EvaluationResultImpl lessThanOrEqualValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
- EvaluationResultImpl lessThanValid(BinaryExpression node, ValidResult leftOperand) => this;
+ EvaluationResultImpl lessThanValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
EvaluationResultImpl logicalAndError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
- EvaluationResultImpl logicalAndValid(BinaryExpression node, ValidResult leftOperand) => this;
+ EvaluationResultImpl logicalAndValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
EvaluationResultImpl logicalOrError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
- EvaluationResultImpl logicalOrValid(BinaryExpression node, ValidResult leftOperand) => this;
+ EvaluationResultImpl logicalOrValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
- EvaluationResultImpl minusValid(BinaryExpression node, ValidResult leftOperand) => this;
+ EvaluationResultImpl minusValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
EvaluationResultImpl notEqualError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
- EvaluationResultImpl notEqualValid(BinaryExpression node, ValidResult leftOperand) => this;
+ EvaluationResultImpl notEqualValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
- EvaluationResultImpl remainderValid(BinaryExpression node, ValidResult leftOperand) => this;
+ EvaluationResultImpl remainderValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
- EvaluationResultImpl shiftLeftValid(BinaryExpression node, ValidResult leftOperand) => this;
+ EvaluationResultImpl shiftLeftValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
- EvaluationResultImpl shiftRightValid(BinaryExpression node, ValidResult leftOperand) => this;
+ EvaluationResultImpl shiftRightValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
- EvaluationResultImpl timesValid(BinaryExpression node, ValidResult leftOperand) => this;
+ EvaluationResultImpl timesValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
}
class ErrorResult_ErrorData {
@@ -924,143 +1173,144 @@ class ErrorResult_ErrorData {
* expression.
*/
abstract class EvaluationResultImpl {
- EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOperand);
+ EvaluationResultImpl add(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
/**
* Return the result of applying boolean conversion to this result.
*
+ * @param typeProvider the type provider used to access known types
* @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 applyBooleanConversion(TypeProvider typeProvider, ASTNode node);
- EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightOperand);
+ EvaluationResultImpl bitAnd(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
- EvaluationResultImpl bitNot(Expression node);
+ EvaluationResultImpl bitNot(TypeProvider typeProvider, Expression node);
- EvaluationResultImpl bitOr(BinaryExpression node, EvaluationResultImpl rightOperand);
+ EvaluationResultImpl bitOr(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
- EvaluationResultImpl bitXor(BinaryExpression node, EvaluationResultImpl rightOperand);
+ EvaluationResultImpl bitXor(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
- EvaluationResultImpl concatenate(Expression node, EvaluationResultImpl rightOperand);
+ EvaluationResultImpl concatenate(TypeProvider typeProvider, Expression node, EvaluationResultImpl rightOperand);
- EvaluationResultImpl divide(BinaryExpression node, EvaluationResultImpl rightOperand);
+ EvaluationResultImpl divide(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
- EvaluationResultImpl equalEqual(Expression node, EvaluationResultImpl rightOperand);
+ EvaluationResultImpl equalEqual(TypeProvider typeProvider, Expression node, EvaluationResultImpl rightOperand);
- bool equalValues(EvaluationResultImpl result);
+ bool equalValues(TypeProvider typeProvider, EvaluationResultImpl result);
- EvaluationResultImpl greaterThan(BinaryExpression node, EvaluationResultImpl rightOperand);
+ EvaluationResultImpl greaterThan(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
- EvaluationResultImpl greaterThanOrEqual(BinaryExpression node, EvaluationResultImpl rightOperand);
+ EvaluationResultImpl greaterThanOrEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
- EvaluationResultImpl integerDivide(BinaryExpression node, EvaluationResultImpl rightOperand);
+ EvaluationResultImpl integerDivide(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
- EvaluationResultImpl lessThan(BinaryExpression node, EvaluationResultImpl rightOperand);
+ EvaluationResultImpl lessThan(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
- EvaluationResultImpl lessThanOrEqual(BinaryExpression node, EvaluationResultImpl rightOperand);
+ EvaluationResultImpl lessThanOrEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
- EvaluationResultImpl logicalAnd(BinaryExpression node, EvaluationResultImpl rightOperand);
+ EvaluationResultImpl logicalAnd(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
- EvaluationResultImpl logicalNot(Expression node);
+ EvaluationResultImpl logicalNot(TypeProvider typeProvider, Expression node);
- EvaluationResultImpl logicalOr(BinaryExpression node, EvaluationResultImpl rightOperand);
+ EvaluationResultImpl logicalOr(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
- EvaluationResultImpl minus(BinaryExpression node, EvaluationResultImpl rightOperand);
+ EvaluationResultImpl minus(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
- EvaluationResultImpl negated(Expression node);
+ EvaluationResultImpl negated(TypeProvider typeProvider, Expression node);
- EvaluationResultImpl notEqual(BinaryExpression node, EvaluationResultImpl rightOperand);
+ EvaluationResultImpl notEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
- EvaluationResultImpl performToString(ASTNode node);
+ EvaluationResultImpl performToString(TypeProvider typeProvider, ASTNode node);
- EvaluationResultImpl remainder(BinaryExpression node, EvaluationResultImpl rightOperand);
+ EvaluationResultImpl remainder(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
- EvaluationResultImpl shiftLeft(BinaryExpression node, EvaluationResultImpl rightOperand);
+ EvaluationResultImpl shiftLeft(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
- EvaluationResultImpl shiftRight(BinaryExpression node, EvaluationResultImpl rightOperand);
+ EvaluationResultImpl shiftRight(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
- EvaluationResultImpl times(BinaryExpression node, EvaluationResultImpl rightOperand);
+ EvaluationResultImpl times(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
EvaluationResultImpl addToError(BinaryExpression node, ErrorResult leftOperand);
- EvaluationResultImpl addToValid(BinaryExpression node, ValidResult leftOperand);
+ EvaluationResultImpl addToValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
EvaluationResultImpl bitAndError(BinaryExpression node, ErrorResult leftOperand);
- EvaluationResultImpl bitAndValid(BinaryExpression node, ValidResult leftOperand);
+ EvaluationResultImpl bitAndValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
EvaluationResultImpl bitOrError(BinaryExpression node, ErrorResult leftOperand);
- EvaluationResultImpl bitOrValid(BinaryExpression node, ValidResult leftOperand);
+ EvaluationResultImpl bitOrValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
EvaluationResultImpl bitXorError(BinaryExpression node, ErrorResult leftOperand);
- EvaluationResultImpl bitXorValid(BinaryExpression node, ValidResult leftOperand);
+ EvaluationResultImpl bitXorValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
EvaluationResultImpl concatenateError(Expression node, ErrorResult leftOperand);
- EvaluationResultImpl concatenateValid(Expression node, ValidResult leftOperand);
+ EvaluationResultImpl concatenateValid(TypeProvider typeProvider, Expression node, ValidResult leftOperand);
EvaluationResultImpl divideError(BinaryExpression node, ErrorResult leftOperand);
- EvaluationResultImpl divideValid(BinaryExpression node, ValidResult leftOperand);
+ EvaluationResultImpl divideValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
EvaluationResultImpl equalEqualError(Expression node, ErrorResult leftOperand);
- EvaluationResultImpl equalEqualValid(Expression node, ValidResult leftOperand);
+ EvaluationResultImpl equalEqualValid(TypeProvider typeProvider, Expression node, ValidResult leftOperand);
EvaluationResultImpl greaterThanError(BinaryExpression node, ErrorResult leftOperand);
EvaluationResultImpl greaterThanOrEqualError(BinaryExpression node, ErrorResult leftOperand);
- EvaluationResultImpl greaterThanOrEqualValid(BinaryExpression node, ValidResult leftOperand);
+ EvaluationResultImpl greaterThanOrEqualValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
- EvaluationResultImpl greaterThanValid(BinaryExpression node, ValidResult leftOperand);
+ EvaluationResultImpl greaterThanValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
EvaluationResultImpl integerDivideError(BinaryExpression node, ErrorResult leftOperand);
- EvaluationResultImpl integerDivideValid(BinaryExpression node, ValidResult leftOperand);
+ EvaluationResultImpl integerDivideValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
EvaluationResultImpl lessThanError(BinaryExpression node, ErrorResult leftOperand);
EvaluationResultImpl lessThanOrEqualError(BinaryExpression node, ErrorResult leftOperand);
- EvaluationResultImpl lessThanOrEqualValid(BinaryExpression node, ValidResult leftOperand);
+ EvaluationResultImpl lessThanOrEqualValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
- EvaluationResultImpl lessThanValid(BinaryExpression node, ValidResult leftOperand);
+ EvaluationResultImpl lessThanValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
EvaluationResultImpl logicalAndError(BinaryExpression node, ErrorResult leftOperand);
- EvaluationResultImpl logicalAndValid(BinaryExpression node, ValidResult leftOperand);
+ EvaluationResultImpl logicalAndValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
EvaluationResultImpl logicalOrError(BinaryExpression node, ErrorResult leftOperand);
- EvaluationResultImpl logicalOrValid(BinaryExpression node, ValidResult leftOperand);
+ EvaluationResultImpl logicalOrValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand);
- EvaluationResultImpl minusValid(BinaryExpression node, ValidResult leftOperand);
+ EvaluationResultImpl minusValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
EvaluationResultImpl notEqualError(BinaryExpression node, ErrorResult leftOperand);
- EvaluationResultImpl notEqualValid(BinaryExpression node, ValidResult leftOperand);
+ EvaluationResultImpl notEqualValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOperand);
- EvaluationResultImpl remainderValid(BinaryExpression node, ValidResult leftOperand);
+ EvaluationResultImpl remainderValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOperand);
- EvaluationResultImpl shiftLeftValid(BinaryExpression node, ValidResult leftOperand);
+ EvaluationResultImpl shiftLeftValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOperand);
- EvaluationResultImpl shiftRightValid(BinaryExpression node, ValidResult leftOperand);
+ EvaluationResultImpl shiftRightValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand);
- EvaluationResultImpl timesValid(BinaryExpression node, ValidResult leftOperand);
+ EvaluationResultImpl timesValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
}
/**
@@ -1113,66 +1363,9 @@ class ReferenceFinder extends RecursiveASTVisitor<Object> {
*/
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(0);
-
- /**
- * 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 symbol on which no further operations can be
- * performed.
- */
- static ValidResult RESULT_SYMBOL = 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.
*/
- final Object value;
+ final DartObjectImpl value;
/**
* Initialize a newly created result to represent the given value.
@@ -1181,7 +1374,7 @@ class ValidResult extends EvaluationResultImpl {
*/
ValidResult(this.value);
- EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.addToValid(node, this);
+ EvaluationResultImpl add(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.addToValid(typeProvider, node, this);
/**
* Return the result of applying boolean conversion to this result.
@@ -1189,106 +1382,133 @@ class ValidResult extends EvaluationResultImpl {
* @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 applyBooleanConversion(TypeProvider typeProvider, ASTNode node) {
+ try {
+ return valueOf(value.convertToBool(typeProvider));
+ } on EvaluationException catch (exception) {
+ return error(node, exception.errorCode);
+ }
+ }
- EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitAndValid(node, this);
+ EvaluationResultImpl bitAnd(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitAndValid(typeProvider, node, this);
- EvaluationResultImpl bitNot(Expression node) {
- if (isSomeInt) {
- return RESULT_INT;
+ EvaluationResultImpl bitNot(TypeProvider typeProvider, Expression node) {
+ try {
+ return valueOf(value.bitNot(typeProvider));
+ } on EvaluationException catch (exception) {
+ return error(node, exception.errorCode);
}
- if (value == null) {
- return error(node);
- } else if (value is int) {
- return valueOf(~(value as int));
+ }
+
+ EvaluationResultImpl bitOr(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitOrValid(typeProvider, node, this);
+
+ EvaluationResultImpl bitXor(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitXorValid(typeProvider, node, this);
+
+ EvaluationResultImpl concatenate(TypeProvider typeProvider, Expression node, EvaluationResultImpl rightOperand) => rightOperand.concatenateValid(typeProvider, node, this);
+
+ EvaluationResultImpl divide(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.divideValid(typeProvider, node, this);
+
+ EvaluationResultImpl equalEqual(TypeProvider typeProvider, Expression node, EvaluationResultImpl rightOperand) => rightOperand.equalEqualValid(typeProvider, node, this);
+
+ bool equalValues(TypeProvider typeProvider, EvaluationResultImpl result) {
+ if (result is! ValidResult) {
+ return false;
}
- return error(node);
+ return value == (result as ValidResult).value;
}
- EvaluationResultImpl bitOr(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitOrValid(node, this);
+ EvaluationResultImpl greaterThan(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanValid(typeProvider, node, this);
- EvaluationResultImpl bitXor(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitXorValid(node, this);
+ EvaluationResultImpl greaterThanOrEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanOrEqualValid(typeProvider, node, this);
- EvaluationResultImpl concatenate(Expression node, EvaluationResultImpl rightOperand) => rightOperand.concatenateValid(node, this);
+ EvaluationResultImpl integerDivide(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.integerDivideValid(typeProvider, node, this);
- EvaluationResultImpl divide(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.divideValid(node, this);
+ /**
+ * Return `true` if this object represents an object whose type is 'bool'.
+ *
+ * @return `true` if this object represents a boolean value
+ */
+ bool get isBool => value.isBool;
- EvaluationResultImpl equalEqual(Expression node, EvaluationResultImpl rightOperand) => rightOperand.equalEqualValid(node, this);
+ /**
+ * Return `true` if this object represents an object whose type is either 'bool', 'num',
+ * 'String', or 'Null'.
+ *
+ * @return `true` if this object represents either a boolean, numeric, string or null value
+ */
+ bool get isBoolNumStringOrNull => value.isBoolNumStringOrNull;
- bool equalValues(EvaluationResultImpl result) => identical(equalEqual(null, result), RESULT_TRUE);
+ /**
+ * Return `true` if this result represents the value 'false'.
+ *
+ * @return `true` if this result represents the value 'false'
+ */
+ bool get isFalse => value.isFalse;
- EvaluationResultImpl greaterThan(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanValid(node, this);
+ /**
+ * Return `true` if this result represents the value 'null'.
+ *
+ * @return `true` if this result represents the value 'null'
+ */
+ bool get isNull => value.isNull;
- EvaluationResultImpl greaterThanOrEqual(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanOrEqualValid(node, this);
+ /**
+ * Return `true` if this result represents the value 'true'.
+ *
+ * @return `true` if this result represents the value 'true'
+ */
+ bool get isTrue => value.isTrue;
- EvaluationResultImpl integerDivide(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.integerDivideValid(node, this);
+ /**
+ * Return `true` if this object represents an instance of a user-defined class.
+ *
+ * @return `true` if this object represents an instance of a user-defined class
+ */
+ bool get isUserDefinedObject => value.isUserDefinedObject;
- EvaluationResultImpl lessThan(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanValid(node, this);
+ EvaluationResultImpl lessThan(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanValid(typeProvider, node, this);
- EvaluationResultImpl lessThanOrEqual(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanOrEqualValid(node, this);
+ EvaluationResultImpl lessThanOrEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanOrEqualValid(typeProvider, node, this);
- EvaluationResultImpl logicalAnd(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalAndValid(node, this);
+ EvaluationResultImpl logicalAnd(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalAndValid(typeProvider, 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;
+ EvaluationResultImpl logicalNot(TypeProvider typeProvider, Expression node) {
+ try {
+ return valueOf(value.logicalNot(typeProvider));
+ } on EvaluationException catch (exception) {
+ return error(node, exception.errorCode);
}
- return error(node);
}
- EvaluationResultImpl logicalOr(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalOrValid(node, this);
+ EvaluationResultImpl logicalOr(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalOrValid(typeProvider, node, this);
- EvaluationResultImpl minus(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.minusValid(node, this);
+ EvaluationResultImpl minus(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.minusValid(typeProvider, 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));
+ EvaluationResultImpl negated(TypeProvider typeProvider, Expression node) {
+ try {
+ return valueOf(value.negated(typeProvider));
+ } on EvaluationException catch (exception) {
+ return error(node, exception.errorCode);
}
- return error(node);
}
- EvaluationResultImpl notEqual(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.notEqualValid(node, this);
+ EvaluationResultImpl notEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.notEqualValid(typeProvider, 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;
- } else if (isSomeBool) {
- return valueOf4("<some bool>");
- } else if (isSomeInt) {
- return valueOf4("<some int>");
- } else if (isSomeNum) {
- return valueOf4("<some num>");
+ EvaluationResultImpl performToString(TypeProvider typeProvider, ASTNode node) {
+ try {
+ return valueOf(value.performToString(typeProvider));
+ } on EvaluationException catch (exception) {
+ return error(node, exception.errorCode);
}
- return error(node);
}
- EvaluationResultImpl remainder(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.remainderValid(node, this);
+ EvaluationResultImpl remainder(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.remainderValid(typeProvider, node, this);
- EvaluationResultImpl shiftLeft(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.shiftLeftValid(node, this);
+ EvaluationResultImpl shiftLeft(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.shiftLeftValid(typeProvider, node, this);
- EvaluationResultImpl shiftRight(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.shiftRightValid(node, this);
+ EvaluationResultImpl shiftRight(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.shiftRightValid(typeProvider, node, this);
- EvaluationResultImpl times(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.timesValid(node, this);
+ EvaluationResultImpl times(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.timesValid(typeProvider, node, this);
String toString() {
if (value == null) {
@@ -1299,188 +1519,71 @@ class ValidResult extends EvaluationResultImpl {
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)}");
- }
+ EvaluationResultImpl addToValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+ try {
+ return valueOf(leftOperand.value.add(typeProvider, value));
+ } on EvaluationException catch (exception) {
+ return error(node, exception.errorCode);
}
- 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);
+ EvaluationResultImpl bitAndValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+ try {
+ return valueOf(leftOperand.value.bitAnd(typeProvider, value));
+ } on EvaluationException catch (exception) {
+ return error(node, exception.errorCode);
}
- 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);
+ EvaluationResultImpl bitOrValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+ try {
+ return valueOf(leftOperand.value.bitOr(typeProvider, value));
+ } on EvaluationException catch (exception) {
+ return error(node, exception.errorCode);
}
- 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);
+ EvaluationResultImpl bitXorValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+ try {
+ return valueOf(leftOperand.value.bitXor(typeProvider, value));
+ } on EvaluationException catch (exception) {
+ return error(node, exception.errorCode);
}
- 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)}");
+ EvaluationResultImpl concatenateValid(TypeProvider typeProvider, Expression node, ValidResult leftOperand) {
+ try {
+ return valueOf(leftOperand.value.concatenate(typeProvider, value));
+ } on EvaluationException catch (exception) {
+ return error(node, exception.errorCode);
}
- 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));
- }
+ EvaluationResultImpl divideValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+ try {
+ return valueOf(leftOperand.value.divide(typeProvider, value));
+ } on EvaluationException catch (exception) {
+ return error(node, exception.errorCode);
}
- 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 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 {
- return valueOf2(leftValue == value);
+ EvaluationResultImpl equalEqualValid(TypeProvider typeProvider, Expression node, ValidResult leftOperand) {
+ try {
+ return valueOf(leftOperand.value.equalEqual(typeProvider, value));
+ } on EvaluationException catch (exception) {
+ return error(node, exception.errorCode);
}
}
@@ -1488,403 +1591,132 @@ class ValidResult extends EvaluationResultImpl {
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;
+ EvaluationResultImpl greaterThanOrEqualValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+ try {
+ return valueOf(leftOperand.value.greaterThanOrEqual(typeProvider, value));
+ } on EvaluationException catch (exception) {
+ return error(node, exception.errorCode);
}
- 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;
+ EvaluationResultImpl greaterThanValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+ try {
+ return valueOf(leftOperand.value.greaterThan(typeProvider, value));
+ } on EvaluationException catch (exception) {
+ return error(node, exception.errorCode);
}
- 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());
- }
+ EvaluationResultImpl integerDivideValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+ try {
+ return valueOf(leftOperand.value.integerDivide(typeProvider, value));
+ } on EvaluationException catch (exception) {
+ return error(node, exception.errorCode);
}
- 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));
- }
+ EvaluationResultImpl lessThanOrEqualValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+ try {
+ return valueOf(leftOperand.value.lessThanOrEqual(typeProvider, value));
+ } on EvaluationException catch (exception) {
+ return error(node, exception.errorCode);
}
- 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));
- }
+ EvaluationResultImpl lessThanValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+ try {
+ return valueOf(leftOperand.value.lessThan(typeProvider, value));
+ } on EvaluationException catch (exception) {
+ return error(node, exception.errorCode);
}
- 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;
+ EvaluationResultImpl logicalAndValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+ try {
+ return valueOf(leftOperand.value.logicalAnd(typeProvider, value));
+ } on EvaluationException catch (exception) {
+ return error(node, exception.errorCode);
}
- 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;
+ EvaluationResultImpl logicalOrValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+ try {
+ return valueOf(leftOperand.value.logicalOr(typeProvider, value));
+ } on EvaluationException catch (exception) {
+ return error(node, exception.errorCode);
}
- 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;
+ EvaluationResultImpl minusValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+ try {
+ return valueOf(leftOperand.value.minus(typeProvider, value));
+ } on EvaluationException catch (exception) {
+ return error(node, exception.errorCode);
}
- 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;
+ EvaluationResultImpl notEqualValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+ try {
+ return valueOf(leftOperand.value.notEqual(typeProvider, value));
+ } on EvaluationException catch (exception) {
+ return error(node, exception.errorCode);
}
- 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));
- }
+ EvaluationResultImpl remainderValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+ try {
+ return valueOf(leftOperand.value.remainder(typeProvider, value));
+ } on EvaluationException catch (exception) {
+ return error(node, exception.errorCode);
}
- 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;
+ EvaluationResultImpl shiftLeftValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+ try {
+ return valueOf(leftOperand.value.shiftLeft(typeProvider, value));
+ } on EvaluationException catch (exception) {
+ return error(node, exception.errorCode);
}
- 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 RESULT_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;
+ EvaluationResultImpl shiftRightValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+ try {
+ return valueOf(leftOperand.value.shiftRight(typeProvider, value));
+ } on EvaluationException catch (exception) {
+ return error(node, exception.errorCode);
}
- 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;
- }
+ EvaluationResultImpl timesValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+ try {
+ return valueOf(leftOperand.value.times(typeProvider, value));
+ } on EvaluationException catch (exception) {
+ return error(node, exception.errorCode);
}
- return error(node);
}
- ErrorResult error(ASTNode node) => error2(node, CompileTimeErrorCode.INVALID_CONSTANT);
-
/**
* Return a result object representing an error associated with the given node.
*
@@ -1892,83 +1724,2339 @@ class ValidResult extends EvaluationResultImpl {
* @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);
+ ErrorResult error(ASTNode node, ErrorCode code) => new ErrorResult.con1(node, code);
/**
- * Checks if this result has type "bool", with known or unknown 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
*/
- bool get isAnyBool => isSomeBool || identical(this, RESULT_TRUE) || identical(this, RESULT_FALSE);
+ ValidResult valueOf(DartObjectImpl value) => new ValidResult(value);
+}
+/**
+ * Instances of the class `BoolState` represent the state of an object representing a boolean
+ * value.
+ */
+class BoolState extends InstanceState {
/**
- * Checks if this result has type "int", with known or unknown value.
+ * The value of this instance.
*/
- bool get isAnyInt => identical(this, RESULT_INT) || value is int;
+ final bool value;
/**
- * Checks if this result has one of the types - "bool", "num" or "string"; or may be `null`.
+ * An instance representing the boolean value 'false'.
*/
- bool get isAnyNullBoolNumString => isNull || isAnyBool || isAnyNum || value is String;
+ static BoolState FALSE_STATE = new BoolState(false);
/**
- * Checks if this result has type "num", with known or unknown value.
+ * An instance representing the boolean value 'true'.
*/
- bool get isAnyNum => isSomeNum || value is num;
+ static BoolState TRUE_STATE = new BoolState(true);
/**
- * Checks if this result has type "bool", exact value of which we don't know.
+ * A state that can be used to represent a boolean whose value is not known.
*/
- bool get isSomeBool => identical(this, RESULT_BOOL);
+ static BoolState UNKNOWN_VALUE = new BoolState(null);
/**
- * Checks if this result has type "int", exact value of which we don't know.
+ * Return the boolean state representing the given boolean value.
+ *
+ * @param value the value to be represented
+ * @return the boolean state representing the given boolean value
*/
- bool get isSomeInt => identical(this, RESULT_INT);
+ static BoolState from(bool value) => value ? BoolState.TRUE_STATE : BoolState.FALSE_STATE;
/**
- * Checks if this result has type "num" (or "int"), exact value of which we don't know.
+ * Initialize a newly created state to represent the given value.
+ *
+ * @param value the value of this instance
*/
- bool get isSomeNum => identical(this, RESULT_DYNAMIC) || identical(this, RESULT_INT) || identical(this, RESULT_NUM);
+ BoolState(this.value);
- double toDouble(int value) => value.toDouble();
+ BoolState convertToBool() => this;
+
+ StringState convertToString() {
+ if (value == null) {
+ return StringState.UNKNOWN_VALUE;
+ }
+ return new StringState(value ? "true" : "false");
+ }
+
+ BoolState equalEqual(InstanceState rightOperand) {
+ assertBoolNumStringOrNull(rightOperand);
+ if (value == null) {
+ return UNKNOWN_VALUE;
+ }
+ if (rightOperand is BoolState) {
+ bool rightValue = (rightOperand as BoolState).value;
+ if (rightValue == null) {
+ return UNKNOWN_VALUE;
+ }
+ return BoolState.from(identical(value, rightValue));
+ } else if (rightOperand is DynamicState) {
+ return UNKNOWN_VALUE;
+ }
+ return FALSE_STATE;
+ }
+
+ bool operator ==(Object object) => object is BoolState && identical(value, (object as BoolState).value);
+
+ String get typeName => "bool";
+
+ int get hashCode => value == null ? 0 : (value ? 2 : 3);
+
+ /**
+ * Return `true` if this object represents an object whose type is 'bool'.
+ *
+ * @return `true` if this object represents a boolean value
+ */
+ bool get isBool => true;
+
+ bool get isBoolNumStringOrNull => true;
+
+ BoolState logicalAnd(InstanceState rightOperand) {
+ assertBool(rightOperand);
+ if (value == null) {
+ return UNKNOWN_VALUE;
+ }
+ return value ? rightOperand.convertToBool() : FALSE_STATE;
+ }
+
+ BoolState logicalNot() {
+ if (value == null) {
+ return UNKNOWN_VALUE;
+ }
+ return value ? FALSE_STATE : TRUE_STATE;
+ }
+
+ BoolState logicalOr(InstanceState rightOperand) {
+ assertBool(rightOperand);
+ if (value == null) {
+ return UNKNOWN_VALUE;
+ }
+ return value ? TRUE_STATE : rightOperand.convertToBool();
+ }
+
+ String toString() => value == null ? "-unknown-" : (value ? "true" : "false");
+}
+
+/**
+ * Instances of the class `DartObjectImpl` represent an instance of a Dart class.
+ */
+class DartObjectImpl implements DartObject {
+ /**
+ * The run-time type of this object.
+ */
+ final InterfaceType type;
+
+ /**
+ * The state of the object.
+ */
+ InstanceState _state;
+
+ /**
+ * Initialize a newly created object to have the given type and state.
+ *
+ * @param type the run-time type of this object
+ * @param state the state of the object
+ */
+ DartObjectImpl(this.type, InstanceState state) {
+ this._state = state;
+ }
+
+ /**
+ * Return the result of invoking the '+' operator on this object with the given argument.
+ *
+ * @param typeProvider the type provider used to find known types
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '+' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ DartObjectImpl add(TypeProvider typeProvider, DartObjectImpl rightOperand) {
+ InstanceState result = _state.add(rightOperand._state);
+ if (result is IntState) {
+ return new DartObjectImpl(typeProvider.intType, result);
+ } else if (result is DoubleState) {
+ return new DartObjectImpl(typeProvider.doubleType, result);
+ } else if (result is NumState) {
+ return new DartObjectImpl(typeProvider.numType, result);
+ }
+ throw new IllegalStateException("add returned a ${result.runtimeType.toString()}");
+ }
+
+ /**
+ * Return the result of invoking the '&' operator on this object with the given argument.
+ *
+ * @param typeProvider the type provider used to find known types
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '&' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ DartObjectImpl bitAnd(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.intType, _state.bitAnd(rightOperand._state));
+
+ /**
+ * Return the result of invoking the '~' operator on this object.
+ *
+ * @param typeProvider the type provider used to find known types
+ * @return the result of invoking the '~' operator on this object
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ DartObjectImpl bitNot(TypeProvider typeProvider) => new DartObjectImpl(typeProvider.intType, _state.bitNot());
+
+ /**
+ * Return the result of invoking the '|' operator on this object with the given argument.
+ *
+ * @param typeProvider the type provider used to find known types
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '|' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ DartObjectImpl bitOr(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.intType, _state.bitOr(rightOperand._state));
+
+ /**
+ * Return the result of invoking the '^' operator on this object with the given argument.
+ *
+ * @param typeProvider the type provider used to find known types
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '^' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ DartObjectImpl bitXor(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.intType, _state.bitXor(rightOperand._state));
+
+ /**
+ * Return the result of invoking the ' ' operator on this object with the given argument.
+ *
+ * @param typeProvider the type provider used to find known types
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the ' ' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ DartObjectImpl concatenate(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.stringType, _state.concatenate(rightOperand._state));
+
+ /**
+ * Return the result of applying boolean conversion to this object.
+ *
+ * @param typeProvider the type provider used to find known types
+ * @return the result of applying boolean conversion to this object
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ DartObjectImpl convertToBool(TypeProvider typeProvider) {
+ InterfaceType boolType = typeProvider.boolType;
+ if (identical(type, boolType)) {
+ return this;
+ }
+ return new DartObjectImpl(boolType, _state.convertToBool());
+ }
+
+ /**
+ * Return the result of invoking the '/' operator on this object with the given argument.
+ *
+ * @param typeProvider the type provider used to find known types
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '/' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ DartObjectImpl divide(TypeProvider typeProvider, DartObjectImpl rightOperand) {
+ InstanceState result = _state.divide(rightOperand._state);
+ if (result is IntState) {
+ return new DartObjectImpl(typeProvider.intType, result);
+ } else if (result is DoubleState) {
+ return new DartObjectImpl(typeProvider.doubleType, result);
+ } else if (result is NumState) {
+ return new DartObjectImpl(typeProvider.numType, result);
+ }
+ throw new IllegalStateException("divide returned a ${result.runtimeType.toString()}");
+ }
+
+ /**
+ * Return the result of invoking the '==' operator on this object with the given argument.
+ *
+ * @param typeProvider the type provider used to find known types
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '==' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ DartObjectImpl equalEqual(TypeProvider typeProvider, DartObjectImpl rightOperand) {
+ if (type != rightOperand.type) {
+ String typeName = type.name;
+ if (!(typeName == "bool" || typeName == "double" || typeName == "int" || typeName == "num" || typeName == "String" || typeName == "Null" || type.isDynamic)) {
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING);
+ }
+ }
+ return new DartObjectImpl(typeProvider.boolType, _state.equalEqual(rightOperand._state));
+ }
+
+ bool operator ==(Object object) {
+ if (object is! DartObjectImpl) {
+ return false;
+ }
+ DartObjectImpl dartObject = object as DartObjectImpl;
+ return type == dartObject.type && _state == dartObject._state;
+ }
+
+ Object get boolValue {
+ if (_state is BoolState) {
+ return (_state as BoolState).value;
+ }
+ return null;
+ }
+
+ double get doubleValue {
+ if (_state is DoubleState) {
+ return (_state as DoubleState).value;
+ }
+ return null;
+ }
+
+ int get intValue {
+ if (_state is IntState) {
+ return (_state as IntState).value;
+ }
+ return null;
+ }
+
+ String get stringValue {
+ if (_state is StringState) {
+ return (_state as StringState).value;
+ }
+ return null;
+ }
+
+ /**
+ * Return the result of invoking the '&gt;' operator on this object with the given argument.
+ *
+ * @param typeProvider the type provider used to find known types
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '&gt;' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ DartObjectImpl greaterThan(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.boolType, _state.greaterThan(rightOperand._state));
+
+ /**
+ * Return the result of invoking the '&gt;=' operator on this object with the given argument.
+ *
+ * @param typeProvider the type provider used to find known types
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '&gt;=' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ DartObjectImpl greaterThanOrEqual(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.boolType, _state.greaterThanOrEqual(rightOperand._state));
+
+ int get hashCode => ObjectUtilities.combineHashCodes(type.hashCode, _state.hashCode);
+
+ /**
+ * Return the result of invoking the '~/' operator on this object with the given argument.
+ *
+ * @param typeProvider the type provider used to find known types
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '~/' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ DartObjectImpl integerDivide(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.intType, _state.integerDivide(rightOperand._state));
+
+ /**
+ * Return `true` if this object represents an object whose type is 'bool'.
+ *
+ * @return `true` if this object represents a boolean value
+ */
+ bool get isBool => _state.isBool;
+
+ /**
+ * Return `true` if this object represents an object whose type is either 'bool', 'num',
+ * 'String', or 'Null'.
+ *
+ * @return `true` if this object represents either a boolean, numeric, string or null value
+ */
+ bool get isBoolNumStringOrNull => _state.isBoolNumStringOrNull;
+
+ bool get isFalse => _state is BoolState && identical((_state as BoolState).value, false);
+
+ bool get isNull => _state is NullState;
+
+ bool get isTrue => _state is BoolState && identical((_state as BoolState).value, true);
+
+ /**
+ * Return `true` if this object represents an instance of a user-defined class.
+ *
+ * @return `true` if this object represents an instance of a user-defined class
+ */
+ bool get isUserDefinedObject => _state is GenericState;
+
+ /**
+ * Return the result of invoking the '&lt;' operator on this object with the given argument.
+ *
+ * @param typeProvider the type provider used to find known types
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '&lt;' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ DartObjectImpl lessThan(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.boolType, _state.lessThan(rightOperand._state));
+
+ /**
+ * Return the result of invoking the '&lt;=' operator on this object with the given argument.
+ *
+ * @param typeProvider the type provider used to find known types
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '&lt;=' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ DartObjectImpl lessThanOrEqual(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.boolType, _state.lessThanOrEqual(rightOperand._state));
+
+ /**
+ * Return the result of invoking the '&&' operator on this object with the given argument.
+ *
+ * @param typeProvider the type provider used to find known types
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '&&' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ DartObjectImpl logicalAnd(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.boolType, _state.logicalAnd(rightOperand._state));
+
+ /**
+ * Return the result of invoking the '!' operator on this object.
+ *
+ * @param typeProvider the type provider used to find known types
+ * @return the result of invoking the '!' operator on this object
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ DartObjectImpl logicalNot(TypeProvider typeProvider) => new DartObjectImpl(typeProvider.boolType, _state.logicalNot());
+
+ /**
+ * Return the result of invoking the '||' operator on this object with the given argument.
+ *
+ * @param typeProvider the type provider used to find known types
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '||' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ DartObjectImpl logicalOr(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.boolType, _state.logicalOr(rightOperand._state));
+
+ /**
+ * Return the result of invoking the '-' operator on this object with the given argument.
+ *
+ * @param typeProvider the type provider used to find known types
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '-' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ DartObjectImpl minus(TypeProvider typeProvider, DartObjectImpl rightOperand) {
+ InstanceState result = _state.minus(rightOperand._state);
+ if (result is IntState) {
+ return new DartObjectImpl(typeProvider.intType, result);
+ } else if (result is DoubleState) {
+ return new DartObjectImpl(typeProvider.doubleType, result);
+ } else if (result is NumState) {
+ return new DartObjectImpl(typeProvider.numType, result);
+ }
+ throw new IllegalStateException("minus returned a ${result.runtimeType.toString()}");
+ }
+
+ /**
+ * Return the result of invoking the '-' operator on this object.
+ *
+ * @param typeProvider the type provider used to find known types
+ * @return the result of invoking the '-' operator on this object
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ DartObjectImpl negated(TypeProvider typeProvider) {
+ InstanceState result = _state.negated();
+ if (result is IntState) {
+ return new DartObjectImpl(typeProvider.intType, result);
+ } else if (result is DoubleState) {
+ return new DartObjectImpl(typeProvider.doubleType, result);
+ } else if (result is NumState) {
+ return new DartObjectImpl(typeProvider.numType, result);
+ }
+ throw new IllegalStateException("negated returned a ${result.runtimeType.toString()}");
+ }
+
+ /**
+ * Return the result of invoking the '!=' operator on this object with the given argument.
+ *
+ * @param typeProvider the type provider used to find known types
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '!=' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ DartObjectImpl notEqual(TypeProvider typeProvider, DartObjectImpl rightOperand) {
+ if (type != rightOperand.type) {
+ String typeName = type.name;
+ if (typeName != "bool" && typeName != "double" && typeName != "int" && typeName != "num" && typeName != "String") {
+ return new DartObjectImpl(typeProvider.boolType, BoolState.TRUE_STATE);
+ }
+ }
+ return new DartObjectImpl(typeProvider.boolType, _state.equalEqual(rightOperand._state).logicalNot());
+ }
+
+ /**
+ * Return the result of converting this object to a String.
+ *
+ * @param typeProvider the type provider used to find known types
+ * @return the result of converting this object to a String
+ * @throws EvaluationException if the object cannot be converted to a String
+ */
+ DartObjectImpl performToString(TypeProvider typeProvider) {
+ InterfaceType stringType = typeProvider.stringType;
+ if (identical(type, stringType)) {
+ return this;
+ }
+ return new DartObjectImpl(stringType, _state.convertToString());
+ }
+
+ /**
+ * Return the result of invoking the '%' operator on this object with the given argument.
+ *
+ * @param typeProvider the type provider used to find known types
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '%' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ DartObjectImpl remainder(TypeProvider typeProvider, DartObjectImpl rightOperand) {
+ InstanceState result = _state.remainder(rightOperand._state);
+ if (result is IntState) {
+ return new DartObjectImpl(typeProvider.intType, result);
+ } else if (result is DoubleState) {
+ return new DartObjectImpl(typeProvider.doubleType, result);
+ } else if (result is NumState) {
+ return new DartObjectImpl(typeProvider.numType, result);
+ }
+ throw new IllegalStateException("remainder returned a ${result.runtimeType.toString()}");
+ }
+
+ /**
+ * Return the result of invoking the '&lt;&lt;' operator on this object with the given argument.
+ *
+ * @param typeProvider the type provider used to find known types
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '&lt;&lt;' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ DartObjectImpl shiftLeft(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.intType, _state.shiftLeft(rightOperand._state));
+
+ /**
+ * Return the result of invoking the '&gt;&gt;' operator on this object with the given argument.
+ *
+ * @param typeProvider the type provider used to find known types
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '&gt;&gt;' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ DartObjectImpl shiftRight(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.intType, _state.shiftRight(rightOperand._state));
+
+ /**
+ * Return the result of invoking the '*' operator on this object with the given argument.
+ *
+ * @param typeProvider the type provider used to find known types
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '*' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ DartObjectImpl times(TypeProvider typeProvider, DartObjectImpl rightOperand) {
+ InstanceState result = _state.times(rightOperand._state);
+ if (result is IntState) {
+ return new DartObjectImpl(typeProvider.intType, result);
+ } else if (result is DoubleState) {
+ return new DartObjectImpl(typeProvider.doubleType, result);
+ } else if (result is NumState) {
+ return new DartObjectImpl(typeProvider.numType, result);
+ }
+ throw new IllegalStateException("times returned a ${result.runtimeType.toString()}");
+ }
+
+ String toString() => "${type.displayName} (${_state.toString()})";
+}
+
+/**
+ * Instances of the class `DoubleState` represent the state of an object representing a
+ * double.
+ */
+class DoubleState extends NumState {
+ /**
+ * The value of this instance.
+ */
+ final double value;
+
+ /**
+ * A state that can be used to represent a double whose value is not known.
+ */
+ static DoubleState UNKNOWN_VALUE = new DoubleState(null);
+
+ /**
+ * Initialize a newly created state to represent a double with the given value.
+ *
+ * @param value the value of this instance
+ */
+ DoubleState(this.value);
+
+ NumState add(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ if (value == null) {
+ return UNKNOWN_VALUE;
+ }
+ if (rightOperand is IntState) {
+ int rightValue = (rightOperand as IntState).value;
+ if (rightValue == null) {
+ return UNKNOWN_VALUE;
+ }
+ return new DoubleState(value + rightValue.toDouble());
+ } else if (rightOperand is DoubleState) {
+ double rightValue = (rightOperand as DoubleState).value;
+ if (rightValue == null) {
+ return UNKNOWN_VALUE;
+ }
+ return new DoubleState(value + rightValue);
+ } else if (rightOperand is DynamicState || rightOperand is NumState) {
+ return UNKNOWN_VALUE;
+ }
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+ }
+
+ StringState convertToString() {
+ if (value == null) {
+ return StringState.UNKNOWN_VALUE;
+ }
+ return new StringState(value.toString());
+ }
+
+ NumState divide(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ if (value == null) {
+ return UNKNOWN_VALUE;
+ }
+ if (rightOperand is IntState) {
+ int rightValue = (rightOperand as IntState).value;
+ if (rightValue == null) {
+ return UNKNOWN_VALUE;
+ }
+ return new DoubleState(value / rightValue.toDouble());
+ } else if (rightOperand is DoubleState) {
+ double rightValue = (rightOperand as DoubleState).value;
+ if (rightValue == null) {
+ return UNKNOWN_VALUE;
+ }
+ return new DoubleState(value / rightValue);
+ } else if (rightOperand is DynamicState || rightOperand is NumState) {
+ return UNKNOWN_VALUE;
+ }
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+ }
+
+ bool operator ==(Object object) => object is DoubleState && (value == (object as DoubleState).value);
+
+ BoolState equalEqual(InstanceState rightOperand) {
+ assertBoolNumStringOrNull(rightOperand);
+ if (value == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ if (rightOperand is DoubleState) {
+ double rightValue = (rightOperand as DoubleState).value;
+ if (rightValue == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.from(value == rightValue);
+ } else if (rightOperand is IntState) {
+ int rightValue = (rightOperand as IntState).value;
+ if (rightValue == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.from(value == rightValue.toDouble());
+ } else if (rightOperand is DynamicState || rightOperand is NumState) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.FALSE_STATE;
+ }
+
+ String get typeName => "double";
+
+ BoolState greaterThan(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ if (value == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ if (rightOperand is IntState) {
+ int rightValue = (rightOperand as IntState).value;
+ if (rightValue == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.from(value > rightValue.toDouble());
+ } else if (rightOperand is DoubleState) {
+ double rightValue = (rightOperand as DoubleState).value;
+ if (rightValue == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.from(value > rightValue);
+ } else if (rightOperand is DynamicState || rightOperand is NumState) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+ }
+
+ BoolState greaterThanOrEqual(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ if (value == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ if (rightOperand is IntState) {
+ int rightValue = (rightOperand as IntState).value;
+ if (rightValue == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.from(value >= rightValue.toDouble());
+ } else if (rightOperand is DoubleState) {
+ double rightValue = (rightOperand as DoubleState).value;
+ if (rightValue == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.from(value >= rightValue);
+ } else if (rightOperand is DynamicState || rightOperand is NumState) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+ }
+
+ int get hashCode => value == null ? 0 : value.hashCode;
+
+ IntState integerDivide(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ if (value == null) {
+ return IntState.UNKNOWN_VALUE;
+ }
+ if (rightOperand is IntState) {
+ int rightValue = (rightOperand as IntState).value;
+ if (rightValue == null) {
+ return IntState.UNKNOWN_VALUE;
+ }
+ double result = value / rightValue.toDouble();
+ return new IntState(result.toInt());
+ } else if (rightOperand is DoubleState) {
+ double rightValue = (rightOperand as DoubleState).value;
+ if (rightValue == null) {
+ return IntState.UNKNOWN_VALUE;
+ }
+ double result = value / rightValue;
+ return new IntState(result.toInt());
+ } else if (rightOperand is DynamicState || rightOperand is NumState) {
+ return IntState.UNKNOWN_VALUE;
+ }
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+ }
+
+ bool get isBoolNumStringOrNull => true;
+
+ BoolState lessThan(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ if (value == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ if (rightOperand is IntState) {
+ int rightValue = (rightOperand as IntState).value;
+ if (rightValue == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.from(value < rightValue.toDouble());
+ } else if (rightOperand is DoubleState) {
+ double rightValue = (rightOperand as DoubleState).value;
+ if (rightValue == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.from(value < rightValue);
+ } else if (rightOperand is DynamicState || rightOperand is NumState) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+ }
+
+ BoolState lessThanOrEqual(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ if (value == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ if (rightOperand is IntState) {
+ int rightValue = (rightOperand as IntState).value;
+ if (rightValue == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.from(value <= rightValue.toDouble());
+ } else if (rightOperand is DoubleState) {
+ double rightValue = (rightOperand as DoubleState).value;
+ if (rightValue == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.from(value <= rightValue);
+ } else if (rightOperand is DynamicState || rightOperand is NumState) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+ }
+
+ NumState minus(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ if (value == null) {
+ return UNKNOWN_VALUE;
+ }
+ if (rightOperand is IntState) {
+ int rightValue = (rightOperand as IntState).value;
+ if (rightValue == null) {
+ return UNKNOWN_VALUE;
+ }
+ return new DoubleState(value - rightValue.toDouble());
+ } else if (rightOperand is DoubleState) {
+ double rightValue = (rightOperand as DoubleState).value;
+ if (rightValue == null) {
+ return UNKNOWN_VALUE;
+ }
+ return new DoubleState(value - rightValue);
+ } else if (rightOperand is DynamicState || rightOperand is NumState) {
+ return UNKNOWN_VALUE;
+ }
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+ }
+
+ NumState negated() {
+ if (value == null) {
+ return UNKNOWN_VALUE;
+ }
+ return new DoubleState(-(value));
+ }
+
+ NumState remainder(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ if (value == null) {
+ return UNKNOWN_VALUE;
+ }
+ if (rightOperand is IntState) {
+ int rightValue = (rightOperand as IntState).value;
+ if (rightValue == null) {
+ return UNKNOWN_VALUE;
+ }
+ return new DoubleState(value % rightValue.toDouble());
+ } else if (rightOperand is DoubleState) {
+ double rightValue = (rightOperand as DoubleState).value;
+ if (rightValue == null) {
+ return UNKNOWN_VALUE;
+ }
+ return new DoubleState(value % rightValue);
+ } else if (rightOperand is DynamicState || rightOperand is NumState) {
+ return UNKNOWN_VALUE;
+ }
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+ }
+
+ NumState times(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ if (value == null) {
+ return UNKNOWN_VALUE;
+ }
+ if (rightOperand is IntState) {
+ int rightValue = (rightOperand as IntState).value;
+ if (rightValue == null) {
+ return UNKNOWN_VALUE;
+ }
+ return new DoubleState(value * rightValue.toDouble());
+ } else if (rightOperand is DoubleState) {
+ double rightValue = (rightOperand as DoubleState).value;
+ if (rightValue == null) {
+ return UNKNOWN_VALUE;
+ }
+ return new DoubleState(value * rightValue);
+ } else if (rightOperand is DynamicState || rightOperand is NumState) {
+ return UNKNOWN_VALUE;
+ }
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+ }
+
+ String toString() => value == null ? "-unknown-" : value.toString();
+}
+
+/**
+ * Instances of the class `DynamicState` represent the state of an object representing a Dart
+ * object for which there is no type information.
+ */
+class DynamicState extends InstanceState {
+ /**
+ * The unique instance of this class.
+ */
+ static DynamicState DYNAMIC_STATE = new DynamicState();
+
+ NumState add(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ return unknownNum(rightOperand);
+ }
+
+ IntState bitAnd(InstanceState rightOperand) {
+ assertIntOrNull(rightOperand);
+ return IntState.UNKNOWN_VALUE;
+ }
+
+ IntState bitNot() => IntState.UNKNOWN_VALUE;
+
+ IntState bitOr(InstanceState rightOperand) {
+ assertIntOrNull(rightOperand);
+ return IntState.UNKNOWN_VALUE;
+ }
+
+ IntState bitXor(InstanceState rightOperand) {
+ assertIntOrNull(rightOperand);
+ return IntState.UNKNOWN_VALUE;
+ }
+
+ StringState concatenate(InstanceState rightOperand) {
+ assertString(rightOperand);
+ return StringState.UNKNOWN_VALUE;
+ }
+
+ BoolState convertToBool() => BoolState.UNKNOWN_VALUE;
+
+ StringState convertToString() => StringState.UNKNOWN_VALUE;
+
+ NumState divide(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ return unknownNum(rightOperand);
+ }
+
+ BoolState equalEqual(InstanceState rightOperand) {
+ assertBoolNumStringOrNull(rightOperand);
+ return BoolState.UNKNOWN_VALUE;
+ }
+
+ String get typeName => "dynamic";
+
+ BoolState greaterThan(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ return BoolState.UNKNOWN_VALUE;
+ }
+
+ BoolState greaterThanOrEqual(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ return BoolState.UNKNOWN_VALUE;
+ }
+
+ IntState integerDivide(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ return IntState.UNKNOWN_VALUE;
+ }
+
+ bool get isBool => true;
+
+ bool get isBoolNumStringOrNull => true;
+
+ BoolState lessThan(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ return BoolState.UNKNOWN_VALUE;
+ }
+
+ BoolState lessThanOrEqual(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ return BoolState.UNKNOWN_VALUE;
+ }
+
+ BoolState logicalAnd(InstanceState rightOperand) {
+ assertBool(rightOperand);
+ return BoolState.UNKNOWN_VALUE;
+ }
+
+ BoolState logicalNot() => BoolState.UNKNOWN_VALUE;
+
+ BoolState logicalOr(InstanceState rightOperand) {
+ assertBool(rightOperand);
+ return rightOperand.convertToBool();
+ }
+
+ NumState minus(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ return unknownNum(rightOperand);
+ }
+
+ NumState negated() => NumState.UNKNOWN_VALUE;
+
+ NumState remainder(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ return unknownNum(rightOperand);
+ }
+
+ IntState shiftLeft(InstanceState rightOperand) {
+ assertIntOrNull(rightOperand);
+ return IntState.UNKNOWN_VALUE;
+ }
+
+ IntState shiftRight(InstanceState rightOperand) {
+ assertIntOrNull(rightOperand);
+ return IntState.UNKNOWN_VALUE;
+ }
+
+ NumState times(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ return unknownNum(rightOperand);
+ }
+
+ /**
+ * Return an object representing an unknown numeric value whose type is based on the type of the
+ * right-hand operand.
+ *
+ * @param rightOperand the operand whose type will determine the type of the result
+ * @return an object representing an unknown numeric value
+ */
+ NumState unknownNum(InstanceState rightOperand) {
+ if (rightOperand is IntState) {
+ return IntState.UNKNOWN_VALUE;
+ } else if (rightOperand is DoubleState) {
+ return DoubleState.UNKNOWN_VALUE;
+ }
+ return NumState.UNKNOWN_VALUE;
+ }
+}
+
+/**
+ * Instances of the class `EvaluationException` represent a run-time exception that would be
+ * thrown during the evaluation of Dart code.
+ */
+class EvaluationException extends JavaException {
+ /**
+ * The error code associated with the exception.
+ */
+ final ErrorCode errorCode;
+
+ /**
+ * Initialize a newly created exception to have the given error code.
+ *
+ * @param errorCode the error code associated with the exception
+ */
+ EvaluationException(this.errorCode);
+}
+
+/**
+ * Instances of the class `FunctionState` represent the state of an object representing a
+ * function.
+ */
+class FunctionState extends InstanceState {
+ /**
+ * The element representing the function being modeled.
+ */
+ ExecutableElement _element;
+
+ /**
+ * Initialize a newly created state to represent the given function.
+ *
+ * @param element the element representing the function being modeled
+ */
+ FunctionState(ExecutableElement element) {
+ this._element = element;
+ }
+
+ StringState convertToString() {
+ if (_element == null) {
+ return StringState.UNKNOWN_VALUE;
+ }
+ return new StringState(_element.name);
+ }
+
+ bool operator ==(Object object) => object is FunctionState && (_element == (object as FunctionState)._element);
+
+ BoolState equalEqual(InstanceState rightOperand) {
+ if (_element == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ if (rightOperand is FunctionState) {
+ ExecutableElement rightElement = (rightOperand as FunctionState)._element;
+ if (rightElement == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.from(_element == rightElement);
+ } else if (rightOperand is DynamicState) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.FALSE_STATE;
+ }
+
+ String get typeName => "Function";
+
+ int get hashCode => _element == null ? 0 : _element.hashCode;
+
+ String toString() => _element == null ? "-unknown-" : _element.name;
+}
+
+/**
+ * Instances of the class `GenericState` represent the state of an object representing a Dart
+ * object for which there is no more specific state.
+ */
+class GenericState extends InstanceState {
+ /**
+ * The values of the fields of this instance.
+ */
+ Map<String, DartObjectImpl> _fieldMap = new Map<String, DartObjectImpl>();
+
+ /**
+ * A state that can be used to represent an object whose state is not known.
+ */
+ static GenericState UNKNOWN_VALUE = new GenericState(new Map<String, DartObjectImpl>());
+
+ /**
+ * Initialize a newly created state to represent a newly created object.
+ *
+ * @param fieldMap the values of the fields of this instance
+ */
+ GenericState(Map<String, DartObjectImpl> fieldMap) {
+ this._fieldMap = fieldMap;
+ }
+
+ StringState convertToString() => StringState.UNKNOWN_VALUE;
+
+ bool operator ==(Object object) {
+ if (object is! GenericState) {
+ return false;
+ }
+ GenericState state = object as GenericState;
+ Set<String> otherFields = new Set<String>();
+ for (String fieldName in _fieldMap.keys.toSet()) {
+ if (_fieldMap[fieldName] != state._fieldMap[fieldName]) {
+ return false;
+ }
+ otherFields.remove(fieldName);
+ }
+ for (String fieldName in otherFields) {
+ if (state._fieldMap[fieldName] != _fieldMap[fieldName]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ BoolState equalEqual(InstanceState rightOperand) {
+ assertBoolNumStringOrNull(rightOperand);
+ if (rightOperand is DynamicState) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.from(this == rightOperand);
+ }
+
+ String get typeName => "user defined type";
+
+ int get hashCode {
+ int hashCode = 0;
+ for (DartObjectImpl value in _fieldMap.values) {
+ hashCode += value.hashCode;
+ }
+ return hashCode;
+ }
+}
+
+/**
+ * The class `InstanceState` defines the behavior of objects representing the state of a Dart
+ * object.
+ */
+abstract class InstanceState {
+ /**
+ * Return the result of invoking the '+' operator on this object with the given argument.
+ *
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '+' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ NumState add(InstanceState rightOperand) {
+ assertNumOrNull(this);
+ assertNumOrNull(rightOperand);
+ throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ }
+
+ /**
+ * Return the result of invoking the '&' operator on this object with the given argument.
+ *
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '&' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ IntState bitAnd(InstanceState rightOperand) {
+ assertIntOrNull(this);
+ assertIntOrNull(rightOperand);
+ throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ }
+
+ /**
+ * Return the result of invoking the '~' operator on this object.
+ *
+ * @return the result of invoking the '~' operator on this object
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ IntState bitNot() {
+ assertIntOrNull(this);
+ throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ }
+
+ /**
+ * Return the result of invoking the '|' operator on this object with the given argument.
+ *
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '|' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ IntState bitOr(InstanceState rightOperand) {
+ assertIntOrNull(this);
+ assertIntOrNull(rightOperand);
+ throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ }
+
+ /**
+ * Return the result of invoking the '^' operator on this object with the given argument.
+ *
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '^' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ IntState bitXor(InstanceState rightOperand) {
+ assertIntOrNull(this);
+ assertIntOrNull(rightOperand);
+ throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ }
+
+ /**
+ * Return the result of invoking the ' ' operator on this object with the given argument.
+ *
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the ' ' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ StringState concatenate(InstanceState rightOperand) {
+ throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ }
+
+ /**
+ * Return the result of applying boolean conversion to this object.
+ *
+ * @param typeProvider the type provider used to find known types
+ * @return the result of applying boolean conversion to this object
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ BoolState convertToBool() => BoolState.FALSE_STATE;
+
+ /**
+ * Return the result of converting this object to a String.
+ *
+ * @return the result of converting this object to a String
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ StringState convertToString();
+
+ /**
+ * Return the result of invoking the '/' operator on this object with the given argument.
+ *
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '/' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ NumState divide(InstanceState rightOperand) {
+ assertNumOrNull(this);
+ assertNumOrNull(rightOperand);
+ throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ }
+
+ /**
+ * Return the result of invoking the '==' operator on this object with the given argument.
+ *
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '==' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ BoolState equalEqual(InstanceState rightOperand);
+
+ /**
+ * Return the name of the type of this value.
+ *
+ * @return the name of the type of this value
+ */
+ String get typeName;
+
+ /**
+ * Return the result of invoking the '&gt;' operator on this object with the given argument.
+ *
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '&gt;' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ BoolState greaterThan(InstanceState rightOperand) {
+ assertNumOrNull(this);
+ assertNumOrNull(rightOperand);
+ throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ }
+
+ /**
+ * Return the result of invoking the '&gt;=' operator on this object with the given argument.
+ *
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '&gt;=' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ BoolState greaterThanOrEqual(InstanceState rightOperand) {
+ assertNumOrNull(this);
+ assertNumOrNull(rightOperand);
+ throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ }
+
+ /**
+ * Return the result of invoking the '~/' operator on this object with the given argument.
+ *
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '~/' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ IntState integerDivide(InstanceState rightOperand) {
+ assertNumOrNull(this);
+ assertNumOrNull(rightOperand);
+ throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ }
+
+ /**
+ * Return `true` if this object represents an object whose type is 'bool'.
+ *
+ * @return `true` if this object represents a boolean value
+ */
+ bool get isBool => false;
+
+ /**
+ * Return `true` if this object represents an object whose type is either 'bool', 'num',
+ * 'String', or 'Null'.
+ *
+ * @return `true` if this object represents either a boolean, numeric, string or null value
+ */
+ bool get isBoolNumStringOrNull => false;
+
+ /**
+ * Return the result of invoking the '&lt;' operator on this object with the given argument.
+ *
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '&lt;' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ BoolState lessThan(InstanceState rightOperand) {
+ assertNumOrNull(this);
+ assertNumOrNull(rightOperand);
+ throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ }
+
+ /**
+ * Return the result of invoking the '&lt;=' operator on this object with the given argument.
+ *
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '&lt;=' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ BoolState lessThanOrEqual(InstanceState rightOperand) {
+ assertNumOrNull(this);
+ assertNumOrNull(rightOperand);
+ throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ }
+
+ /**
+ * Return the result of invoking the '&&' operator on this object with the given argument.
+ *
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '&&' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ BoolState logicalAnd(InstanceState rightOperand) {
+ assertBool(this);
+ assertBool(rightOperand);
+ return BoolState.FALSE_STATE;
+ }
+
+ /**
+ * Return the result of invoking the '!' operator on this object.
+ *
+ * @return the result of invoking the '!' operator on this object
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ BoolState logicalNot() {
+ assertBool(this);
+ return BoolState.TRUE_STATE;
+ }
+
+ /**
+ * Return the result of invoking the '||' operator on this object with the given argument.
+ *
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '||' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ BoolState logicalOr(InstanceState rightOperand) {
+ assertBool(this);
+ assertBool(rightOperand);
+ return rightOperand.convertToBool();
+ }
+
+ /**
+ * Return the result of invoking the '-' operator on this object with the given argument.
+ *
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '-' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ NumState minus(InstanceState rightOperand) {
+ assertNumOrNull(this);
+ assertNumOrNull(rightOperand);
+ throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ }
+
+ /**
+ * Return the result of invoking the '-' operator on this object.
+ *
+ * @return the result of invoking the '-' operator on this object
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ NumState negated() {
+ assertNumOrNull(this);
+ throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ }
+
+ /**
+ * Return the result of invoking the '%' operator on this object with the given argument.
+ *
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '%' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ NumState remainder(InstanceState rightOperand) {
+ assertNumOrNull(this);
+ assertNumOrNull(rightOperand);
+ throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ }
+
+ /**
+ * Return the result of invoking the '&lt;&lt;' operator on this object with the given argument.
+ *
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '&lt;&lt;' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ IntState shiftLeft(InstanceState rightOperand) {
+ assertIntOrNull(this);
+ assertIntOrNull(rightOperand);
+ throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ }
+
+ /**
+ * Return the result of invoking the '&gt;&gt;' operator on this object with the given argument.
+ *
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '&gt;&gt;' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ IntState shiftRight(InstanceState rightOperand) {
+ assertIntOrNull(this);
+ assertIntOrNull(rightOperand);
+ throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ }
+
+ /**
+ * Return the result of invoking the '*' operator on this object with the given argument.
+ *
+ * @param rightOperand the right-hand operand of the operation
+ * @return the result of invoking the '*' operator on this object with the given argument
+ * @throws EvaluationException if the operator is not appropriate for an object of this kind
+ */
+ NumState times(InstanceState rightOperand) {
+ assertNumOrNull(this);
+ assertNumOrNull(rightOperand);
+ throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ }
+
+ /**
+ * Throw an exception if the given state does not represent a boolean value.
+ *
+ * @param state the state being tested
+ * @throws EvaluationException if the given state does not represent a boolean value
+ */
+ void assertBool(InstanceState state) {
+ if (!(state is BoolState || state is DynamicState)) {
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL);
+ }
+ }
+
+ /**
+ * Throw an exception if the given state does not represent a boolean, numeric, string or null
+ * value.
+ *
+ * @param state the state being tested
+ * @throws EvaluationException if the given state does not represent a boolean, numeric, string or
+ * null value
+ */
+ void assertBoolNumStringOrNull(InstanceState state) {
+ if (!(state is BoolState || state is DoubleState || state is IntState || state is NumState || state is StringState || state is NullState || state is DynamicState)) {
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING);
+ }
+ }
+
+ /**
+ * Throw an exception if the given state does not represent an integer or null value.
+ *
+ * @param state the state being tested
+ * @throws EvaluationException if the given state does not represent an integer or null value
+ */
+ void assertIntOrNull(InstanceState state) {
+ if (!(state is IntState || state is NumState || state is NullState || state is DynamicState)) {
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
+ }
+ }
+
+ /**
+ * Throw an exception if the given state does not represent a boolean, numeric, string or null
+ * value.
+ *
+ * @param state the state being tested
+ * @throws EvaluationException if the given state does not represent a boolean, numeric, string or
+ * null value
+ */
+ void assertNumOrNull(InstanceState state) {
+ if (!(state is DoubleState || state is IntState || state is NumState || state is NullState || state is DynamicState)) {
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
+ }
+ }
+
+ /**
+ * Throw an exception if the given state does not represent a String value.
+ *
+ * @param state the state being tested
+ * @throws EvaluationException if the given state does not represent a String value
+ */
+ void assertString(InstanceState state) {
+ if (!(state is StringState || state is DynamicState)) {
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL);
+ }
+ }
+}
+
+/**
+ * Instances of the class `IntState` represent the state of an object representing an int.
+ */
+class IntState extends NumState {
+ /**
+ * The value of this instance.
+ */
+ final int value;
+
+ /**
+ * A state that can be used to represent an int whose value is not known.
+ */
+ static IntState UNKNOWN_VALUE = new IntState(null);
+
+ /**
+ * Initialize a newly created state to represent an int with the given value.
+ *
+ * @param value the value of this instance
+ */
+ IntState(this.value);
+
+ NumState add(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ if (value == null) {
+ if (rightOperand is DoubleState) {
+ return DoubleState.UNKNOWN_VALUE;
+ }
+ return UNKNOWN_VALUE;
+ }
+ if (rightOperand is IntState) {
+ int rightValue = (rightOperand as IntState).value;
+ if (rightValue == null) {
+ return UNKNOWN_VALUE;
+ }
+ return new IntState(value + rightValue);
+ } else if (rightOperand is DoubleState) {
+ double rightValue = (rightOperand as DoubleState).value;
+ if (rightValue == null) {
+ return DoubleState.UNKNOWN_VALUE;
+ }
+ return new DoubleState(value.toDouble() + rightValue);
+ } else if (rightOperand is DynamicState || rightOperand is NumState) {
+ return UNKNOWN_VALUE;
+ }
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+ }
+
+ IntState bitAnd(InstanceState rightOperand) {
+ assertIntOrNull(rightOperand);
+ if (value == null) {
+ return UNKNOWN_VALUE;
+ }
+ if (rightOperand is IntState) {
+ int rightValue = (rightOperand as IntState).value;
+ if (rightValue == null) {
+ return UNKNOWN_VALUE;
+ }
+ return new IntState(value & rightValue);
+ } else if (rightOperand is DynamicState || rightOperand is NumState) {
+ return UNKNOWN_VALUE;
+ }
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+ }
+
+ IntState bitNot() {
+ if (value == null) {
+ return UNKNOWN_VALUE;
+ }
+ return new IntState(~value);
+ }
+
+ IntState bitOr(InstanceState rightOperand) {
+ assertIntOrNull(rightOperand);
+ if (value == null) {
+ return UNKNOWN_VALUE;
+ }
+ if (rightOperand is IntState) {
+ int rightValue = (rightOperand as IntState).value;
+ if (rightValue == null) {
+ return UNKNOWN_VALUE;
+ }
+ return new IntState(value | rightValue);
+ } else if (rightOperand is DynamicState || rightOperand is NumState) {
+ return UNKNOWN_VALUE;
+ }
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+ }
+
+ IntState bitXor(InstanceState rightOperand) {
+ assertIntOrNull(rightOperand);
+ if (value == null) {
+ return UNKNOWN_VALUE;
+ }
+ if (rightOperand is IntState) {
+ int rightValue = (rightOperand as IntState).value;
+ if (rightValue == null) {
+ return UNKNOWN_VALUE;
+ }
+ return new IntState(value ^ rightValue);
+ } else if (rightOperand is DynamicState || rightOperand is NumState) {
+ return UNKNOWN_VALUE;
+ }
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+ }
+
+ StringState convertToString() {
+ if (value == null) {
+ return StringState.UNKNOWN_VALUE;
+ }
+ return new StringState(value.toString());
+ }
+
+ NumState divide(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ if (value == null) {
+ if (rightOperand is DoubleState) {
+ return DoubleState.UNKNOWN_VALUE;
+ }
+ return UNKNOWN_VALUE;
+ }
+ if (rightOperand is IntState) {
+ int rightValue = (rightOperand as IntState).value;
+ if (rightValue == null) {
+ return UNKNOWN_VALUE;
+ } else if (rightValue == 0) {
+ return new DoubleState(value.toDouble() / rightValue.toDouble());
+ }
+ return new IntState(value ~/ rightValue);
+ } else if (rightOperand is DoubleState) {
+ double rightValue = (rightOperand as DoubleState).value;
+ if (rightValue == null) {
+ return DoubleState.UNKNOWN_VALUE;
+ }
+ return new DoubleState(value.toDouble() / rightValue);
+ } else if (rightOperand is DynamicState || rightOperand is NumState) {
+ return UNKNOWN_VALUE;
+ }
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+ }
+
+ bool operator ==(Object object) => object is IntState && (value == (object as IntState).value);
+
+ BoolState equalEqual(InstanceState rightOperand) {
+ assertBoolNumStringOrNull(rightOperand);
+ if (value == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ if (rightOperand is IntState) {
+ int rightValue = (rightOperand as IntState).value;
+ if (rightValue == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.from(value == rightValue);
+ } else if (rightOperand is DoubleState) {
+ double rightValue = (rightOperand as DoubleState).value;
+ if (rightValue == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.from(rightValue == value.toDouble());
+ } else if (rightOperand is DynamicState || rightOperand is NumState) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.FALSE_STATE;
+ }
+
+ String get typeName => "int";
+
+ BoolState greaterThan(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ if (value == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ if (rightOperand is IntState) {
+ int rightValue = (rightOperand as IntState).value;
+ if (rightValue == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.from(value.compareTo(rightValue) > 0);
+ } else if (rightOperand is DoubleState) {
+ double rightValue = (rightOperand as DoubleState).value;
+ if (rightValue == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.from(value.toDouble() > rightValue);
+ } else if (rightOperand is DynamicState || rightOperand is NumState) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+ }
+
+ BoolState greaterThanOrEqual(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ if (value == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ if (rightOperand is IntState) {
+ int rightValue = (rightOperand as IntState).value;
+ if (rightValue == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.from(value.compareTo(rightValue) >= 0);
+ } else if (rightOperand is DoubleState) {
+ double rightValue = (rightOperand as DoubleState).value;
+ if (rightValue == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.from(value.toDouble() >= rightValue);
+ } else if (rightOperand is DynamicState || rightOperand is NumState) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+ }
+
+ int get hashCode => value == null ? 0 : value.hashCode;
+
+ IntState integerDivide(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ if (value == null) {
+ return UNKNOWN_VALUE;
+ }
+ if (rightOperand is IntState) {
+ int rightValue = (rightOperand as IntState).value;
+ if (rightValue == null) {
+ return UNKNOWN_VALUE;
+ } else if (rightValue == 0) {
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE);
+ }
+ return new IntState(value ~/ rightValue);
+ } else if (rightOperand is DoubleState) {
+ double rightValue = (rightOperand as DoubleState).value;
+ if (rightValue == null) {
+ return UNKNOWN_VALUE;
+ }
+ double result = value.toDouble() / rightValue;
+ return new IntState(result.toInt());
+ } else if (rightOperand is DynamicState || rightOperand is NumState) {
+ return UNKNOWN_VALUE;
+ }
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+ }
+
+ bool get isBoolNumStringOrNull => true;
+
+ BoolState lessThan(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ if (value == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ if (rightOperand is IntState) {
+ int rightValue = (rightOperand as IntState).value;
+ if (rightValue == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.from(value.compareTo(rightValue) < 0);
+ } else if (rightOperand is DoubleState) {
+ double rightValue = (rightOperand as DoubleState).value;
+ if (rightValue == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.from(value.toDouble() < rightValue);
+ } else if (rightOperand is DynamicState || rightOperand is NumState) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+ }
+
+ BoolState lessThanOrEqual(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ if (value == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ if (rightOperand is IntState) {
+ int rightValue = (rightOperand as IntState).value;
+ if (rightValue == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.from(value.compareTo(rightValue) <= 0);
+ } else if (rightOperand is DoubleState) {
+ double rightValue = (rightOperand as DoubleState).value;
+ if (rightValue == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.from(value.toDouble() <= rightValue);
+ } else if (rightOperand is DynamicState || rightOperand is NumState) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+ }
+
+ NumState minus(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ if (value == null) {
+ if (rightOperand is DoubleState) {
+ return DoubleState.UNKNOWN_VALUE;
+ }
+ return UNKNOWN_VALUE;
+ }
+ if (rightOperand is IntState) {
+ int rightValue = (rightOperand as IntState).value;
+ if (rightValue == null) {
+ return UNKNOWN_VALUE;
+ }
+ return new IntState(value - rightValue);
+ } else if (rightOperand is DoubleState) {
+ double rightValue = (rightOperand as DoubleState).value;
+ if (rightValue == null) {
+ return DoubleState.UNKNOWN_VALUE;
+ }
+ return new DoubleState(value.toDouble() - rightValue);
+ } else if (rightOperand is DynamicState || rightOperand is NumState) {
+ return UNKNOWN_VALUE;
+ }
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+ }
+
+ NumState negated() {
+ if (value == null) {
+ return UNKNOWN_VALUE;
+ }
+ return new IntState(-value);
+ }
+
+ NumState remainder(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ if (value == null) {
+ if (rightOperand is DoubleState) {
+ return DoubleState.UNKNOWN_VALUE;
+ }
+ return UNKNOWN_VALUE;
+ }
+ if (rightOperand is IntState) {
+ int rightValue = (rightOperand as IntState).value;
+ if (rightValue == null) {
+ return UNKNOWN_VALUE;
+ } else if (rightValue == 0) {
+ return new DoubleState(value.toDouble() % rightValue.toDouble());
+ }
+ return new IntState(value.remainder(rightValue));
+ } else if (rightOperand is DoubleState) {
+ double rightValue = (rightOperand as DoubleState).value;
+ if (rightValue == null) {
+ return DoubleState.UNKNOWN_VALUE;
+ }
+ return new DoubleState(value.toDouble() % rightValue);
+ } else if (rightOperand is DynamicState || rightOperand is NumState) {
+ return UNKNOWN_VALUE;
+ }
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+ }
+
+ IntState shiftLeft(InstanceState rightOperand) {
+ assertIntOrNull(rightOperand);
+ if (value == null) {
+ return UNKNOWN_VALUE;
+ }
+ if (rightOperand is IntState) {
+ int rightValue = (rightOperand as IntState).value;
+ if (rightValue == null) {
+ return UNKNOWN_VALUE;
+ } else if (rightValue.bitLength > 31) {
+ return UNKNOWN_VALUE;
+ }
+ return new IntState(value << rightValue);
+ } else if (rightOperand is DynamicState || rightOperand is NumState) {
+ return UNKNOWN_VALUE;
+ }
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+ }
+
+ IntState shiftRight(InstanceState rightOperand) {
+ assertIntOrNull(rightOperand);
+ if (value == null) {
+ return UNKNOWN_VALUE;
+ }
+ if (rightOperand is IntState) {
+ int rightValue = (rightOperand as IntState).value;
+ if (rightValue == null) {
+ return UNKNOWN_VALUE;
+ } else if (rightValue.bitLength > 31) {
+ return UNKNOWN_VALUE;
+ }
+ return new IntState(value >> rightValue);
+ } else if (rightOperand is DynamicState || rightOperand is NumState) {
+ return UNKNOWN_VALUE;
+ }
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+ }
+
+ NumState times(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ if (value == null) {
+ if (rightOperand is DoubleState) {
+ return DoubleState.UNKNOWN_VALUE;
+ }
+ return UNKNOWN_VALUE;
+ }
+ if (rightOperand is IntState) {
+ int rightValue = (rightOperand as IntState).value;
+ if (rightValue == null) {
+ return UNKNOWN_VALUE;
+ }
+ return new IntState(value * rightValue);
+ } else if (rightOperand is DoubleState) {
+ double rightValue = (rightOperand as DoubleState).value;
+ if (rightValue == null) {
+ return DoubleState.UNKNOWN_VALUE;
+ }
+ return new DoubleState(value.toDouble() * rightValue);
+ } else if (rightOperand is DynamicState || rightOperand is NumState) {
+ return UNKNOWN_VALUE;
+ }
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+ }
+
+ String toString() => value == null ? "-unknown-" : value.toString();
+}
+
+/**
+ * The unique instance of the class `ListState` represents the state of an object representing
+ * a list.
+ */
+class ListState extends InstanceState {
+ /**
+ * The elements of the list.
+ */
+ List<DartObjectImpl> _elements;
/**
- * Return an error result that is the union of the two given error results.
+ * Initialize a newly created state to represent a list with the given elements.
*
- * @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
+ * @param elements the elements of the list
+ */
+ ListState(List<DartObjectImpl> elements) {
+ this._elements = elements;
+ }
+
+ StringState convertToString() => StringState.UNKNOWN_VALUE;
+
+ bool operator ==(Object object) {
+ if (object is! ListState) {
+ return false;
+ }
+ List<DartObjectImpl> otherElements = (object as ListState)._elements;
+ int count = _elements.length;
+ if (otherElements.length != count) {
+ return false;
+ } else if (count == 0) {
+ return true;
+ }
+ for (int i = 0; i < count; i++) {
+ if (_elements[i] != otherElements[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ BoolState equalEqual(InstanceState rightOperand) {
+ assertBoolNumStringOrNull(rightOperand);
+ if (rightOperand is DynamicState) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.from(this == rightOperand);
+ }
+
+ String get typeName => "List";
+
+ int get hashCode {
+ int value = 0;
+ int count = _elements.length;
+ for (int i = 0; i < count; i++) {
+ value = (value << 3) ^ _elements[i].hashCode;
+ }
+ return value;
+ }
+}
+
+/**
+ * The unique instance of the class `ListState` represents the state of an object representing
+ * a map.
+ */
+class MapState extends InstanceState {
+ /**
+ * The entries in the map.
*/
- ErrorResult union(ErrorResult firstError, ErrorResult secondError) => new ErrorResult.con2(firstError, secondError);
+ Map<DartObjectImpl, DartObjectImpl> _entries;
/**
- * Return a result object representing the given value.
+ * Initialize a newly created state to represent a map with the given entries.
*
- * @param value the value to be represented as a result object
- * @return a result object representing the given value
+ * @param entries the entries in the map
+ */
+ MapState(Map<DartObjectImpl, DartObjectImpl> entries) {
+ this._entries = entries;
+ }
+
+ StringState convertToString() => StringState.UNKNOWN_VALUE;
+
+ bool operator ==(Object object) {
+ if (object is! MapState) {
+ return false;
+ }
+ Map<DartObjectImpl, DartObjectImpl> otherElements = (object as MapState)._entries;
+ int count = _entries.length;
+ if (otherElements.length != count) {
+ return false;
+ } else if (count == 0) {
+ return true;
+ }
+ for (MapEntry<DartObjectImpl, DartObjectImpl> entry in getMapEntrySet(_entries)) {
+ DartObjectImpl key = entry.getKey();
+ DartObjectImpl value = entry.getValue();
+ DartObjectImpl otherValue = otherElements[key];
+ if (value != otherValue) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ BoolState equalEqual(InstanceState rightOperand) {
+ assertBoolNumStringOrNull(rightOperand);
+ if (rightOperand is DynamicState) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.from(this == rightOperand);
+ }
+
+ String get typeName => "Map";
+
+ int get hashCode {
+ int value = 0;
+ for (DartObjectImpl key in _entries.keys.toSet()) {
+ value = (value << 3) ^ key.hashCode;
+ }
+ return value;
+ }
+}
+
+/**
+ * The unique instance of the class `NullState` represents the state of the value 'null'.
+ */
+class NullState extends InstanceState {
+ /**
+ * An instance representing the boolean value 'true'.
*/
- ValidResult valueOf(int value) => new ValidResult(value);
+ static NullState NULL_STATE = new NullState();
+
+ BoolState convertToBool() {
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+ }
+
+ StringState convertToString() => new StringState("null");
+
+ BoolState equalEqual(InstanceState rightOperand) {
+ assertBoolNumStringOrNull(rightOperand);
+ if (rightOperand is DynamicState) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.from(rightOperand is NullState);
+ }
+
+ bool operator ==(Object object) => object is NullState;
+
+ String get typeName => "Null";
+
+ int get hashCode => 0;
+
+ bool get isBoolNumStringOrNull => true;
+
+ BoolState logicalNot() {
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+ }
+
+ String toString() => "null";
+}
+/**
+ * Instances of the class `NumState` represent the state of an object representing a number of
+ * an unknown type (a 'num').
+ */
+class NumState extends InstanceState {
/**
- * Return a result object representing the given value.
+ * A state that can be used to represent a number whose value is not known.
+ */
+ static NumState UNKNOWN_VALUE = new NumState();
+
+ NumState add(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ return UNKNOWN_VALUE;
+ }
+
+ StringState convertToString() => StringState.UNKNOWN_VALUE;
+
+ NumState divide(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ return UNKNOWN_VALUE;
+ }
+
+ bool operator ==(Object object) => object is NumState;
+
+ BoolState equalEqual(InstanceState rightOperand) {
+ assertBoolNumStringOrNull(rightOperand);
+ return BoolState.UNKNOWN_VALUE;
+ }
+
+ String get typeName => "num";
+
+ BoolState greaterThan(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ return BoolState.UNKNOWN_VALUE;
+ }
+
+ BoolState greaterThanOrEqual(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ return BoolState.UNKNOWN_VALUE;
+ }
+
+ int get hashCode => 7;
+
+ IntState integerDivide(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ if (rightOperand is IntState) {
+ int rightValue = (rightOperand as IntState).value;
+ if (rightValue == null) {
+ return IntState.UNKNOWN_VALUE;
+ } else if (rightValue == 0) {
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE);
+ }
+ } else if (rightOperand is DynamicState) {
+ return IntState.UNKNOWN_VALUE;
+ }
+ return IntState.UNKNOWN_VALUE;
+ }
+
+ bool get isBoolNumStringOrNull => true;
+
+ BoolState lessThan(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ return BoolState.UNKNOWN_VALUE;
+ }
+
+ BoolState lessThanOrEqual(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ return BoolState.UNKNOWN_VALUE;
+ }
+
+ NumState minus(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ return UNKNOWN_VALUE;
+ }
+
+ NumState negated() => UNKNOWN_VALUE;
+
+ NumState remainder(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ return UNKNOWN_VALUE;
+ }
+
+ NumState times(InstanceState rightOperand) {
+ assertNumOrNull(rightOperand);
+ return UNKNOWN_VALUE;
+ }
+
+ String toString() => "-unknown-";
+}
+
+/**
+ * Instances of the class `StringState` represent the state of an object representing a
+ * string.
+ */
+class StringState extends InstanceState {
+ /**
+ * The value of this instance.
+ */
+ final String value;
+
+ /**
+ * A state that can be used to represent a double whose value is not known.
+ */
+ static StringState UNKNOWN_VALUE = new StringState(null);
+
+ /**
+ * Initialize a newly created state to represent the given value.
*
- * @param value the value to be represented as a result object
- * @return a result object representing the given value
+ * @param value the value of this instance
+ */
+ StringState(this.value);
+
+ StringState concatenate(InstanceState rightOperand) {
+ if (value == null) {
+ return UNKNOWN_VALUE;
+ }
+ if (rightOperand is StringState) {
+ String rightValue = (rightOperand as StringState).value;
+ if (rightValue == null) {
+ return UNKNOWN_VALUE;
+ }
+ return new StringState("${value}${rightValue}");
+ } else if (rightOperand is DynamicState) {
+ return UNKNOWN_VALUE;
+ }
+ return super.concatenate(rightOperand);
+ }
+
+ StringState convertToString() => this;
+
+ bool operator ==(Object object) => object is StringState && (value == (object as StringState).value);
+
+ BoolState equalEqual(InstanceState rightOperand) {
+ assertBoolNumStringOrNull(rightOperand);
+ if (value == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ if (rightOperand is StringState) {
+ String rightValue = (rightOperand as StringState).value;
+ if (rightValue == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.from(value == rightValue);
+ } else if (rightOperand is DynamicState) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.FALSE_STATE;
+ }
+
+ String get typeName => "String";
+
+ int get hashCode => value == null ? 0 : value.hashCode;
+
+ bool get isBoolNumStringOrNull => true;
+
+ String toString() => value == null ? "-unknown-" : "'${value}'";
+}
+
+/**
+ * Instances of the class `StringState` represent the state of an object representing a
+ * symbol.
+ */
+class SymbolState extends InstanceState {
+ /**
+ * The value of this instance.
*/
- ValidResult valueOf2(bool value) => value ? RESULT_TRUE : RESULT_FALSE;
+ final String value;
/**
- * Return a result object representing the given value.
+ * Initialize a newly created state to represent the given value.
*
- * @param value the value to be represented as a result object
- * @return a result object representing the given value
+ * @param value the value of this instance
+ */
+ SymbolState(this.value);
+
+ StringState convertToString() {
+ if (value == null) {
+ return StringState.UNKNOWN_VALUE;
+ }
+ return new StringState(value);
+ }
+
+ bool operator ==(Object object) => object is SymbolState && (value == (object as SymbolState).value);
+
+ BoolState equalEqual(InstanceState rightOperand) {
+ assertBoolNumStringOrNull(rightOperand);
+ if (value == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ if (rightOperand is SymbolState) {
+ String rightValue = (rightOperand as SymbolState).value;
+ if (rightValue == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.from(value == rightValue);
+ } else if (rightOperand is DynamicState) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.FALSE_STATE;
+ }
+
+ String get typeName => "Symbol";
+
+ int get hashCode => value == null ? 0 : value.hashCode;
+
+ String toString() => value == null ? "-unknown-" : "#${value}";
+}
+
+/**
+ * Instances of the class `TypeState` represent the state of an object representing a type.
+ */
+class TypeState extends InstanceState {
+ /**
+ * The element representing the type being modeled.
*/
- ValidResult valueOf3(double value) => new ValidResult(value);
+ Element _element;
/**
- * Return a result object representing the given value.
+ * Initialize a newly created state to represent the given value.
*
- * @param value the value to be represented as a result object
- * @return a result object representing the given value
+ * @param element the element representing the type being modeled
*/
- ValidResult valueOf4(String value) => new ValidResult(value);
+ TypeState(Element element) {
+ this._element = element;
+ }
+
+ StringState convertToString() {
+ if (_element == null) {
+ return StringState.UNKNOWN_VALUE;
+ }
+ return new StringState(_element.name);
+ }
+
+ bool operator ==(Object object) => object is TypeState && (_element == (object as TypeState)._element);
+
+ BoolState equalEqual(InstanceState rightOperand) {
+ assertBoolNumStringOrNull(rightOperand);
+ if (_element == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ if (rightOperand is TypeState) {
+ Element rightElement = (rightOperand as TypeState)._element;
+ if (rightElement == null) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.from(_element == rightElement);
+ } else if (rightOperand is DynamicState) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.FALSE_STATE;
+ }
+
+ String get typeName => "Type";
+
+ int get hashCode => _element == null ? 0 : _element.hashCode;
+
+ String toString() => _element == null ? "-unknown-" : _element.name;
}

Powered by Google App Engine
This is Rietveld 408576698