| 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 967a31cbe898eb9d99bea861da9f04cf63c6fd0e..b2dd26104132e7d2f9ff94a4d13e87cc176b1258 100644
|
| --- a/pkg/analyzer/lib/src/generated/constant.dart
|
| +++ b/pkg/analyzer/lib/src/generated/constant.dart
|
| @@ -20,6 +20,128 @@ import 'utilities_dart.dart' show ParameterKind;
|
| import 'utilities_collection.dart';
|
|
|
| /**
|
| + * Instances of the class `BoolState` represent the state of an object representing a boolean
|
| + * value.
|
| + */
|
| +class BoolState extends InstanceState {
|
| + /**
|
| + * The value of this instance.
|
| + */
|
| + final bool value;
|
| +
|
| + /**
|
| + * An instance representing the boolean value 'false'.
|
| + */
|
| + static BoolState FALSE_STATE = new BoolState(false);
|
| +
|
| + /**
|
| + * An instance representing the boolean value 'true'.
|
| + */
|
| + static BoolState TRUE_STATE = new BoolState(true);
|
| +
|
| + /**
|
| + * A state that can be used to represent a boolean whose value is not known.
|
| + */
|
| + static BoolState UNKNOWN_VALUE = new BoolState(null);
|
| +
|
| + /**
|
| + * 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
|
| + */
|
| + static BoolState from(bool value) => value ? BoolState.TRUE_STATE : BoolState.FALSE_STATE;
|
| +
|
| + /**
|
| + * Initialize a newly created state to represent the given value.
|
| + *
|
| + * @param value the value of this instance
|
| + */
|
| + BoolState(this.value);
|
| +
|
| + @override
|
| + BoolState convertToBool() => this;
|
| +
|
| + @override
|
| + StringState convertToString() {
|
| + if (value == null) {
|
| + return StringState.UNKNOWN_VALUE;
|
| + }
|
| + return new StringState(value ? "true" : "false");
|
| + }
|
| +
|
| + @override
|
| + BoolState equalEqual(InstanceState rightOperand) {
|
| + assertBoolNumStringOrNull(rightOperand);
|
| + if (value == null) {
|
| + return UNKNOWN_VALUE;
|
| + }
|
| + if (rightOperand is BoolState) {
|
| + bool rightValue = rightOperand.value;
|
| + if (rightValue == null) {
|
| + return UNKNOWN_VALUE;
|
| + }
|
| + return BoolState.from(identical(value, rightValue));
|
| + } else if (rightOperand is DynamicState) {
|
| + return UNKNOWN_VALUE;
|
| + }
|
| + return FALSE_STATE;
|
| + }
|
| +
|
| + @override
|
| + bool operator ==(Object object) => object is BoolState && identical(value, object.value);
|
| +
|
| + @override
|
| + String get typeName => "bool";
|
| +
|
| + @override
|
| + bool get hasExactValue => true;
|
| +
|
| + @override
|
| + 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
|
| + */
|
| + @override
|
| + bool get isBool => true;
|
| +
|
| + @override
|
| + bool get isBoolNumStringOrNull => true;
|
| +
|
| + @override
|
| + BoolState logicalAnd(InstanceState rightOperand) {
|
| + assertBool(rightOperand);
|
| + if (value == null) {
|
| + return UNKNOWN_VALUE;
|
| + }
|
| + return value ? rightOperand.convertToBool() : FALSE_STATE;
|
| + }
|
| +
|
| + @override
|
| + BoolState logicalNot() {
|
| + if (value == null) {
|
| + return UNKNOWN_VALUE;
|
| + }
|
| + return value ? FALSE_STATE : TRUE_STATE;
|
| + }
|
| +
|
| + @override
|
| + BoolState logicalOr(InstanceState rightOperand) {
|
| + assertBool(rightOperand);
|
| + if (value == null) {
|
| + return UNKNOWN_VALUE;
|
| + }
|
| + return value ? TRUE_STATE : rightOperand.convertToBool();
|
| + }
|
| +
|
| + @override
|
| + String toString() => value == null ? "-unknown-" : (value ? "true" : "false");
|
| +}
|
| +
|
| +/**
|
| * Instances of the class `ConstantEvaluator` evaluate constant expressions to produce their
|
| * compile-time value. According to the Dart Language Specification: <blockquote> A constant
|
| * expression is one of the following:
|
| @@ -96,257 +218,116 @@ class ConstantEvaluator {
|
| }
|
|
|
| /**
|
| - * The interface `DartObject` defines the behavior of objects that represent the state of a
|
| - * Dart object.
|
| + * Instances of the class `ConstantFinder` are used to traverse the AST structures of all of
|
| + * the compilation units being resolved and build a table mapping constant variable elements to the
|
| + * declarations of those variables.
|
| */
|
| -abstract class DartObject {
|
| +class ConstantFinder extends RecursiveAstVisitor<Object> {
|
| /**
|
| - * 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
|
| + * A table mapping constant variable elements to the declarations of those variables.
|
| */
|
| - bool get boolValue;
|
| + final Map<VariableElement, VariableDeclaration> variableMap = new Map<VariableElement, VariableDeclaration>();
|
|
|
| - /**
|
| - * 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;
|
| + @override
|
| + Object visitVariableDeclaration(VariableDeclaration node) {
|
| + super.visitVariableDeclaration(node);
|
| + Expression initializer = node.initializer;
|
| + if (initializer != null && node.isConst) {
|
| + VariableElement element = node.element;
|
| + if (element != null) {
|
| + variableMap[element] = node;
|
| + }
|
| + }
|
| + return null;
|
| + }
|
| +}
|
|
|
| +/**
|
| + * Instances of the class `ConstantValueComputer` compute the values of constant variables in
|
| + * one or more compilation units. The expected usage pattern is for the compilation units to be
|
| + * added to this computer using the method [add] and then for the method
|
| + * [computeValues] to be invoked exactly once. Any use of an instance after invoking the
|
| + * method [computeValues] will result in unpredictable behavior.
|
| + */
|
| +class ConstantValueComputer {
|
| /**
|
| - * 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
|
| + * The type provider used to access the known types.
|
| */
|
| - int get intValue;
|
| + final TypeProvider _typeProvider;
|
|
|
| /**
|
| - * 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
|
| + * The object used to find constant variables in the compilation units that were added.
|
| */
|
| - String get stringValue;
|
| + ConstantFinder _constantFinder = new ConstantFinder();
|
|
|
| /**
|
| - * Return the run-time type of this object.
|
| - *
|
| - * @return the run-time type of this object
|
| + * A graph in which the nodes are the constant variables and the edges are from each variable to
|
| + * the other constant variables that are referenced in the head's initializer.
|
| */
|
| - InterfaceType get type;
|
| + DirectedGraph<VariableElement> _referenceGraph = new DirectedGraph<VariableElement>();
|
|
|
| /**
|
| - * Return this object's value if it can be represented exactly, or `null` if either the
|
| - * value cannot be represented exactly or if the value is `null`. Clients should use
|
| - * [hasExactValue] to distinguish between these two cases.
|
| - *
|
| - * @return this object's value
|
| + * A table mapping constant variables to the declarations of those variables.
|
| */
|
| - Object get value;
|
| + Map<VariableElement, VariableDeclaration> _declarationMap;
|
|
|
| /**
|
| - * Return `true` if this object's value can be represented exactly.
|
| + * Initialize a newly created constant value computer.
|
| *
|
| - * @return `true` if this object's value can be represented exactly
|
| + * @param typeProvider the type provider used to access known types
|
| */
|
| - bool get hasExactValue;
|
| + ConstantValueComputer(this._typeProvider);
|
|
|
| /**
|
| - * Return `true` if this object represents the value 'false'.
|
| + * Add the constant variables in the given compilation unit to the list of constant variables
|
| + * whose value needs to be computed.
|
| *
|
| - * @return `true` if this object represents the value 'false'
|
| + * @param unit the compilation unit defining the constant variables to be added
|
| */
|
| - bool get isFalse;
|
| + void add(CompilationUnit unit) {
|
| + unit.accept(_constantFinder);
|
| + }
|
|
|
| /**
|
| - * Return `true` if this object represents the value 'null'.
|
| - *
|
| - * @return `true` if this object represents the value 'null'
|
| + * Compute values for all of the constant variables in the compilation units that were added.
|
| */
|
| - bool get isNull;
|
| + void computeValues() {
|
| + _declarationMap = _constantFinder.variableMap;
|
| + for (MapEntry<VariableElement, VariableDeclaration> entry in getMapEntrySet(_declarationMap)) {
|
| + VariableElement element = entry.getKey();
|
| + ReferenceFinder referenceFinder = new ReferenceFinder(element, _referenceGraph);
|
| + _referenceGraph.addNode(element);
|
| + entry.getValue().initializer.accept(referenceFinder);
|
| + }
|
| + while (!_referenceGraph.isEmpty) {
|
| + VariableElement element = _referenceGraph.removeSink();
|
| + while (element != null) {
|
| + _computeValueFor(element);
|
| + element = _referenceGraph.removeSink();
|
| + }
|
| + if (!_referenceGraph.isEmpty) {
|
| + List<VariableElement> variablesInCycle = _referenceGraph.findCycle();
|
| + if (variablesInCycle == null) {
|
| + //
|
| + // This should not happen. Either the graph should be empty, or there should be at least
|
| + // one sink, or there should be a cycle. If this does happen we exit to prevent an
|
| + // infinite loop.
|
| + //
|
| + 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) {
|
| + _generateCycleError(variablesInCycle, variable);
|
| + }
|
| + _referenceGraph.removeAllNodes(variablesInCycle);
|
| + }
|
| + }
|
| + }
|
|
|
| /**
|
| - * Return `true` if this object represents the value 'true'.
|
| + * Compute a value for the given variable.
|
| *
|
| - * @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.
|
| - */
|
| -class EvaluationResult {
|
| - /**
|
| - * Return an evaluation result representing the result of evaluating an expression that is not a
|
| - * compile-time constant because of the given errors.
|
| - *
|
| - * @param errors the errors that should be reported for the expression(s) that were evaluated
|
| - * @return the result of evaluating an expression that is not a compile-time constant
|
| - */
|
| - static EvaluationResult forErrors(List<AnalysisError> errors) => new EvaluationResult(null, errors);
|
| -
|
| - /**
|
| - * Return an evaluation result representing the result of evaluating an expression that is a
|
| - * compile-time constant that evaluates to the given value.
|
| - *
|
| - * @param value the value of the expression
|
| - * @return the result of evaluating an expression that is a compile-time constant
|
| - */
|
| - static EvaluationResult forValue(DartObject value) => new EvaluationResult(value, null);
|
| -
|
| - /**
|
| - * The value of the expression.
|
| - */
|
| - final DartObject value;
|
| -
|
| - /**
|
| - * The errors that should be reported for the expression(s) that were evaluated.
|
| - */
|
| - final List<AnalysisError> _errors;
|
| -
|
| - /**
|
| - * Initialize a newly created result object with the given state. Clients should use one of the
|
| - * factory methods: [forErrors] and [forValue].
|
| - *
|
| - * @param value the value of the expression
|
| - * @param errors the errors that should be reported for the expression(s) that were evaluated
|
| - */
|
| - EvaluationResult(this.value, this._errors);
|
| -
|
| - /**
|
| - * Return an array containing the errors that should be reported for the expression(s) that were
|
| - * evaluated. If there are no such errors, the array will be empty. The array can be empty even if
|
| - * the expression is not a valid compile time constant if the errors would have been reported by
|
| - * other parts of the analysis engine.
|
| - */
|
| - List<AnalysisError> get errors => _errors == null ? AnalysisError.NO_ERRORS : _errors;
|
| -
|
| - /**
|
| - * Return `true` if the expression is a compile-time constant expression that would not
|
| - * throw an exception when evaluated.
|
| - *
|
| - * @return `true` if the expression is a valid compile-time constant expression
|
| - */
|
| - bool get isValid => _errors == null;
|
| -}
|
| -
|
| -/**
|
| - * Instances of the class `ConstantFinder` are used to traverse the AST structures of all of
|
| - * the compilation units being resolved and build a table mapping constant variable elements to the
|
| - * declarations of those variables.
|
| - */
|
| -class ConstantFinder extends RecursiveAstVisitor<Object> {
|
| - /**
|
| - * A table mapping constant variable elements to the declarations of those variables.
|
| - */
|
| - final Map<VariableElement, VariableDeclaration> variableMap = new Map<VariableElement, VariableDeclaration>();
|
| -
|
| - @override
|
| - Object visitVariableDeclaration(VariableDeclaration node) {
|
| - super.visitVariableDeclaration(node);
|
| - Expression initializer = node.initializer;
|
| - if (initializer != null && node.isConst) {
|
| - VariableElement element = node.element;
|
| - if (element != null) {
|
| - variableMap[element] = node;
|
| - }
|
| - }
|
| - return null;
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * Instances of the class `ConstantValueComputer` compute the values of constant variables in
|
| - * one or more compilation units. The expected usage pattern is for the compilation units to be
|
| - * added to this computer using the method [add] and then for the method
|
| - * [computeValues] to 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.
|
| - */
|
| - final TypeProvider _typeProvider;
|
| -
|
| - /**
|
| - * The object used to find constant variables in the compilation units that were added.
|
| - */
|
| - ConstantFinder _constantFinder = new ConstantFinder();
|
| -
|
| - /**
|
| - * A graph in which the nodes are the constant variables and the edges are from each variable to
|
| - * the other constant variables that are referenced in the head's initializer.
|
| - */
|
| - DirectedGraph<VariableElement> _referenceGraph = new DirectedGraph<VariableElement>();
|
| -
|
| - /**
|
| - * A table mapping constant variables to the declarations of those variables.
|
| - */
|
| - Map<VariableElement, VariableDeclaration> _declarationMap;
|
| -
|
| - /**
|
| - * Initialize a newly created constant value computer.
|
| - *
|
| - * @param typeProvider the type provider used to access known types
|
| - */
|
| - ConstantValueComputer(this._typeProvider);
|
| -
|
| - /**
|
| - * Add the constant variables in the given compilation unit to the list of constant variables
|
| - * whose value needs to be computed.
|
| - *
|
| - * @param unit the compilation unit defining the constant variables to be added
|
| - */
|
| - void add(CompilationUnit unit) {
|
| - unit.accept(_constantFinder);
|
| - }
|
| -
|
| - /**
|
| - * Compute values for all of the constant variables in the compilation units that were added.
|
| - */
|
| - void computeValues() {
|
| - _declarationMap = _constantFinder.variableMap;
|
| - for (MapEntry<VariableElement, VariableDeclaration> entry in getMapEntrySet(_declarationMap)) {
|
| - VariableElement element = entry.getKey();
|
| - ReferenceFinder referenceFinder = new ReferenceFinder(element, _referenceGraph);
|
| - _referenceGraph.addNode(element);
|
| - entry.getValue().initializer.accept(referenceFinder);
|
| - }
|
| - while (!_referenceGraph.isEmpty) {
|
| - VariableElement element = _referenceGraph.removeSink();
|
| - while (element != null) {
|
| - _computeValueFor(element);
|
| - element = _referenceGraph.removeSink();
|
| - }
|
| - if (!_referenceGraph.isEmpty) {
|
| - List<VariableElement> variablesInCycle = _referenceGraph.findCycle();
|
| - if (variablesInCycle == null) {
|
| - //
|
| - // This should not happen. Either the graph should be empty, or there should be at least
|
| - // one sink, or there should be a cycle. If this does happen we exit to prevent an
|
| - // infinite loop.
|
| - //
|
| - 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) {
|
| - _generateCycleError(variablesInCycle, variable);
|
| - }
|
| - _referenceGraph.removeAllNodes(variablesInCycle);
|
| - }
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Compute a value for the given variable.
|
| - *
|
| - * @param variable the variable for which a value is to be computed
|
| + * @param variable the variable for which a value is to be computed
|
| */
|
| void _computeValueFor(VariableElement variable) {
|
| VariableDeclaration declaration = _declarationMap[variable];
|
| @@ -883,2744 +864,2757 @@ class ConstantVisitor extends UnifyingAstVisitor<EvaluationResultImpl> {
|
| }
|
|
|
| /**
|
| - * Instances of the class `ErrorResult` represent the result of evaluating an expression that
|
| - * is not a valid compile time constant.
|
| + * The interface `DartObject` defines the behavior of objects that represent the state of a
|
| + * Dart object.
|
| */
|
| -class ErrorResult extends EvaluationResultImpl {
|
| +abstract class DartObject {
|
| /**
|
| - * The errors that prevent the expression from being a valid compile time constant.
|
| + * 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
|
| */
|
| - List<ErrorResult_ErrorData> _errors = new List<ErrorResult_ErrorData>();
|
| + bool get boolValue;
|
|
|
| /**
|
| - * Initialize a newly created result representing the error with the given code reported against
|
| - * the given node.
|
| + * 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'.
|
| *
|
| - * @param node the node against which the error should be reported
|
| - * @param errorCode the error code for the error to be generated
|
| + * @return the floating point value of this object
|
| */
|
| - ErrorResult.con1(AstNode node, ErrorCode errorCode) {
|
| - _errors.add(new ErrorResult_ErrorData(node, errorCode));
|
| - }
|
| + double get doubleValue;
|
|
|
| /**
|
| - * Initialize a newly created result to represent the union of the errors in the given result
|
| - * objects.
|
| + * 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'.
|
| *
|
| - * @param firstResult the first set of results being merged
|
| - * @param secondResult the second set of results being merged
|
| + * @return the integer value of this object
|
| */
|
| - ErrorResult.con2(ErrorResult firstResult, ErrorResult secondResult) {
|
| - _errors.addAll(firstResult._errors);
|
| - _errors.addAll(secondResult._errors);
|
| - }
|
| + int get intValue;
|
|
|
| - @override
|
| - EvaluationResultImpl add(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.addToError(node, this);
|
| + /**
|
| + * 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;
|
|
|
| - @override
|
| - EvaluationResultImpl applyBooleanConversion(TypeProvider typeProvider, AstNode node) => this;
|
| + /**
|
| + * Return the run-time type of this object.
|
| + *
|
| + * @return the run-time type of this object
|
| + */
|
| + InterfaceType get type;
|
|
|
| - @override
|
| - EvaluationResultImpl bitAnd(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitAndError(node, this);
|
| + /**
|
| + * Return this object's value if it can be represented exactly, or `null` if either the
|
| + * value cannot be represented exactly or if the value is `null`. Clients should use
|
| + * [hasExactValue] to distinguish between these two cases.
|
| + *
|
| + * @return this object's value
|
| + */
|
| + Object get value;
|
|
|
| - @override
|
| - EvaluationResultImpl bitNot(TypeProvider typeProvider, Expression node) => this;
|
| + /**
|
| + * Return `true` if this object's value can be represented exactly.
|
| + *
|
| + * @return `true` if this object's value can be represented exactly
|
| + */
|
| + bool get hasExactValue;
|
|
|
| - @override
|
| - EvaluationResultImpl bitOr(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitOrError(node, this);
|
| + /**
|
| + * Return `true` if this object represents the value 'false'.
|
| + *
|
| + * @return `true` if this object represents the value 'false'
|
| + */
|
| + bool get isFalse;
|
|
|
| - @override
|
| - EvaluationResultImpl bitXor(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitXorError(node, this);
|
| + /**
|
| + * Return `true` if this object represents the value 'null'.
|
| + *
|
| + * @return `true` if this object represents the value 'null'
|
| + */
|
| + bool get isNull;
|
|
|
| - @override
|
| - EvaluationResultImpl concatenate(TypeProvider typeProvider, Expression node, EvaluationResultImpl rightOperand) => rightOperand.concatenateError(node, this);
|
| + /**
|
| + * Return `true` if this object represents the value 'true'.
|
| + *
|
| + * @return `true` if this object represents the value 'true'
|
| + */
|
| + bool get isTrue;
|
| +}
|
|
|
| - @override
|
| - EvaluationResultImpl divide(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.divideError(node, this);
|
| +/**
|
| + * 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;
|
|
|
| - @override
|
| - EvaluationResultImpl equalEqual(TypeProvider typeProvider, Expression node, EvaluationResultImpl rightOperand) => rightOperand.equalEqualError(node, this);
|
| + /**
|
| + * The state of the object.
|
| + */
|
| + final InstanceState _state;
|
|
|
| - @override
|
| - bool equalValues(TypeProvider typeProvider, EvaluationResultImpl result) => false;
|
| + /**
|
| + * 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, this._state);
|
|
|
| - List<ErrorResult_ErrorData> get errorData => _errors;
|
| + /**
|
| + * 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);
|
| + }
|
| + // We should never get here.
|
| + throw new IllegalStateException("add returned a ${result.runtimeType.toString()}");
|
| + }
|
|
|
| - @override
|
| - EvaluationResultImpl greaterThan(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanError(node, this);
|
| + /**
|
| + * 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));
|
|
|
| - @override
|
| - EvaluationResultImpl greaterThanOrEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanOrEqualError(node, this);
|
| + /**
|
| + * 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());
|
|
|
| - @override
|
| - EvaluationResultImpl integerDivide(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.integerDivideError(node, this);
|
| + /**
|
| + * 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));
|
|
|
| - @override
|
| - EvaluationResultImpl integerDivideValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
|
| + /**
|
| + * 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));
|
|
|
| - @override
|
| - EvaluationResultImpl lessThan(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanError(node, this);
|
| + /**
|
| + * 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));
|
|
|
| - @override
|
| - EvaluationResultImpl lessThanOrEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanOrEqualError(node, this);
|
| + /**
|
| + * 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());
|
| + }
|
|
|
| - @override
|
| - EvaluationResultImpl logicalAnd(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalAndError(node, this);
|
| + /**
|
| + * 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);
|
| + }
|
| + // We should never get here.
|
| + throw new IllegalStateException("divide returned a ${result.runtimeType.toString()}");
|
| + }
|
|
|
| - @override
|
| - EvaluationResultImpl logicalNot(TypeProvider typeProvider, Expression node) => this;
|
| + /**
|
| + * 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));
|
| + }
|
|
|
| @override
|
| - EvaluationResultImpl logicalOr(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalOrError(node, this);
|
| + bool operator ==(Object object) {
|
| + if (object is! DartObjectImpl) {
|
| + return false;
|
| + }
|
| + DartObjectImpl dartObject = object as DartObjectImpl;
|
| + return type == dartObject.type && _state == dartObject._state;
|
| + }
|
|
|
| @override
|
| - EvaluationResultImpl minus(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.minusError(node, this);
|
| + bool get boolValue {
|
| + if (_state is BoolState) {
|
| + return (_state as BoolState).value;
|
| + }
|
| + return null;
|
| + }
|
|
|
| @override
|
| - EvaluationResultImpl negated(TypeProvider typeProvider, Expression node) => this;
|
| + double get doubleValue {
|
| + if (_state is DoubleState) {
|
| + return (_state as DoubleState).value;
|
| + }
|
| + return null;
|
| + }
|
|
|
| @override
|
| - EvaluationResultImpl notEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.notEqualError(node, this);
|
| + int get intValue {
|
| + if (_state is IntState) {
|
| + return (_state as IntState).value;
|
| + }
|
| + return null;
|
| + }
|
|
|
| @override
|
| - EvaluationResultImpl performToString(TypeProvider typeProvider, AstNode node) => this;
|
| + String get stringValue {
|
| + if (_state is StringState) {
|
| + return (_state as StringState).value;
|
| + }
|
| + return null;
|
| + }
|
|
|
| @override
|
| - EvaluationResultImpl remainder(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.remainderError(node, this);
|
| + Object get value => _state.value;
|
|
|
| - @override
|
| - EvaluationResultImpl shiftLeft(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.shiftLeftError(node, this);
|
| + /**
|
| + * 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 greaterThan(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.boolType, _state.greaterThan(rightOperand._state));
|
|
|
| - @override
|
| - EvaluationResultImpl shiftRight(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.shiftRightError(node, this);
|
| + /**
|
| + * 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 greaterThanOrEqual(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.boolType, _state.greaterThanOrEqual(rightOperand._state));
|
|
|
| @override
|
| - EvaluationResultImpl times(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.timesError(node, this);
|
| + bool get hasExactValue => _state.hasExactValue;
|
|
|
| @override
|
| - EvaluationResultImpl addToError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
| + int get hashCode => ObjectUtilities.combineHashCodes(type.hashCode, _state.hashCode);
|
|
|
| - @override
|
| - EvaluationResultImpl addToValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
|
| + /**
|
| + * 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));
|
|
|
| - @override
|
| - EvaluationResultImpl bitAndError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
| + /**
|
| + * 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;
|
|
|
| - @override
|
| - EvaluationResultImpl bitAndValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => 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 => _state.isBoolNumStringOrNull;
|
|
|
| @override
|
| - EvaluationResultImpl bitOrError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
| -
|
| - @override
|
| - EvaluationResultImpl bitOrValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
|
| -
|
| - @override
|
| - EvaluationResultImpl bitXorError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
| -
|
| - @override
|
| - EvaluationResultImpl bitXorValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
|
| -
|
| - @override
|
| - EvaluationResultImpl concatenateError(Expression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
| -
|
| - @override
|
| - EvaluationResultImpl concatenateValid(TypeProvider typeProvider, Expression node, ValidResult leftOperand) => this;
|
| -
|
| - @override
|
| - EvaluationResultImpl divideError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
| -
|
| - @override
|
| - EvaluationResultImpl divideValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
|
| -
|
| - @override
|
| - EvaluationResultImpl equalEqualError(Expression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
| -
|
| - @override
|
| - EvaluationResultImpl equalEqualValid(TypeProvider typeProvider, Expression node, ValidResult leftOperand) => this;
|
| -
|
| - @override
|
| - EvaluationResultImpl greaterThanError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
| -
|
| - @override
|
| - EvaluationResultImpl greaterThanOrEqualError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
| -
|
| - @override
|
| - EvaluationResultImpl greaterThanOrEqualValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
|
| -
|
| - @override
|
| - EvaluationResultImpl greaterThanValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
|
| -
|
| - @override
|
| - EvaluationResultImpl integerDivideError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
| -
|
| - @override
|
| - EvaluationResultImpl lessThanError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
| -
|
| - @override
|
| - EvaluationResultImpl lessThanOrEqualError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
| -
|
| - @override
|
| - EvaluationResultImpl lessThanOrEqualValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
|
| -
|
| - @override
|
| - EvaluationResultImpl lessThanValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
|
| -
|
| - @override
|
| - EvaluationResultImpl logicalAndError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
| -
|
| - @override
|
| - EvaluationResultImpl logicalAndValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
|
| -
|
| - @override
|
| - EvaluationResultImpl logicalOrError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
| -
|
| - @override
|
| - EvaluationResultImpl logicalOrValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
|
| -
|
| - @override
|
| - EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
| -
|
| - @override
|
| - EvaluationResultImpl minusValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
|
| -
|
| - @override
|
| - EvaluationResultImpl notEqualError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
| -
|
| - @override
|
| - EvaluationResultImpl notEqualValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
|
| -
|
| - @override
|
| - EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
| -
|
| - @override
|
| - EvaluationResultImpl remainderValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
|
| -
|
| - @override
|
| - EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
| + bool get isFalse => _state is BoolState && identical((_state as BoolState).value, false);
|
|
|
| @override
|
| - EvaluationResultImpl shiftLeftValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
|
| + bool get isNull => _state is NullState;
|
|
|
| @override
|
| - EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
| + bool get isTrue => _state is BoolState && identical((_state as BoolState).value, true);
|
|
|
| - @override
|
| - EvaluationResultImpl shiftRightValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => 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 => _state is GenericState;
|
|
|
| - @override
|
| - EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
| + /**
|
| + * 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 lessThan(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.boolType, _state.lessThan(rightOperand._state));
|
|
|
| - @override
|
| - EvaluationResultImpl timesValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
|
| -}
|
| + /**
|
| + * 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 lessThanOrEqual(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.boolType, _state.lessThanOrEqual(rightOperand._state));
|
|
|
| -class ErrorResult_ErrorData {
|
| /**
|
| - * The node against which the error should be reported.
|
| + * 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
|
| */
|
| - final AstNode node;
|
| + DartObjectImpl logicalAnd(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.boolType, _state.logicalAnd(rightOperand._state));
|
|
|
| /**
|
| - * The error code for the error to be generated.
|
| + * 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
|
| */
|
| - final ErrorCode errorCode;
|
| + DartObjectImpl logicalNot(TypeProvider typeProvider) => new DartObjectImpl(typeProvider.boolType, _state.logicalNot());
|
|
|
| /**
|
| - * Initialize a newly created data holder to represent the error with the given code reported
|
| - * against the given node.
|
| + * Return the result of invoking the '||' operator on this object with the given argument.
|
| *
|
| - * @param node the node against which the error should be reported
|
| - * @param errorCode the error code for the error to be generated
|
| + * @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
|
| */
|
| - ErrorResult_ErrorData(this.node, this.errorCode);
|
| -}
|
| + DartObjectImpl logicalOr(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.boolType, _state.logicalOr(rightOperand._state));
|
|
|
| -/**
|
| - * Instances of the class `InternalResult` represent the result of attempting to evaluate a
|
| - * expression.
|
| - */
|
| -abstract class EvaluationResultImpl {
|
| - EvaluationResultImpl add(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
| + /**
|
| + * 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);
|
| + }
|
| + // We should never get here.
|
| + throw new IllegalStateException("minus returned a ${result.runtimeType.toString()}");
|
| + }
|
|
|
| /**
|
| - * Return the result of applying boolean conversion to this result.
|
| + * Return the result of invoking the '-' operator on this object.
|
| *
|
| - * @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
|
| + * @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
|
| */
|
| - EvaluationResultImpl applyBooleanConversion(TypeProvider typeProvider, AstNode node);
|
| + 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);
|
| + }
|
| + // We should never get here.
|
| + throw new IllegalStateException("negated returned a ${result.runtimeType.toString()}");
|
| + }
|
|
|
| - EvaluationResultImpl bitAnd(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
| + /**
|
| + * 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());
|
| + }
|
|
|
| - EvaluationResultImpl bitNot(TypeProvider typeProvider, Expression node);
|
| + /**
|
| + * 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());
|
| + }
|
|
|
| - EvaluationResultImpl bitOr(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
| + /**
|
| + * 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);
|
| + }
|
| + // We should never get here.
|
| + throw new IllegalStateException("remainder returned a ${result.runtimeType.toString()}");
|
| + }
|
|
|
| - EvaluationResultImpl bitXor(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
| -
|
| - EvaluationResultImpl concatenate(TypeProvider typeProvider, Expression node, EvaluationResultImpl rightOperand);
|
| -
|
| - EvaluationResultImpl divide(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
| -
|
| - EvaluationResultImpl equalEqual(TypeProvider typeProvider, Expression node, EvaluationResultImpl rightOperand);
|
| -
|
| - bool equalValues(TypeProvider typeProvider, EvaluationResultImpl result);
|
| -
|
| - EvaluationResultImpl greaterThan(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
| -
|
| - EvaluationResultImpl greaterThanOrEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
| -
|
| - EvaluationResultImpl integerDivide(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
| -
|
| - EvaluationResultImpl lessThan(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
| -
|
| - EvaluationResultImpl lessThanOrEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
| -
|
| - EvaluationResultImpl logicalAnd(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
| -
|
| - EvaluationResultImpl logicalNot(TypeProvider typeProvider, Expression node);
|
| -
|
| - EvaluationResultImpl logicalOr(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
| -
|
| - EvaluationResultImpl minus(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
| -
|
| - EvaluationResultImpl negated(TypeProvider typeProvider, Expression node);
|
| -
|
| - EvaluationResultImpl notEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
| -
|
| - EvaluationResultImpl performToString(TypeProvider typeProvider, AstNode node);
|
| -
|
| - EvaluationResultImpl remainder(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
| -
|
| - EvaluationResultImpl shiftLeft(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
| -
|
| - EvaluationResultImpl shiftRight(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
| -
|
| - EvaluationResultImpl times(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
| -
|
| - EvaluationResultImpl addToError(BinaryExpression node, ErrorResult leftOperand);
|
| -
|
| - EvaluationResultImpl addToValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| -
|
| - EvaluationResultImpl bitAndError(BinaryExpression node, ErrorResult leftOperand);
|
| -
|
| - EvaluationResultImpl bitAndValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| -
|
| - EvaluationResultImpl bitOrError(BinaryExpression node, ErrorResult leftOperand);
|
| -
|
| - EvaluationResultImpl bitOrValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| -
|
| - EvaluationResultImpl bitXorError(BinaryExpression node, ErrorResult leftOperand);
|
| -
|
| - EvaluationResultImpl bitXorValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| -
|
| - EvaluationResultImpl concatenateError(Expression node, ErrorResult leftOperand);
|
| -
|
| - EvaluationResultImpl concatenateValid(TypeProvider typeProvider, Expression node, ValidResult leftOperand);
|
| -
|
| - EvaluationResultImpl divideError(BinaryExpression node, ErrorResult leftOperand);
|
| -
|
| - EvaluationResultImpl divideValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| -
|
| - EvaluationResultImpl equalEqualError(Expression node, ErrorResult leftOperand);
|
| -
|
| - EvaluationResultImpl equalEqualValid(TypeProvider typeProvider, Expression node, ValidResult leftOperand);
|
| -
|
| - EvaluationResultImpl greaterThanError(BinaryExpression node, ErrorResult leftOperand);
|
| -
|
| - EvaluationResultImpl greaterThanOrEqualError(BinaryExpression node, ErrorResult leftOperand);
|
| -
|
| - EvaluationResultImpl greaterThanOrEqualValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| -
|
| - EvaluationResultImpl greaterThanValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| -
|
| - EvaluationResultImpl integerDivideError(BinaryExpression node, ErrorResult leftOperand);
|
| -
|
| - EvaluationResultImpl integerDivideValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| -
|
| - EvaluationResultImpl lessThanError(BinaryExpression node, ErrorResult leftOperand);
|
| -
|
| - EvaluationResultImpl lessThanOrEqualError(BinaryExpression node, ErrorResult leftOperand);
|
| -
|
| - EvaluationResultImpl lessThanOrEqualValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| -
|
| - EvaluationResultImpl lessThanValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| -
|
| - EvaluationResultImpl logicalAndError(BinaryExpression node, ErrorResult leftOperand);
|
| -
|
| - EvaluationResultImpl logicalAndValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| -
|
| - EvaluationResultImpl logicalOrError(BinaryExpression node, ErrorResult leftOperand);
|
| -
|
| - EvaluationResultImpl logicalOrValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| -
|
| - EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand);
|
| -
|
| - EvaluationResultImpl minusValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| -
|
| - EvaluationResultImpl notEqualError(BinaryExpression node, ErrorResult leftOperand);
|
| -
|
| - EvaluationResultImpl notEqualValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| -
|
| - EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOperand);
|
| -
|
| - EvaluationResultImpl remainderValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| -
|
| - EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOperand);
|
| -
|
| - EvaluationResultImpl shiftLeftValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| -
|
| - EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOperand);
|
| -
|
| - EvaluationResultImpl shiftRightValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| -
|
| - EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand);
|
| -
|
| - EvaluationResultImpl timesValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| -}
|
| -
|
| -/**
|
| - * Instances of the class `ReferenceFinder` add reference information for a given variable to
|
| - * the bi-directional mapping used to order the evaluation of constants.
|
| - */
|
| -class ReferenceFinder extends RecursiveAstVisitor<Object> {
|
| /**
|
| - * The element representing the variable whose initializer will be visited.
|
| + * 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
|
| */
|
| - final VariableElement _source;
|
| + DartObjectImpl shiftLeft(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.intType, _state.shiftLeft(rightOperand._state));
|
|
|
| /**
|
| - * A graph in which the nodes are the constant variables and the edges are from each variable to
|
| - * the other constant variables that are referenced in the head's initializer.
|
| + * 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
|
| */
|
| - final DirectedGraph<VariableElement> _referenceGraph;
|
| + DartObjectImpl shiftRight(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.intType, _state.shiftRight(rightOperand._state));
|
|
|
| /**
|
| - * Initialize a newly created reference finder to find references from the given variable to other
|
| - * variables and to add those references to the given graph.
|
| + * Return the result of invoking the '*' operator on this object with the given argument.
|
| *
|
| - * @param source the element representing the variable whose initializer will be visited
|
| - * @param referenceGraph a graph recording which variables (heads) reference which other variables
|
| - * (tails) in their initializers
|
| + * @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
|
| */
|
| - ReferenceFinder(this._source, this._referenceGraph);
|
| -
|
| - @override
|
| - Object visitSimpleIdentifier(SimpleIdentifier node) {
|
| - Element element = node.staticElement;
|
| - if (element is PropertyAccessorElement) {
|
| - element = (element as PropertyAccessorElement).variable;
|
| - }
|
| - if (element is VariableElement) {
|
| - VariableElement variable = element as VariableElement;
|
| - if (variable.isConst) {
|
| - _referenceGraph.addEdge(_source, variable);
|
| - }
|
| + 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);
|
| }
|
| - return null;
|
| + // We should never get here.
|
| + throw new IllegalStateException("times returned a ${result.runtimeType.toString()}");
|
| }
|
| +
|
| + @override
|
| + String toString() => "${type.displayName} (${_state.toString()})";
|
| }
|
|
|
| /**
|
| - * Instances of the class `ValidResult` represent the result of attempting to evaluate a valid
|
| - * compile time constant expression.
|
| + * Instances of the class `DoubleState` represent the state of an object representing a
|
| + * double.
|
| */
|
| -class ValidResult extends EvaluationResultImpl {
|
| +class DoubleState extends NumState {
|
| /**
|
| - * The value of the expression.
|
| + * The value of this instance.
|
| */
|
| - final DartObjectImpl value;
|
| + final double value;
|
|
|
| /**
|
| - * Initialize a newly created result to represent the given value.
|
| - *
|
| - * @param value the value of the expression
|
| + * A state that can be used to represent a double whose value is not known.
|
| */
|
| - ValidResult(this.value);
|
| -
|
| - @override
|
| - EvaluationResultImpl add(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.addToValid(typeProvider, node, this);
|
| + static DoubleState UNKNOWN_VALUE = new DoubleState(null);
|
|
|
| /**
|
| - * Return the result of applying boolean conversion to this result.
|
| + * Initialize a newly created state to represent a double with the given value.
|
| *
|
| - * @param node the node against which errors should be reported
|
| - * @return the result of applying boolean conversion to the given value
|
| + * @param value the value of this instance
|
| */
|
| + DoubleState(this.value);
|
| +
|
| @override
|
| - EvaluationResultImpl applyBooleanConversion(TypeProvider typeProvider, AstNode node) {
|
| - try {
|
| - return _valueOf(value.convertToBool(typeProvider));
|
| - } on EvaluationException catch (exception) {
|
| - return _error(node, exception.errorCode);
|
| + NumState add(InstanceState rightOperand) {
|
| + assertNumOrNull(rightOperand);
|
| + if (value == null) {
|
| + return UNKNOWN_VALUE;
|
| + }
|
| + if (rightOperand is IntState) {
|
| + int rightValue = rightOperand.value;
|
| + if (rightValue == null) {
|
| + return UNKNOWN_VALUE;
|
| + }
|
| + return new DoubleState(value + rightValue.toDouble());
|
| + } else if (rightOperand is DoubleState) {
|
| + double rightValue = rightOperand.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);
|
| }
|
|
|
| @override
|
| - EvaluationResultImpl bitAnd(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitAndValid(typeProvider, node, this);
|
| -
|
| - @override
|
| - EvaluationResultImpl bitNot(TypeProvider typeProvider, Expression node) {
|
| - try {
|
| - return _valueOf(value.bitNot(typeProvider));
|
| - } on EvaluationException catch (exception) {
|
| - return _error(node, exception.errorCode);
|
| + StringState convertToString() {
|
| + if (value == null) {
|
| + return StringState.UNKNOWN_VALUE;
|
| }
|
| + return new StringState(value.toString());
|
| }
|
|
|
| @override
|
| - EvaluationResultImpl bitOr(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitOrValid(typeProvider, node, this);
|
| -
|
| - @override
|
| - EvaluationResultImpl bitXor(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitXorValid(typeProvider, node, this);
|
| -
|
| - @override
|
| - EvaluationResultImpl concatenate(TypeProvider typeProvider, Expression node, EvaluationResultImpl rightOperand) => rightOperand.concatenateValid(typeProvider, node, this);
|
| -
|
| - @override
|
| - EvaluationResultImpl divide(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.divideValid(typeProvider, node, this);
|
| -
|
| - @override
|
| - EvaluationResultImpl equalEqual(TypeProvider typeProvider, Expression node, EvaluationResultImpl rightOperand) => rightOperand.equalEqualValid(typeProvider, node, this);
|
| -
|
| - @override
|
| - bool equalValues(TypeProvider typeProvider, EvaluationResultImpl result) {
|
| - if (result is! ValidResult) {
|
| - return false;
|
| + NumState divide(InstanceState rightOperand) {
|
| + assertNumOrNull(rightOperand);
|
| + if (value == null) {
|
| + return UNKNOWN_VALUE;
|
| }
|
| - return value == (result as ValidResult).value;
|
| + if (rightOperand is IntState) {
|
| + int rightValue = rightOperand.value;
|
| + if (rightValue == null) {
|
| + return UNKNOWN_VALUE;
|
| + }
|
| + return new DoubleState(value / rightValue.toDouble());
|
| + } else if (rightOperand is DoubleState) {
|
| + double rightValue = rightOperand.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);
|
| }
|
|
|
| @override
|
| - EvaluationResultImpl greaterThan(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanValid(typeProvider, node, this);
|
| -
|
| - @override
|
| - EvaluationResultImpl greaterThanOrEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanOrEqualValid(typeProvider, node, this);
|
| -
|
| - @override
|
| - EvaluationResultImpl integerDivide(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.integerDivideValid(typeProvider, 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;
|
| -
|
| - /**
|
| - * 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;
|
| -
|
| - /**
|
| - * Return `true` if this result represents the value 'false'.
|
| - *
|
| - * @return `true` if this result represents the value 'false'
|
| - */
|
| - bool get isFalse => value.isFalse;
|
| -
|
| - /**
|
| - * Return `true` if this result represents the value 'null'.
|
| - *
|
| - * @return `true` if this result represents the value 'null'
|
| - */
|
| - bool get isNull => value.isNull;
|
| -
|
| - /**
|
| - * Return `true` if this result represents the value 'true'.
|
| - *
|
| - * @return `true` if this result represents the value 'true'
|
| - */
|
| - bool get isTrue => value.isTrue;
|
| -
|
| - /**
|
| - * 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;
|
| -
|
| - @override
|
| - EvaluationResultImpl lessThan(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanValid(typeProvider, node, this);
|
| -
|
| - @override
|
| - EvaluationResultImpl lessThanOrEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanOrEqualValid(typeProvider, node, this);
|
| -
|
| - @override
|
| - EvaluationResultImpl logicalAnd(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalAndValid(typeProvider, node, this);
|
| -
|
| - @override
|
| - EvaluationResultImpl logicalNot(TypeProvider typeProvider, Expression node) {
|
| - try {
|
| - return _valueOf(value.logicalNot(typeProvider));
|
| - } on EvaluationException catch (exception) {
|
| - return _error(node, exception.errorCode);
|
| + BoolState equalEqual(InstanceState rightOperand) {
|
| + assertBoolNumStringOrNull(rightOperand);
|
| + if (value == null) {
|
| + return BoolState.UNKNOWN_VALUE;
|
| + }
|
| + if (rightOperand is DoubleState) {
|
| + double rightValue = rightOperand.value;
|
| + if (rightValue == null) {
|
| + return BoolState.UNKNOWN_VALUE;
|
| + }
|
| + return BoolState.from(value == rightValue);
|
| + } else if (rightOperand is IntState) {
|
| + int rightValue = rightOperand.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;
|
| }
|
|
|
| @override
|
| - EvaluationResultImpl logicalOr(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalOrValid(typeProvider, node, this);
|
| + bool operator ==(Object object) => object is DoubleState && (value == object.value);
|
|
|
| @override
|
| - EvaluationResultImpl minus(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.minusValid(typeProvider, node, this);
|
| + String get typeName => "double";
|
|
|
| @override
|
| - EvaluationResultImpl negated(TypeProvider typeProvider, Expression node) {
|
| - try {
|
| - return _valueOf(value.negated(typeProvider));
|
| - } on EvaluationException catch (exception) {
|
| - return _error(node, exception.errorCode);
|
| + BoolState greaterThan(InstanceState rightOperand) {
|
| + assertNumOrNull(rightOperand);
|
| + if (value == null) {
|
| + return BoolState.UNKNOWN_VALUE;
|
| }
|
| + if (rightOperand is IntState) {
|
| + int rightValue = rightOperand.value;
|
| + if (rightValue == null) {
|
| + return BoolState.UNKNOWN_VALUE;
|
| + }
|
| + return BoolState.from(value > rightValue.toDouble());
|
| + } else if (rightOperand is DoubleState) {
|
| + double rightValue = rightOperand.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);
|
| }
|
|
|
| @override
|
| - EvaluationResultImpl notEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.notEqualValid(typeProvider, node, this);
|
| -
|
| - @override
|
| - EvaluationResultImpl performToString(TypeProvider typeProvider, AstNode node) {
|
| - try {
|
| - return _valueOf(value.performToString(typeProvider));
|
| - } on EvaluationException catch (exception) {
|
| - return _error(node, exception.errorCode);
|
| + BoolState greaterThanOrEqual(InstanceState rightOperand) {
|
| + assertNumOrNull(rightOperand);
|
| + if (value == null) {
|
| + return BoolState.UNKNOWN_VALUE;
|
| + }
|
| + if (rightOperand is IntState) {
|
| + int rightValue = rightOperand.value;
|
| + if (rightValue == null) {
|
| + return BoolState.UNKNOWN_VALUE;
|
| + }
|
| + return BoolState.from(value >= rightValue.toDouble());
|
| + } else if (rightOperand is DoubleState) {
|
| + double rightValue = rightOperand.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);
|
| }
|
|
|
| @override
|
| - EvaluationResultImpl remainder(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.remainderValid(typeProvider, node, this);
|
| -
|
| - @override
|
| - EvaluationResultImpl shiftLeft(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.shiftLeftValid(typeProvider, node, this);
|
| -
|
| - @override
|
| - EvaluationResultImpl shiftRight(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.shiftRightValid(typeProvider, node, this);
|
| + bool get hasExactValue => true;
|
|
|
| @override
|
| - EvaluationResultImpl times(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.timesValid(typeProvider, node, this);
|
| + int get hashCode => value == null ? 0 : value.hashCode;
|
|
|
| @override
|
| - String toString() {
|
| + IntState integerDivide(InstanceState rightOperand) {
|
| + assertNumOrNull(rightOperand);
|
| if (value == null) {
|
| - return "null";
|
| + return IntState.UNKNOWN_VALUE;
|
| }
|
| - return value.toString();
|
| - }
|
| -
|
| - @override
|
| - EvaluationResultImpl addToError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
| -
|
| - @override
|
| - 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);
|
| + if (rightOperand is IntState) {
|
| + int rightValue = rightOperand.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.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);
|
| }
|
|
|
| @override
|
| - EvaluationResultImpl bitAndError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
| + bool get isBoolNumStringOrNull => true;
|
|
|
| @override
|
| - 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);
|
| + BoolState lessThan(InstanceState rightOperand) {
|
| + assertNumOrNull(rightOperand);
|
| + if (value == null) {
|
| + return BoolState.UNKNOWN_VALUE;
|
| }
|
| - }
|
| -
|
| - @override
|
| - EvaluationResultImpl bitOrError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
| -
|
| - @override
|
| - 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);
|
| + if (rightOperand is IntState) {
|
| + int rightValue = rightOperand.value;
|
| + if (rightValue == null) {
|
| + return BoolState.UNKNOWN_VALUE;
|
| + }
|
| + return BoolState.from(value < rightValue.toDouble());
|
| + } else if (rightOperand is DoubleState) {
|
| + double rightValue = rightOperand.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);
|
| }
|
|
|
| @override
|
| - EvaluationResultImpl bitXorError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
| -
|
| - @override
|
| - 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);
|
| + BoolState lessThanOrEqual(InstanceState rightOperand) {
|
| + assertNumOrNull(rightOperand);
|
| + if (value == null) {
|
| + return BoolState.UNKNOWN_VALUE;
|
| + }
|
| + if (rightOperand is IntState) {
|
| + int rightValue = rightOperand.value;
|
| + if (rightValue == null) {
|
| + return BoolState.UNKNOWN_VALUE;
|
| + }
|
| + return BoolState.from(value <= rightValue.toDouble());
|
| + } else if (rightOperand is DoubleState) {
|
| + double rightValue = rightOperand.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);
|
| }
|
|
|
| @override
|
| - EvaluationResultImpl concatenateError(Expression node, ErrorResult leftOperand) => leftOperand;
|
| + NumState minus(InstanceState rightOperand) {
|
| + assertNumOrNull(rightOperand);
|
| + if (value == null) {
|
| + return UNKNOWN_VALUE;
|
| + }
|
| + if (rightOperand is IntState) {
|
| + int rightValue = rightOperand.value;
|
| + if (rightValue == null) {
|
| + return UNKNOWN_VALUE;
|
| + }
|
| + return new DoubleState(value - rightValue.toDouble());
|
| + } else if (rightOperand is DoubleState) {
|
| + double rightValue = rightOperand.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);
|
| + }
|
|
|
| @override
|
| - 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);
|
| + NumState negated() {
|
| + if (value == null) {
|
| + return UNKNOWN_VALUE;
|
| }
|
| + return new DoubleState(-(value));
|
| }
|
|
|
| @override
|
| - EvaluationResultImpl divideError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
| + NumState remainder(InstanceState rightOperand) {
|
| + assertNumOrNull(rightOperand);
|
| + if (value == null) {
|
| + return UNKNOWN_VALUE;
|
| + }
|
| + if (rightOperand is IntState) {
|
| + int rightValue = rightOperand.value;
|
| + if (rightValue == null) {
|
| + return UNKNOWN_VALUE;
|
| + }
|
| + return new DoubleState(value % rightValue.toDouble());
|
| + } else if (rightOperand is DoubleState) {
|
| + double rightValue = rightOperand.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);
|
| + }
|
|
|
| @override
|
| - 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);
|
| + NumState times(InstanceState rightOperand) {
|
| + assertNumOrNull(rightOperand);
|
| + if (value == null) {
|
| + return UNKNOWN_VALUE;
|
| + }
|
| + if (rightOperand is IntState) {
|
| + int rightValue = rightOperand.value;
|
| + if (rightValue == null) {
|
| + return UNKNOWN_VALUE;
|
| + }
|
| + return new DoubleState(value * rightValue.toDouble());
|
| + } else if (rightOperand is DoubleState) {
|
| + double rightValue = rightOperand.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);
|
| }
|
|
|
| @override
|
| - EvaluationResultImpl equalEqualError(Expression node, ErrorResult leftOperand) => leftOperand;
|
| + 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();
|
|
|
| @override
|
| - 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);
|
| - }
|
| + NumState add(InstanceState rightOperand) {
|
| + assertNumOrNull(rightOperand);
|
| + return _unknownNum(rightOperand);
|
| }
|
|
|
| @override
|
| - EvaluationResultImpl greaterThanError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
| + IntState bitAnd(InstanceState rightOperand) {
|
| + assertIntOrNull(rightOperand);
|
| + return IntState.UNKNOWN_VALUE;
|
| + }
|
|
|
| @override
|
| - EvaluationResultImpl greaterThanOrEqualError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
| + IntState bitNot() => IntState.UNKNOWN_VALUE;
|
|
|
| @override
|
| - 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);
|
| - }
|
| + IntState bitOr(InstanceState rightOperand) {
|
| + assertIntOrNull(rightOperand);
|
| + return IntState.UNKNOWN_VALUE;
|
| }
|
|
|
| @override
|
| - 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);
|
| - }
|
| + IntState bitXor(InstanceState rightOperand) {
|
| + assertIntOrNull(rightOperand);
|
| + return IntState.UNKNOWN_VALUE;
|
| }
|
|
|
| @override
|
| - EvaluationResultImpl integerDivideError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
| -
|
| - @override
|
| - 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);
|
| - }
|
| + StringState concatenate(InstanceState rightOperand) {
|
| + assertString(rightOperand);
|
| + return StringState.UNKNOWN_VALUE;
|
| }
|
|
|
| @override
|
| - EvaluationResultImpl lessThanError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
| + BoolState convertToBool() => BoolState.UNKNOWN_VALUE;
|
|
|
| @override
|
| - EvaluationResultImpl lessThanOrEqualError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
| + StringState convertToString() => StringState.UNKNOWN_VALUE;
|
|
|
| @override
|
| - 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);
|
| - }
|
| + NumState divide(InstanceState rightOperand) {
|
| + assertNumOrNull(rightOperand);
|
| + return _unknownNum(rightOperand);
|
| }
|
|
|
| @override
|
| - 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);
|
| - }
|
| + BoolState equalEqual(InstanceState rightOperand) {
|
| + assertBoolNumStringOrNull(rightOperand);
|
| + return BoolState.UNKNOWN_VALUE;
|
| }
|
|
|
| @override
|
| - EvaluationResultImpl logicalAndError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
| + String get typeName => "dynamic";
|
|
|
| @override
|
| - 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);
|
| - }
|
| + BoolState greaterThan(InstanceState rightOperand) {
|
| + assertNumOrNull(rightOperand);
|
| + return BoolState.UNKNOWN_VALUE;
|
| }
|
|
|
| @override
|
| - EvaluationResultImpl logicalOrError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
| + BoolState greaterThanOrEqual(InstanceState rightOperand) {
|
| + assertNumOrNull(rightOperand);
|
| + return BoolState.UNKNOWN_VALUE;
|
| + }
|
|
|
| @override
|
| - 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);
|
| - }
|
| + IntState integerDivide(InstanceState rightOperand) {
|
| + assertNumOrNull(rightOperand);
|
| + return IntState.UNKNOWN_VALUE;
|
| }
|
|
|
| @override
|
| - EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
| + bool get isBool => true;
|
|
|
| @override
|
| - 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);
|
| - }
|
| + bool get isBoolNumStringOrNull => true;
|
| +
|
| + @override
|
| + BoolState lessThan(InstanceState rightOperand) {
|
| + assertNumOrNull(rightOperand);
|
| + return BoolState.UNKNOWN_VALUE;
|
| }
|
|
|
| @override
|
| - EvaluationResultImpl notEqualError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
| + BoolState lessThanOrEqual(InstanceState rightOperand) {
|
| + assertNumOrNull(rightOperand);
|
| + return BoolState.UNKNOWN_VALUE;
|
| + }
|
|
|
| @override
|
| - 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);
|
| - }
|
| + BoolState logicalAnd(InstanceState rightOperand) {
|
| + assertBool(rightOperand);
|
| + return BoolState.UNKNOWN_VALUE;
|
| }
|
|
|
| @override
|
| - EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
| + BoolState logicalNot() => BoolState.UNKNOWN_VALUE;
|
|
|
| @override
|
| - 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);
|
| - }
|
| + BoolState logicalOr(InstanceState rightOperand) {
|
| + assertBool(rightOperand);
|
| + return rightOperand.convertToBool();
|
| }
|
|
|
| @override
|
| - EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
| + NumState minus(InstanceState rightOperand) {
|
| + assertNumOrNull(rightOperand);
|
| + return _unknownNum(rightOperand);
|
| + }
|
|
|
| @override
|
| - 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);
|
| - }
|
| - }
|
| + NumState negated() => NumState.UNKNOWN_VALUE;
|
|
|
| @override
|
| - EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
| + NumState remainder(InstanceState rightOperand) {
|
| + assertNumOrNull(rightOperand);
|
| + return _unknownNum(rightOperand);
|
| + }
|
|
|
| @override
|
| - 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);
|
| - }
|
| + IntState shiftLeft(InstanceState rightOperand) {
|
| + assertIntOrNull(rightOperand);
|
| + return IntState.UNKNOWN_VALUE;
|
| }
|
|
|
| @override
|
| - EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
| + IntState shiftRight(InstanceState rightOperand) {
|
| + assertIntOrNull(rightOperand);
|
| + return IntState.UNKNOWN_VALUE;
|
| + }
|
|
|
| @override
|
| - 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);
|
| - }
|
| + NumState times(InstanceState rightOperand) {
|
| + assertNumOrNull(rightOperand);
|
| + return _unknownNum(rightOperand);
|
| }
|
|
|
| /**
|
| - * Return a result object representing an error associated with the given node.
|
| - *
|
| - * @param node the AST node associated with the error
|
| - * @param code the error code indicating the nature of the error
|
| - * @return a result object representing an error associated with the given node
|
| - */
|
| - ErrorResult _error(AstNode node, ErrorCode code) => new ErrorResult.con1(node, code);
|
| -
|
| - /**
|
| - * Return a result object representing the given value.
|
| + * Return an object representing an unknown numeric value whose type is based on the type of the
|
| + * right-hand operand.
|
| *
|
| - * @param value the value to be represented as a result object
|
| - * @return a result object representing the given value
|
| + * @param rightOperand the operand whose type will determine the type of the result
|
| + * @return an object representing an unknown numeric value
|
| */
|
| - ValidResult _valueOf(DartObjectImpl value) => new ValidResult(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 `BoolState` represent the state of an object representing a boolean
|
| - * value.
|
| + * Instances of the class `ErrorResult` represent the result of evaluating an expression that
|
| + * is not a valid compile time constant.
|
| */
|
| -class BoolState extends InstanceState {
|
| +class ErrorResult extends EvaluationResultImpl {
|
| /**
|
| - * The value of this instance.
|
| + * The errors that prevent the expression from being a valid compile time constant.
|
| */
|
| - final bool value;
|
| + List<ErrorResult_ErrorData> _errors = new List<ErrorResult_ErrorData>();
|
|
|
| /**
|
| - * An instance representing the boolean value 'false'.
|
| + * Initialize a newly created result representing the error with the given code reported against
|
| + * the given node.
|
| + *
|
| + * @param node the node against which the error should be reported
|
| + * @param errorCode the error code for the error to be generated
|
| */
|
| - static BoolState FALSE_STATE = new BoolState(false);
|
| + ErrorResult.con1(AstNode node, ErrorCode errorCode) {
|
| + _errors.add(new ErrorResult_ErrorData(node, errorCode));
|
| + }
|
|
|
| /**
|
| - * An instance representing the boolean value 'true'.
|
| + * Initialize a newly created result to represent the union of the errors in the given result
|
| + * objects.
|
| + *
|
| + * @param firstResult the first set of results being merged
|
| + * @param secondResult the second set of results being merged
|
| */
|
| - static BoolState TRUE_STATE = new BoolState(true);
|
| + ErrorResult.con2(ErrorResult firstResult, ErrorResult secondResult) {
|
| + _errors.addAll(firstResult._errors);
|
| + _errors.addAll(secondResult._errors);
|
| + }
|
|
|
| - /**
|
| - * A state that can be used to represent a boolean whose value is not known.
|
| - */
|
| - static BoolState UNKNOWN_VALUE = new BoolState(null);
|
| + @override
|
| + EvaluationResultImpl add(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.addToError(node, this);
|
|
|
| - /**
|
| - * 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
|
| - */
|
| - static BoolState from(bool value) => value ? BoolState.TRUE_STATE : BoolState.FALSE_STATE;
|
| + @override
|
| + EvaluationResultImpl applyBooleanConversion(TypeProvider typeProvider, AstNode node) => this;
|
|
|
| - /**
|
| - * Initialize a newly created state to represent the given value.
|
| - *
|
| - * @param value the value of this instance
|
| - */
|
| - BoolState(this.value);
|
| + @override
|
| + EvaluationResultImpl bitAnd(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitAndError(node, this);
|
|
|
| @override
|
| - BoolState convertToBool() => this;
|
| + EvaluationResultImpl bitNot(TypeProvider typeProvider, Expression node) => this;
|
|
|
| @override
|
| - StringState convertToString() {
|
| - if (value == null) {
|
| - return StringState.UNKNOWN_VALUE;
|
| - }
|
| - return new StringState(value ? "true" : "false");
|
| - }
|
| + EvaluationResultImpl bitOr(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitOrError(node, this);
|
|
|
| @override
|
| - BoolState equalEqual(InstanceState rightOperand) {
|
| - assertBoolNumStringOrNull(rightOperand);
|
| - if (value == null) {
|
| - return UNKNOWN_VALUE;
|
| - }
|
| - if (rightOperand is BoolState) {
|
| - bool rightValue = rightOperand.value;
|
| - if (rightValue == null) {
|
| - return UNKNOWN_VALUE;
|
| - }
|
| - return BoolState.from(identical(value, rightValue));
|
| - } else if (rightOperand is DynamicState) {
|
| - return UNKNOWN_VALUE;
|
| - }
|
| - return FALSE_STATE;
|
| - }
|
| + EvaluationResultImpl bitXor(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitXorError(node, this);
|
|
|
| @override
|
| - bool operator ==(Object object) => object is BoolState && identical(value, object.value);
|
| + EvaluationResultImpl concatenate(TypeProvider typeProvider, Expression node, EvaluationResultImpl rightOperand) => rightOperand.concatenateError(node, this);
|
|
|
| @override
|
| - String get typeName => "bool";
|
| + EvaluationResultImpl divide(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.divideError(node, this);
|
|
|
| @override
|
| - bool get hasExactValue => true;
|
| + EvaluationResultImpl equalEqual(TypeProvider typeProvider, Expression node, EvaluationResultImpl rightOperand) => rightOperand.equalEqualError(node, this);
|
|
|
| @override
|
| - int get hashCode => value == null ? 0 : (value ? 2 : 3);
|
| + bool equalValues(TypeProvider typeProvider, EvaluationResultImpl result) => false;
|
| +
|
| + List<ErrorResult_ErrorData> get errorData => _errors;
|
|
|
| - /**
|
| - * Return `true` if this object represents an object whose type is 'bool'.
|
| - *
|
| - * @return `true` if this object represents a boolean value
|
| - */
|
| @override
|
| - bool get isBool => true;
|
| + EvaluationResultImpl greaterThan(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanError(node, this);
|
|
|
| @override
|
| - bool get isBoolNumStringOrNull => true;
|
| + EvaluationResultImpl greaterThanOrEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanOrEqualError(node, this);
|
|
|
| @override
|
| - BoolState logicalAnd(InstanceState rightOperand) {
|
| - assertBool(rightOperand);
|
| - if (value == null) {
|
| - return UNKNOWN_VALUE;
|
| - }
|
| - return value ? rightOperand.convertToBool() : FALSE_STATE;
|
| - }
|
| + EvaluationResultImpl integerDivide(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.integerDivideError(node, this);
|
|
|
| @override
|
| - BoolState logicalNot() {
|
| - if (value == null) {
|
| - return UNKNOWN_VALUE;
|
| - }
|
| - return value ? FALSE_STATE : TRUE_STATE;
|
| - }
|
| + EvaluationResultImpl integerDivideValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
|
|
|
| @override
|
| - BoolState logicalOr(InstanceState rightOperand) {
|
| - assertBool(rightOperand);
|
| - if (value == null) {
|
| - return UNKNOWN_VALUE;
|
| - }
|
| - return value ? TRUE_STATE : rightOperand.convertToBool();
|
| - }
|
| + EvaluationResultImpl lessThan(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanError(node, this);
|
|
|
| @override
|
| - String toString() => value == null ? "-unknown-" : (value ? "true" : "false");
|
| -}
|
| + EvaluationResultImpl lessThanOrEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanOrEqualError(node, this);
|
|
|
| -/**
|
| - * 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;
|
| + @override
|
| + EvaluationResultImpl logicalAnd(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalAndError(node, this);
|
|
|
| - /**
|
| - * The state of the object.
|
| - */
|
| - final InstanceState _state;
|
| + @override
|
| + EvaluationResultImpl logicalNot(TypeProvider typeProvider, Expression node) => this;
|
|
|
| - /**
|
| - * 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, this._state);
|
| + @override
|
| + EvaluationResultImpl logicalOr(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalOrError(node, this);
|
|
|
| - /**
|
| - * 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);
|
| - }
|
| - // We should never get here.
|
| - throw new IllegalStateException("add returned a ${result.runtimeType.toString()}");
|
| - }
|
| + @override
|
| + EvaluationResultImpl minus(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.minusError(node, this);
|
|
|
| - /**
|
| - * 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));
|
| + @override
|
| + EvaluationResultImpl negated(TypeProvider typeProvider, Expression node) => this;
|
|
|
| - /**
|
| - * 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());
|
| + @override
|
| + EvaluationResultImpl notEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.notEqualError(node, this);
|
|
|
| - /**
|
| - * 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));
|
| + @override
|
| + EvaluationResultImpl performToString(TypeProvider typeProvider, AstNode node) => this;
|
|
|
| - /**
|
| - * 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));
|
| + @override
|
| + EvaluationResultImpl remainder(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.remainderError(node, this);
|
|
|
| - /**
|
| - * 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));
|
| + @override
|
| + EvaluationResultImpl shiftLeft(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.shiftLeftError(node, this);
|
|
|
| - /**
|
| - * 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());
|
| - }
|
| + @override
|
| + EvaluationResultImpl shiftRight(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.shiftRightError(node, this);
|
|
|
| - /**
|
| - * 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);
|
| - }
|
| - // We should never get here.
|
| - throw new IllegalStateException("divide returned a ${result.runtimeType.toString()}");
|
| - }
|
| + @override
|
| + EvaluationResultImpl times(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.timesError(node, this);
|
|
|
| - /**
|
| - * 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));
|
| - }
|
| + @override
|
| + EvaluationResultImpl addToError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
|
|
| @override
|
| - bool operator ==(Object object) {
|
| - if (object is! DartObjectImpl) {
|
| - return false;
|
| - }
|
| - DartObjectImpl dartObject = object as DartObjectImpl;
|
| - return type == dartObject.type && _state == dartObject._state;
|
| - }
|
| + EvaluationResultImpl addToValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
|
|
|
| @override
|
| - bool get boolValue {
|
| - if (_state is BoolState) {
|
| - return (_state as BoolState).value;
|
| - }
|
| - return null;
|
| - }
|
| + EvaluationResultImpl bitAndError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
|
|
| @override
|
| - double get doubleValue {
|
| - if (_state is DoubleState) {
|
| - return (_state as DoubleState).value;
|
| - }
|
| - return null;
|
| - }
|
| + EvaluationResultImpl bitAndValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
|
|
|
| @override
|
| - int get intValue {
|
| - if (_state is IntState) {
|
| - return (_state as IntState).value;
|
| - }
|
| - return null;
|
| - }
|
| + EvaluationResultImpl bitOrError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
|
|
| @override
|
| - String get stringValue {
|
| - if (_state is StringState) {
|
| - return (_state as StringState).value;
|
| - }
|
| - return null;
|
| - }
|
| + EvaluationResultImpl bitOrValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
|
|
|
| @override
|
| - Object get value => _state.value;
|
| + EvaluationResultImpl bitXorError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
|
|
| - /**
|
| - * 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 greaterThan(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.boolType, _state.greaterThan(rightOperand._state));
|
| + @override
|
| + EvaluationResultImpl bitXorValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
|
|
|
| - /**
|
| - * 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 greaterThanOrEqual(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.boolType, _state.greaterThanOrEqual(rightOperand._state));
|
| + @override
|
| + EvaluationResultImpl concatenateError(Expression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
|
|
| @override
|
| - bool get hasExactValue => _state.hasExactValue;
|
| + EvaluationResultImpl concatenateValid(TypeProvider typeProvider, Expression node, ValidResult leftOperand) => this;
|
|
|
| @override
|
| - int get hashCode => ObjectUtilities.combineHashCodes(type.hashCode, _state.hashCode);
|
| + EvaluationResultImpl divideError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
|
|
| - /**
|
| - * 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));
|
| + @override
|
| + EvaluationResultImpl divideValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => 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 => _state.isBool;
|
| + @override
|
| + EvaluationResultImpl equalEqualError(Expression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
|
|
| - /**
|
| - * 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;
|
| + @override
|
| + EvaluationResultImpl equalEqualValid(TypeProvider typeProvider, Expression node, ValidResult leftOperand) => this;
|
|
|
| @override
|
| - bool get isFalse => _state is BoolState && identical((_state as BoolState).value, false);
|
| + EvaluationResultImpl greaterThanError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
|
|
| @override
|
| - bool get isNull => _state is NullState;
|
| + EvaluationResultImpl greaterThanOrEqualError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
|
|
| @override
|
| - bool get isTrue => _state is BoolState && identical((_state as BoolState).value, true);
|
| + EvaluationResultImpl greaterThanOrEqualValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => 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 => _state is GenericState;
|
| + @override
|
| + EvaluationResultImpl greaterThanValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
|
|
|
| - /**
|
| - * 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 lessThan(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.boolType, _state.lessThan(rightOperand._state));
|
| + @override
|
| + EvaluationResultImpl integerDivideError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
|
|
| - /**
|
| - * 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 lessThanOrEqual(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.boolType, _state.lessThanOrEqual(rightOperand._state));
|
| + @override
|
| + EvaluationResultImpl lessThanError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
|
|
| - /**
|
| - * 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));
|
| + @override
|
| + EvaluationResultImpl lessThanOrEqualError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
|
|
| - /**
|
| - * 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());
|
| + @override
|
| + EvaluationResultImpl lessThanOrEqualValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
|
|
|
| - /**
|
| - * 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));
|
| + @override
|
| + EvaluationResultImpl lessThanValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
|
|
|
| - /**
|
| - * 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);
|
| - }
|
| - // We should never get here.
|
| - throw new IllegalStateException("minus returned a ${result.runtimeType.toString()}");
|
| - }
|
| + @override
|
| + EvaluationResultImpl logicalAndError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
| +
|
| + @override
|
| + EvaluationResultImpl logicalAndValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
|
| +
|
| + @override
|
| + EvaluationResultImpl logicalOrError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
| +
|
| + @override
|
| + EvaluationResultImpl logicalOrValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
|
| +
|
| + @override
|
| + EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
| +
|
| + @override
|
| + EvaluationResultImpl minusValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
|
| +
|
| + @override
|
| + EvaluationResultImpl notEqualError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
| +
|
| + @override
|
| + EvaluationResultImpl notEqualValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
|
| +
|
| + @override
|
| + EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
| +
|
| + @override
|
| + EvaluationResultImpl remainderValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
|
| +
|
| + @override
|
| + EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
| +
|
| + @override
|
| + EvaluationResultImpl shiftLeftValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
|
| +
|
| + @override
|
| + EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
| +
|
| + @override
|
| + EvaluationResultImpl shiftRightValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
|
| +
|
| + @override
|
| + EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
|
| +
|
| + @override
|
| + EvaluationResultImpl timesValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
|
| +}
|
|
|
| +class ErrorResult_ErrorData {
|
| /**
|
| - * 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
|
| + * The node against which the error should be reported.
|
| */
|
| - 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);
|
| - }
|
| - // We should never get here.
|
| - throw new IllegalStateException("negated returned a ${result.runtimeType.toString()}");
|
| - }
|
| + final AstNode node;
|
|
|
| /**
|
| - * 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
|
| + * The error code for the error to be generated.
|
| */
|
| - 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());
|
| - }
|
| + final ErrorCode errorCode;
|
|
|
| /**
|
| - * Return the result of converting this object to a String.
|
| + * Initialize a newly created data holder to represent the error with the given code reported
|
| + * against the given node.
|
| *
|
| - * @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
|
| + * @param node the node against which the error should be reported
|
| + * @param errorCode the error code for the error to be generated
|
| */
|
| - DartObjectImpl performToString(TypeProvider typeProvider) {
|
| - InterfaceType stringType = typeProvider.stringType;
|
| - if (identical(type, stringType)) {
|
| - return this;
|
| - }
|
| - return new DartObjectImpl(stringType, _state.convertToString());
|
| - }
|
| + ErrorResult_ErrorData(this.node, this.errorCode);
|
| +}
|
|
|
| +/**
|
| + * Instances of the class `EvaluationException` represent a run-time exception that would be
|
| + * thrown during the evaluation of Dart code.
|
| + */
|
| +class EvaluationException extends JavaException {
|
| /**
|
| - * 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
|
| + * The error code associated with the exception.
|
| */
|
| - 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);
|
| - }
|
| - // We should never get here.
|
| - throw new IllegalStateException("remainder returned a ${result.runtimeType.toString()}");
|
| - }
|
| + final ErrorCode errorCode;
|
|
|
| /**
|
| - * Return the result of invoking the '<<' operator on this object with the given argument.
|
| + * Initialize a newly created exception to have the given error code.
|
| *
|
| - * @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
|
| + * @param errorCode the error code associated with the exception
|
| */
|
| - DartObjectImpl shiftLeft(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.intType, _state.shiftLeft(rightOperand._state));
|
| + EvaluationException(this.errorCode);
|
| +}
|
|
|
| +/**
|
| + * Instances of the class `EvaluationResult` represent the result of attempting to evaluate an
|
| + * expression.
|
| + */
|
| +class EvaluationResult {
|
| /**
|
| - * Return the result of invoking the '>>' operator on this object with the given argument.
|
| + * Return an evaluation result representing the result of evaluating an expression that is not a
|
| + * compile-time constant because of the given errors.
|
| *
|
| - * @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
|
| + * @param errors the errors that should be reported for the expression(s) that were evaluated
|
| + * @return the result of evaluating an expression that is not a compile-time constant
|
| */
|
| - DartObjectImpl shiftRight(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.intType, _state.shiftRight(rightOperand._state));
|
| + static EvaluationResult forErrors(List<AnalysisError> errors) => new EvaluationResult(null, errors);
|
|
|
| /**
|
| - * Return the result of invoking the '*' operator on this object with the given argument.
|
| + * Return an evaluation result representing the result of evaluating an expression that is a
|
| + * compile-time constant that evaluates to the given value.
|
| *
|
| - * @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
|
| + * @param value the value of the expression
|
| + * @return the result of evaluating an expression that is a compile-time constant
|
| */
|
| - 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);
|
| - }
|
| - // We should never get here.
|
| - throw new IllegalStateException("times returned a ${result.runtimeType.toString()}");
|
| - }
|
| -
|
| - @override
|
| - String toString() => "${type.displayName} (${_state.toString()})";
|
| -}
|
| + static EvaluationResult forValue(DartObject value) => new EvaluationResult(value, null);
|
|
|
| -/**
|
| - * Instances of the class `DoubleState` represent the state of an object representing a
|
| - * double.
|
| - */
|
| -class DoubleState extends NumState {
|
| /**
|
| - * The value of this instance.
|
| + * The value of the expression.
|
| */
|
| - final double value;
|
| + final DartObject value;
|
|
|
| /**
|
| - * A state that can be used to represent a double whose value is not known.
|
| + * The errors that should be reported for the expression(s) that were evaluated.
|
| */
|
| - static DoubleState UNKNOWN_VALUE = new DoubleState(null);
|
| + final List<AnalysisError> _errors;
|
|
|
| /**
|
| - * Initialize a newly created state to represent a double with the given value.
|
| + * Initialize a newly created result object with the given state. Clients should use one of the
|
| + * factory methods: [forErrors] and [forValue].
|
| *
|
| - * @param value the value of this instance
|
| + * @param value the value of the expression
|
| + * @param errors the errors that should be reported for the expression(s) that were evaluated
|
| */
|
| - DoubleState(this.value);
|
| + EvaluationResult(this.value, this._errors);
|
|
|
| - @override
|
| - NumState add(InstanceState rightOperand) {
|
| - assertNumOrNull(rightOperand);
|
| - if (value == null) {
|
| - return UNKNOWN_VALUE;
|
| - }
|
| - if (rightOperand is IntState) {
|
| - int rightValue = rightOperand.value;
|
| - if (rightValue == null) {
|
| - return UNKNOWN_VALUE;
|
| - }
|
| - return new DoubleState(value + rightValue.toDouble());
|
| - } else if (rightOperand is DoubleState) {
|
| - double rightValue = rightOperand.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);
|
| - }
|
| + /**
|
| + * Return an array containing the errors that should be reported for the expression(s) that were
|
| + * evaluated. If there are no such errors, the array will be empty. The array can be empty even if
|
| + * the expression is not a valid compile time constant if the errors would have been reported by
|
| + * other parts of the analysis engine.
|
| + */
|
| + List<AnalysisError> get errors => _errors == null ? AnalysisError.NO_ERRORS : _errors;
|
|
|
| - @override
|
| - StringState convertToString() {
|
| - if (value == null) {
|
| - return StringState.UNKNOWN_VALUE;
|
| - }
|
| - return new StringState(value.toString());
|
| - }
|
| + /**
|
| + * Return `true` if the expression is a compile-time constant expression that would not
|
| + * throw an exception when evaluated.
|
| + *
|
| + * @return `true` if the expression is a valid compile-time constant expression
|
| + */
|
| + bool get isValid => _errors == null;
|
| +}
|
|
|
| - @override
|
| - NumState divide(InstanceState rightOperand) {
|
| - assertNumOrNull(rightOperand);
|
| - if (value == null) {
|
| - return UNKNOWN_VALUE;
|
| - }
|
| - if (rightOperand is IntState) {
|
| - int rightValue = rightOperand.value;
|
| - if (rightValue == null) {
|
| - return UNKNOWN_VALUE;
|
| - }
|
| - return new DoubleState(value / rightValue.toDouble());
|
| - } else if (rightOperand is DoubleState) {
|
| - double rightValue = rightOperand.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);
|
| - }
|
| +/**
|
| + * Instances of the class `InternalResult` represent the result of attempting to evaluate a
|
| + * expression.
|
| + */
|
| +abstract class EvaluationResultImpl {
|
| + EvaluationResultImpl add(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
|
|
| - @override
|
| - BoolState equalEqual(InstanceState rightOperand) {
|
| - assertBoolNumStringOrNull(rightOperand);
|
| - if (value == null) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| - if (rightOperand is DoubleState) {
|
| - double rightValue = rightOperand.value;
|
| - if (rightValue == null) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| - return BoolState.from(value == rightValue);
|
| - } else if (rightOperand is IntState) {
|
| - int rightValue = rightOperand.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;
|
| - }
|
| + /**
|
| + * 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(TypeProvider typeProvider, AstNode node);
|
|
|
| - @override
|
| - bool operator ==(Object object) => object is DoubleState && (value == object.value);
|
| + EvaluationResultImpl bitAnd(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
|
|
| - @override
|
| - String get typeName => "double";
|
| + EvaluationResultImpl bitNot(TypeProvider typeProvider, Expression node);
|
|
|
| - @override
|
| - BoolState greaterThan(InstanceState rightOperand) {
|
| - assertNumOrNull(rightOperand);
|
| - if (value == null) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| - if (rightOperand is IntState) {
|
| - int rightValue = rightOperand.value;
|
| - if (rightValue == null) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| - return BoolState.from(value > rightValue.toDouble());
|
| - } else if (rightOperand is DoubleState) {
|
| - double rightValue = rightOperand.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);
|
| - }
|
| + EvaluationResultImpl bitOr(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
|
|
| - @override
|
| - BoolState greaterThanOrEqual(InstanceState rightOperand) {
|
| - assertNumOrNull(rightOperand);
|
| - if (value == null) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| - if (rightOperand is IntState) {
|
| - int rightValue = rightOperand.value;
|
| - if (rightValue == null) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| - return BoolState.from(value >= rightValue.toDouble());
|
| - } else if (rightOperand is DoubleState) {
|
| - double rightValue = rightOperand.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);
|
| - }
|
| + EvaluationResultImpl bitXor(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
|
|
| - @override
|
| - bool get hasExactValue => true;
|
| + EvaluationResultImpl concatenate(TypeProvider typeProvider, Expression node, EvaluationResultImpl rightOperand);
|
|
|
| - @override
|
| - int get hashCode => value == null ? 0 : value.hashCode;
|
| + EvaluationResultImpl divide(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
|
|
| - @override
|
| - IntState integerDivide(InstanceState rightOperand) {
|
| - assertNumOrNull(rightOperand);
|
| - if (value == null) {
|
| - return IntState.UNKNOWN_VALUE;
|
| - }
|
| - if (rightOperand is IntState) {
|
| - int rightValue = rightOperand.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.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);
|
| - }
|
| + EvaluationResultImpl equalEqual(TypeProvider typeProvider, Expression node, EvaluationResultImpl rightOperand);
|
|
|
| - @override
|
| - bool get isBoolNumStringOrNull => true;
|
| + bool equalValues(TypeProvider typeProvider, EvaluationResultImpl result);
|
|
|
| - @override
|
| - BoolState lessThan(InstanceState rightOperand) {
|
| - assertNumOrNull(rightOperand);
|
| - if (value == null) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| - if (rightOperand is IntState) {
|
| - int rightValue = rightOperand.value;
|
| - if (rightValue == null) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| - return BoolState.from(value < rightValue.toDouble());
|
| - } else if (rightOperand is DoubleState) {
|
| - double rightValue = rightOperand.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);
|
| - }
|
| + EvaluationResultImpl greaterThan(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
|
|
| - @override
|
| - BoolState lessThanOrEqual(InstanceState rightOperand) {
|
| - assertNumOrNull(rightOperand);
|
| - if (value == null) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| - if (rightOperand is IntState) {
|
| - int rightValue = rightOperand.value;
|
| - if (rightValue == null) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| - return BoolState.from(value <= rightValue.toDouble());
|
| - } else if (rightOperand is DoubleState) {
|
| - double rightValue = rightOperand.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);
|
| - }
|
| + EvaluationResultImpl greaterThanOrEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
|
|
| - @override
|
| - NumState minus(InstanceState rightOperand) {
|
| - assertNumOrNull(rightOperand);
|
| - if (value == null) {
|
| - return UNKNOWN_VALUE;
|
| - }
|
| - if (rightOperand is IntState) {
|
| - int rightValue = rightOperand.value;
|
| - if (rightValue == null) {
|
| - return UNKNOWN_VALUE;
|
| - }
|
| - return new DoubleState(value - rightValue.toDouble());
|
| - } else if (rightOperand is DoubleState) {
|
| - double rightValue = rightOperand.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);
|
| - }
|
| + EvaluationResultImpl integerDivide(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
|
|
| - @override
|
| - NumState negated() {
|
| - if (value == null) {
|
| - return UNKNOWN_VALUE;
|
| - }
|
| - return new DoubleState(-(value));
|
| - }
|
| + EvaluationResultImpl lessThan(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
|
|
| - @override
|
| - NumState remainder(InstanceState rightOperand) {
|
| - assertNumOrNull(rightOperand);
|
| - if (value == null) {
|
| - return UNKNOWN_VALUE;
|
| - }
|
| - if (rightOperand is IntState) {
|
| - int rightValue = rightOperand.value;
|
| - if (rightValue == null) {
|
| - return UNKNOWN_VALUE;
|
| - }
|
| - return new DoubleState(value % rightValue.toDouble());
|
| - } else if (rightOperand is DoubleState) {
|
| - double rightValue = rightOperand.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);
|
| - }
|
| + EvaluationResultImpl lessThanOrEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
|
|
| - @override
|
| - NumState times(InstanceState rightOperand) {
|
| - assertNumOrNull(rightOperand);
|
| - if (value == null) {
|
| - return UNKNOWN_VALUE;
|
| - }
|
| - if (rightOperand is IntState) {
|
| - int rightValue = rightOperand.value;
|
| - if (rightValue == null) {
|
| - return UNKNOWN_VALUE;
|
| - }
|
| - return new DoubleState(value * rightValue.toDouble());
|
| - } else if (rightOperand is DoubleState) {
|
| - double rightValue = rightOperand.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);
|
| - }
|
| + EvaluationResultImpl logicalAnd(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
|
|
| - @override
|
| - String toString() => value == null ? "-unknown-" : value.toString();
|
| -}
|
| + EvaluationResultImpl logicalNot(TypeProvider typeProvider, Expression node);
|
|
|
| -/**
|
| - * 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();
|
| + EvaluationResultImpl logicalOr(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
|
|
| - @override
|
| - NumState add(InstanceState rightOperand) {
|
| - assertNumOrNull(rightOperand);
|
| - return _unknownNum(rightOperand);
|
| - }
|
| + EvaluationResultImpl minus(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
|
|
| - @override
|
| - IntState bitAnd(InstanceState rightOperand) {
|
| - assertIntOrNull(rightOperand);
|
| - return IntState.UNKNOWN_VALUE;
|
| - }
|
| + EvaluationResultImpl negated(TypeProvider typeProvider, Expression node);
|
|
|
| - @override
|
| - IntState bitNot() => IntState.UNKNOWN_VALUE;
|
| + EvaluationResultImpl notEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
|
|
| - @override
|
| - IntState bitOr(InstanceState rightOperand) {
|
| - assertIntOrNull(rightOperand);
|
| - return IntState.UNKNOWN_VALUE;
|
| - }
|
| + EvaluationResultImpl performToString(TypeProvider typeProvider, AstNode node);
|
| +
|
| + EvaluationResultImpl remainder(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
| +
|
| + EvaluationResultImpl shiftLeft(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
| +
|
| + EvaluationResultImpl shiftRight(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
| +
|
| + EvaluationResultImpl times(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
|
| +
|
| + EvaluationResultImpl addToError(BinaryExpression node, ErrorResult leftOperand);
|
| +
|
| + EvaluationResultImpl addToValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| +
|
| + EvaluationResultImpl bitAndError(BinaryExpression node, ErrorResult leftOperand);
|
| +
|
| + EvaluationResultImpl bitAndValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| +
|
| + EvaluationResultImpl bitOrError(BinaryExpression node, ErrorResult leftOperand);
|
| +
|
| + EvaluationResultImpl bitOrValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| +
|
| + EvaluationResultImpl bitXorError(BinaryExpression node, ErrorResult leftOperand);
|
| +
|
| + EvaluationResultImpl bitXorValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| +
|
| + EvaluationResultImpl concatenateError(Expression node, ErrorResult leftOperand);
|
| +
|
| + EvaluationResultImpl concatenateValid(TypeProvider typeProvider, Expression node, ValidResult leftOperand);
|
| +
|
| + EvaluationResultImpl divideError(BinaryExpression node, ErrorResult leftOperand);
|
| +
|
| + EvaluationResultImpl divideValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| +
|
| + EvaluationResultImpl equalEqualError(Expression node, ErrorResult leftOperand);
|
| +
|
| + EvaluationResultImpl equalEqualValid(TypeProvider typeProvider, Expression node, ValidResult leftOperand);
|
| +
|
| + EvaluationResultImpl greaterThanError(BinaryExpression node, ErrorResult leftOperand);
|
| +
|
| + EvaluationResultImpl greaterThanOrEqualError(BinaryExpression node, ErrorResult leftOperand);
|
| +
|
| + EvaluationResultImpl greaterThanOrEqualValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| +
|
| + EvaluationResultImpl greaterThanValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| +
|
| + EvaluationResultImpl integerDivideError(BinaryExpression node, ErrorResult leftOperand);
|
| +
|
| + EvaluationResultImpl integerDivideValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| +
|
| + EvaluationResultImpl lessThanError(BinaryExpression node, ErrorResult leftOperand);
|
| +
|
| + EvaluationResultImpl lessThanOrEqualError(BinaryExpression node, ErrorResult leftOperand);
|
| +
|
| + EvaluationResultImpl lessThanOrEqualValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| +
|
| + EvaluationResultImpl lessThanValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| +
|
| + EvaluationResultImpl logicalAndError(BinaryExpression node, ErrorResult leftOperand);
|
| +
|
| + EvaluationResultImpl logicalAndValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| +
|
| + EvaluationResultImpl logicalOrError(BinaryExpression node, ErrorResult leftOperand);
|
| +
|
| + EvaluationResultImpl logicalOrValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| +
|
| + EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand);
|
| +
|
| + EvaluationResultImpl minusValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| +
|
| + EvaluationResultImpl notEqualError(BinaryExpression node, ErrorResult leftOperand);
|
| +
|
| + EvaluationResultImpl notEqualValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| +
|
| + EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOperand);
|
| +
|
| + EvaluationResultImpl remainderValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| +
|
| + EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOperand);
|
| +
|
| + EvaluationResultImpl shiftLeftValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| +
|
| + EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOperand);
|
| +
|
| + EvaluationResultImpl shiftRightValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| +
|
| + EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand);
|
|
|
| - @override
|
| - IntState bitXor(InstanceState rightOperand) {
|
| - assertIntOrNull(rightOperand);
|
| - return IntState.UNKNOWN_VALUE;
|
| - }
|
| + EvaluationResultImpl timesValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
|
| +}
|
|
|
| - @override
|
| - StringState concatenate(InstanceState rightOperand) {
|
| - assertString(rightOperand);
|
| - return StringState.UNKNOWN_VALUE;
|
| - }
|
| +/**
|
| + * 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.
|
| + */
|
| + final ExecutableElement _element;
|
|
|
| - @override
|
| - BoolState convertToBool() => BoolState.UNKNOWN_VALUE;
|
| + /**
|
| + * Initialize a newly created state to represent the given function.
|
| + *
|
| + * @param element the element representing the function being modeled
|
| + */
|
| + FunctionState(this._element);
|
|
|
| @override
|
| - StringState convertToString() => StringState.UNKNOWN_VALUE;
|
| + StringState convertToString() {
|
| + if (_element == null) {
|
| + return StringState.UNKNOWN_VALUE;
|
| + }
|
| + return new StringState(_element.name);
|
| + }
|
|
|
| @override
|
| - NumState divide(InstanceState rightOperand) {
|
| - assertNumOrNull(rightOperand);
|
| - return _unknownNum(rightOperand);
|
| - }
|
| + bool operator ==(Object object) => object is FunctionState && (_element == object._element);
|
|
|
| @override
|
| BoolState equalEqual(InstanceState rightOperand) {
|
| - assertBoolNumStringOrNull(rightOperand);
|
| - return BoolState.UNKNOWN_VALUE;
|
| + if (_element == null) {
|
| + return BoolState.UNKNOWN_VALUE;
|
| + }
|
| + if (rightOperand is FunctionState) {
|
| + ExecutableElement rightElement = rightOperand._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;
|
| }
|
|
|
| @override
|
| - String get typeName => "dynamic";
|
| + String get typeName => "Function";
|
|
|
| @override
|
| - BoolState greaterThan(InstanceState rightOperand) {
|
| - assertNumOrNull(rightOperand);
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| + int get hashCode => _element == null ? 0 : _element.hashCode;
|
|
|
| @override
|
| - BoolState greaterThanOrEqual(InstanceState rightOperand) {
|
| - assertNumOrNull(rightOperand);
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| + String toString() => _element == null ? "-unknown-" : _element.name;
|
| +}
|
|
|
| - @override
|
| - IntState integerDivide(InstanceState rightOperand) {
|
| - assertNumOrNull(rightOperand);
|
| - return IntState.UNKNOWN_VALUE;
|
| - }
|
| +/**
|
| + * 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.
|
| + */
|
| + final Map<String, DartObjectImpl> _fieldMap;
|
|
|
| - @override
|
| - bool get isBool => true;
|
| + /**
|
| + * 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>());
|
|
|
| - @override
|
| - bool get isBoolNumStringOrNull => true;
|
| + /**
|
| + * Initialize a newly created state to represent a newly created object.
|
| + *
|
| + * @param fieldMap the values of the fields of this instance
|
| + */
|
| + GenericState(this._fieldMap);
|
|
|
| @override
|
| - BoolState lessThan(InstanceState rightOperand) {
|
| - assertNumOrNull(rightOperand);
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| + StringState convertToString() => StringState.UNKNOWN_VALUE;
|
|
|
| @override
|
| - BoolState lessThanOrEqual(InstanceState rightOperand) {
|
| - assertNumOrNull(rightOperand);
|
| - return BoolState.UNKNOWN_VALUE;
|
| + bool operator ==(Object object) {
|
| + if (object is! GenericState) {
|
| + return false;
|
| + }
|
| + GenericState state = object as GenericState;
|
| + Set<String> otherFields = new Set<String>.from(state._fieldMap.keys.toSet());
|
| + 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;
|
| }
|
|
|
| @override
|
| - BoolState logicalAnd(InstanceState rightOperand) {
|
| - assertBool(rightOperand);
|
| - return BoolState.UNKNOWN_VALUE;
|
| + BoolState equalEqual(InstanceState rightOperand) {
|
| + assertBoolNumStringOrNull(rightOperand);
|
| + if (rightOperand is DynamicState) {
|
| + return BoolState.UNKNOWN_VALUE;
|
| + }
|
| + return BoolState.from(this == rightOperand);
|
| }
|
|
|
| @override
|
| - BoolState logicalNot() => BoolState.UNKNOWN_VALUE;
|
| + String get typeName => "user defined type";
|
|
|
| @override
|
| - BoolState logicalOr(InstanceState rightOperand) {
|
| - assertBool(rightOperand);
|
| - return rightOperand.convertToBool();
|
| + int get hashCode {
|
| + int hashCode = 0;
|
| + for (DartObjectImpl value in _fieldMap.values) {
|
| + hashCode += value.hashCode;
|
| + }
|
| + return hashCode;
|
| }
|
| +}
|
|
|
| - @override
|
| - NumState minus(InstanceState rightOperand) {
|
| +/**
|
| + * 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);
|
| - return _unknownNum(rightOperand);
|
| + throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
|
| }
|
|
|
| - @override
|
| - NumState negated() => NumState.UNKNOWN_VALUE;
|
| + /**
|
| + * 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);
|
| + }
|
|
|
| - @override
|
| - NumState remainder(InstanceState rightOperand) {
|
| - assertNumOrNull(rightOperand);
|
| - return _unknownNum(rightOperand);
|
| + /**
|
| + * 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);
|
| }
|
|
|
| - @override
|
| - IntState shiftLeft(InstanceState rightOperand) {
|
| + /**
|
| + * 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);
|
| - return IntState.UNKNOWN_VALUE;
|
| + throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
|
| }
|
|
|
| - @override
|
| - IntState shiftRight(InstanceState rightOperand) {
|
| + /**
|
| + * 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);
|
| - return IntState.UNKNOWN_VALUE;
|
| + throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
|
| }
|
|
|
| - @override
|
| - NumState times(InstanceState rightOperand) {
|
| + /**
|
| + * 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);
|
| - return _unknownNum(rightOperand);
|
| + throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
|
| }
|
|
|
| /**
|
| - * Return an object representing an unknown numeric value whose type is based on the type of the
|
| - * right-hand operand.
|
| + * Return the result of invoking the '==' operator on this object with the given argument.
|
| *
|
| - * @param rightOperand the operand whose type will determine the type of the result
|
| - * @return an object representing an unknown numeric value
|
| + * @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 _unknownNum(InstanceState rightOperand) {
|
| - if (rightOperand is IntState) {
|
| - return IntState.UNKNOWN_VALUE;
|
| - } else if (rightOperand is DoubleState) {
|
| - return DoubleState.UNKNOWN_VALUE;
|
| - }
|
| - return NumState.UNKNOWN_VALUE;
|
| - }
|
| -}
|
| + BoolState equalEqual(InstanceState rightOperand);
|
|
|
| -/**
|
| - * 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.
|
| + * Return the name of the type of this value.
|
| + *
|
| + * @return the name of the type of this value
|
| */
|
| - final ErrorCode errorCode;
|
| + String get typeName;
|
|
|
| /**
|
| - * Initialize a newly created exception to have the given error code.
|
| + * Return this object's value if it can be represented exactly, or `null` if either the
|
| + * value cannot be represented exactly or if the value is `null`. Clients should use
|
| + * [hasExactValue] to distinguish between these two cases.
|
| *
|
| - * @param errorCode the error code associated with the exception
|
| + * @return this object's value
|
| */
|
| - EvaluationException(this.errorCode);
|
| -}
|
| + Object get value => null;
|
|
|
| -/**
|
| - * 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.
|
| + * 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
|
| */
|
| - final ExecutableElement _element;
|
| + BoolState greaterThan(InstanceState rightOperand) {
|
| + assertNumOrNull(this);
|
| + assertNumOrNull(rightOperand);
|
| + throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
|
| + }
|
|
|
| /**
|
| - * Initialize a newly created state to represent the given function.
|
| + * Return the result of invoking the '>=' operator on this object with the given argument.
|
| *
|
| - * @param element the element representing the function being modeled
|
| + * @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
|
| */
|
| - FunctionState(this._element);
|
| -
|
| - @override
|
| - StringState convertToString() {
|
| - if (_element == null) {
|
| - return StringState.UNKNOWN_VALUE;
|
| - }
|
| - return new StringState(_element.name);
|
| + BoolState greaterThanOrEqual(InstanceState rightOperand) {
|
| + assertNumOrNull(this);
|
| + assertNumOrNull(rightOperand);
|
| + throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
|
| }
|
|
|
| - @override
|
| - bool operator ==(Object object) => object is FunctionState && (_element == object._element);
|
| + /**
|
| + * Return `true` if this object's value can be represented exactly.
|
| + *
|
| + * @return `true` if this object's value can be represented exactly
|
| + */
|
| + bool get hasExactValue => false;
|
|
|
| - @override
|
| - BoolState equalEqual(InstanceState rightOperand) {
|
| - if (_element == null) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| - if (rightOperand is FunctionState) {
|
| - ExecutableElement rightElement = rightOperand._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;
|
| + /**
|
| + * 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);
|
| }
|
|
|
| - @override
|
| - String get typeName => "Function";
|
| -
|
| - @override
|
| - int get hashCode => _element == null ? 0 : _element.hashCode;
|
| -
|
| - @override
|
| - String toString() => _element == null ? "-unknown-" : _element.name;
|
| -}
|
| + /**
|
| + * 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;
|
|
|
| -/**
|
| - * 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.
|
| + * 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
|
| */
|
| - final Map<String, DartObjectImpl> _fieldMap;
|
| + bool get isBoolNumStringOrNull => false;
|
|
|
| /**
|
| - * A state that can be used to represent an object whose state is not known.
|
| + * 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
|
| */
|
| - static GenericState UNKNOWN_VALUE = new GenericState(new Map<String, DartObjectImpl>());
|
| + BoolState lessThan(InstanceState rightOperand) {
|
| + assertNumOrNull(this);
|
| + assertNumOrNull(rightOperand);
|
| + throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
|
| + }
|
|
|
| /**
|
| - * Initialize a newly created state to represent a newly created object.
|
| + * Return the result of invoking the '<=' operator on this object with the given argument.
|
| *
|
| - * @param fieldMap the values of the fields of this instance
|
| + * @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
|
| */
|
| - GenericState(this._fieldMap);
|
| + BoolState lessThanOrEqual(InstanceState rightOperand) {
|
| + assertNumOrNull(this);
|
| + assertNumOrNull(rightOperand);
|
| + throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
|
| + }
|
|
|
| - @override
|
| - StringState convertToString() => StringState.UNKNOWN_VALUE;
|
| + /**
|
| + * 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;
|
| + }
|
|
|
| - @override
|
| - bool operator ==(Object object) {
|
| - if (object is! GenericState) {
|
| - return false;
|
| - }
|
| - GenericState state = object as GenericState;
|
| - Set<String> otherFields = new Set<String>.from(state._fieldMap.keys.toSet());
|
| - 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;
|
| + /**
|
| + * 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;
|
| }
|
|
|
| - @override
|
| - BoolState equalEqual(InstanceState rightOperand) {
|
| - assertBoolNumStringOrNull(rightOperand);
|
| - if (rightOperand is DynamicState) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| - return BoolState.from(this == rightOperand);
|
| + /**
|
| + * 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();
|
| }
|
|
|
| - @override
|
| - String get typeName => "user defined type";
|
| + /**
|
| + * 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);
|
| + }
|
|
|
| - @override
|
| - int get hashCode {
|
| - int hashCode = 0;
|
| - for (DartObjectImpl value in _fieldMap.values) {
|
| - hashCode += value.hashCode;
|
| - }
|
| - return hashCode;
|
| + /**
|
| + * 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);
|
| }
|
| -}
|
|
|
| -/**
|
| - * 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.
|
| + * 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
|
| + * @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) {
|
| + NumState remainder(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.
|
| + * 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
|
| + * @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) {
|
| + IntState shiftLeft(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 with the given argument.
|
| *
|
| - * @return the result of invoking the '~' operator on this object
|
| + * @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 bitNot() {
|
| + 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.
|
| + * 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
|
| + * @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);
|
| + NumState times(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.
|
| + * Throw an exception if the given state does not represent a boolean value.
|
| *
|
| - * @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
|
| + * @param state the state being tested
|
| + * @throws EvaluationException if the given state does not represent a boolean value
|
| */
|
| - IntState bitXor(InstanceState rightOperand) {
|
| - assertIntOrNull(this);
|
| - assertIntOrNull(rightOperand);
|
| - throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
|
| + void assertBool(InstanceState state) {
|
| + if (!(state is BoolState || state is DynamicState)) {
|
| + throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL);
|
| + }
|
| }
|
|
|
| /**
|
| - * Return the result of invoking the ' ' operator on this object with the given argument.
|
| + * Throw an exception if the given state does not represent a boolean, numeric, string or null
|
| + * value.
|
| *
|
| - * @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
|
| + * @param state the state being tested
|
| + * @throws EvaluationException if the given state does not represent a boolean, numeric, string or
|
| + * null value
|
| */
|
| - StringState concatenate(InstanceState rightOperand) {
|
| - throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
|
| + 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);
|
| + }
|
| }
|
|
|
| /**
|
| - * Return the result of applying boolean conversion to this object.
|
| + * Throw an exception if the given state does not represent an integer or null value.
|
| *
|
| - * @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
|
| + * @param state the state being tested
|
| + * @throws EvaluationException if the given state does not represent an integer or null value
|
| */
|
| - BoolState convertToBool() => BoolState.FALSE_STATE;
|
| + 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);
|
| + }
|
| + }
|
|
|
| /**
|
| - * Return the result of converting this object to a String.
|
| + * Throw an exception if the given state does not represent a boolean, numeric, string or null
|
| + * value.
|
| *
|
| - * @return the result of converting this object to a String
|
| - * @throws EvaluationException if the operator is not appropriate for an object of this kind
|
| + * @param state the state being tested
|
| + * @throws EvaluationException if the given state does not represent a boolean, numeric, string or
|
| + * null value
|
| */
|
| - StringState convertToString();
|
| + 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);
|
| + }
|
| + }
|
|
|
| /**
|
| - * Return the result of invoking the '/' operator on this object with the given argument.
|
| + * Throw an exception if the given state does not represent a String value.
|
| *
|
| - * @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
|
| + * @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);
|
| +
|
| + @override
|
| + 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.value;
|
| + if (rightValue == null) {
|
| + return UNKNOWN_VALUE;
|
| + }
|
| + return new IntState(value + rightValue);
|
| + } else if (rightOperand is DoubleState) {
|
| + double rightValue = rightOperand.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);
|
| + }
|
| +
|
| + @override
|
| + IntState bitAnd(InstanceState rightOperand) {
|
| + assertIntOrNull(rightOperand);
|
| + if (value == null) {
|
| + return UNKNOWN_VALUE;
|
| + }
|
| + if (rightOperand is IntState) {
|
| + int rightValue = rightOperand.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);
|
| + }
|
| +
|
| + @override
|
| + IntState bitNot() {
|
| + if (value == null) {
|
| + return UNKNOWN_VALUE;
|
| + }
|
| + return new IntState(~value);
|
| + }
|
| +
|
| + @override
|
| + IntState bitOr(InstanceState rightOperand) {
|
| + assertIntOrNull(rightOperand);
|
| + if (value == null) {
|
| + return UNKNOWN_VALUE;
|
| + }
|
| + if (rightOperand is IntState) {
|
| + int rightValue = rightOperand.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);
|
| + }
|
| +
|
| + @override
|
| + IntState bitXor(InstanceState rightOperand) {
|
| + assertIntOrNull(rightOperand);
|
| + if (value == null) {
|
| + return UNKNOWN_VALUE;
|
| + }
|
| + if (rightOperand is IntState) {
|
| + int rightValue = rightOperand.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);
|
| + }
|
| +
|
| + @override
|
| + StringState convertToString() {
|
| + if (value == null) {
|
| + return StringState.UNKNOWN_VALUE;
|
| + }
|
| + return new StringState(value.toString());
|
| + }
|
| +
|
| + @override
|
| NumState divide(InstanceState rightOperand) {
|
| - assertNumOrNull(this);
|
| assertNumOrNull(rightOperand);
|
| - throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
|
| + if (value == null) {
|
| + if (rightOperand is DoubleState) {
|
| + return DoubleState.UNKNOWN_VALUE;
|
| + }
|
| + return UNKNOWN_VALUE;
|
| + }
|
| + if (rightOperand is IntState) {
|
| + int rightValue = rightOperand.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.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);
|
| + }
|
| +
|
| + @override
|
| + BoolState equalEqual(InstanceState rightOperand) {
|
| + assertBoolNumStringOrNull(rightOperand);
|
| + if (value == null) {
|
| + return BoolState.UNKNOWN_VALUE;
|
| + }
|
| + if (rightOperand is IntState) {
|
| + int rightValue = rightOperand.value;
|
| + if (rightValue == null) {
|
| + return BoolState.UNKNOWN_VALUE;
|
| + }
|
| + return BoolState.from(value == rightValue);
|
| + } else if (rightOperand is DoubleState) {
|
| + double rightValue = rightOperand.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;
|
| }
|
|
|
| - /**
|
| - * 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;
|
| + @override
|
| + bool operator ==(Object object) => object is IntState && (value == object.value);
|
|
|
| - /**
|
| - * Return this object's value if it can be represented exactly, or `null` if either the
|
| - * value cannot be represented exactly or if the value is `null`. Clients should use
|
| - * [hasExactValue] to distinguish between these two cases.
|
| - *
|
| - * @return this object's value
|
| - */
|
| - Object get value => null;
|
| + @override
|
| + String get typeName => "int";
|
|
|
| - /**
|
| - * 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
|
| - */
|
| + @override
|
| BoolState greaterThan(InstanceState rightOperand) {
|
| - assertNumOrNull(this);
|
| assertNumOrNull(rightOperand);
|
| - throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
|
| + if (value == null) {
|
| + return BoolState.UNKNOWN_VALUE;
|
| + }
|
| + if (rightOperand is IntState) {
|
| + int rightValue = rightOperand.value;
|
| + if (rightValue == null) {
|
| + return BoolState.UNKNOWN_VALUE;
|
| + }
|
| + return BoolState.from(value.compareTo(rightValue) > 0);
|
| + } else if (rightOperand is DoubleState) {
|
| + double rightValue = rightOperand.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);
|
| }
|
|
|
| - /**
|
| - * 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
|
| - */
|
| + @override
|
| BoolState greaterThanOrEqual(InstanceState rightOperand) {
|
| - assertNumOrNull(this);
|
| assertNumOrNull(rightOperand);
|
| - throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
|
| + if (value == null) {
|
| + return BoolState.UNKNOWN_VALUE;
|
| + }
|
| + if (rightOperand is IntState) {
|
| + int rightValue = rightOperand.value;
|
| + if (rightValue == null) {
|
| + return BoolState.UNKNOWN_VALUE;
|
| + }
|
| + return BoolState.from(value.compareTo(rightValue) >= 0);
|
| + } else if (rightOperand is DoubleState) {
|
| + double rightValue = rightOperand.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);
|
| }
|
|
|
| - /**
|
| - * Return `true` if this object's value can be represented exactly.
|
| - *
|
| - * @return `true` if this object's value can be represented exactly
|
| - */
|
| - bool get hasExactValue => false;
|
| + @override
|
| + bool get hasExactValue => true;
|
|
|
| - /**
|
| - * 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
|
| - */
|
| + @override
|
| + int get hashCode => value == null ? 0 : value.hashCode;
|
| +
|
| + @override
|
| IntState integerDivide(InstanceState rightOperand) {
|
| - assertNumOrNull(this);
|
| assertNumOrNull(rightOperand);
|
| - throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
|
| + if (value == null) {
|
| + return UNKNOWN_VALUE;
|
| + }
|
| + if (rightOperand is IntState) {
|
| + int rightValue = rightOperand.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.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);
|
| }
|
|
|
| - /**
|
| - * 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;
|
| + @override
|
| + bool get isBoolNumStringOrNull => true;
|
|
|
| - /**
|
| - * 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
|
| - */
|
| + @override
|
| BoolState lessThan(InstanceState rightOperand) {
|
| - assertNumOrNull(this);
|
| assertNumOrNull(rightOperand);
|
| - throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
|
| + if (value == null) {
|
| + return BoolState.UNKNOWN_VALUE;
|
| + }
|
| + if (rightOperand is IntState) {
|
| + int rightValue = rightOperand.value;
|
| + if (rightValue == null) {
|
| + return BoolState.UNKNOWN_VALUE;
|
| + }
|
| + return BoolState.from(value.compareTo(rightValue) < 0);
|
| + } else if (rightOperand is DoubleState) {
|
| + double rightValue = rightOperand.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);
|
| }
|
|
|
| - /**
|
| - * 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
|
| - */
|
| + @override
|
| 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
|
| - */
|
| + if (value == null) {
|
| + return BoolState.UNKNOWN_VALUE;
|
| + }
|
| + if (rightOperand is IntState) {
|
| + int rightValue = rightOperand.value;
|
| + if (rightValue == null) {
|
| + return BoolState.UNKNOWN_VALUE;
|
| + }
|
| + return BoolState.from(value.compareTo(rightValue) <= 0);
|
| + } else if (rightOperand is DoubleState) {
|
| + double rightValue = rightOperand.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);
|
| + }
|
| +
|
| + @override
|
| NumState minus(InstanceState rightOperand) {
|
| - assertNumOrNull(this);
|
| assertNumOrNull(rightOperand);
|
| - throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
|
| + if (value == null) {
|
| + if (rightOperand is DoubleState) {
|
| + return DoubleState.UNKNOWN_VALUE;
|
| + }
|
| + return UNKNOWN_VALUE;
|
| + }
|
| + if (rightOperand is IntState) {
|
| + int rightValue = rightOperand.value;
|
| + if (rightValue == null) {
|
| + return UNKNOWN_VALUE;
|
| + }
|
| + return new IntState(value - rightValue);
|
| + } else if (rightOperand is DoubleState) {
|
| + double rightValue = rightOperand.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);
|
| }
|
|
|
| - /**
|
| - * 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
|
| - */
|
| + @override
|
| NumState negated() {
|
| - assertNumOrNull(this);
|
| - throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
|
| + if (value == null) {
|
| + return UNKNOWN_VALUE;
|
| + }
|
| + return new IntState(-value);
|
| }
|
|
|
| - /**
|
| - * 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
|
| - */
|
| + @override
|
| NumState remainder(InstanceState rightOperand) {
|
| - assertNumOrNull(this);
|
| assertNumOrNull(rightOperand);
|
| - throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
|
| + if (value == null) {
|
| + if (rightOperand is DoubleState) {
|
| + return DoubleState.UNKNOWN_VALUE;
|
| + }
|
| + return UNKNOWN_VALUE;
|
| + }
|
| + if (rightOperand is IntState) {
|
| + int rightValue = rightOperand.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.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);
|
| }
|
|
|
| - /**
|
| - * 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
|
| - */
|
| + @override
|
| IntState shiftLeft(InstanceState rightOperand) {
|
| - assertIntOrNull(this);
|
| assertIntOrNull(rightOperand);
|
| - throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
|
| + if (value == null) {
|
| + return UNKNOWN_VALUE;
|
| + }
|
| + if (rightOperand is IntState) {
|
| + int rightValue = rightOperand.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);
|
| }
|
|
|
| - /**
|
| - * 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
|
| - */
|
| + @override
|
| IntState shiftRight(InstanceState rightOperand) {
|
| - assertIntOrNull(this);
|
| assertIntOrNull(rightOperand);
|
| - throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
|
| + if (value == null) {
|
| + return UNKNOWN_VALUE;
|
| + }
|
| + if (rightOperand is IntState) {
|
| + int rightValue = rightOperand.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);
|
| }
|
|
|
| - /**
|
| - * 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
|
| - */
|
| + @override
|
| NumState times(InstanceState rightOperand) {
|
| - assertNumOrNull(this);
|
| assertNumOrNull(rightOperand);
|
| - throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
|
| + if (value == null) {
|
| + if (rightOperand is DoubleState) {
|
| + return DoubleState.UNKNOWN_VALUE;
|
| + }
|
| + return UNKNOWN_VALUE;
|
| + }
|
| + if (rightOperand is IntState) {
|
| + int rightValue = rightOperand.value;
|
| + if (rightValue == null) {
|
| + return UNKNOWN_VALUE;
|
| + }
|
| + return new IntState(value * rightValue);
|
| + } else if (rightOperand is DoubleState) {
|
| + double rightValue = rightOperand.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);
|
| }
|
|
|
| + @override
|
| + 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 {
|
| /**
|
| - * 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
|
| + * The elements of the list.
|
| */
|
| - void assertBool(InstanceState state) {
|
| - if (!(state is BoolState || state is DynamicState)) {
|
| - throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL);
|
| - }
|
| - }
|
| + final List<DartObjectImpl> _elements;
|
|
|
| /**
|
| - * Throw an exception if the given state does not represent a boolean, numeric, string or null
|
| - * value.
|
| + * Initialize a newly created state to represent a list with the given elements.
|
| *
|
| - * @param state the state being tested
|
| - * @throws EvaluationException if the given state does not represent a boolean, numeric, string or
|
| - * null value
|
| + * @param elements the elements of the list
|
| */
|
| - 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);
|
| + ListState(this._elements);
|
| +
|
| + @override
|
| + StringState convertToString() => StringState.UNKNOWN_VALUE;
|
| +
|
| + @override
|
| + BoolState equalEqual(InstanceState rightOperand) {
|
| + assertBoolNumStringOrNull(rightOperand);
|
| + if (rightOperand is DynamicState) {
|
| + return BoolState.UNKNOWN_VALUE;
|
| }
|
| + return BoolState.from(this == rightOperand);
|
| }
|
|
|
| - /**
|
| - * 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);
|
| + @override
|
| + 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;
|
| }
|
|
|
| - /**
|
| - * 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);
|
| + @override
|
| + String get typeName => "List";
|
| +
|
| + @override
|
| + List<Object> get value {
|
| + int count = _elements.length;
|
| + List<Object> result = new List<Object>(count);
|
| + for (int i = 0; i < count; i++) {
|
| + DartObjectImpl element = _elements[i];
|
| + if (!element.hasExactValue) {
|
| + return null;
|
| + }
|
| + result[i] = element.value;
|
| + }
|
| + return result;
|
| + }
|
| +
|
| + @override
|
| + bool get hasExactValue {
|
| + int count = _elements.length;
|
| + for (int i = 0; i < count; i++) {
|
| + if (!_elements[i].hasExactValue) {
|
| + return false;
|
| + }
|
| }
|
| + return true;
|
| }
|
|
|
| - /**
|
| - * 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);
|
| + @override
|
| + 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;
|
| }
|
| }
|
|
|
| /**
|
| - * Instances of the class `IntState` represent the state of an object representing an int.
|
| + * The unique instance of the class `ListState` represents the state of an object representing
|
| + * a map.
|
| */
|
| -class IntState extends NumState {
|
| - /**
|
| - * The value of this instance.
|
| - */
|
| - final int value;
|
| -
|
| +class MapState extends InstanceState {
|
| /**
|
| - * A state that can be used to represent an int whose value is not known.
|
| + * The entries in the map.
|
| */
|
| - static IntState UNKNOWN_VALUE = new IntState(null);
|
| + final Map<DartObjectImpl, DartObjectImpl> _entries;
|
|
|
| /**
|
| - * Initialize a newly created state to represent an int with the given value.
|
| + * Initialize a newly created state to represent a map with the given entries.
|
| *
|
| - * @param value the value of this instance
|
| + * @param entries the entries in the map
|
| */
|
| - IntState(this.value);
|
| + MapState(this._entries);
|
|
|
| @override
|
| - 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.value;
|
| - if (rightValue == null) {
|
| - return UNKNOWN_VALUE;
|
| - }
|
| - return new IntState(value + rightValue);
|
| - } else if (rightOperand is DoubleState) {
|
| - double rightValue = rightOperand.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;
|
| + StringState convertToString() => StringState.UNKNOWN_VALUE;
|
| +
|
| + @override
|
| + BoolState equalEqual(InstanceState rightOperand) {
|
| + assertBoolNumStringOrNull(rightOperand);
|
| + if (rightOperand is DynamicState) {
|
| + return BoolState.UNKNOWN_VALUE;
|
| }
|
| - throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
|
| + return BoolState.from(this == rightOperand);
|
| }
|
|
|
| @override
|
| - IntState bitAnd(InstanceState rightOperand) {
|
| - assertIntOrNull(rightOperand);
|
| - if (value == null) {
|
| - return UNKNOWN_VALUE;
|
| + bool operator ==(Object object) {
|
| + if (object is! MapState) {
|
| + return false;
|
| }
|
| - if (rightOperand is IntState) {
|
| - int rightValue = rightOperand.value;
|
| - if (rightValue == null) {
|
| - return UNKNOWN_VALUE;
|
| + 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 new IntState(value & rightValue);
|
| - } else if (rightOperand is DynamicState || rightOperand is NumState) {
|
| - return UNKNOWN_VALUE;
|
| }
|
| - throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
|
| + return true;
|
| }
|
|
|
| @override
|
| - IntState bitNot() {
|
| - if (value == null) {
|
| - return UNKNOWN_VALUE;
|
| - }
|
| - return new IntState(~value);
|
| - }
|
| + String get typeName => "Map";
|
|
|
| @override
|
| - IntState bitOr(InstanceState rightOperand) {
|
| - assertIntOrNull(rightOperand);
|
| - if (value == null) {
|
| - return UNKNOWN_VALUE;
|
| - }
|
| - if (rightOperand is IntState) {
|
| - int rightValue = rightOperand.value;
|
| - if (rightValue == null) {
|
| - return UNKNOWN_VALUE;
|
| + Map<Object, Object> get value {
|
| + Map<Object, Object> result = new Map<Object, Object>();
|
| + for (MapEntry<DartObjectImpl, DartObjectImpl> entry in getMapEntrySet(_entries)) {
|
| + DartObjectImpl key = entry.getKey();
|
| + DartObjectImpl value = entry.getValue();
|
| + if (!key.hasExactValue || !value.hasExactValue) {
|
| + return null;
|
| }
|
| - return new IntState(value | rightValue);
|
| - } else if (rightOperand is DynamicState || rightOperand is NumState) {
|
| - return UNKNOWN_VALUE;
|
| + result[key.value] = value.value;
|
| }
|
| - throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
|
| + return result;
|
| }
|
|
|
| @override
|
| - IntState bitXor(InstanceState rightOperand) {
|
| - assertIntOrNull(rightOperand);
|
| - if (value == null) {
|
| - return UNKNOWN_VALUE;
|
| - }
|
| - if (rightOperand is IntState) {
|
| - int rightValue = rightOperand.value;
|
| - if (rightValue == null) {
|
| - return UNKNOWN_VALUE;
|
| + bool get hasExactValue {
|
| + for (MapEntry<DartObjectImpl, DartObjectImpl> entry in getMapEntrySet(_entries)) {
|
| + if (!entry.getKey().hasExactValue || !entry.getValue().hasExactValue) {
|
| + return false;
|
| }
|
| - return new IntState(value ^ rightValue);
|
| - } else if (rightOperand is DynamicState || rightOperand is NumState) {
|
| - return UNKNOWN_VALUE;
|
| }
|
| - throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
|
| + return true;
|
| }
|
|
|
| @override
|
| - StringState convertToString() {
|
| - if (value == null) {
|
| - return StringState.UNKNOWN_VALUE;
|
| + int get hashCode {
|
| + int value = 0;
|
| + for (DartObjectImpl key in _entries.keys.toSet()) {
|
| + value = (value << 3) ^ key.hashCode;
|
| }
|
| - return new StringState(value.toString());
|
| + 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'.
|
| + */
|
| + static NullState NULL_STATE = new NullState();
|
|
|
| @override
|
| - 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.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.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;
|
| - }
|
| + BoolState convertToBool() {
|
| throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
|
| }
|
|
|
| @override
|
| + StringState convertToString() => new StringState("null");
|
| +
|
| + @override
|
| BoolState equalEqual(InstanceState rightOperand) {
|
| assertBoolNumStringOrNull(rightOperand);
|
| - if (value == null) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| - if (rightOperand is IntState) {
|
| - int rightValue = rightOperand.value;
|
| - if (rightValue == null) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| - return BoolState.from(value == rightValue);
|
| - } else if (rightOperand is DoubleState) {
|
| - double rightValue = rightOperand.value;
|
| - if (rightValue == null) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| - return BoolState.from(rightValue == value.toDouble());
|
| - } else if (rightOperand is DynamicState || rightOperand is NumState) {
|
| + if (rightOperand is DynamicState) {
|
| return BoolState.UNKNOWN_VALUE;
|
| }
|
| - return BoolState.FALSE_STATE;
|
| + return BoolState.from(rightOperand is NullState);
|
| + }
|
| +
|
| + @override
|
| + bool operator ==(Object object) => object is NullState;
|
| +
|
| + @override
|
| + String get typeName => "Null";
|
| +
|
| + @override
|
| + bool get hasExactValue => true;
|
| +
|
| + @override
|
| + int get hashCode => 0;
|
| +
|
| + @override
|
| + bool get isBoolNumStringOrNull => true;
|
| +
|
| + @override
|
| + BoolState logicalNot() {
|
| + throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
|
| + }
|
| +
|
| + @override
|
| + 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 {
|
| + /**
|
| + * A state that can be used to represent a number whose value is not known.
|
| + */
|
| + static NumState UNKNOWN_VALUE = new NumState();
|
| +
|
| + @override
|
| + NumState add(InstanceState rightOperand) {
|
| + assertNumOrNull(rightOperand);
|
| + return UNKNOWN_VALUE;
|
| }
|
|
|
| @override
|
| - bool operator ==(Object object) => object is IntState && (value == object.value);
|
| + StringState convertToString() => StringState.UNKNOWN_VALUE;
|
|
|
| @override
|
| - String get typeName => "int";
|
| + NumState divide(InstanceState rightOperand) {
|
| + assertNumOrNull(rightOperand);
|
| + return UNKNOWN_VALUE;
|
| + }
|
| +
|
| + @override
|
| + bool operator ==(Object object) => object is NumState;
|
| +
|
| + @override
|
| + BoolState equalEqual(InstanceState rightOperand) {
|
| + assertBoolNumStringOrNull(rightOperand);
|
| + return BoolState.UNKNOWN_VALUE;
|
| + }
|
| +
|
| + @override
|
| + String get typeName => "num";
|
|
|
| @override
|
| BoolState greaterThan(InstanceState rightOperand) {
|
| assertNumOrNull(rightOperand);
|
| - if (value == null) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| - if (rightOperand is IntState) {
|
| - int rightValue = rightOperand.value;
|
| - if (rightValue == null) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| - return BoolState.from(value.compareTo(rightValue) > 0);
|
| - } else if (rightOperand is DoubleState) {
|
| - double rightValue = rightOperand.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);
|
| + return BoolState.UNKNOWN_VALUE;
|
| }
|
|
|
| @override
|
| BoolState greaterThanOrEqual(InstanceState rightOperand) {
|
| assertNumOrNull(rightOperand);
|
| - if (value == null) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| - if (rightOperand is IntState) {
|
| - int rightValue = rightOperand.value;
|
| - if (rightValue == null) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| - return BoolState.from(value.compareTo(rightValue) >= 0);
|
| - } else if (rightOperand is DoubleState) {
|
| - double rightValue = rightOperand.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);
|
| + return BoolState.UNKNOWN_VALUE;
|
| }
|
|
|
| @override
|
| - bool get hasExactValue => true;
|
| -
|
| - @override
|
| - int get hashCode => value == null ? 0 : value.hashCode;
|
| + int get hashCode => 7;
|
|
|
| @override
|
| IntState integerDivide(InstanceState rightOperand) {
|
| assertNumOrNull(rightOperand);
|
| - if (value == null) {
|
| - return UNKNOWN_VALUE;
|
| - }
|
| if (rightOperand is IntState) {
|
| int rightValue = rightOperand.value;
|
| if (rightValue == null) {
|
| - return UNKNOWN_VALUE;
|
| + return IntState.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.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;
|
| + } else if (rightOperand is DynamicState) {
|
| + return IntState.UNKNOWN_VALUE;
|
| }
|
| - throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
|
| + return IntState.UNKNOWN_VALUE;
|
| }
|
|
|
| @override
|
| @@ -3629,710 +3623,716 @@ class IntState extends NumState {
|
| @override
|
| BoolState lessThan(InstanceState rightOperand) {
|
| assertNumOrNull(rightOperand);
|
| - if (value == null) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| - if (rightOperand is IntState) {
|
| - int rightValue = rightOperand.value;
|
| - if (rightValue == null) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| - return BoolState.from(value.compareTo(rightValue) < 0);
|
| - } else if (rightOperand is DoubleState) {
|
| - double rightValue = rightOperand.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);
|
| + return BoolState.UNKNOWN_VALUE;
|
| }
|
|
|
| @override
|
| BoolState lessThanOrEqual(InstanceState rightOperand) {
|
| assertNumOrNull(rightOperand);
|
| - if (value == null) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| - if (rightOperand is IntState) {
|
| - int rightValue = rightOperand.value;
|
| - if (rightValue == null) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| - return BoolState.from(value.compareTo(rightValue) <= 0);
|
| - } else if (rightOperand is DoubleState) {
|
| - double rightValue = rightOperand.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);
|
| + return BoolState.UNKNOWN_VALUE;
|
| }
|
|
|
| @override
|
| 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.value;
|
| - if (rightValue == null) {
|
| - return UNKNOWN_VALUE;
|
| - }
|
| - return new IntState(value - rightValue);
|
| - } else if (rightOperand is DoubleState) {
|
| - double rightValue = rightOperand.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);
|
| + return UNKNOWN_VALUE;
|
| }
|
|
|
| @override
|
| - NumState negated() {
|
| - if (value == null) {
|
| - return UNKNOWN_VALUE;
|
| - }
|
| - return new IntState(-value);
|
| - }
|
| + NumState negated() => UNKNOWN_VALUE;
|
|
|
| @override
|
| 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.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.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);
|
| + return UNKNOWN_VALUE;
|
| }
|
|
|
| @override
|
| - IntState shiftLeft(InstanceState rightOperand) {
|
| - assertIntOrNull(rightOperand);
|
| - if (value == null) {
|
| - return UNKNOWN_VALUE;
|
| + NumState times(InstanceState rightOperand) {
|
| + assertNumOrNull(rightOperand);
|
| + return UNKNOWN_VALUE;
|
| + }
|
| +
|
| + @override
|
| + String toString() => "-unknown-";
|
| +}
|
| +
|
| +/**
|
| + * Instances of the class `ReferenceFinder` add reference information for a given variable to
|
| + * the bi-directional mapping used to order the evaluation of constants.
|
| + */
|
| +class ReferenceFinder extends RecursiveAstVisitor<Object> {
|
| + /**
|
| + * The element representing the variable whose initializer will be visited.
|
| + */
|
| + final VariableElement _source;
|
| +
|
| + /**
|
| + * A graph in which the nodes are the constant variables and the edges are from each variable to
|
| + * the other constant variables that are referenced in the head's initializer.
|
| + */
|
| + final DirectedGraph<VariableElement> _referenceGraph;
|
| +
|
| + /**
|
| + * Initialize a newly created reference finder to find references from the given variable to other
|
| + * variables and to add those references to the given graph.
|
| + *
|
| + * @param source the element representing the variable whose initializer will be visited
|
| + * @param referenceGraph a graph recording which variables (heads) reference which other variables
|
| + * (tails) in their initializers
|
| + */
|
| + ReferenceFinder(this._source, this._referenceGraph);
|
| +
|
| + @override
|
| + Object visitSimpleIdentifier(SimpleIdentifier node) {
|
| + Element element = node.staticElement;
|
| + if (element is PropertyAccessorElement) {
|
| + element = (element as PropertyAccessorElement).variable;
|
| }
|
| - if (rightOperand is IntState) {
|
| - int rightValue = rightOperand.value;
|
| - if (rightValue == null) {
|
| - return UNKNOWN_VALUE;
|
| - } else if (rightValue.bitLength > 31) {
|
| - return UNKNOWN_VALUE;
|
| + if (element is VariableElement) {
|
| + VariableElement variable = element as VariableElement;
|
| + if (variable.isConst) {
|
| + _referenceGraph.addEdge(_source, variable);
|
| }
|
| - return new IntState(value << rightValue);
|
| - } else if (rightOperand is DynamicState || rightOperand is NumState) {
|
| - return UNKNOWN_VALUE;
|
| }
|
| - throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
|
| + return null;
|
| }
|
| +}
|
| +
|
| +/**
|
| + * 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 of this instance
|
| + */
|
| + StringState(this.value);
|
|
|
| @override
|
| - IntState shiftRight(InstanceState rightOperand) {
|
| - assertIntOrNull(rightOperand);
|
| + StringState concatenate(InstanceState rightOperand) {
|
| if (value == null) {
|
| return UNKNOWN_VALUE;
|
| }
|
| - if (rightOperand is IntState) {
|
| - int rightValue = rightOperand.value;
|
| + if (rightOperand is StringState) {
|
| + String rightValue = rightOperand.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 new StringState("${value}${rightValue}");
|
| + } else if (rightOperand is DynamicState) {
|
| return UNKNOWN_VALUE;
|
| }
|
| - throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
|
| + return super.concatenate(rightOperand);
|
| }
|
|
|
| @override
|
| - NumState times(InstanceState rightOperand) {
|
| - assertNumOrNull(rightOperand);
|
| + StringState convertToString() => this;
|
| +
|
| + @override
|
| + BoolState equalEqual(InstanceState rightOperand) {
|
| + assertBoolNumStringOrNull(rightOperand);
|
| if (value == null) {
|
| - if (rightOperand is DoubleState) {
|
| - return DoubleState.UNKNOWN_VALUE;
|
| - }
|
| - return UNKNOWN_VALUE;
|
| + return BoolState.UNKNOWN_VALUE;
|
| }
|
| - if (rightOperand is IntState) {
|
| - int rightValue = rightOperand.value;
|
| - if (rightValue == null) {
|
| - return UNKNOWN_VALUE;
|
| - }
|
| - return new IntState(value * rightValue);
|
| - } else if (rightOperand is DoubleState) {
|
| - double rightValue = rightOperand.value;
|
| + if (rightOperand is StringState) {
|
| + String rightValue = rightOperand.value;
|
| if (rightValue == null) {
|
| - return DoubleState.UNKNOWN_VALUE;
|
| + return BoolState.UNKNOWN_VALUE;
|
| }
|
| - return new DoubleState(value.toDouble() * rightValue);
|
| - } else if (rightOperand is DynamicState || rightOperand is NumState) {
|
| - return UNKNOWN_VALUE;
|
| + return BoolState.from(value == rightValue);
|
| + } else if (rightOperand is DynamicState) {
|
| + return BoolState.UNKNOWN_VALUE;
|
| }
|
| - throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
|
| + return BoolState.FALSE_STATE;
|
| }
|
|
|
| @override
|
| - String toString() => value == null ? "-unknown-" : value.toString();
|
| + bool operator ==(Object object) => object is StringState && (value == object.value);
|
| +
|
| + @override
|
| + String get typeName => "String";
|
| +
|
| + @override
|
| + bool get hasExactValue => true;
|
| +
|
| + @override
|
| + int get hashCode => value == null ? 0 : value.hashCode;
|
| +
|
| + @override
|
| + bool get isBoolNumStringOrNull => true;
|
| +
|
| + @override
|
| + String toString() => value == null ? "-unknown-" : "'${value}'";
|
| }
|
|
|
| /**
|
| - * The unique instance of the class `ListState` represents the state of an object representing
|
| - * a list.
|
| + * Instances of the class `StringState` represent the state of an object representing a
|
| + * symbol.
|
| */
|
| -class ListState extends InstanceState {
|
| +class SymbolState extends InstanceState {
|
| /**
|
| - * The elements of the list.
|
| + * The value of this instance.
|
| */
|
| - final List<DartObjectImpl> _elements;
|
| + final String value;
|
|
|
| /**
|
| - * Initialize a newly created state to represent a list with the given elements.
|
| + * Initialize a newly created state to represent the given value.
|
| *
|
| - * @param elements the elements of the list
|
| + * @param value the value of this instance
|
| */
|
| - ListState(this._elements);
|
| + SymbolState(this.value);
|
|
|
| @override
|
| - StringState convertToString() => StringState.UNKNOWN_VALUE;
|
| + StringState convertToString() {
|
| + if (value == null) {
|
| + return StringState.UNKNOWN_VALUE;
|
| + }
|
| + return new StringState(value);
|
| + }
|
|
|
| @override
|
| BoolState equalEqual(InstanceState rightOperand) {
|
| assertBoolNumStringOrNull(rightOperand);
|
| - if (rightOperand is DynamicState) {
|
| + if (value == null) {
|
| return BoolState.UNKNOWN_VALUE;
|
| }
|
| - return BoolState.from(this == rightOperand);
|
| - }
|
| -
|
| - @override
|
| - 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;
|
| + if (rightOperand is SymbolState) {
|
| + String rightValue = rightOperand.value;
|
| + if (rightValue == null) {
|
| + return BoolState.UNKNOWN_VALUE;
|
| }
|
| + return BoolState.from(value == rightValue);
|
| + } else if (rightOperand is DynamicState) {
|
| + return BoolState.UNKNOWN_VALUE;
|
| }
|
| - return true;
|
| + return BoolState.FALSE_STATE;
|
| }
|
|
|
| @override
|
| - String get typeName => "List";
|
| + bool operator ==(Object object) => object is SymbolState && (value == object.value);
|
|
|
| @override
|
| - List<Object> get value {
|
| - int count = _elements.length;
|
| - List<Object> result = new List<Object>(count);
|
| - for (int i = 0; i < count; i++) {
|
| - DartObjectImpl element = _elements[i];
|
| - if (!element.hasExactValue) {
|
| - return null;
|
| - }
|
| - result[i] = element.value;
|
| - }
|
| - return result;
|
| - }
|
| + String get typeName => "Symbol";
|
|
|
| @override
|
| - bool get hasExactValue {
|
| - int count = _elements.length;
|
| - for (int i = 0; i < count; i++) {
|
| - if (!_elements[i].hasExactValue) {
|
| - return false;
|
| - }
|
| - }
|
| - return true;
|
| - }
|
| + bool get hasExactValue => true;
|
|
|
| @override
|
| - 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;
|
| - }
|
| + int get hashCode => value == null ? 0 : value.hashCode;
|
| +
|
| + @override
|
| + String toString() => value == null ? "-unknown-" : "#${value}";
|
| }
|
|
|
| /**
|
| - * The unique instance of the class `ListState` represents the state of an object representing
|
| - * a map.
|
| + * Instances of the class `TypeState` represent the state of an object representing a type.
|
| */
|
| -class MapState extends InstanceState {
|
| +class TypeState extends InstanceState {
|
| /**
|
| - * The entries in the map.
|
| + * The element representing the type being modeled.
|
| */
|
| - final Map<DartObjectImpl, DartObjectImpl> _entries;
|
| + final Element _element;
|
|
|
| /**
|
| - * Initialize a newly created state to represent a map with the given entries.
|
| + * Initialize a newly created state to represent the given value.
|
| *
|
| - * @param entries the entries in the map
|
| + * @param element the element representing the type being modeled
|
| */
|
| - MapState(this._entries);
|
| + TypeState(this._element);
|
|
|
| @override
|
| - StringState convertToString() => StringState.UNKNOWN_VALUE;
|
| + StringState convertToString() {
|
| + if (_element == null) {
|
| + return StringState.UNKNOWN_VALUE;
|
| + }
|
| + return new StringState(_element.name);
|
| + }
|
| +
|
| + @override
|
| + bool operator ==(Object object) => object is TypeState && (_element == object._element);
|
|
|
| @override
|
| BoolState equalEqual(InstanceState rightOperand) {
|
| assertBoolNumStringOrNull(rightOperand);
|
| - if (rightOperand is DynamicState) {
|
| + if (_element == null) {
|
| return BoolState.UNKNOWN_VALUE;
|
| }
|
| - return BoolState.from(this == rightOperand);
|
| - }
|
| -
|
| - @override
|
| - 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;
|
| + if (rightOperand is TypeState) {
|
| + Element rightElement = rightOperand._element;
|
| + if (rightElement == null) {
|
| + return BoolState.UNKNOWN_VALUE;
|
| }
|
| + return BoolState.from(_element == rightElement);
|
| + } else if (rightOperand is DynamicState) {
|
| + return BoolState.UNKNOWN_VALUE;
|
| }
|
| - return true;
|
| + return BoolState.FALSE_STATE;
|
| }
|
|
|
| @override
|
| - String get typeName => "Map";
|
| + String get typeName => "Type";
|
|
|
| @override
|
| - Map<Object, Object> get value {
|
| - Map<Object, Object> result = new Map<Object, Object>();
|
| - for (MapEntry<DartObjectImpl, DartObjectImpl> entry in getMapEntrySet(_entries)) {
|
| - DartObjectImpl key = entry.getKey();
|
| - DartObjectImpl value = entry.getValue();
|
| - if (!key.hasExactValue || !value.hasExactValue) {
|
| - return null;
|
| - }
|
| - result[key.value] = value.value;
|
| - }
|
| - return result;
|
| - }
|
| + int get hashCode => _element == null ? 0 : _element.hashCode;
|
|
|
| @override
|
| - bool get hasExactValue {
|
| - for (MapEntry<DartObjectImpl, DartObjectImpl> entry in getMapEntrySet(_entries)) {
|
| - if (!entry.getKey().hasExactValue || !entry.getValue().hasExactValue) {
|
| - return false;
|
| - }
|
| - }
|
| - return true;
|
| - }
|
| + String toString() => _element == null ? "-unknown-" : _element.name;
|
| +}
|
| +
|
| +/**
|
| + * Instances of the class `ValidResult` represent the result of attempting to evaluate a valid
|
| + * compile time constant expression.
|
| + */
|
| +class ValidResult extends EvaluationResultImpl {
|
| + /**
|
| + * The value of the expression.
|
| + */
|
| + final DartObjectImpl value;
|
| +
|
| + /**
|
| + * Initialize a newly created result to represent the given value.
|
| + *
|
| + * @param value the value of the expression
|
| + */
|
| + ValidResult(this.value);
|
|
|
| @override
|
| - int get hashCode {
|
| - int value = 0;
|
| - for (DartObjectImpl key in _entries.keys.toSet()) {
|
| - value = (value << 3) ^ key.hashCode;
|
| - }
|
| - return value;
|
| - }
|
| -}
|
| + EvaluationResultImpl add(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.addToValid(typeProvider, node, this);
|
|
|
| -/**
|
| - * 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'.
|
| + * Return the result of applying boolean conversion to this result.
|
| + *
|
| + * @param node the node against which errors should be reported
|
| + * @return the result of applying boolean conversion to the given value
|
| */
|
| - static NullState NULL_STATE = new NullState();
|
| -
|
| @override
|
| - BoolState convertToBool() {
|
| - throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
|
| + EvaluationResultImpl applyBooleanConversion(TypeProvider typeProvider, AstNode node) {
|
| + try {
|
| + return _valueOf(value.convertToBool(typeProvider));
|
| + } on EvaluationException catch (exception) {
|
| + return _error(node, exception.errorCode);
|
| + }
|
| }
|
|
|
| @override
|
| - StringState convertToString() => new StringState("null");
|
| + EvaluationResultImpl bitAnd(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitAndValid(typeProvider, node, this);
|
|
|
| @override
|
| - BoolState equalEqual(InstanceState rightOperand) {
|
| - assertBoolNumStringOrNull(rightOperand);
|
| - if (rightOperand is DynamicState) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| + EvaluationResultImpl bitNot(TypeProvider typeProvider, Expression node) {
|
| + try {
|
| + return _valueOf(value.bitNot(typeProvider));
|
| + } on EvaluationException catch (exception) {
|
| + return _error(node, exception.errorCode);
|
| }
|
| - return BoolState.from(rightOperand is NullState);
|
| }
|
|
|
| @override
|
| - bool operator ==(Object object) => object is NullState;
|
| + EvaluationResultImpl bitOr(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitOrValid(typeProvider, node, this);
|
|
|
| @override
|
| - String get typeName => "Null";
|
| + EvaluationResultImpl bitXor(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitXorValid(typeProvider, node, this);
|
|
|
| @override
|
| - bool get hasExactValue => true;
|
| + EvaluationResultImpl concatenate(TypeProvider typeProvider, Expression node, EvaluationResultImpl rightOperand) => rightOperand.concatenateValid(typeProvider, node, this);
|
|
|
| @override
|
| - int get hashCode => 0;
|
| + EvaluationResultImpl divide(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.divideValid(typeProvider, node, this);
|
|
|
| @override
|
| - bool get isBoolNumStringOrNull => true;
|
| + EvaluationResultImpl equalEqual(TypeProvider typeProvider, Expression node, EvaluationResultImpl rightOperand) => rightOperand.equalEqualValid(typeProvider, node, this);
|
|
|
| @override
|
| - BoolState logicalNot() {
|
| - throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
|
| + bool equalValues(TypeProvider typeProvider, EvaluationResultImpl result) {
|
| + if (result is! ValidResult) {
|
| + return false;
|
| + }
|
| + return value == (result as ValidResult).value;
|
| }
|
|
|
| @override
|
| - String toString() => "null";
|
| -}
|
| + EvaluationResultImpl greaterThan(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanValid(typeProvider, node, this);
|
| +
|
| + @override
|
| + EvaluationResultImpl greaterThanOrEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanOrEqualValid(typeProvider, node, this);
|
| +
|
| + @override
|
| + EvaluationResultImpl integerDivide(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.integerDivideValid(typeProvider, node, this);
|
|
|
| -/**
|
| - * Instances of the class `NumState` represent the state of an object representing a number of
|
| - * an unknown type (a 'num').
|
| - */
|
| -class NumState extends InstanceState {
|
| /**
|
| - * A state that can be used to represent a number whose value is not known.
|
| + * Return `true` if this object represents an object whose type is 'bool'.
|
| + *
|
| + * @return `true` if this object represents a boolean value
|
| */
|
| - static NumState UNKNOWN_VALUE = new NumState();
|
| + bool get isBool => value.isBool;
|
|
|
| - @override
|
| - NumState add(InstanceState rightOperand) {
|
| - assertNumOrNull(rightOperand);
|
| - return UNKNOWN_VALUE;
|
| - }
|
| + /**
|
| + * 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;
|
| +
|
| + /**
|
| + * Return `true` if this result represents the value 'false'.
|
| + *
|
| + * @return `true` if this result represents the value 'false'
|
| + */
|
| + bool get isFalse => value.isFalse;
|
| +
|
| + /**
|
| + * Return `true` if this result represents the value 'null'.
|
| + *
|
| + * @return `true` if this result represents the value 'null'
|
| + */
|
| + bool get isNull => value.isNull;
|
| +
|
| + /**
|
| + * Return `true` if this result represents the value 'true'.
|
| + *
|
| + * @return `true` if this result represents the value 'true'
|
| + */
|
| + bool get isTrue => value.isTrue;
|
| +
|
| + /**
|
| + * 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;
|
|
|
| @override
|
| - StringState convertToString() => StringState.UNKNOWN_VALUE;
|
| + EvaluationResultImpl lessThan(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanValid(typeProvider, node, this);
|
|
|
| @override
|
| - NumState divide(InstanceState rightOperand) {
|
| - assertNumOrNull(rightOperand);
|
| - return UNKNOWN_VALUE;
|
| - }
|
| + EvaluationResultImpl lessThanOrEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanOrEqualValid(typeProvider, node, this);
|
|
|
| @override
|
| - bool operator ==(Object object) => object is NumState;
|
| + EvaluationResultImpl logicalAnd(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalAndValid(typeProvider, node, this);
|
|
|
| @override
|
| - BoolState equalEqual(InstanceState rightOperand) {
|
| - assertBoolNumStringOrNull(rightOperand);
|
| - return BoolState.UNKNOWN_VALUE;
|
| + EvaluationResultImpl logicalNot(TypeProvider typeProvider, Expression node) {
|
| + try {
|
| + return _valueOf(value.logicalNot(typeProvider));
|
| + } on EvaluationException catch (exception) {
|
| + return _error(node, exception.errorCode);
|
| + }
|
| }
|
|
|
| @override
|
| - String get typeName => "num";
|
| + EvaluationResultImpl logicalOr(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalOrValid(typeProvider, node, this);
|
|
|
| @override
|
| - BoolState greaterThan(InstanceState rightOperand) {
|
| - assertNumOrNull(rightOperand);
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| + EvaluationResultImpl minus(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.minusValid(typeProvider, node, this);
|
|
|
| @override
|
| - BoolState greaterThanOrEqual(InstanceState rightOperand) {
|
| - assertNumOrNull(rightOperand);
|
| - return BoolState.UNKNOWN_VALUE;
|
| + EvaluationResultImpl negated(TypeProvider typeProvider, Expression node) {
|
| + try {
|
| + return _valueOf(value.negated(typeProvider));
|
| + } on EvaluationException catch (exception) {
|
| + return _error(node, exception.errorCode);
|
| + }
|
| }
|
|
|
| @override
|
| - int get hashCode => 7;
|
| + EvaluationResultImpl notEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.notEqualValid(typeProvider, node, this);
|
|
|
| @override
|
| - IntState integerDivide(InstanceState rightOperand) {
|
| - assertNumOrNull(rightOperand);
|
| - if (rightOperand is IntState) {
|
| - int rightValue = rightOperand.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;
|
| + EvaluationResultImpl performToString(TypeProvider typeProvider, AstNode node) {
|
| + try {
|
| + return _valueOf(value.performToString(typeProvider));
|
| + } on EvaluationException catch (exception) {
|
| + return _error(node, exception.errorCode);
|
| }
|
| - return IntState.UNKNOWN_VALUE;
|
| }
|
|
|
| @override
|
| - bool get isBoolNumStringOrNull => true;
|
| + EvaluationResultImpl remainder(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.remainderValid(typeProvider, node, this);
|
|
|
| @override
|
| - BoolState lessThan(InstanceState rightOperand) {
|
| - assertNumOrNull(rightOperand);
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| + EvaluationResultImpl shiftLeft(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.shiftLeftValid(typeProvider, node, this);
|
|
|
| @override
|
| - BoolState lessThanOrEqual(InstanceState rightOperand) {
|
| - assertNumOrNull(rightOperand);
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| + EvaluationResultImpl shiftRight(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.shiftRightValid(typeProvider, node, this);
|
|
|
| @override
|
| - NumState minus(InstanceState rightOperand) {
|
| - assertNumOrNull(rightOperand);
|
| - return UNKNOWN_VALUE;
|
| + EvaluationResultImpl times(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.timesValid(typeProvider, node, this);
|
| +
|
| + @override
|
| + String toString() {
|
| + if (value == null) {
|
| + return "null";
|
| + }
|
| + return value.toString();
|
| }
|
|
|
| @override
|
| - NumState negated() => UNKNOWN_VALUE;
|
| + EvaluationResultImpl addToError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
|
|
| @override
|
| - NumState remainder(InstanceState rightOperand) {
|
| - assertNumOrNull(rightOperand);
|
| - return UNKNOWN_VALUE;
|
| + 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);
|
| + }
|
| }
|
|
|
| @override
|
| - NumState times(InstanceState rightOperand) {
|
| - assertNumOrNull(rightOperand);
|
| - return UNKNOWN_VALUE;
|
| + EvaluationResultImpl bitAndError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
| +
|
| + @override
|
| + 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);
|
| + }
|
| }
|
|
|
| @override
|
| - String toString() => "-unknown-";
|
| -}
|
| + EvaluationResultImpl bitOrError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
|
|
| -/**
|
| - * 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;
|
| + @override
|
| + 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);
|
| + }
|
| + }
|
|
|
| - /**
|
| - * A state that can be used to represent a double whose value is not known.
|
| - */
|
| - static StringState UNKNOWN_VALUE = new StringState(null);
|
| + @override
|
| + EvaluationResultImpl bitXorError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
|
|
| - /**
|
| - * Initialize a newly created state to represent the given value.
|
| - *
|
| - * @param value the value of this instance
|
| - */
|
| - StringState(this.value);
|
| + @override
|
| + 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);
|
| + }
|
| + }
|
|
|
| @override
|
| - StringState concatenate(InstanceState rightOperand) {
|
| - if (value == null) {
|
| - return UNKNOWN_VALUE;
|
| - }
|
| - if (rightOperand is StringState) {
|
| - String rightValue = rightOperand.value;
|
| - if (rightValue == null) {
|
| - return UNKNOWN_VALUE;
|
| - }
|
| - return new StringState("${value}${rightValue}");
|
| - } else if (rightOperand is DynamicState) {
|
| - return UNKNOWN_VALUE;
|
| + EvaluationResultImpl concatenateError(Expression node, ErrorResult leftOperand) => leftOperand;
|
| +
|
| + @override
|
| + 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 super.concatenate(rightOperand);
|
| }
|
|
|
| @override
|
| - StringState convertToString() => this;
|
| + EvaluationResultImpl divideError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
|
|
| @override
|
| - BoolState equalEqual(InstanceState rightOperand) {
|
| - assertBoolNumStringOrNull(rightOperand);
|
| - if (value == null) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| + 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);
|
| }
|
| - if (rightOperand is StringState) {
|
| - String rightValue = rightOperand.value;
|
| - if (rightValue == null) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| - return BoolState.from(value == rightValue);
|
| - } else if (rightOperand is DynamicState) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| + }
|
| +
|
| + @override
|
| + EvaluationResultImpl equalEqualError(Expression node, ErrorResult leftOperand) => leftOperand;
|
| +
|
| + @override
|
| + 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);
|
| }
|
| - return BoolState.FALSE_STATE;
|
| }
|
|
|
| @override
|
| - bool operator ==(Object object) => object is StringState && (value == object.value);
|
| + EvaluationResultImpl greaterThanError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
|
|
| @override
|
| - String get typeName => "String";
|
| + EvaluationResultImpl greaterThanOrEqualError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
|
|
| @override
|
| - bool get hasExactValue => true;
|
| + 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);
|
| + }
|
| + }
|
|
|
| @override
|
| - int get hashCode => value == null ? 0 : value.hashCode;
|
| + 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);
|
| + }
|
| + }
|
|
|
| @override
|
| - bool get isBoolNumStringOrNull => true;
|
| + EvaluationResultImpl integerDivideError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
|
|
| @override
|
| - String toString() => value == null ? "-unknown-" : "'${value}'";
|
| -}
|
| + 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);
|
| + }
|
| + }
|
|
|
| -/**
|
| - * Instances of the class `StringState` represent the state of an object representing a
|
| - * symbol.
|
| - */
|
| -class SymbolState extends InstanceState {
|
| - /**
|
| - * The value of this instance.
|
| - */
|
| - final String value;
|
| + @override
|
| + EvaluationResultImpl lessThanError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
|
|
| - /**
|
| - * Initialize a newly created state to represent the given value.
|
| - *
|
| - * @param value the value of this instance
|
| - */
|
| - SymbolState(this.value);
|
| + @override
|
| + EvaluationResultImpl lessThanOrEqualError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
|
|
| @override
|
| - StringState convertToString() {
|
| - if (value == null) {
|
| - return StringState.UNKNOWN_VALUE;
|
| + 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 new StringState(value);
|
| }
|
|
|
| @override
|
| - BoolState equalEqual(InstanceState rightOperand) {
|
| - assertBoolNumStringOrNull(rightOperand);
|
| - if (value == null) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| - if (rightOperand is SymbolState) {
|
| - String rightValue = rightOperand.value;
|
| - if (rightValue == null) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| - return BoolState.from(value == rightValue);
|
| - } else if (rightOperand is DynamicState) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| + 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 BoolState.FALSE_STATE;
|
| }
|
|
|
| @override
|
| - bool operator ==(Object object) => object is SymbolState && (value == object.value);
|
| + EvaluationResultImpl logicalAndError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
|
|
| @override
|
| - String get typeName => "Symbol";
|
| + 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);
|
| + }
|
| + }
|
|
|
| @override
|
| - bool get hasExactValue => true;
|
| + EvaluationResultImpl logicalOrError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
|
|
| @override
|
| - int get hashCode => value == null ? 0 : value.hashCode;
|
| + 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);
|
| + }
|
| + }
|
|
|
| @override
|
| - String toString() => value == null ? "-unknown-" : "#${value}";
|
| -}
|
| + EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
|
|
| -/**
|
| - * 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.
|
| - */
|
| - final Element _element;
|
| + @override
|
| + 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);
|
| + }
|
| + }
|
|
|
| - /**
|
| - * Initialize a newly created state to represent the given value.
|
| - *
|
| - * @param element the element representing the type being modeled
|
| - */
|
| - TypeState(this._element);
|
| + @override
|
| + EvaluationResultImpl notEqualError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
|
|
| @override
|
| - StringState convertToString() {
|
| - if (_element == null) {
|
| - return StringState.UNKNOWN_VALUE;
|
| + 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 new StringState(_element.name);
|
| }
|
|
|
| @override
|
| - bool operator ==(Object object) => object is TypeState && (_element == object._element);
|
| + EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
|
|
| @override
|
| - BoolState equalEqual(InstanceState rightOperand) {
|
| - assertBoolNumStringOrNull(rightOperand);
|
| - if (_element == null) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| + 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);
|
| }
|
| - if (rightOperand is TypeState) {
|
| - Element rightElement = rightOperand._element;
|
| - if (rightElement == null) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| - }
|
| - return BoolState.from(_element == rightElement);
|
| - } else if (rightOperand is DynamicState) {
|
| - return BoolState.UNKNOWN_VALUE;
|
| + }
|
| +
|
| + @override
|
| + EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
| +
|
| + @override
|
| + 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);
|
| }
|
| - return BoolState.FALSE_STATE;
|
| }
|
|
|
| @override
|
| - String get typeName => "Type";
|
| + EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
|
|
| @override
|
| - int get hashCode => _element == null ? 0 : _element.hashCode;
|
| + 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);
|
| + }
|
| + }
|
|
|
| @override
|
| - String toString() => _element == null ? "-unknown-" : _element.name;
|
| + EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
|
| +
|
| + @override
|
| + 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 a result object representing an error associated with the given node.
|
| + *
|
| + * @param node the AST node associated with the error
|
| + * @param code the error code indicating the nature of the error
|
| + * @return a result object representing an error associated with the given node
|
| + */
|
| + ErrorResult _error(AstNode node, ErrorCode code) => new ErrorResult.con1(node, code);
|
| +
|
| + /**
|
| + * Return a result object representing the given value.
|
| + *
|
| + * @param value the value to be represented as a result object
|
| + * @return a result object representing the given value
|
| + */
|
| + ValidResult _valueOf(DartObjectImpl value) => new ValidResult(value);
|
| }
|
|
|