| OLD | NEW |
| 1 // This code was auto-generated, is not intended to be edited, and is subject to | 1 // This code was auto-generated, is not intended to be edited, and is subject to |
| 2 // significant change. Please see the README file for more information. | 2 // significant change. Please see the README file for more information. |
| 3 | 3 |
| 4 library engine.constant; | 4 library engine.constant; |
| 5 | 5 |
| 6 import 'java_core.dart'; | 6 import 'java_core.dart'; |
| 7 import 'java_engine.dart' show ObjectUtilities; |
| 7 import 'source.dart' show Source; | 8 import 'source.dart' show Source; |
| 8 import 'error.dart' show AnalysisError, ErrorCode, CompileTimeErrorCode; | 9 import 'error.dart' show AnalysisError, ErrorCode, CompileTimeErrorCode; |
| 9 import 'scanner.dart' show TokenType; | 10 import 'scanner.dart' show Token, TokenType; |
| 10 import 'ast.dart'; | 11 import 'ast.dart'; |
| 11 import 'element.dart'; | 12 import 'element.dart'; |
| 13 import 'resolver.dart' show TypeProvider; |
| 12 import 'engine.dart' show AnalysisEngine; | 14 import 'engine.dart' show AnalysisEngine; |
| 15 import 'utilities_dart.dart' show ParameterKind; |
| 13 | 16 |
| 14 /** | 17 /** |
| 15 * Instances of the class `ConstantEvaluator` evaluate constant expressions to p
roduce their | 18 * Instances of the class `ConstantEvaluator` evaluate constant expressions to p
roduce their |
| 16 * compile-time value. According to the Dart Language Specification: <blockquote
> A constant | 19 * compile-time value. According to the Dart Language Specification: <blockquote
> A constant |
| 17 * expression is one of the following: | 20 * expression is one of the following: |
| 18 * | 21 * |
| 19 * * A literal number. | 22 * * A literal number. |
| 20 * * A literal boolean. | 23 * * A literal boolean. |
| 21 * * A literal string where any interpolated expression is a compile-time consta
nt that evaluates | 24 * * A literal string where any interpolated expression is a compile-time consta
nt that evaluates |
| 22 * to a numeric, string or boolean value or to `null`. | 25 * to a numeric, string or boolean value or to <b>null</b>. |
| 23 * * `null`. | 26 * * A literal symbol. |
| 24 * * A reference to a static constant variable. | 27 * * <b>null</b>. |
| 25 * * An identifier expression that denotes a constant variable, a class or a typ
e parameter. | 28 * * A qualified reference to a static constant variable. |
| 29 * * An identifier expression that denotes a constant variable, class or type al
ias. |
| 26 * * A constant constructor invocation. | 30 * * A constant constructor invocation. |
| 27 * * A constant list literal. | 31 * * A constant list literal. |
| 28 * * A constant map literal. | 32 * * A constant map literal. |
| 29 * * A simple or qualified identifier denoting a top-level function or a static
method. | 33 * * A simple or qualified identifier denoting a top-level function or a static
method. |
| 30 * * A parenthesized expression `(e)` where `e` is a constant expression. | 34 * * A parenthesized expression <i>(e)</i> where <i>e</i> is a constant expressi
on. |
| 31 * * An expression of one of the forms `identical(e1, e2)`, `e1 == e2`, | 35 * * An expression of the form <i>identical(e<sub>1</sub>, e<sub>2</sub>)</i> wh
ere |
| 32 * `e1 != e2` where `e1` and `e2` are constant expressions that evaluate to a | 36 * <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant expressions and <i
>identical()</i> is |
| 33 * numeric, string or boolean value or to `null`. | 37 * statically bound to the predefined dart function <i>identical()</i> discussed
above. |
| 34 * * An expression of one of the forms `!e`, `e1 && e2` or `e1 || e2`, where | 38 * * An expression of one of the forms <i>e<sub>1</sub> == e<sub>2</sub></i> or
<i>e<sub>1</sub> |
| 35 * `e`, `e1` and `e2` are constant expressions that evaluate to a boolean value
or | 39 * != e<sub>2</sub></i> where <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are
constant expressions |
| 36 * to `null`. | 40 * that evaluate to a numeric, string or boolean value. |
| 37 * * An expression of one of the forms `~e`, `e1 ^ e2`, `e1 & e2`, | 41 * * An expression of one of the forms <i>!e</i>, <i>e<sub>1</sub> && e<
sub>2</sub></i> or |
| 38 * `e1 | e2`, `e1 >> e2` or `e1 << e2`, where `e`, `e1` and `e2` | 42 * <i>e<sub>1</sub> || e<sub>2</sub></i>, where <i>e</i>, <i>e1</sub></i> and <i
>e2</sub></i> are |
| 39 * are constant expressions that evaluate to an integer value or to `null`. | 43 * constant expressions that evaluate to a boolean value. |
| 40 * * An expression of one of the forms `-e`, `e1 + e2`, `e1 - e2`, | 44 * * An expression of one of the forms <i>~e</i>, <i>e<sub>1</sub> ^ e<sub>2</su
b></i>, |
| 41 * `e1 * e2`, `e1 / e2`, `e1 ~/ e2`, `e1 > e2`, `e1 < e2`, | 45 * <i>e<sub>1</sub> & e<sub>2</sub></i>, <i>e<sub>1</sub> | e<sub>2</sub></i
>, <i>e<sub>1</sub> |
| 42 * `e1 >= e2`, `e1 <= e2` or `e1 % e2`, where `e`, `e1` and `e2` | 46 * >> e<sub>2</sub></i> or <i>e<sub>1</sub> << e<sub>2</sub></i>, wh
ere <i>e</i>, |
| 43 * are constant expressions that evaluate to a numeric value or to `null`. | 47 * <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant expressions that e
valuate to an |
| 48 * integer value or to <b>null</b>. |
| 49 * * An expression of one of the forms <i>-e</i>, <i>e<sub>1</sub> + e<sub>2</su
b></i>, |
| 50 * <i>e<sub>1</sub> -e<sub>2</sub></i>, <i>e<sub>1</sub> * e<sub>2</sub></i>, <i
>e<sub>1</sub> / |
| 51 * e<sub>2</sub></i>, <i>e<sub>1</sub> ~/ e<sub>2</sub></i>, <i>e<sub>1</sub> &g
t; |
| 52 * e<sub>2</sub></i>, <i>e<sub>1</sub> < e<sub>2</sub></i>, <i>e<sub>1</sub>
>= |
| 53 * e<sub>2</sub></i>, <i>e<sub>1</sub> <= e<sub>2</sub></i> or <i>e<sub>1</su
b> % |
| 54 * e<sub>2</sub></i>, where <i>e</i>, <i>e<sub>1</sub></i> and <i>e<sub>2</sub><
/i> are constant |
| 55 * expressions that evaluate to a numeric value or to <b>null</b>. |
| 56 * * An expression of the form <i>e<sub>1</sub> ? e<sub>2</sub> : e<sub>3</sub><
/i> where |
| 57 * <i>e<sub>1</sub></i>, <i>e<sub>2</sub></i> and <i>e<sub>3</sub></i> are const
ant expressions, and |
| 58 * <i>e<sub>1</sub></i> evaluates to a boolean value. |
| 44 * | 59 * |
| 45 * </blockquote> The values returned by instances of this class are therefore `n
ull` and | 60 * </blockquote> |
| 46 * instances of the classes `Boolean`, `BigInteger`, `Double`, `String`, and | |
| 47 * `DartObject`. | |
| 48 * | |
| 49 * In addition, this class defines several values that can be returned to indica
te various | |
| 50 * conditions encountered during evaluation. These are documented with the stati
c field that define | |
| 51 * those values. | |
| 52 */ | 61 */ |
| 53 class ConstantEvaluator { | 62 class ConstantEvaluator { |
| 54 /** | 63 /** |
| 55 * The source containing the expression(s) that will be evaluated. | 64 * The source containing the expression(s) that will be evaluated. |
| 56 */ | 65 */ |
| 57 Source _source; | 66 Source _source; |
| 58 | 67 |
| 59 /** | 68 /** |
| 69 * The type provider used to access the known types. |
| 70 */ |
| 71 TypeProvider _typeProvider; |
| 72 |
| 73 /** |
| 60 * Initialize a newly created evaluator to evaluate expressions in the given s
ource. | 74 * Initialize a newly created evaluator to evaluate expressions in the given s
ource. |
| 61 * | 75 * |
| 62 * @param source the source containing the expression(s) that will be evaluate
d | 76 * @param source the source containing the expression(s) that will be evaluate
d |
| 77 * @param typeProvider the type provider used to access known types |
| 63 */ | 78 */ |
| 64 ConstantEvaluator(Source source) { | 79 ConstantEvaluator(Source source, TypeProvider typeProvider) { |
| 65 this._source = source; | 80 this._source = source; |
| 81 this._typeProvider = typeProvider; |
| 66 } | 82 } |
| 67 | 83 |
| 68 EvaluationResult evaluate(Expression expression) { | 84 EvaluationResult evaluate(Expression expression) { |
| 69 EvaluationResultImpl result = expression.accept(new ConstantVisitor()); | 85 EvaluationResultImpl result = expression.accept(new ConstantVisitor(_typePro
vider)); |
| 70 if (result is ValidResult) { | 86 if (result is ValidResult) { |
| 71 return EvaluationResult.forValue((result as ValidResult).value); | 87 return EvaluationResult.forValue((result as ValidResult).value); |
| 72 } | 88 } |
| 73 List<AnalysisError> errors = new List<AnalysisError>(); | 89 List<AnalysisError> errors = new List<AnalysisError>(); |
| 74 for (ErrorResult_ErrorData data in (result as ErrorResult).errorData) { | 90 for (ErrorResult_ErrorData data in (result as ErrorResult).errorData) { |
| 75 ASTNode node = data.node; | 91 ASTNode node = data.node; |
| 76 errors.add(new AnalysisError.con2(_source, node.offset, node.length, data.
errorCode, [])); | 92 errors.add(new AnalysisError.con2(_source, node.offset, node.length, data.
errorCode, [])); |
| 77 } | 93 } |
| 78 return EvaluationResult.forErrors(new List.from(errors)); | 94 return EvaluationResult.forErrors(new List.from(errors)); |
| 79 } | 95 } |
| 80 } | 96 } |
| 81 | 97 |
| 82 /** | 98 /** |
| 99 * The interface `DartObject` defines the behavior of objects that represent the
state of a |
| 100 * Dart object. |
| 101 */ |
| 102 abstract class DartObject { |
| 103 /** |
| 104 * Return the boolean value of this object, or `null` if either the value of t
his object is |
| 105 * not known or this object is not of type 'bool'. |
| 106 * |
| 107 * @return the boolean value of this object |
| 108 */ |
| 109 Object get boolValue; |
| 110 |
| 111 /** |
| 112 * Return the floating point value of this object, or `null` if either the val
ue of this |
| 113 * object is not known or this object is not of type 'double'. |
| 114 * |
| 115 * @return the floating point value of this object |
| 116 */ |
| 117 double get doubleValue; |
| 118 |
| 119 /** |
| 120 * Return the integer value of this object, or `null` if either the value of t
his object is |
| 121 * not known or this object is not of type 'int'. |
| 122 * |
| 123 * @return the integer value of this object |
| 124 */ |
| 125 int get intValue; |
| 126 |
| 127 /** |
| 128 * Return the string value of this object, or `null` if either the value of th
is object is |
| 129 * not known or this object is not of type 'String'. |
| 130 * |
| 131 * @return the string value of this object |
| 132 */ |
| 133 String get stringValue; |
| 134 |
| 135 /** |
| 136 * Return the run-time type of this object. |
| 137 * |
| 138 * @return the run-time type of this object |
| 139 */ |
| 140 InterfaceType get type; |
| 141 |
| 142 /** |
| 143 * Return `true` if this object represents the value 'false'. |
| 144 * |
| 145 * @return `true` if this object represents the value 'false' |
| 146 */ |
| 147 bool get isFalse; |
| 148 |
| 149 /** |
| 150 * Return `true` if this object represents the value 'null'. |
| 151 * |
| 152 * @return `true` if this object represents the value 'null' |
| 153 */ |
| 154 bool get isNull; |
| 155 |
| 156 /** |
| 157 * Return `true` if this object represents the value 'true'. |
| 158 * |
| 159 * @return `true` if this object represents the value 'true' |
| 160 */ |
| 161 bool get isTrue; |
| 162 } |
| 163 |
| 164 /** |
| 83 * Instances of the class `EvaluationResult` represent the result of attempting
to evaluate an | 165 * Instances of the class `EvaluationResult` represent the result of attempting
to evaluate an |
| 84 * expression. | 166 * expression. |
| 85 */ | 167 */ |
| 86 class EvaluationResult { | 168 class EvaluationResult { |
| 87 /** | 169 /** |
| 88 * Return an evaluation result representing the result of evaluating an expres
sion that is not a | 170 * Return an evaluation result representing the result of evaluating an expres
sion that is not a |
| 89 * compile-time constant because of the given errors. | 171 * compile-time constant because of the given errors. |
| 90 * | 172 * |
| 91 * @param errors the errors that should be reported for the expression(s) that
were evaluated | 173 * @param errors the errors that should be reported for the expression(s) that
were evaluated |
| 92 * @return the result of evaluating an expression that is not a compile-time c
onstant | 174 * @return the result of evaluating an expression that is not a compile-time c
onstant |
| 93 */ | 175 */ |
| 94 static EvaluationResult forErrors(List<AnalysisError> errors) => new Evaluatio
nResult(null, errors); | 176 static EvaluationResult forErrors(List<AnalysisError> errors) => new Evaluatio
nResult(null, errors); |
| 95 | 177 |
| 96 /** | 178 /** |
| 97 * Return an evaluation result representing the result of evaluating an expres
sion that is a | 179 * Return an evaluation result representing the result of evaluating an expres
sion that is a |
| 98 * compile-time constant that evaluates to the given value. | 180 * compile-time constant that evaluates to the given value. |
| 99 * | 181 * |
| 100 * @param value the value of the expression | 182 * @param value the value of the expression |
| 101 * @return the result of evaluating an expression that is a compile-time const
ant | 183 * @return the result of evaluating an expression that is a compile-time const
ant |
| 102 */ | 184 */ |
| 103 static EvaluationResult forValue(Object value) => new EvaluationResult(value,
null); | 185 static EvaluationResult forValue(DartObject value) => new EvaluationResult(val
ue, null); |
| 104 | 186 |
| 105 /** | 187 /** |
| 106 * The value of the expression. | 188 * The value of the expression. |
| 107 */ | 189 */ |
| 108 final Object value; | 190 final DartObject value; |
| 109 | 191 |
| 110 /** | 192 /** |
| 111 * The errors that should be reported for the expression(s) that were evaluate
d. | 193 * The errors that should be reported for the expression(s) that were evaluate
d. |
| 112 */ | 194 */ |
| 113 List<AnalysisError> _errors; | 195 List<AnalysisError> _errors; |
| 114 | 196 |
| 115 /** | 197 /** |
| 116 * Initialize a newly created result object with the given state. Clients shou
ld use one of the | 198 * Initialize a newly created result object with the given state. Clients shou
ld use one of the |
| 117 * factory methods: [forErrors] and [forValue]. | 199 * factory methods: [forErrors] and [forValue]. |
| 118 * | 200 * |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 } | 243 } |
| 162 } | 244 } |
| 163 return null; | 245 return null; |
| 164 } | 246 } |
| 165 } | 247 } |
| 166 | 248 |
| 167 /** | 249 /** |
| 168 * Instances of the class `ConstantValueComputer` compute the values of constant
variables in | 250 * Instances of the class `ConstantValueComputer` compute the values of constant
variables in |
| 169 * one or more compilation units. The expected usage pattern is for the compilat
ion units to be | 251 * one or more compilation units. The expected usage pattern is for the compilat
ion units to be |
| 170 * added to this computer using the method [add] and then for the method | 252 * added to this computer using the method [add] and then for the method |
| 171 * [computeValues] to invoked exactly once. Any use of an instance after invokin
g the | 253 * [computeValues] to be invoked exactly once. Any use of an instance after invo
king the |
| 172 * method [computeValues] will result in unpredictable behavior. | 254 * method [computeValues] will result in unpredictable behavior. |
| 173 */ | 255 */ |
| 174 class ConstantValueComputer { | 256 class ConstantValueComputer { |
| 175 /** | 257 /** |
| 258 * The type provider used to access the known types. |
| 259 */ |
| 260 TypeProvider _typeProvider; |
| 261 |
| 262 /** |
| 176 * The object used to find constant variables in the compilation units that we
re added. | 263 * The object used to find constant variables in the compilation units that we
re added. |
| 177 */ | 264 */ |
| 178 ConstantFinder _constantFinder = new ConstantFinder(); | 265 ConstantFinder _constantFinder = new ConstantFinder(); |
| 179 | 266 |
| 180 /** | 267 /** |
| 181 * A graph in which the nodes are the constant variables and the edges are fro
m each variable to | 268 * A graph in which the nodes are the constant variables and the edges are fro
m each variable to |
| 182 * the other constant variables that are referenced in the head's initializer. | 269 * the other constant variables that are referenced in the head's initializer. |
| 183 */ | 270 */ |
| 184 DirectedGraph<VariableElement> _referenceGraph = new DirectedGraph<VariableEle
ment>(); | 271 DirectedGraph<VariableElement> _referenceGraph = new DirectedGraph<VariableEle
ment>(); |
| 185 | 272 |
| 186 /** | 273 /** |
| 187 * A table mapping constant variables to the declarations of those variables. | 274 * A table mapping constant variables to the declarations of those variables. |
| 188 */ | 275 */ |
| 189 Map<VariableElement, VariableDeclaration> _declarationMap; | 276 Map<VariableElement, VariableDeclaration> _declarationMap; |
| 190 | 277 |
| 191 /** | 278 /** |
| 279 * Initialize a newly created constant value computer. |
| 280 * |
| 281 * @param typeProvider the type provider used to access known types |
| 282 */ |
| 283 ConstantValueComputer(TypeProvider typeProvider) { |
| 284 this._typeProvider = typeProvider; |
| 285 } |
| 286 |
| 287 /** |
| 192 * Add the constant variables in the given compilation unit to the list of con
stant variables | 288 * Add the constant variables in the given compilation unit to the list of con
stant variables |
| 193 * whose value needs to be computed. | 289 * whose value needs to be computed. |
| 194 * | 290 * |
| 195 * @param unit the compilation unit defining the constant variables to be adde
d | 291 * @param unit the compilation unit defining the constant variables to be adde
d |
| 196 */ | 292 */ |
| 197 void add(CompilationUnit unit) { | 293 void add(CompilationUnit unit) { |
| 198 unit.accept(_constantFinder); | 294 unit.accept(_constantFinder); |
| 199 } | 295 } |
| 200 | 296 |
| 201 /** | 297 /** |
| 202 * Compute values for all of the constant variables in the compilation units t
hat were added. | 298 * Compute values for all of the constant variables in the compilation units t
hat were added. |
| 203 */ | 299 */ |
| 204 void computeValues() { | 300 void computeValues() { |
| 205 _declarationMap = _constantFinder.variableMap; | 301 _declarationMap = _constantFinder.variableMap; |
| 206 for (MapEntry<VariableElement, VariableDeclaration> entry in getMapEntrySet(
_declarationMap)) { | 302 for (MapEntry<VariableElement, VariableDeclaration> entry in getMapEntrySet(
_declarationMap)) { |
| 207 VariableElement element = entry.getKey(); | 303 VariableElement element = entry.getKey(); |
| 208 ReferenceFinder referenceFinder = new ReferenceFinder(element, _referenceG
raph); | 304 ReferenceFinder referenceFinder = new ReferenceFinder(element, _referenceG
raph); |
| 209 _referenceGraph.addNode(element); | 305 _referenceGraph.addNode(element); |
| 210 entry.getValue().initializer.accept(referenceFinder); | 306 entry.getValue().initializer.accept(referenceFinder); |
| 211 } | 307 } |
| 212 while (!_referenceGraph.isEmpty) { | 308 while (!_referenceGraph.isEmpty) { |
| 213 VariableElement element = _referenceGraph.removeSink(); | 309 VariableElement element = _referenceGraph.removeSink(); |
| 214 while (element != null) { | 310 while (element != null) { |
| 215 computeValueFor(element); | 311 computeValueFor(element); |
| 216 element = _referenceGraph.removeSink(); | 312 element = _referenceGraph.removeSink(); |
| 217 } | 313 } |
| 218 if (!_referenceGraph.isEmpty) { | 314 if (!_referenceGraph.isEmpty) { |
| 219 List<VariableElement> variablesInCycle = _referenceGraph.findCycle(); | 315 List<VariableElement> variablesInCycle = _referenceGraph.findCycle(); |
| 220 if (variablesInCycle == null) { | 316 if (variablesInCycle == null) { |
| 221 AnalysisEngine.instance.logger.logError("Exiting constant value comput
er with ${_referenceGraph.nodeCount} variables that are neither sinks no in a cy
cle"); | 317 AnalysisEngine.instance.logger.logError("Exiting constant value comput
er with ${_referenceGraph.nodeCount} variables that are neither sinks nor in a c
ycle"); |
| 222 return; | 318 return; |
| 223 } | 319 } |
| 224 for (VariableElement variable in variablesInCycle) { | 320 for (VariableElement variable in variablesInCycle) { |
| 225 generateCycleError(variablesInCycle, variable); | 321 generateCycleError(variablesInCycle, variable); |
| 226 } | 322 } |
| 227 _referenceGraph.removeAllNodes(variablesInCycle); | 323 _referenceGraph.removeAllNodes(variablesInCycle); |
| 228 } | 324 } |
| 229 } | 325 } |
| 230 } | 326 } |
| 231 | 327 |
| 232 /** | 328 /** |
| 233 * Compute a value for the given variable. | 329 * Compute a value for the given variable. |
| 234 * | 330 * |
| 235 * @param variable the variable for which a value is to be computed | 331 * @param variable the variable for which a value is to be computed |
| 236 */ | 332 */ |
| 237 void computeValueFor(VariableElement variable) { | 333 void computeValueFor(VariableElement variable) { |
| 238 VariableDeclaration declaration = _declarationMap[variable]; | 334 VariableDeclaration declaration = _declarationMap[variable]; |
| 239 if (declaration == null) { | 335 if (declaration == null) { |
| 240 return; | 336 return; |
| 241 } | 337 } |
| 242 EvaluationResultImpl result = declaration.initializer.accept(new ConstantVis
itor()); | 338 EvaluationResultImpl result = declaration.initializer.accept(new ConstantVis
itor(_typeProvider)); |
| 243 (variable as VariableElementImpl).evaluationResult = result; | 339 (variable as VariableElementImpl).evaluationResult = result; |
| 244 if (result is ErrorResult) { | 340 if (result is ErrorResult) { |
| 245 List<AnalysisError> errors = new List<AnalysisError>(); | 341 List<AnalysisError> errors = new List<AnalysisError>(); |
| 246 for (ErrorResult_ErrorData data in (result as ErrorResult).errorData) { | 342 for (ErrorResult_ErrorData data in (result as ErrorResult).errorData) { |
| 247 ASTNode node = data.node; | 343 ASTNode node = data.node; |
| 248 Source source = variable.getAncestor(CompilationUnitElement).source; | 344 Source source = variable.getAncestor(CompilationUnitElement).source; |
| 249 errors.add(new AnalysisError.con2(source, node.offset, node.length, data
.errorCode, [])); | 345 errors.add(new AnalysisError.con2(source, node.offset, node.length, data
.errorCode, [])); |
| 250 } | 346 } |
| 251 } | 347 } |
| 252 } | 348 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 264 } | 360 } |
| 265 | 361 |
| 266 /** | 362 /** |
| 267 * Instances of the class `ConstantVisitor` evaluate constant expressions to pro
duce their | 363 * Instances of the class `ConstantVisitor` evaluate constant expressions to pro
duce their |
| 268 * compile-time value. According to the Dart Language Specification: <blockquote
> A constant | 364 * compile-time value. According to the Dart Language Specification: <blockquote
> A constant |
| 269 * expression is one of the following: | 365 * expression is one of the following: |
| 270 * | 366 * |
| 271 * * A literal number. | 367 * * A literal number. |
| 272 * * A literal boolean. | 368 * * A literal boolean. |
| 273 * * A literal string where any interpolated expression is a compile-time consta
nt that evaluates | 369 * * A literal string where any interpolated expression is a compile-time consta
nt that evaluates |
| 274 * to a numeric, string or boolean value or to `null`. | 370 * to a numeric, string or boolean value or to <b>null</b>. |
| 275 * * `null`. | 371 * * A literal symbol. |
| 276 * * A reference to a static constant variable. | 372 * * <b>null</b>. |
| 277 * * An identifier expression that denotes a constant variable, a class or a typ
e parameter. | 373 * * A qualified reference to a static constant variable. |
| 374 * * An identifier expression that denotes a constant variable, class or type al
ias. |
| 278 * * A constant constructor invocation. | 375 * * A constant constructor invocation. |
| 279 * * A constant list literal. | 376 * * A constant list literal. |
| 280 * * A constant map literal. | 377 * * A constant map literal. |
| 281 * * A simple or qualified identifier denoting a top-level function or a static
method. | 378 * * A simple or qualified identifier denoting a top-level function or a static
method. |
| 282 * * A parenthesized expression `(e)` where `e` is a constant expression. | 379 * * A parenthesized expression <i>(e)</i> where <i>e</i> is a constant expressi
on. |
| 283 * * An expression of one of the forms `identical(e1, e2)`, `e1 == e2`, | 380 * * An expression of the form <i>identical(e<sub>1</sub>, e<sub>2</sub>)</i> wh
ere |
| 284 * `e1 != e2` where `e1` and `e2` are constant expressions that evaluate to a | 381 * <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant expressions and <i
>identical()</i> is |
| 285 * numeric, string or boolean value or to `null`. | 382 * statically bound to the predefined dart function <i>identical()</i> discussed
above. |
| 286 * * An expression of one of the forms `!e`, `e1 && e2` or `e1 || e2`, where | 383 * * An expression of one of the forms <i>e<sub>1</sub> == e<sub>2</sub></i> or
<i>e<sub>1</sub> |
| 287 * `e`, `e1` and `e2` are constant expressions that evaluate to a boolean value
or | 384 * != e<sub>2</sub></i> where <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are
constant expressions |
| 288 * to `null`. | 385 * that evaluate to a numeric, string or boolean value. |
| 289 * * An expression of one of the forms `~e`, `e1 ^ e2`, `e1 & e2`, | 386 * * An expression of one of the forms <i>!e</i>, <i>e<sub>1</sub> && e<
sub>2</sub></i> or |
| 290 * `e1 | e2`, `e1 >> e2` or `e1 << e2`, where `e`, `e1` and `e2` | 387 * <i>e<sub>1</sub> || e<sub>2</sub></i>, where <i>e</i>, <i>e1</sub></i> and <i
>e2</sub></i> are |
| 291 * are constant expressions that evaluate to an integer value or to `null`. | 388 * constant expressions that evaluate to a boolean value. |
| 292 * * An expression of one of the forms `-e`, `e1 + e2`, `e1 - e2`, | 389 * * An expression of one of the forms <i>~e</i>, <i>e<sub>1</sub> ^ e<sub>2</su
b></i>, |
| 293 * `e1 * e2`, `e1 / e2`, `e1 ~/ e2`, `e1 > e2`, `e1 < e2`, | 390 * <i>e<sub>1</sub> & e<sub>2</sub></i>, <i>e<sub>1</sub> | e<sub>2</sub></i
>, <i>e<sub>1</sub> |
| 294 * `e1 >= e2`, `e1 <= e2` or `e1 % e2`, where `e`, `e1` and `e2` | 391 * >> e<sub>2</sub></i> or <i>e<sub>1</sub> << e<sub>2</sub></i>, wh
ere <i>e</i>, |
| 295 * are constant expressions that evaluate to a numeric value or to `null`. | 392 * <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant expressions that e
valuate to an |
| 393 * integer value or to <b>null</b>. |
| 394 * * An expression of one of the forms <i>-e</i>, <i>e<sub>1</sub> + e<sub>2</su
b></i>, |
| 395 * <i>e<sub>1</sub> - e<sub>2</sub></i>, <i>e<sub>1</sub> * e<sub>2</sub></i>, <
i>e<sub>1</sub> / |
| 396 * e<sub>2</sub></i>, <i>e<sub>1</sub> ~/ e<sub>2</sub></i>, <i>e<sub>1</sub> &g
t; |
| 397 * e<sub>2</sub></i>, <i>e<sub>1</sub> < e<sub>2</sub></i>, <i>e<sub>1</sub>
>= |
| 398 * e<sub>2</sub></i>, <i>e<sub>1</sub> <= e<sub>2</sub></i> or <i>e<sub>1</su
b> % |
| 399 * e<sub>2</sub></i>, where <i>e</i>, <i>e<sub>1</sub></i> and <i>e<sub>2</sub><
/i> are constant |
| 400 * expressions that evaluate to a numeric value or to <b>null</b>. |
| 401 * * An expression of the form <i>e<sub>1</sub> ? e<sub>2</sub> : e<sub>3</sub><
/i> where |
| 402 * <i>e<sub>1</sub></i>, <i>e<sub>2</sub></i> and <i>e<sub>3</sub></i> are const
ant expressions, and |
| 403 * <i>e<sub>1</sub></i> evaluates to a boolean value. |
| 296 * | 404 * |
| 297 * </blockquote> | 405 * </blockquote> |
| 298 */ | 406 */ |
| 299 class ConstantVisitor extends UnifyingASTVisitor<EvaluationResultImpl> { | 407 class ConstantVisitor extends UnifyingASTVisitor<EvaluationResultImpl> { |
| 408 /** |
| 409 * The type provider used to access the known types. |
| 410 */ |
| 411 TypeProvider _typeProvider; |
| 412 |
| 413 /** |
| 414 * An shared object representing the value 'null'. |
| 415 */ |
| 416 DartObjectImpl _nullObject; |
| 417 |
| 418 /** |
| 419 * Initialize a newly created constant visitor. |
| 420 * |
| 421 * @param typeProvider the type provider used to access known types |
| 422 */ |
| 423 ConstantVisitor(TypeProvider typeProvider) { |
| 424 this._typeProvider = typeProvider; |
| 425 } |
| 426 |
| 300 EvaluationResultImpl visitAdjacentStrings(AdjacentStrings node) { | 427 EvaluationResultImpl visitAdjacentStrings(AdjacentStrings node) { |
| 301 EvaluationResultImpl result = null; | 428 EvaluationResultImpl result = null; |
| 302 for (StringLiteral string in node.strings) { | 429 for (StringLiteral string in node.strings) { |
| 303 if (result == null) { | 430 if (result == null) { |
| 304 result = string.accept(this); | 431 result = string.accept(this); |
| 305 } else { | 432 } else { |
| 306 result = result.concatenate(node, string.accept(this)); | 433 result = result.concatenate(_typeProvider, node, string.accept(this)); |
| 307 } | 434 } |
| 308 } | 435 } |
| 309 return result; | 436 return result; |
| 310 } | 437 } |
| 311 | 438 |
| 312 EvaluationResultImpl visitBinaryExpression(BinaryExpression node) { | 439 EvaluationResultImpl visitBinaryExpression(BinaryExpression node) { |
| 313 EvaluationResultImpl leftResult = node.leftOperand.accept(this); | 440 EvaluationResultImpl leftResult = node.leftOperand.accept(this); |
| 314 EvaluationResultImpl rightResult = node.rightOperand.accept(this); | 441 EvaluationResultImpl rightResult = node.rightOperand.accept(this); |
| 315 TokenType operatorType = node.operator.type; | 442 TokenType operatorType = node.operator.type; |
| 316 if (operatorType != TokenType.BANG_EQ && operatorType != TokenType.EQ_EQ) { | 443 if (operatorType != TokenType.BANG_EQ && operatorType != TokenType.EQ_EQ) { |
| 317 if (leftResult is ValidResult && (leftResult as ValidResult).isNull || rig
htResult is ValidResult && (rightResult as ValidResult).isNull) { | 444 if (leftResult is ValidResult && (leftResult as ValidResult).isNull || rig
htResult is ValidResult && (rightResult as ValidResult).isNull) { |
| 318 return error(node, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION); | 445 return error(node, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION); |
| 319 } | 446 } |
| 320 } | 447 } |
| 321 while (true) { | 448 while (true) { |
| 322 if (operatorType == TokenType.AMPERSAND) { | 449 if (operatorType == TokenType.AMPERSAND) { |
| 323 return leftResult.bitAnd(node, rightResult); | 450 return leftResult.bitAnd(_typeProvider, node, rightResult); |
| 324 } else if (operatorType == TokenType.AMPERSAND_AMPERSAND) { | 451 } else if (operatorType == TokenType.AMPERSAND_AMPERSAND) { |
| 325 return leftResult.logicalAnd(node, rightResult); | 452 return leftResult.logicalAnd(_typeProvider, node, rightResult); |
| 326 } else if (operatorType == TokenType.BANG_EQ) { | 453 } else if (operatorType == TokenType.BANG_EQ) { |
| 327 return leftResult.notEqual(node, rightResult); | 454 return leftResult.notEqual(_typeProvider, node, rightResult); |
| 328 } else if (operatorType == TokenType.BAR) { | 455 } else if (operatorType == TokenType.BAR) { |
| 329 return leftResult.bitOr(node, rightResult); | 456 return leftResult.bitOr(_typeProvider, node, rightResult); |
| 330 } else if (operatorType == TokenType.BAR_BAR) { | 457 } else if (operatorType == TokenType.BAR_BAR) { |
| 331 return leftResult.logicalOr(node, rightResult); | 458 return leftResult.logicalOr(_typeProvider, node, rightResult); |
| 332 } else if (operatorType == TokenType.CARET) { | 459 } else if (operatorType == TokenType.CARET) { |
| 333 return leftResult.bitXor(node, rightResult); | 460 return leftResult.bitXor(_typeProvider, node, rightResult); |
| 334 } else if (operatorType == TokenType.EQ_EQ) { | 461 } else if (operatorType == TokenType.EQ_EQ) { |
| 335 return leftResult.equalEqual(node, rightResult); | 462 return leftResult.equalEqual(_typeProvider, node, rightResult); |
| 336 } else if (operatorType == TokenType.GT) { | 463 } else if (operatorType == TokenType.GT) { |
| 337 return leftResult.greaterThan(node, rightResult); | 464 return leftResult.greaterThan(_typeProvider, node, rightResult); |
| 338 } else if (operatorType == TokenType.GT_EQ) { | 465 } else if (operatorType == TokenType.GT_EQ) { |
| 339 return leftResult.greaterThanOrEqual(node, rightResult); | 466 return leftResult.greaterThanOrEqual(_typeProvider, node, rightResult); |
| 340 } else if (operatorType == TokenType.GT_GT) { | 467 } else if (operatorType == TokenType.GT_GT) { |
| 341 return leftResult.shiftRight(node, rightResult); | 468 return leftResult.shiftRight(_typeProvider, node, rightResult); |
| 342 } else if (operatorType == TokenType.LT) { | 469 } else if (operatorType == TokenType.LT) { |
| 343 return leftResult.lessThan(node, rightResult); | 470 return leftResult.lessThan(_typeProvider, node, rightResult); |
| 344 } else if (operatorType == TokenType.LT_EQ) { | 471 } else if (operatorType == TokenType.LT_EQ) { |
| 345 return leftResult.lessThanOrEqual(node, rightResult); | 472 return leftResult.lessThanOrEqual(_typeProvider, node, rightResult); |
| 346 } else if (operatorType == TokenType.LT_LT) { | 473 } else if (operatorType == TokenType.LT_LT) { |
| 347 return leftResult.shiftLeft(node, rightResult); | 474 return leftResult.shiftLeft(_typeProvider, node, rightResult); |
| 348 } else if (operatorType == TokenType.MINUS) { | 475 } else if (operatorType == TokenType.MINUS) { |
| 349 return leftResult.minus(node, rightResult); | 476 return leftResult.minus(_typeProvider, node, rightResult); |
| 350 } else if (operatorType == TokenType.PERCENT) { | 477 } else if (operatorType == TokenType.PERCENT) { |
| 351 return leftResult.remainder(node, rightResult); | 478 return leftResult.remainder(_typeProvider, node, rightResult); |
| 352 } else if (operatorType == TokenType.PLUS) { | 479 } else if (operatorType == TokenType.PLUS) { |
| 353 return leftResult.add(node, rightResult); | 480 return leftResult.add(_typeProvider, node, rightResult); |
| 354 } else if (operatorType == TokenType.STAR) { | 481 } else if (operatorType == TokenType.STAR) { |
| 355 return leftResult.times(node, rightResult); | 482 return leftResult.times(_typeProvider, node, rightResult); |
| 356 } else if (operatorType == TokenType.SLASH) { | 483 } else if (operatorType == TokenType.SLASH) { |
| 357 return leftResult.divide(node, rightResult); | 484 return leftResult.divide(_typeProvider, node, rightResult); |
| 358 } else if (operatorType == TokenType.TILDE_SLASH) { | 485 } else if (operatorType == TokenType.TILDE_SLASH) { |
| 359 return leftResult.integerDivide(node, rightResult); | 486 return leftResult.integerDivide(_typeProvider, node, rightResult); |
| 360 } | 487 } |
| 361 break; | 488 break; |
| 362 } | 489 } |
| 363 return error(node, null); | 490 return error(node, null); |
| 364 } | 491 } |
| 365 | 492 |
| 366 EvaluationResultImpl visitBooleanLiteral(BooleanLiteral node) => node.value ?
ValidResult.RESULT_TRUE : ValidResult.RESULT_FALSE; | 493 EvaluationResultImpl visitBooleanLiteral(BooleanLiteral node) => valid2(_typeP
rovider.boolType, BoolState.from(node.value)); |
| 367 | 494 |
| 368 EvaluationResultImpl visitConditionalExpression(ConditionalExpression node) { | 495 EvaluationResultImpl visitConditionalExpression(ConditionalExpression node) { |
| 369 Expression condition = node.condition; | 496 Expression condition = node.condition; |
| 370 EvaluationResultImpl conditionResult = condition.accept(this); | 497 EvaluationResultImpl conditionResult = condition.accept(this); |
| 371 conditionResult = conditionResult.applyBooleanConversion(condition); | 498 EvaluationResultImpl thenResult = node.thenExpression.accept(this); |
| 499 EvaluationResultImpl elseResult = node.elseExpression.accept(this); |
| 500 if (conditionResult is ErrorResult) { |
| 501 return union(union(conditionResult as ErrorResult, thenResult), elseResult
); |
| 502 } else if (!(conditionResult as ValidResult).isBool) { |
| 503 return new ErrorResult.con1(condition, CompileTimeErrorCode.CONST_EVAL_TYP
E_BOOL); |
| 504 } else if (thenResult is ErrorResult) { |
| 505 return union(thenResult as ErrorResult, elseResult); |
| 506 } else if (elseResult is ErrorResult) { |
| 507 return elseResult; |
| 508 } |
| 509 conditionResult = conditionResult.applyBooleanConversion(_typeProvider, cond
ition); |
| 372 if (conditionResult is ErrorResult) { | 510 if (conditionResult is ErrorResult) { |
| 373 return conditionResult; | 511 return conditionResult; |
| 374 } | 512 } |
| 375 EvaluationResultImpl thenResult = node.thenExpression.accept(this); | 513 ValidResult validResult = conditionResult as ValidResult; |
| 376 if (thenResult is ErrorResult) { | 514 if (validResult.isTrue) { |
| 377 return thenResult; | 515 return thenResult; |
| 378 } | 516 } else if (validResult.isFalse) { |
| 379 EvaluationResultImpl elseResult = node.elseExpression.accept(this); | |
| 380 if (elseResult is ErrorResult) { | |
| 381 return elseResult; | 517 return elseResult; |
| 382 } | 518 } |
| 383 return (identical(conditionResult, ValidResult.RESULT_TRUE)) ? thenResult :
elseResult; | 519 InterfaceType thenType = (thenResult as ValidResult).value.type; |
| 520 InterfaceType elseType = (elseResult as ValidResult).value.type; |
| 521 return valid(thenType.getLeastUpperBound(elseType) as InterfaceType); |
| 384 } | 522 } |
| 385 | 523 |
| 386 EvaluationResultImpl visitDoubleLiteral(DoubleLiteral node) => new ValidResult
(node.value); | 524 EvaluationResultImpl visitDoubleLiteral(DoubleLiteral node) => valid2(_typePro
vider.doubleType, new DoubleState(node.value)); |
| 387 | 525 |
| 388 EvaluationResultImpl visitInstanceCreationExpression(InstanceCreationExpressio
n node) { | 526 EvaluationResultImpl visitInstanceCreationExpression(InstanceCreationExpressio
n node) { |
| 389 if (!node.isConst) { | 527 if (!node.isConst) { |
| 390 return error(node, null); | 528 return error(node, null); |
| 391 } | 529 } |
| 392 ConstructorElement constructor = node.staticElement; | 530 ConstructorElement constructor = node.staticElement; |
| 393 if (constructor != null && constructor.isConst) { | 531 if (constructor != null && constructor.isConst) { |
| 394 node.argumentList.accept(this); | 532 NodeList<Expression> arguments = node.argumentList.arguments; |
| 395 return ValidResult.RESULT_OBJECT; | 533 int argumentCount = arguments.length; |
| 534 List<DartObjectImpl> argumentValues = new List<DartObjectImpl>(argumentCou
nt); |
| 535 Map<String, DartObjectImpl> namedArgumentValues = new Map<String, DartObje
ctImpl>(); |
| 536 for (int i = 0; i < argumentCount; i++) { |
| 537 Expression argument = arguments[i]; |
| 538 if (argument is NamedExpression) { |
| 539 NamedExpression namedExpression = argument as NamedExpression; |
| 540 String name = namedExpression.name.label.name; |
| 541 namedArgumentValues[name] = valueOf(namedExpression.expression); |
| 542 argumentValues[i] = null2; |
| 543 } else { |
| 544 argumentValues[i] = valueOf(argument); |
| 545 } |
| 546 } |
| 547 InterfaceType definingClass = constructor.returnType as InterfaceType; |
| 548 if (definingClass.element.library.isDartCore) { |
| 549 String className = definingClass.name; |
| 550 if (className == "Symbol" && argumentCount == 1) { |
| 551 String argumentValue = argumentValues[0].stringValue; |
| 552 if (argumentValue != null) { |
| 553 return valid2(definingClass, new SymbolState(argumentValue)); |
| 554 } |
| 555 } |
| 556 } |
| 557 Map<String, DartObjectImpl> fieldMap = new Map<String, DartObjectImpl>(); |
| 558 List<ParameterElement> parameters = constructor.parameters; |
| 559 int parameterCount = parameters.length; |
| 560 for (int i = 0; i < parameterCount; i++) { |
| 561 ParameterElement parameter = parameters[i]; |
| 562 if (parameter.isInitializingFormal) { |
| 563 String fieldName = (parameter as FieldFormalParameterElement).field.na
me; |
| 564 if (identical(parameter.parameterKind, ParameterKind.NAMED)) { |
| 565 DartObjectImpl argumentValue = namedArgumentValues[parameter.name]; |
| 566 if (argumentValue != null) { |
| 567 fieldMap[fieldName] = argumentValue; |
| 568 } |
| 569 } else if (i < argumentCount) { |
| 570 fieldMap[fieldName] = argumentValues[i]; |
| 571 } |
| 572 } |
| 573 } |
| 574 return valid2(definingClass, new GenericState(fieldMap)); |
| 396 } | 575 } |
| 397 return error(node, null); | 576 return error(node, null); |
| 398 } | 577 } |
| 399 | 578 |
| 400 EvaluationResultImpl visitIntegerLiteral(IntegerLiteral node) => new ValidResu
lt(node.value); | 579 EvaluationResultImpl visitIntegerLiteral(IntegerLiteral node) => valid2(_typeP
rovider.intType, new IntState(node.value)); |
| 401 | 580 |
| 402 EvaluationResultImpl visitInterpolationExpression(InterpolationExpression node
) { | 581 EvaluationResultImpl visitInterpolationExpression(InterpolationExpression node
) { |
| 403 EvaluationResultImpl result = node.expression.accept(this); | 582 EvaluationResultImpl result = node.expression.accept(this); |
| 404 return result.performToString(node); | 583 if (result is ValidResult && !(result as ValidResult).isBoolNumStringOrNull)
{ |
| 584 return error(node, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING); |
| 585 } |
| 586 return result.performToString(_typeProvider, node); |
| 405 } | 587 } |
| 406 | 588 |
| 407 EvaluationResultImpl visitInterpolationString(InterpolationString node) => new
ValidResult(node.value); | 589 EvaluationResultImpl visitInterpolationString(InterpolationString node) => val
id2(_typeProvider.stringType, new StringState(node.value)); |
| 408 | 590 |
| 409 EvaluationResultImpl visitListLiteral(ListLiteral node) { | 591 EvaluationResultImpl visitListLiteral(ListLiteral node) { |
| 410 if (node.constKeyword == null) { | 592 if (node.constKeyword == null) { |
| 411 return new ErrorResult.con1(node, CompileTimeErrorCode.MISSING_CONST_IN_LI
ST_LITERAL); | 593 return new ErrorResult.con1(node, CompileTimeErrorCode.MISSING_CONST_IN_LI
ST_LITERAL); |
| 412 } | 594 } |
| 413 ErrorResult result = null; | 595 ErrorResult result = null; |
| 596 List<DartObjectImpl> elements = new List<DartObjectImpl>(); |
| 414 for (Expression element in node.elements) { | 597 for (Expression element in node.elements) { |
| 415 result = union(result, element.accept(this)); | 598 EvaluationResultImpl elementResult = element.accept(this); |
| 599 result = union(result, elementResult); |
| 600 if (elementResult is ValidResult) { |
| 601 elements.add((elementResult as ValidResult).value); |
| 602 } |
| 416 } | 603 } |
| 417 if (result != null) { | 604 if (result != null) { |
| 418 return result; | 605 return result; |
| 419 } | 606 } |
| 420 return ValidResult.RESULT_OBJECT; | 607 return valid2(_typeProvider.listType, new ListState(new List.from(elements))
); |
| 421 } | 608 } |
| 422 | 609 |
| 423 EvaluationResultImpl visitMapLiteral(MapLiteral node) { | 610 EvaluationResultImpl visitMapLiteral(MapLiteral node) { |
| 424 if (node.constKeyword == null) { | 611 if (node.constKeyword == null) { |
| 425 return new ErrorResult.con1(node, CompileTimeErrorCode.MISSING_CONST_IN_MA
P_LITERAL); | 612 return new ErrorResult.con1(node, CompileTimeErrorCode.MISSING_CONST_IN_MA
P_LITERAL); |
| 426 } | 613 } |
| 427 ErrorResult result = null; | 614 ErrorResult result = null; |
| 615 Map<DartObjectImpl, DartObjectImpl> map = new Map<DartObjectImpl, DartObject
Impl>(); |
| 428 for (MapLiteralEntry entry in node.entries) { | 616 for (MapLiteralEntry entry in node.entries) { |
| 429 result = union(result, entry.key.accept(this)); | 617 EvaluationResultImpl keyResult = entry.key.accept(this); |
| 430 result = union(result, entry.value.accept(this)); | 618 EvaluationResultImpl valueResult = entry.value.accept(this); |
| 619 result = union(result, keyResult); |
| 620 result = union(result, valueResult); |
| 621 if (keyResult is ValidResult && valueResult is ValidResult) { |
| 622 map[(keyResult as ValidResult).value] = (valueResult as ValidResult).val
ue; |
| 623 } |
| 431 } | 624 } |
| 432 if (result != null) { | 625 if (result != null) { |
| 433 return result; | 626 return result; |
| 434 } | 627 } |
| 435 return ValidResult.RESULT_OBJECT; | 628 return valid2(_typeProvider.mapType, new MapState(map)); |
| 436 } | 629 } |
| 437 | 630 |
| 438 EvaluationResultImpl visitMethodInvocation(MethodInvocation node) { | 631 EvaluationResultImpl visitMethodInvocation(MethodInvocation node) { |
| 439 Element element = node.methodName.staticElement; | 632 Element element = node.methodName.staticElement; |
| 440 if (element is FunctionElement) { | 633 if (element is FunctionElement) { |
| 441 FunctionElement function = element as FunctionElement; | 634 FunctionElement function = element as FunctionElement; |
| 442 if (function.name == "identical") { | 635 if (function.name == "identical") { |
| 443 NodeList<Expression> arguments = node.argumentList.arguments; | 636 NodeList<Expression> arguments = node.argumentList.arguments; |
| 444 if (arguments.length == 2) { | 637 if (arguments.length == 2) { |
| 445 Element enclosingElement = function.enclosingElement; | 638 Element enclosingElement = function.enclosingElement; |
| 446 if (enclosingElement is CompilationUnitElement) { | 639 if (enclosingElement is CompilationUnitElement) { |
| 447 LibraryElement library = (enclosingElement as CompilationUnitElement
).library; | 640 LibraryElement library = (enclosingElement as CompilationUnitElement
).library; |
| 448 if (library.isDartCore) { | 641 if (library.isDartCore) { |
| 449 EvaluationResultImpl leftArgument = arguments[0].accept(this); | 642 EvaluationResultImpl leftArgument = arguments[0].accept(this); |
| 450 EvaluationResultImpl rightArgument = arguments[1].accept(this); | 643 EvaluationResultImpl rightArgument = arguments[1].accept(this); |
| 451 return leftArgument.equalEqual(node, rightArgument); | 644 return leftArgument.equalEqual(_typeProvider, node, rightArgument)
; |
| 452 } | 645 } |
| 453 } | 646 } |
| 454 } | 647 } |
| 455 } | 648 } |
| 456 } | 649 } |
| 457 return error(node, null); | 650 return error(node, null); |
| 458 } | 651 } |
| 459 | 652 |
| 460 EvaluationResultImpl visitNamedExpression(NamedExpression node) => node.expres
sion.accept(this); | 653 EvaluationResultImpl visitNamedExpression(NamedExpression node) => node.expres
sion.accept(this); |
| 461 | 654 |
| 462 EvaluationResultImpl visitNode(ASTNode node) => error(node, null); | 655 EvaluationResultImpl visitNode(ASTNode node) => error(node, null); |
| 463 | 656 |
| 464 EvaluationResultImpl visitNullLiteral(NullLiteral node) => ValidResult.RESULT_
NULL; | 657 EvaluationResultImpl visitNullLiteral(NullLiteral node) => new ValidResult(nul
l2); |
| 465 | 658 |
| 466 EvaluationResultImpl visitParenthesizedExpression(ParenthesizedExpression node
) => node.expression.accept(this); | 659 EvaluationResultImpl visitParenthesizedExpression(ParenthesizedExpression node
) => node.expression.accept(this); |
| 467 | 660 |
| 468 EvaluationResultImpl visitPrefixedIdentifier(PrefixedIdentifier node) { | 661 EvaluationResultImpl visitPrefixedIdentifier(PrefixedIdentifier node) { |
| 469 SimpleIdentifier prefixNode = node.prefix; | 662 SimpleIdentifier prefixNode = node.prefix; |
| 470 Element prefixElement = prefixNode.staticElement; | 663 Element prefixElement = prefixNode.staticElement; |
| 471 if (prefixElement is! PrefixElement) { | 664 if (prefixElement is! PrefixElement) { |
| 472 EvaluationResultImpl prefixResult = prefixNode.accept(this); | 665 EvaluationResultImpl prefixResult = prefixNode.accept(this); |
| 473 if (prefixResult is! ValidResult) { | 666 if (prefixResult is! ValidResult) { |
| 474 return error(node, null); | 667 return error(node, null); |
| 475 } | 668 } |
| 476 } | 669 } |
| 477 return getConstantValue(node, node.staticElement); | 670 return getConstantValue(node, node.staticElement); |
| 478 } | 671 } |
| 479 | 672 |
| 480 EvaluationResultImpl visitPrefixExpression(PrefixExpression node) { | 673 EvaluationResultImpl visitPrefixExpression(PrefixExpression node) { |
| 481 EvaluationResultImpl operand = node.operand.accept(this); | 674 EvaluationResultImpl operand = node.operand.accept(this); |
| 482 if (operand is ValidResult && (operand as ValidResult).isNull) { | 675 if (operand is ValidResult && (operand as ValidResult).isNull) { |
| 483 return error(node, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION); | 676 return error(node, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION); |
| 484 } | 677 } |
| 485 while (true) { | 678 while (true) { |
| 486 if (node.operator.type == TokenType.BANG) { | 679 if (node.operator.type == TokenType.BANG) { |
| 487 return operand.logicalNot(node); | 680 return operand.logicalNot(_typeProvider, node); |
| 488 } else if (node.operator.type == TokenType.TILDE) { | 681 } else if (node.operator.type == TokenType.TILDE) { |
| 489 return operand.bitNot(node); | 682 return operand.bitNot(_typeProvider, node); |
| 490 } else if (node.operator.type == TokenType.MINUS) { | 683 } else if (node.operator.type == TokenType.MINUS) { |
| 491 return operand.negated(node); | 684 return operand.negated(_typeProvider, node); |
| 492 } | 685 } |
| 493 break; | 686 break; |
| 494 } | 687 } |
| 495 return error(node, null); | 688 return error(node, null); |
| 496 } | 689 } |
| 497 | 690 |
| 498 EvaluationResultImpl visitPropertyAccess(PropertyAccess node) => getConstantVa
lue(node, node.propertyName.staticElement); | 691 EvaluationResultImpl visitPropertyAccess(PropertyAccess node) => getConstantVa
lue(node, node.propertyName.staticElement); |
| 499 | 692 |
| 500 EvaluationResultImpl visitSimpleIdentifier(SimpleIdentifier node) => getConsta
ntValue(node, node.staticElement); | 693 EvaluationResultImpl visitSimpleIdentifier(SimpleIdentifier node) => getConsta
ntValue(node, node.staticElement); |
| 501 | 694 |
| 502 EvaluationResultImpl visitSimpleStringLiteral(SimpleStringLiteral node) => new
ValidResult(node.value); | 695 EvaluationResultImpl visitSimpleStringLiteral(SimpleStringLiteral node) => val
id2(_typeProvider.stringType, new StringState(node.value)); |
| 503 | 696 |
| 504 EvaluationResultImpl visitStringInterpolation(StringInterpolation node) { | 697 EvaluationResultImpl visitStringInterpolation(StringInterpolation node) { |
| 505 EvaluationResultImpl result = null; | 698 EvaluationResultImpl result = null; |
| 506 for (InterpolationElement element in node.elements) { | 699 for (InterpolationElement element in node.elements) { |
| 507 if (result == null) { | 700 if (result == null) { |
| 508 result = element.accept(this); | 701 result = element.accept(this); |
| 509 } else { | 702 } else { |
| 510 result = result.concatenate(node, element.accept(this)); | 703 result = result.concatenate(_typeProvider, node, element.accept(this)); |
| 511 } | 704 } |
| 512 } | 705 } |
| 513 return result; | 706 return result; |
| 514 } | 707 } |
| 515 | 708 |
| 516 EvaluationResultImpl visitSymbolLiteral(SymbolLiteral node) => ValidResult.RES
ULT_SYMBOL; | 709 EvaluationResultImpl visitSymbolLiteral(SymbolLiteral node) { |
| 710 JavaStringBuilder builder = new JavaStringBuilder(); |
| 711 List<Token> components = node.components; |
| 712 for (int i = 0; i < components.length; i++) { |
| 713 if (i > 0) { |
| 714 builder.appendChar(0x2E); |
| 715 } |
| 716 builder.append(components[i].lexeme); |
| 717 } |
| 718 return valid2(_typeProvider.symbolType, new SymbolState(builder.toString()))
; |
| 719 } |
| 517 | 720 |
| 518 /** | 721 /** |
| 519 * Return a result object representing an error associated with the given node
. | 722 * Return a result object representing an error associated with the given node
. |
| 520 * | 723 * |
| 521 * @param node the AST node associated with the error | 724 * @param node the AST node associated with the error |
| 522 * @param code the error code indicating the nature of the error | 725 * @param code the error code indicating the nature of the error |
| 523 * @return a result object representing an error associated with the given nod
e | 726 * @return a result object representing an error associated with the given nod
e |
| 524 */ | 727 */ |
| 525 ErrorResult error(ASTNode node, ErrorCode code) => new ErrorResult.con1(node,
code == null ? CompileTimeErrorCode.INVALID_CONSTANT : code); | 728 ErrorResult error(ASTNode node, ErrorCode code) => new ErrorResult.con1(node,
code == null ? CompileTimeErrorCode.INVALID_CONSTANT : code); |
| 526 | 729 |
| 527 /** | 730 /** |
| 528 * Return the constant value of the static constant represented by the given e
lement. | 731 * Return the constant value of the static constant represented by the given e
lement. |
| 529 * | 732 * |
| 530 * @param node the node to be used if an error needs to be reported | 733 * @param node the node to be used if an error needs to be reported |
| 531 * @param element the element whose value is to be returned | 734 * @param element the element whose value is to be returned |
| 532 * @return the constant value of the static constant | 735 * @return the constant value of the static constant |
| 533 */ | 736 */ |
| 534 EvaluationResultImpl getConstantValue(ASTNode node, Element element) { | 737 EvaluationResultImpl getConstantValue(ASTNode node, Element element) { |
| 535 if (element is PropertyAccessorElement) { | 738 if (element is PropertyAccessorElement) { |
| 536 element = (element as PropertyAccessorElement).variable; | 739 element = (element as PropertyAccessorElement).variable; |
| 537 } | 740 } |
| 538 if (element is VariableElementImpl) { | 741 if (element is VariableElementImpl) { |
| 539 VariableElementImpl variableElementImpl = element as VariableElementImpl; | 742 VariableElementImpl variableElementImpl = element as VariableElementImpl; |
| 540 EvaluationResultImpl value = variableElementImpl.evaluationResult; | 743 EvaluationResultImpl value = variableElementImpl.evaluationResult; |
| 541 if (variableElementImpl.isConst && value != null) { | 744 if (variableElementImpl.isConst && value != null) { |
| 542 return value; | 745 return value; |
| 543 } | 746 } |
| 544 } else if (element is ExecutableElement) { | 747 } else if (element is ExecutableElement) { |
| 545 if ((element as ExecutableElement).isStatic) { | 748 ExecutableElement function = element as ExecutableElement; |
| 546 return new ValidResult(element); | 749 if (function.isStatic) { |
| 750 return valid2(_typeProvider.functionType, new FunctionState(function)); |
| 547 } | 751 } |
| 548 } else if (element is ClassElement || element is FunctionTypeAliasElement) { | 752 } else if (element is ClassElement || element is FunctionTypeAliasElement) { |
| 549 return ValidResult.RESULT_OBJECT; | 753 return valid2(_typeProvider.typeType, new TypeState(element)); |
| 550 } | 754 } |
| 551 return error(node, null); | 755 return error(node, null); |
| 552 } | 756 } |
| 553 | 757 |
| 554 /** | 758 /** |
| 759 * Return an object representing the value 'null'. |
| 760 * |
| 761 * @return an object representing the value 'null' |
| 762 */ |
| 763 DartObjectImpl get null2 { |
| 764 if (_nullObject == null) { |
| 765 _nullObject = new DartObjectImpl(_typeProvider.nullType, NullState.NULL_ST
ATE); |
| 766 } |
| 767 return _nullObject; |
| 768 } |
| 769 |
| 770 /** |
| 555 * Return the union of the errors encoded in the given results. | 771 * Return the union of the errors encoded in the given results. |
| 556 * | 772 * |
| 557 * @param leftResult the first set of errors, or `null` if there was no previo
us collection | 773 * @param leftResult the first set of errors, or `null` if there was no previo
us collection |
| 558 * of errors | 774 * of errors |
| 559 * @param rightResult the errors to be added to the collection, or a valid res
ult if there are no | 775 * @param rightResult the errors to be added to the collection, or a valid res
ult if there are no |
| 560 * errors to be added | 776 * errors to be added |
| 561 * @return the union of the errors encoded in the given results | 777 * @return the union of the errors encoded in the given results |
| 562 */ | 778 */ |
| 563 ErrorResult union(ErrorResult leftResult, EvaluationResultImpl rightResult) { | 779 ErrorResult union(ErrorResult leftResult, EvaluationResultImpl rightResult) { |
| 564 if (rightResult is ErrorResult) { | 780 if (rightResult is ErrorResult) { |
| 565 if (leftResult != null) { | 781 if (leftResult != null) { |
| 566 return new ErrorResult.con2(leftResult, rightResult as ErrorResult); | 782 return new ErrorResult.con2(leftResult, rightResult as ErrorResult); |
| 567 } else { | 783 } else { |
| 568 return rightResult as ErrorResult; | 784 return rightResult as ErrorResult; |
| 569 } | 785 } |
| 570 } | 786 } |
| 571 return leftResult; | 787 return leftResult; |
| 572 } | 788 } |
| 789 |
| 790 ValidResult valid(InterfaceType type) { |
| 791 if (type.element.library.isDartCore) { |
| 792 String typeName = type.name; |
| 793 if (typeName == "bool") { |
| 794 return valid2(type, BoolState.UNKNOWN_VALUE); |
| 795 } else if (typeName == "double") { |
| 796 return valid2(type, DoubleState.UNKNOWN_VALUE); |
| 797 } else if (typeName == "int") { |
| 798 return valid2(type, IntState.UNKNOWN_VALUE); |
| 799 } else if (typeName == "String") { |
| 800 return valid2(type, StringState.UNKNOWN_VALUE); |
| 801 } |
| 802 } |
| 803 return valid2(type, GenericState.UNKNOWN_VALUE); |
| 804 } |
| 805 |
| 806 ValidResult valid2(InterfaceType type, InstanceState state) => new ValidResult
(new DartObjectImpl(type, state)); |
| 807 |
| 808 /** |
| 809 * Return the value of the given expression, or a representation of 'null' if
the expression |
| 810 * cannot be evaluated. |
| 811 * |
| 812 * @param expression the expression whose value is to be returned |
| 813 * @return the value of the given expression |
| 814 */ |
| 815 DartObjectImpl valueOf(Expression expression) { |
| 816 EvaluationResultImpl expressionValue = expression.accept(this); |
| 817 if (expressionValue is ValidResult) { |
| 818 return (expressionValue as ValidResult).value; |
| 819 } |
| 820 return null2; |
| 821 } |
| 573 } | 822 } |
| 574 | 823 |
| 575 /** | 824 /** |
| 576 * Instances of the class `DirectedGraph` implement a directed graph in which th
e nodes are | 825 * Instances of the class `DirectedGraph` implement a directed graph in which th
e nodes are |
| 577 * arbitrary (client provided) objects and edges are represented implicitly. The
graph will allow an | 826 * arbitrary (client provided) objects and edges are represented implicitly. The
graph will allow an |
| 578 * edge from any node to any other node, including itself, but will not represen
t multiple edges | 827 * edge from any node to any other node, including itself, but will not represen
t multiple edges |
| 579 * between the same pair of nodes. | 828 * between the same pair of nodes. |
| 580 * | 829 * |
| 581 * @param N the type of the nodes in the graph | 830 * @param N the type of the nodes in the graph |
| 582 */ | 831 */ |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 756 * objects. | 1005 * objects. |
| 757 * | 1006 * |
| 758 * @param firstResult the first set of results being merged | 1007 * @param firstResult the first set of results being merged |
| 759 * @param secondResult the second set of results being merged | 1008 * @param secondResult the second set of results being merged |
| 760 */ | 1009 */ |
| 761 ErrorResult.con2(ErrorResult firstResult, ErrorResult secondResult) { | 1010 ErrorResult.con2(ErrorResult firstResult, ErrorResult secondResult) { |
| 762 _errors.addAll(firstResult._errors); | 1011 _errors.addAll(firstResult._errors); |
| 763 _errors.addAll(secondResult._errors); | 1012 _errors.addAll(secondResult._errors); |
| 764 } | 1013 } |
| 765 | 1014 |
| 766 EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOper
and) => rightOperand.addToError(node, this); | 1015 EvaluationResultImpl add(TypeProvider typeProvider, BinaryExpression node, Eva
luationResultImpl rightOperand) => rightOperand.addToError(node, this); |
| 767 | 1016 |
| 768 EvaluationResultImpl applyBooleanConversion(ASTNode node) => this; | 1017 EvaluationResultImpl applyBooleanConversion(TypeProvider typeProvider, ASTNode
node) => this; |
| 769 | 1018 |
| 770 EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightO
perand) => rightOperand.bitAndError(node, this); | 1019 EvaluationResultImpl bitAnd(TypeProvider typeProvider, BinaryExpression node,
EvaluationResultImpl rightOperand) => rightOperand.bitAndError(node, this); |
| 771 | 1020 |
| 772 EvaluationResultImpl bitNot(Expression node) => this; | 1021 EvaluationResultImpl bitNot(TypeProvider typeProvider, Expression node) => thi
s; |
| 773 | 1022 |
| 774 EvaluationResultImpl bitOr(BinaryExpression node, EvaluationResultImpl rightOp
erand) => rightOperand.bitOrError(node, this); | 1023 EvaluationResultImpl bitOr(TypeProvider typeProvider, BinaryExpression node, E
valuationResultImpl rightOperand) => rightOperand.bitOrError(node, this); |
| 775 | 1024 |
| 776 EvaluationResultImpl bitXor(BinaryExpression node, EvaluationResultImpl rightO
perand) => rightOperand.bitXorError(node, this); | 1025 EvaluationResultImpl bitXor(TypeProvider typeProvider, BinaryExpression node,
EvaluationResultImpl rightOperand) => rightOperand.bitXorError(node, this); |
| 777 | 1026 |
| 778 EvaluationResultImpl concatenate(Expression node, EvaluationResultImpl rightOp
erand) => rightOperand.concatenateError(node, this); | 1027 EvaluationResultImpl concatenate(TypeProvider typeProvider, Expression node, E
valuationResultImpl rightOperand) => rightOperand.concatenateError(node, this); |
| 779 | 1028 |
| 780 EvaluationResultImpl divide(BinaryExpression node, EvaluationResultImpl rightO
perand) => rightOperand.divideError(node, this); | 1029 EvaluationResultImpl divide(TypeProvider typeProvider, BinaryExpression node,
EvaluationResultImpl rightOperand) => rightOperand.divideError(node, this); |
| 781 | 1030 |
| 782 EvaluationResultImpl equalEqual(Expression node, EvaluationResultImpl rightOpe
rand) => rightOperand.equalEqualError(node, this); | 1031 EvaluationResultImpl equalEqual(TypeProvider typeProvider, Expression node, Ev
aluationResultImpl rightOperand) => rightOperand.equalEqualError(node, this); |
| 783 | 1032 |
| 784 bool equalValues(EvaluationResultImpl result) => false; | 1033 bool equalValues(TypeProvider typeProvider, EvaluationResultImpl result) => fa
lse; |
| 785 | 1034 |
| 786 List<ErrorResult_ErrorData> get errorData => _errors; | 1035 List<ErrorResult_ErrorData> get errorData => _errors; |
| 787 | 1036 |
| 788 EvaluationResultImpl greaterThan(BinaryExpression node, EvaluationResultImpl r
ightOperand) => rightOperand.greaterThanError(node, this); | 1037 EvaluationResultImpl greaterThan(TypeProvider typeProvider, BinaryExpression n
ode, EvaluationResultImpl rightOperand) => rightOperand.greaterThanError(node, t
his); |
| 789 | 1038 |
| 790 EvaluationResultImpl greaterThanOrEqual(BinaryExpression node, EvaluationResul
tImpl rightOperand) => rightOperand.greaterThanOrEqualError(node, this); | 1039 EvaluationResultImpl greaterThanOrEqual(TypeProvider typeProvider, BinaryExpre
ssion node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanOrEqua
lError(node, this); |
| 791 | 1040 |
| 792 EvaluationResultImpl integerDivide(BinaryExpression node, EvaluationResultImpl
rightOperand) => rightOperand.integerDivideError(node, this); | 1041 EvaluationResultImpl integerDivide(TypeProvider typeProvider, BinaryExpression
node, EvaluationResultImpl rightOperand) => rightOperand.integerDivideError(nod
e, this); |
| 793 | 1042 |
| 794 EvaluationResultImpl integerDivideValid(BinaryExpression node, ValidResult lef
tOperand) => this; | 1043 EvaluationResultImpl integerDivideValid(TypeProvider typeProvider, BinaryExpre
ssion node, ValidResult leftOperand) => this; |
| 795 | 1044 |
| 796 EvaluationResultImpl lessThan(BinaryExpression node, EvaluationResultImpl righ
tOperand) => rightOperand.lessThanError(node, this); | 1045 EvaluationResultImpl lessThan(TypeProvider typeProvider, BinaryExpression node
, EvaluationResultImpl rightOperand) => rightOperand.lessThanError(node, this); |
| 797 | 1046 |
| 798 EvaluationResultImpl lessThanOrEqual(BinaryExpression node, EvaluationResultIm
pl rightOperand) => rightOperand.lessThanOrEqualError(node, this); | 1047 EvaluationResultImpl lessThanOrEqual(TypeProvider typeProvider, BinaryExpressi
on node, EvaluationResultImpl rightOperand) => rightOperand.lessThanOrEqualError
(node, this); |
| 799 | 1048 |
| 800 EvaluationResultImpl logicalAnd(BinaryExpression node, EvaluationResultImpl ri
ghtOperand) => rightOperand.logicalAndError(node, this); | 1049 EvaluationResultImpl logicalAnd(TypeProvider typeProvider, BinaryExpression no
de, EvaluationResultImpl rightOperand) => rightOperand.logicalAndError(node, thi
s); |
| 801 | 1050 |
| 802 EvaluationResultImpl logicalNot(Expression node) => this; | 1051 EvaluationResultImpl logicalNot(TypeProvider typeProvider, Expression node) =>
this; |
| 803 | 1052 |
| 804 EvaluationResultImpl logicalOr(BinaryExpression node, EvaluationResultImpl rig
htOperand) => rightOperand.logicalOrError(node, this); | 1053 EvaluationResultImpl logicalOr(TypeProvider typeProvider, BinaryExpression nod
e, EvaluationResultImpl rightOperand) => rightOperand.logicalOrError(node, this)
; |
| 805 | 1054 |
| 806 EvaluationResultImpl minus(BinaryExpression node, EvaluationResultImpl rightOp
erand) => rightOperand.minusError(node, this); | 1055 EvaluationResultImpl minus(TypeProvider typeProvider, BinaryExpression node, E
valuationResultImpl rightOperand) => rightOperand.minusError(node, this); |
| 807 | 1056 |
| 808 EvaluationResultImpl negated(Expression node) => this; | 1057 EvaluationResultImpl negated(TypeProvider typeProvider, Expression node) => th
is; |
| 809 | 1058 |
| 810 EvaluationResultImpl notEqual(BinaryExpression node, EvaluationResultImpl righ
tOperand) => rightOperand.notEqualError(node, this); | 1059 EvaluationResultImpl notEqual(TypeProvider typeProvider, BinaryExpression node
, EvaluationResultImpl rightOperand) => rightOperand.notEqualError(node, this); |
| 811 | 1060 |
| 812 EvaluationResultImpl performToString(ASTNode node) => this; | 1061 EvaluationResultImpl performToString(TypeProvider typeProvider, ASTNode node)
=> this; |
| 813 | 1062 |
| 814 EvaluationResultImpl remainder(BinaryExpression node, EvaluationResultImpl rig
htOperand) => rightOperand.remainderError(node, this); | 1063 EvaluationResultImpl remainder(TypeProvider typeProvider, BinaryExpression nod
e, EvaluationResultImpl rightOperand) => rightOperand.remainderError(node, this)
; |
| 815 | 1064 |
| 816 EvaluationResultImpl shiftLeft(BinaryExpression node, EvaluationResultImpl rig
htOperand) => rightOperand.shiftLeftError(node, this); | 1065 EvaluationResultImpl shiftLeft(TypeProvider typeProvider, BinaryExpression nod
e, EvaluationResultImpl rightOperand) => rightOperand.shiftLeftError(node, this)
; |
| 817 | 1066 |
| 818 EvaluationResultImpl shiftRight(BinaryExpression node, EvaluationResultImpl ri
ghtOperand) => rightOperand.shiftRightError(node, this); | 1067 EvaluationResultImpl shiftRight(TypeProvider typeProvider, BinaryExpression no
de, EvaluationResultImpl rightOperand) => rightOperand.shiftRightError(node, thi
s); |
| 819 | 1068 |
| 820 EvaluationResultImpl times(BinaryExpression node, EvaluationResultImpl rightOp
erand) => rightOperand.timesError(node, this); | 1069 EvaluationResultImpl times(TypeProvider typeProvider, BinaryExpression node, E
valuationResultImpl rightOperand) => rightOperand.timesError(node, this); |
| 821 | 1070 |
| 822 EvaluationResultImpl addToError(BinaryExpression node, ErrorResult leftOperand
) => new ErrorResult.con2(this, leftOperand); | 1071 EvaluationResultImpl addToError(BinaryExpression node, ErrorResult leftOperand
) => new ErrorResult.con2(this, leftOperand); |
| 823 | 1072 |
| 824 EvaluationResultImpl addToValid(BinaryExpression node, ValidResult leftOperand
) => this; | 1073 EvaluationResultImpl addToValid(TypeProvider typeProvider, BinaryExpression no
de, ValidResult leftOperand) => this; |
| 825 | 1074 |
| 826 EvaluationResultImpl bitAndError(BinaryExpression node, ErrorResult leftOperan
d) => new ErrorResult.con2(this, leftOperand); | 1075 EvaluationResultImpl bitAndError(BinaryExpression node, ErrorResult leftOperan
d) => new ErrorResult.con2(this, leftOperand); |
| 827 | 1076 |
| 828 EvaluationResultImpl bitAndValid(BinaryExpression node, ValidResult leftOperan
d) => this; | 1077 EvaluationResultImpl bitAndValid(TypeProvider typeProvider, BinaryExpression n
ode, ValidResult leftOperand) => this; |
| 829 | 1078 |
| 830 EvaluationResultImpl bitOrError(BinaryExpression node, ErrorResult leftOperand
) => new ErrorResult.con2(this, leftOperand); | 1079 EvaluationResultImpl bitOrError(BinaryExpression node, ErrorResult leftOperand
) => new ErrorResult.con2(this, leftOperand); |
| 831 | 1080 |
| 832 EvaluationResultImpl bitOrValid(BinaryExpression node, ValidResult leftOperand
) => this; | 1081 EvaluationResultImpl bitOrValid(TypeProvider typeProvider, BinaryExpression no
de, ValidResult leftOperand) => this; |
| 833 | 1082 |
| 834 EvaluationResultImpl bitXorError(BinaryExpression node, ErrorResult leftOperan
d) => new ErrorResult.con2(this, leftOperand); | 1083 EvaluationResultImpl bitXorError(BinaryExpression node, ErrorResult leftOperan
d) => new ErrorResult.con2(this, leftOperand); |
| 835 | 1084 |
| 836 EvaluationResultImpl bitXorValid(BinaryExpression node, ValidResult leftOperan
d) => this; | 1085 EvaluationResultImpl bitXorValid(TypeProvider typeProvider, BinaryExpression n
ode, ValidResult leftOperand) => this; |
| 837 | 1086 |
| 838 EvaluationResultImpl concatenateError(Expression node, ErrorResult leftOperand
) => new ErrorResult.con2(this, leftOperand); | 1087 EvaluationResultImpl concatenateError(Expression node, ErrorResult leftOperand
) => new ErrorResult.con2(this, leftOperand); |
| 839 | 1088 |
| 840 EvaluationResultImpl concatenateValid(Expression node, ValidResult leftOperand
) => this; | 1089 EvaluationResultImpl concatenateValid(TypeProvider typeProvider, Expression no
de, ValidResult leftOperand) => this; |
| 841 | 1090 |
| 842 EvaluationResultImpl divideError(BinaryExpression node, ErrorResult leftOperan
d) => new ErrorResult.con2(this, leftOperand); | 1091 EvaluationResultImpl divideError(BinaryExpression node, ErrorResult leftOperan
d) => new ErrorResult.con2(this, leftOperand); |
| 843 | 1092 |
| 844 EvaluationResultImpl divideValid(BinaryExpression node, ValidResult leftOperan
d) => this; | 1093 EvaluationResultImpl divideValid(TypeProvider typeProvider, BinaryExpression n
ode, ValidResult leftOperand) => this; |
| 845 | 1094 |
| 846 EvaluationResultImpl equalEqualError(Expression node, ErrorResult leftOperand)
=> new ErrorResult.con2(this, leftOperand); | 1095 EvaluationResultImpl equalEqualError(Expression node, ErrorResult leftOperand)
=> new ErrorResult.con2(this, leftOperand); |
| 847 | 1096 |
| 848 EvaluationResultImpl equalEqualValid(Expression node, ValidResult leftOperand)
=> this; | 1097 EvaluationResultImpl equalEqualValid(TypeProvider typeProvider, Expression nod
e, ValidResult leftOperand) => this; |
| 849 | 1098 |
| 850 EvaluationResultImpl greaterThanError(BinaryExpression node, ErrorResult leftO
perand) => new ErrorResult.con2(this, leftOperand); | 1099 EvaluationResultImpl greaterThanError(BinaryExpression node, ErrorResult leftO
perand) => new ErrorResult.con2(this, leftOperand); |
| 851 | 1100 |
| 852 EvaluationResultImpl greaterThanOrEqualError(BinaryExpression node, ErrorResul
t leftOperand) => new ErrorResult.con2(this, leftOperand); | 1101 EvaluationResultImpl greaterThanOrEqualError(BinaryExpression node, ErrorResul
t leftOperand) => new ErrorResult.con2(this, leftOperand); |
| 853 | 1102 |
| 854 EvaluationResultImpl greaterThanOrEqualValid(BinaryExpression node, ValidResul
t leftOperand) => this; | 1103 EvaluationResultImpl greaterThanOrEqualValid(TypeProvider typeProvider, Binary
Expression node, ValidResult leftOperand) => this; |
| 855 | 1104 |
| 856 EvaluationResultImpl greaterThanValid(BinaryExpression node, ValidResult leftO
perand) => this; | 1105 EvaluationResultImpl greaterThanValid(TypeProvider typeProvider, BinaryExpress
ion node, ValidResult leftOperand) => this; |
| 857 | 1106 |
| 858 EvaluationResultImpl integerDivideError(BinaryExpression node, ErrorResult lef
tOperand) => new ErrorResult.con2(this, leftOperand); | 1107 EvaluationResultImpl integerDivideError(BinaryExpression node, ErrorResult lef
tOperand) => new ErrorResult.con2(this, leftOperand); |
| 859 | 1108 |
| 860 EvaluationResultImpl lessThanError(BinaryExpression node, ErrorResult leftOper
and) => new ErrorResult.con2(this, leftOperand); | 1109 EvaluationResultImpl lessThanError(BinaryExpression node, ErrorResult leftOper
and) => new ErrorResult.con2(this, leftOperand); |
| 861 | 1110 |
| 862 EvaluationResultImpl lessThanOrEqualError(BinaryExpression node, ErrorResult l
eftOperand) => new ErrorResult.con2(this, leftOperand); | 1111 EvaluationResultImpl lessThanOrEqualError(BinaryExpression node, ErrorResult l
eftOperand) => new ErrorResult.con2(this, leftOperand); |
| 863 | 1112 |
| 864 EvaluationResultImpl lessThanOrEqualValid(BinaryExpression node, ValidResult l
eftOperand) => this; | 1113 EvaluationResultImpl lessThanOrEqualValid(TypeProvider typeProvider, BinaryExp
ression node, ValidResult leftOperand) => this; |
| 865 | 1114 |
| 866 EvaluationResultImpl lessThanValid(BinaryExpression node, ValidResult leftOper
and) => this; | 1115 EvaluationResultImpl lessThanValid(TypeProvider typeProvider, BinaryExpression
node, ValidResult leftOperand) => this; |
| 867 | 1116 |
| 868 EvaluationResultImpl logicalAndError(BinaryExpression node, ErrorResult leftOp
erand) => new ErrorResult.con2(this, leftOperand); | 1117 EvaluationResultImpl logicalAndError(BinaryExpression node, ErrorResult leftOp
erand) => new ErrorResult.con2(this, leftOperand); |
| 869 | 1118 |
| 870 EvaluationResultImpl logicalAndValid(BinaryExpression node, ValidResult leftOp
erand) => this; | 1119 EvaluationResultImpl logicalAndValid(TypeProvider typeProvider, BinaryExpressi
on node, ValidResult leftOperand) => this; |
| 871 | 1120 |
| 872 EvaluationResultImpl logicalOrError(BinaryExpression node, ErrorResult leftOpe
rand) => new ErrorResult.con2(this, leftOperand); | 1121 EvaluationResultImpl logicalOrError(BinaryExpression node, ErrorResult leftOpe
rand) => new ErrorResult.con2(this, leftOperand); |
| 873 | 1122 |
| 874 EvaluationResultImpl logicalOrValid(BinaryExpression node, ValidResult leftOpe
rand) => this; | 1123 EvaluationResultImpl logicalOrValid(TypeProvider typeProvider, BinaryExpressio
n node, ValidResult leftOperand) => this; |
| 875 | 1124 |
| 876 EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand
) => new ErrorResult.con2(this, leftOperand); | 1125 EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand
) => new ErrorResult.con2(this, leftOperand); |
| 877 | 1126 |
| 878 EvaluationResultImpl minusValid(BinaryExpression node, ValidResult leftOperand
) => this; | 1127 EvaluationResultImpl minusValid(TypeProvider typeProvider, BinaryExpression no
de, ValidResult leftOperand) => this; |
| 879 | 1128 |
| 880 EvaluationResultImpl notEqualError(BinaryExpression node, ErrorResult leftOper
and) => new ErrorResult.con2(this, leftOperand); | 1129 EvaluationResultImpl notEqualError(BinaryExpression node, ErrorResult leftOper
and) => new ErrorResult.con2(this, leftOperand); |
| 881 | 1130 |
| 882 EvaluationResultImpl notEqualValid(BinaryExpression node, ValidResult leftOper
and) => this; | 1131 EvaluationResultImpl notEqualValid(TypeProvider typeProvider, BinaryExpression
node, ValidResult leftOperand) => this; |
| 883 | 1132 |
| 884 EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOpe
rand) => new ErrorResult.con2(this, leftOperand); | 1133 EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOpe
rand) => new ErrorResult.con2(this, leftOperand); |
| 885 | 1134 |
| 886 EvaluationResultImpl remainderValid(BinaryExpression node, ValidResult leftOpe
rand) => this; | 1135 EvaluationResultImpl remainderValid(TypeProvider typeProvider, BinaryExpressio
n node, ValidResult leftOperand) => this; |
| 887 | 1136 |
| 888 EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOpe
rand) => new ErrorResult.con2(this, leftOperand); | 1137 EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOpe
rand) => new ErrorResult.con2(this, leftOperand); |
| 889 | 1138 |
| 890 EvaluationResultImpl shiftLeftValid(BinaryExpression node, ValidResult leftOpe
rand) => this; | 1139 EvaluationResultImpl shiftLeftValid(TypeProvider typeProvider, BinaryExpressio
n node, ValidResult leftOperand) => this; |
| 891 | 1140 |
| 892 EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOp
erand) => new ErrorResult.con2(this, leftOperand); | 1141 EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOp
erand) => new ErrorResult.con2(this, leftOperand); |
| 893 | 1142 |
| 894 EvaluationResultImpl shiftRightValid(BinaryExpression node, ValidResult leftOp
erand) => this; | 1143 EvaluationResultImpl shiftRightValid(TypeProvider typeProvider, BinaryExpressi
on node, ValidResult leftOperand) => this; |
| 895 | 1144 |
| 896 EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand
) => new ErrorResult.con2(this, leftOperand); | 1145 EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand
) => new ErrorResult.con2(this, leftOperand); |
| 897 | 1146 |
| 898 EvaluationResultImpl timesValid(BinaryExpression node, ValidResult leftOperand
) => this; | 1147 EvaluationResultImpl timesValid(TypeProvider typeProvider, BinaryExpression no
de, ValidResult leftOperand) => this; |
| 899 } | 1148 } |
| 900 | 1149 |
| 901 class ErrorResult_ErrorData { | 1150 class ErrorResult_ErrorData { |
| 902 /** | 1151 /** |
| 903 * The node against which the error should be reported. | 1152 * The node against which the error should be reported. |
| 904 */ | 1153 */ |
| 905 final ASTNode node; | 1154 final ASTNode node; |
| 906 | 1155 |
| 907 /** | 1156 /** |
| 908 * The error code for the error to be generated. | 1157 * The error code for the error to be generated. |
| 909 */ | 1158 */ |
| 910 final ErrorCode errorCode; | 1159 final ErrorCode errorCode; |
| 911 | 1160 |
| 912 /** | 1161 /** |
| 913 * Initialize a newly created data holder to represent the error with the give
n code reported | 1162 * Initialize a newly created data holder to represent the error with the give
n code reported |
| 914 * against the given node. | 1163 * against the given node. |
| 915 * | 1164 * |
| 916 * @param node the node against which the error should be reported | 1165 * @param node the node against which the error should be reported |
| 917 * @param errorCode the error code for the error to be generated | 1166 * @param errorCode the error code for the error to be generated |
| 918 */ | 1167 */ |
| 919 ErrorResult_ErrorData(this.node, this.errorCode); | 1168 ErrorResult_ErrorData(this.node, this.errorCode); |
| 920 } | 1169 } |
| 921 | 1170 |
| 922 /** | 1171 /** |
| 923 * Instances of the class `InternalResult` represent the result of attempting to
evaluate a | 1172 * Instances of the class `InternalResult` represent the result of attempting to
evaluate a |
| 924 * expression. | 1173 * expression. |
| 925 */ | 1174 */ |
| 926 abstract class EvaluationResultImpl { | 1175 abstract class EvaluationResultImpl { |
| 927 EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOper
and); | 1176 EvaluationResultImpl add(TypeProvider typeProvider, BinaryExpression node, Eva
luationResultImpl rightOperand); |
| 928 | 1177 |
| 929 /** | 1178 /** |
| 930 * Return the result of applying boolean conversion to this result. | 1179 * Return the result of applying boolean conversion to this result. |
| 931 * | 1180 * |
| 1181 * @param typeProvider the type provider used to access known types |
| 932 * @param node the node against which errors should be reported | 1182 * @param node the node against which errors should be reported |
| 933 * @return the result of applying boolean conversion to the given value | 1183 * @return the result of applying boolean conversion to the given value |
| 934 */ | 1184 */ |
| 935 EvaluationResultImpl applyBooleanConversion(ASTNode node); | 1185 EvaluationResultImpl applyBooleanConversion(TypeProvider typeProvider, ASTNode
node); |
| 936 | 1186 |
| 937 EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightO
perand); | 1187 EvaluationResultImpl bitAnd(TypeProvider typeProvider, BinaryExpression node,
EvaluationResultImpl rightOperand); |
| 938 | 1188 |
| 939 EvaluationResultImpl bitNot(Expression node); | 1189 EvaluationResultImpl bitNot(TypeProvider typeProvider, Expression node); |
| 940 | 1190 |
| 941 EvaluationResultImpl bitOr(BinaryExpression node, EvaluationResultImpl rightOp
erand); | 1191 EvaluationResultImpl bitOr(TypeProvider typeProvider, BinaryExpression node, E
valuationResultImpl rightOperand); |
| 942 | 1192 |
| 943 EvaluationResultImpl bitXor(BinaryExpression node, EvaluationResultImpl rightO
perand); | 1193 EvaluationResultImpl bitXor(TypeProvider typeProvider, BinaryExpression node,
EvaluationResultImpl rightOperand); |
| 944 | 1194 |
| 945 EvaluationResultImpl concatenate(Expression node, EvaluationResultImpl rightOp
erand); | 1195 EvaluationResultImpl concatenate(TypeProvider typeProvider, Expression node, E
valuationResultImpl rightOperand); |
| 946 | 1196 |
| 947 EvaluationResultImpl divide(BinaryExpression node, EvaluationResultImpl rightO
perand); | 1197 EvaluationResultImpl divide(TypeProvider typeProvider, BinaryExpression node,
EvaluationResultImpl rightOperand); |
| 948 | 1198 |
| 949 EvaluationResultImpl equalEqual(Expression node, EvaluationResultImpl rightOpe
rand); | 1199 EvaluationResultImpl equalEqual(TypeProvider typeProvider, Expression node, Ev
aluationResultImpl rightOperand); |
| 950 | 1200 |
| 951 bool equalValues(EvaluationResultImpl result); | 1201 bool equalValues(TypeProvider typeProvider, EvaluationResultImpl result); |
| 952 | 1202 |
| 953 EvaluationResultImpl greaterThan(BinaryExpression node, EvaluationResultImpl r
ightOperand); | 1203 EvaluationResultImpl greaterThan(TypeProvider typeProvider, BinaryExpression n
ode, EvaluationResultImpl rightOperand); |
| 954 | 1204 |
| 955 EvaluationResultImpl greaterThanOrEqual(BinaryExpression node, EvaluationResul
tImpl rightOperand); | 1205 EvaluationResultImpl greaterThanOrEqual(TypeProvider typeProvider, BinaryExpre
ssion node, EvaluationResultImpl rightOperand); |
| 956 | 1206 |
| 957 EvaluationResultImpl integerDivide(BinaryExpression node, EvaluationResultImpl
rightOperand); | 1207 EvaluationResultImpl integerDivide(TypeProvider typeProvider, BinaryExpression
node, EvaluationResultImpl rightOperand); |
| 958 | 1208 |
| 959 EvaluationResultImpl lessThan(BinaryExpression node, EvaluationResultImpl righ
tOperand); | 1209 EvaluationResultImpl lessThan(TypeProvider typeProvider, BinaryExpression node
, EvaluationResultImpl rightOperand); |
| 960 | 1210 |
| 961 EvaluationResultImpl lessThanOrEqual(BinaryExpression node, EvaluationResultIm
pl rightOperand); | 1211 EvaluationResultImpl lessThanOrEqual(TypeProvider typeProvider, BinaryExpressi
on node, EvaluationResultImpl rightOperand); |
| 962 | 1212 |
| 963 EvaluationResultImpl logicalAnd(BinaryExpression node, EvaluationResultImpl ri
ghtOperand); | 1213 EvaluationResultImpl logicalAnd(TypeProvider typeProvider, BinaryExpression no
de, EvaluationResultImpl rightOperand); |
| 964 | 1214 |
| 965 EvaluationResultImpl logicalNot(Expression node); | 1215 EvaluationResultImpl logicalNot(TypeProvider typeProvider, Expression node); |
| 966 | 1216 |
| 967 EvaluationResultImpl logicalOr(BinaryExpression node, EvaluationResultImpl rig
htOperand); | 1217 EvaluationResultImpl logicalOr(TypeProvider typeProvider, BinaryExpression nod
e, EvaluationResultImpl rightOperand); |
| 968 | 1218 |
| 969 EvaluationResultImpl minus(BinaryExpression node, EvaluationResultImpl rightOp
erand); | 1219 EvaluationResultImpl minus(TypeProvider typeProvider, BinaryExpression node, E
valuationResultImpl rightOperand); |
| 970 | 1220 |
| 971 EvaluationResultImpl negated(Expression node); | 1221 EvaluationResultImpl negated(TypeProvider typeProvider, Expression node); |
| 972 | 1222 |
| 973 EvaluationResultImpl notEqual(BinaryExpression node, EvaluationResultImpl righ
tOperand); | 1223 EvaluationResultImpl notEqual(TypeProvider typeProvider, BinaryExpression node
, EvaluationResultImpl rightOperand); |
| 974 | 1224 |
| 975 EvaluationResultImpl performToString(ASTNode node); | 1225 EvaluationResultImpl performToString(TypeProvider typeProvider, ASTNode node); |
| 976 | 1226 |
| 977 EvaluationResultImpl remainder(BinaryExpression node, EvaluationResultImpl rig
htOperand); | 1227 EvaluationResultImpl remainder(TypeProvider typeProvider, BinaryExpression nod
e, EvaluationResultImpl rightOperand); |
| 978 | 1228 |
| 979 EvaluationResultImpl shiftLeft(BinaryExpression node, EvaluationResultImpl rig
htOperand); | 1229 EvaluationResultImpl shiftLeft(TypeProvider typeProvider, BinaryExpression nod
e, EvaluationResultImpl rightOperand); |
| 980 | 1230 |
| 981 EvaluationResultImpl shiftRight(BinaryExpression node, EvaluationResultImpl ri
ghtOperand); | 1231 EvaluationResultImpl shiftRight(TypeProvider typeProvider, BinaryExpression no
de, EvaluationResultImpl rightOperand); |
| 982 | 1232 |
| 983 EvaluationResultImpl times(BinaryExpression node, EvaluationResultImpl rightOp
erand); | 1233 EvaluationResultImpl times(TypeProvider typeProvider, BinaryExpression node, E
valuationResultImpl rightOperand); |
| 984 | 1234 |
| 985 EvaluationResultImpl addToError(BinaryExpression node, ErrorResult leftOperand
); | 1235 EvaluationResultImpl addToError(BinaryExpression node, ErrorResult leftOperand
); |
| 986 | 1236 |
| 987 EvaluationResultImpl addToValid(BinaryExpression node, ValidResult leftOperand
); | 1237 EvaluationResultImpl addToValid(TypeProvider typeProvider, BinaryExpression no
de, ValidResult leftOperand); |
| 988 | 1238 |
| 989 EvaluationResultImpl bitAndError(BinaryExpression node, ErrorResult leftOperan
d); | 1239 EvaluationResultImpl bitAndError(BinaryExpression node, ErrorResult leftOperan
d); |
| 990 | 1240 |
| 991 EvaluationResultImpl bitAndValid(BinaryExpression node, ValidResult leftOperan
d); | 1241 EvaluationResultImpl bitAndValid(TypeProvider typeProvider, BinaryExpression n
ode, ValidResult leftOperand); |
| 992 | 1242 |
| 993 EvaluationResultImpl bitOrError(BinaryExpression node, ErrorResult leftOperand
); | 1243 EvaluationResultImpl bitOrError(BinaryExpression node, ErrorResult leftOperand
); |
| 994 | 1244 |
| 995 EvaluationResultImpl bitOrValid(BinaryExpression node, ValidResult leftOperand
); | 1245 EvaluationResultImpl bitOrValid(TypeProvider typeProvider, BinaryExpression no
de, ValidResult leftOperand); |
| 996 | 1246 |
| 997 EvaluationResultImpl bitXorError(BinaryExpression node, ErrorResult leftOperan
d); | 1247 EvaluationResultImpl bitXorError(BinaryExpression node, ErrorResult leftOperan
d); |
| 998 | 1248 |
| 999 EvaluationResultImpl bitXorValid(BinaryExpression node, ValidResult leftOperan
d); | 1249 EvaluationResultImpl bitXorValid(TypeProvider typeProvider, BinaryExpression n
ode, ValidResult leftOperand); |
| 1000 | 1250 |
| 1001 EvaluationResultImpl concatenateError(Expression node, ErrorResult leftOperand
); | 1251 EvaluationResultImpl concatenateError(Expression node, ErrorResult leftOperand
); |
| 1002 | 1252 |
| 1003 EvaluationResultImpl concatenateValid(Expression node, ValidResult leftOperand
); | 1253 EvaluationResultImpl concatenateValid(TypeProvider typeProvider, Expression no
de, ValidResult leftOperand); |
| 1004 | 1254 |
| 1005 EvaluationResultImpl divideError(BinaryExpression node, ErrorResult leftOperan
d); | 1255 EvaluationResultImpl divideError(BinaryExpression node, ErrorResult leftOperan
d); |
| 1006 | 1256 |
| 1007 EvaluationResultImpl divideValid(BinaryExpression node, ValidResult leftOperan
d); | 1257 EvaluationResultImpl divideValid(TypeProvider typeProvider, BinaryExpression n
ode, ValidResult leftOperand); |
| 1008 | 1258 |
| 1009 EvaluationResultImpl equalEqualError(Expression node, ErrorResult leftOperand)
; | 1259 EvaluationResultImpl equalEqualError(Expression node, ErrorResult leftOperand)
; |
| 1010 | 1260 |
| 1011 EvaluationResultImpl equalEqualValid(Expression node, ValidResult leftOperand)
; | 1261 EvaluationResultImpl equalEqualValid(TypeProvider typeProvider, Expression nod
e, ValidResult leftOperand); |
| 1012 | 1262 |
| 1013 EvaluationResultImpl greaterThanError(BinaryExpression node, ErrorResult leftO
perand); | 1263 EvaluationResultImpl greaterThanError(BinaryExpression node, ErrorResult leftO
perand); |
| 1014 | 1264 |
| 1015 EvaluationResultImpl greaterThanOrEqualError(BinaryExpression node, ErrorResul
t leftOperand); | 1265 EvaluationResultImpl greaterThanOrEqualError(BinaryExpression node, ErrorResul
t leftOperand); |
| 1016 | 1266 |
| 1017 EvaluationResultImpl greaterThanOrEqualValid(BinaryExpression node, ValidResul
t leftOperand); | 1267 EvaluationResultImpl greaterThanOrEqualValid(TypeProvider typeProvider, Binary
Expression node, ValidResult leftOperand); |
| 1018 | 1268 |
| 1019 EvaluationResultImpl greaterThanValid(BinaryExpression node, ValidResult leftO
perand); | 1269 EvaluationResultImpl greaterThanValid(TypeProvider typeProvider, BinaryExpress
ion node, ValidResult leftOperand); |
| 1020 | 1270 |
| 1021 EvaluationResultImpl integerDivideError(BinaryExpression node, ErrorResult lef
tOperand); | 1271 EvaluationResultImpl integerDivideError(BinaryExpression node, ErrorResult lef
tOperand); |
| 1022 | 1272 |
| 1023 EvaluationResultImpl integerDivideValid(BinaryExpression node, ValidResult lef
tOperand); | 1273 EvaluationResultImpl integerDivideValid(TypeProvider typeProvider, BinaryExpre
ssion node, ValidResult leftOperand); |
| 1024 | 1274 |
| 1025 EvaluationResultImpl lessThanError(BinaryExpression node, ErrorResult leftOper
and); | 1275 EvaluationResultImpl lessThanError(BinaryExpression node, ErrorResult leftOper
and); |
| 1026 | 1276 |
| 1027 EvaluationResultImpl lessThanOrEqualError(BinaryExpression node, ErrorResult l
eftOperand); | 1277 EvaluationResultImpl lessThanOrEqualError(BinaryExpression node, ErrorResult l
eftOperand); |
| 1028 | 1278 |
| 1029 EvaluationResultImpl lessThanOrEqualValid(BinaryExpression node, ValidResult l
eftOperand); | 1279 EvaluationResultImpl lessThanOrEqualValid(TypeProvider typeProvider, BinaryExp
ression node, ValidResult leftOperand); |
| 1030 | 1280 |
| 1031 EvaluationResultImpl lessThanValid(BinaryExpression node, ValidResult leftOper
and); | 1281 EvaluationResultImpl lessThanValid(TypeProvider typeProvider, BinaryExpression
node, ValidResult leftOperand); |
| 1032 | 1282 |
| 1033 EvaluationResultImpl logicalAndError(BinaryExpression node, ErrorResult leftOp
erand); | 1283 EvaluationResultImpl logicalAndError(BinaryExpression node, ErrorResult leftOp
erand); |
| 1034 | 1284 |
| 1035 EvaluationResultImpl logicalAndValid(BinaryExpression node, ValidResult leftOp
erand); | 1285 EvaluationResultImpl logicalAndValid(TypeProvider typeProvider, BinaryExpressi
on node, ValidResult leftOperand); |
| 1036 | 1286 |
| 1037 EvaluationResultImpl logicalOrError(BinaryExpression node, ErrorResult leftOpe
rand); | 1287 EvaluationResultImpl logicalOrError(BinaryExpression node, ErrorResult leftOpe
rand); |
| 1038 | 1288 |
| 1039 EvaluationResultImpl logicalOrValid(BinaryExpression node, ValidResult leftOpe
rand); | 1289 EvaluationResultImpl logicalOrValid(TypeProvider typeProvider, BinaryExpressio
n node, ValidResult leftOperand); |
| 1040 | 1290 |
| 1041 EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand
); | 1291 EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand
); |
| 1042 | 1292 |
| 1043 EvaluationResultImpl minusValid(BinaryExpression node, ValidResult leftOperand
); | 1293 EvaluationResultImpl minusValid(TypeProvider typeProvider, BinaryExpression no
de, ValidResult leftOperand); |
| 1044 | 1294 |
| 1045 EvaluationResultImpl notEqualError(BinaryExpression node, ErrorResult leftOper
and); | 1295 EvaluationResultImpl notEqualError(BinaryExpression node, ErrorResult leftOper
and); |
| 1046 | 1296 |
| 1047 EvaluationResultImpl notEqualValid(BinaryExpression node, ValidResult leftOper
and); | 1297 EvaluationResultImpl notEqualValid(TypeProvider typeProvider, BinaryExpression
node, ValidResult leftOperand); |
| 1048 | 1298 |
| 1049 EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOpe
rand); | 1299 EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOpe
rand); |
| 1050 | 1300 |
| 1051 EvaluationResultImpl remainderValid(BinaryExpression node, ValidResult leftOpe
rand); | 1301 EvaluationResultImpl remainderValid(TypeProvider typeProvider, BinaryExpressio
n node, ValidResult leftOperand); |
| 1052 | 1302 |
| 1053 EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOpe
rand); | 1303 EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOpe
rand); |
| 1054 | 1304 |
| 1055 EvaluationResultImpl shiftLeftValid(BinaryExpression node, ValidResult leftOpe
rand); | 1305 EvaluationResultImpl shiftLeftValid(TypeProvider typeProvider, BinaryExpressio
n node, ValidResult leftOperand); |
| 1056 | 1306 |
| 1057 EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOp
erand); | 1307 EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOp
erand); |
| 1058 | 1308 |
| 1059 EvaluationResultImpl shiftRightValid(BinaryExpression node, ValidResult leftOp
erand); | 1309 EvaluationResultImpl shiftRightValid(TypeProvider typeProvider, BinaryExpressi
on node, ValidResult leftOperand); |
| 1060 | 1310 |
| 1061 EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand
); | 1311 EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand
); |
| 1062 | 1312 |
| 1063 EvaluationResultImpl timesValid(BinaryExpression node, ValidResult leftOperand
); | 1313 EvaluationResultImpl timesValid(TypeProvider typeProvider, BinaryExpression no
de, ValidResult leftOperand); |
| 1064 } | 1314 } |
| 1065 | 1315 |
| 1066 /** | 1316 /** |
| 1067 * Instances of the class `ReferenceFinder` add reference information for a give
n variable to | 1317 * Instances of the class `ReferenceFinder` add reference information for a give
n variable to |
| 1068 * the bi-directional mapping used to order the evaluation of constants. | 1318 * the bi-directional mapping used to order the evaluation of constants. |
| 1069 */ | 1319 */ |
| 1070 class ReferenceFinder extends RecursiveASTVisitor<Object> { | 1320 class ReferenceFinder extends RecursiveASTVisitor<Object> { |
| 1071 /** | 1321 /** |
| 1072 * The element representing the variable whose initializer will be visited. | 1322 * The element representing the variable whose initializer will be visited. |
| 1073 */ | 1323 */ |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1106 return null; | 1356 return null; |
| 1107 } | 1357 } |
| 1108 } | 1358 } |
| 1109 | 1359 |
| 1110 /** | 1360 /** |
| 1111 * Instances of the class `ValidResult` represent the result of attempting to ev
aluate a valid | 1361 * Instances of the class `ValidResult` represent the result of attempting to ev
aluate a valid |
| 1112 * compile time constant expression. | 1362 * compile time constant expression. |
| 1113 */ | 1363 */ |
| 1114 class ValidResult extends EvaluationResultImpl { | 1364 class ValidResult extends EvaluationResultImpl { |
| 1115 /** | 1365 /** |
| 1116 * A result object representing the value 'false'. | |
| 1117 */ | |
| 1118 static ValidResult RESULT_FALSE = new ValidResult(false); | |
| 1119 | |
| 1120 /** | |
| 1121 * A result object representing the an object without specific type on which n
o further operations | |
| 1122 * can be performed. | |
| 1123 */ | |
| 1124 static ValidResult RESULT_DYNAMIC = new ValidResult(null); | |
| 1125 | |
| 1126 /** | |
| 1127 * A result object representing the an arbitrary integer on which no further o
perations can be | |
| 1128 * performed. | |
| 1129 */ | |
| 1130 static ValidResult RESULT_INT = new ValidResult(0); | |
| 1131 | |
| 1132 /** | |
| 1133 * A result object representing the `null` value. | |
| 1134 */ | |
| 1135 static ValidResult RESULT_NULL = new ValidResult(null); | |
| 1136 | |
| 1137 /** | |
| 1138 * A result object representing the an arbitrary numeric on which no further o
perations can be | |
| 1139 * performed. | |
| 1140 */ | |
| 1141 static ValidResult RESULT_NUM = new ValidResult(null); | |
| 1142 | |
| 1143 /** | |
| 1144 * A result object representing the an arbitrary boolean on which no further o
perations can be | |
| 1145 * performed. | |
| 1146 */ | |
| 1147 static ValidResult RESULT_BOOL = new ValidResult(null); | |
| 1148 | |
| 1149 /** | |
| 1150 * A result object representing the an arbitrary object on which no further op
erations can be | |
| 1151 * performed. | |
| 1152 */ | |
| 1153 static ValidResult RESULT_OBJECT = new ValidResult(new Object()); | |
| 1154 | |
| 1155 /** | |
| 1156 * A result object representing the an arbitrary symbol on which no further op
erations can be | |
| 1157 * performed. | |
| 1158 */ | |
| 1159 static ValidResult RESULT_SYMBOL = new ValidResult(new Object()); | |
| 1160 | |
| 1161 /** | |
| 1162 * A result object representing the an arbitrary string on which no further op
erations can be | |
| 1163 * performed. | |
| 1164 */ | |
| 1165 static ValidResult RESULT_STRING = new ValidResult("<string>"); | |
| 1166 | |
| 1167 /** | |
| 1168 * A result object representing the value 'true'. | |
| 1169 */ | |
| 1170 static ValidResult RESULT_TRUE = new ValidResult(true); | |
| 1171 | |
| 1172 /** | |
| 1173 * The value of the expression. | 1366 * The value of the expression. |
| 1174 */ | 1367 */ |
| 1175 final Object value; | 1368 final DartObjectImpl value; |
| 1176 | 1369 |
| 1177 /** | 1370 /** |
| 1178 * Initialize a newly created result to represent the given value. | 1371 * Initialize a newly created result to represent the given value. |
| 1179 * | 1372 * |
| 1180 * @param value the value of the expression | 1373 * @param value the value of the expression |
| 1181 */ | 1374 */ |
| 1182 ValidResult(this.value); | 1375 ValidResult(this.value); |
| 1183 | 1376 |
| 1184 EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOper
and) => rightOperand.addToValid(node, this); | 1377 EvaluationResultImpl add(TypeProvider typeProvider, BinaryExpression node, Eva
luationResultImpl rightOperand) => rightOperand.addToValid(typeProvider, node, t
his); |
| 1185 | 1378 |
| 1186 /** | 1379 /** |
| 1187 * Return the result of applying boolean conversion to this result. | 1380 * Return the result of applying boolean conversion to this result. |
| 1188 * | 1381 * |
| 1189 * @param node the node against which errors should be reported | 1382 * @param node the node against which errors should be reported |
| 1190 * @return the result of applying boolean conversion to the given value | 1383 * @return the result of applying boolean conversion to the given value |
| 1191 */ | 1384 */ |
| 1192 EvaluationResultImpl applyBooleanConversion(ASTNode node) => booleanConversion
(node, value); | 1385 EvaluationResultImpl applyBooleanConversion(TypeProvider typeProvider, ASTNode
node) { |
| 1193 | 1386 try { |
| 1194 EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightO
perand) => rightOperand.bitAndValid(node, this); | 1387 return valueOf(value.convertToBool(typeProvider)); |
| 1195 | 1388 } on EvaluationException catch (exception) { |
| 1196 EvaluationResultImpl bitNot(Expression node) { | 1389 return error(node, exception.errorCode); |
| 1197 if (isSomeInt) { | |
| 1198 return RESULT_INT; | |
| 1199 } | 1390 } |
| 1200 if (value == null) { | |
| 1201 return error(node); | |
| 1202 } else if (value is int) { | |
| 1203 return valueOf(~(value as int)); | |
| 1204 } | |
| 1205 return error(node); | |
| 1206 } | 1391 } |
| 1207 | 1392 |
| 1208 EvaluationResultImpl bitOr(BinaryExpression node, EvaluationResultImpl rightOp
erand) => rightOperand.bitOrValid(node, this); | 1393 EvaluationResultImpl bitAnd(TypeProvider typeProvider, BinaryExpression node,
EvaluationResultImpl rightOperand) => rightOperand.bitAndValid(typeProvider, nod
e, this); |
| 1209 | 1394 |
| 1210 EvaluationResultImpl bitXor(BinaryExpression node, EvaluationResultImpl rightO
perand) => rightOperand.bitXorValid(node, this); | 1395 EvaluationResultImpl bitNot(TypeProvider typeProvider, Expression node) { |
| 1211 | 1396 try { |
| 1212 EvaluationResultImpl concatenate(Expression node, EvaluationResultImpl rightOp
erand) => rightOperand.concatenateValid(node, this); | 1397 return valueOf(value.bitNot(typeProvider)); |
| 1213 | 1398 } on EvaluationException catch (exception) { |
| 1214 EvaluationResultImpl divide(BinaryExpression node, EvaluationResultImpl rightO
perand) => rightOperand.divideValid(node, this); | 1399 return error(node, exception.errorCode); |
| 1215 | |
| 1216 EvaluationResultImpl equalEqual(Expression node, EvaluationResultImpl rightOpe
rand) => rightOperand.equalEqualValid(node, this); | |
| 1217 | |
| 1218 bool equalValues(EvaluationResultImpl result) => identical(equalEqual(null, re
sult), RESULT_TRUE); | |
| 1219 | |
| 1220 EvaluationResultImpl greaterThan(BinaryExpression node, EvaluationResultImpl r
ightOperand) => rightOperand.greaterThanValid(node, this); | |
| 1221 | |
| 1222 EvaluationResultImpl greaterThanOrEqual(BinaryExpression node, EvaluationResul
tImpl rightOperand) => rightOperand.greaterThanOrEqualValid(node, this); | |
| 1223 | |
| 1224 EvaluationResultImpl integerDivide(BinaryExpression node, EvaluationResultImpl
rightOperand) => rightOperand.integerDivideValid(node, this); | |
| 1225 | |
| 1226 EvaluationResultImpl lessThan(BinaryExpression node, EvaluationResultImpl righ
tOperand) => rightOperand.lessThanValid(node, this); | |
| 1227 | |
| 1228 EvaluationResultImpl lessThanOrEqual(BinaryExpression node, EvaluationResultIm
pl rightOperand) => rightOperand.lessThanOrEqualValid(node, this); | |
| 1229 | |
| 1230 EvaluationResultImpl logicalAnd(BinaryExpression node, EvaluationResultImpl ri
ghtOperand) => rightOperand.logicalAndValid(node, this); | |
| 1231 | |
| 1232 EvaluationResultImpl logicalNot(Expression node) { | |
| 1233 if (isSomeBool) { | |
| 1234 return RESULT_BOOL; | |
| 1235 } | 1400 } |
| 1236 if (value == null) { | |
| 1237 return RESULT_TRUE; | |
| 1238 } else if (value is bool) { | |
| 1239 return (value as bool) ? RESULT_FALSE : RESULT_TRUE; | |
| 1240 } | |
| 1241 return error(node); | |
| 1242 } | 1401 } |
| 1243 | 1402 |
| 1244 EvaluationResultImpl logicalOr(BinaryExpression node, EvaluationResultImpl rig
htOperand) => rightOperand.logicalOrValid(node, this); | 1403 EvaluationResultImpl bitOr(TypeProvider typeProvider, BinaryExpression node, E
valuationResultImpl rightOperand) => rightOperand.bitOrValid(typeProvider, node,
this); |
| 1245 | 1404 |
| 1246 EvaluationResultImpl minus(BinaryExpression node, EvaluationResultImpl rightOp
erand) => rightOperand.minusValid(node, this); | 1405 EvaluationResultImpl bitXor(TypeProvider typeProvider, BinaryExpression node,
EvaluationResultImpl rightOperand) => rightOperand.bitXorValid(typeProvider, nod
e, this); |
| 1247 | 1406 |
| 1248 EvaluationResultImpl negated(Expression node) { | 1407 EvaluationResultImpl concatenate(TypeProvider typeProvider, Expression node, E
valuationResultImpl rightOperand) => rightOperand.concatenateValid(typeProvider,
node, this); |
| 1249 if (isSomeNum) { | 1408 |
| 1250 return RESULT_INT; | 1409 EvaluationResultImpl divide(TypeProvider typeProvider, BinaryExpression node,
EvaluationResultImpl rightOperand) => rightOperand.divideValid(typeProvider, nod
e, this); |
| 1410 |
| 1411 EvaluationResultImpl equalEqual(TypeProvider typeProvider, Expression node, Ev
aluationResultImpl rightOperand) => rightOperand.equalEqualValid(typeProvider, n
ode, this); |
| 1412 |
| 1413 bool equalValues(TypeProvider typeProvider, EvaluationResultImpl result) { |
| 1414 if (result is! ValidResult) { |
| 1415 return false; |
| 1251 } | 1416 } |
| 1252 if (value == null) { | 1417 return value == (result as ValidResult).value; |
| 1253 return error(node); | |
| 1254 } else if (value is int) { | |
| 1255 return valueOf(-(value as int)); | |
| 1256 } else if (value is double) { | |
| 1257 return valueOf3(-(value as double)); | |
| 1258 } | |
| 1259 return error(node); | |
| 1260 } | 1418 } |
| 1261 | 1419 |
| 1262 EvaluationResultImpl notEqual(BinaryExpression node, EvaluationResultImpl righ
tOperand) => rightOperand.notEqualValid(node, this); | 1420 EvaluationResultImpl greaterThan(TypeProvider typeProvider, BinaryExpression n
ode, EvaluationResultImpl rightOperand) => rightOperand.greaterThanValid(typePro
vider, node, this); |
| 1263 | 1421 |
| 1264 EvaluationResultImpl performToString(ASTNode node) { | 1422 EvaluationResultImpl greaterThanOrEqual(TypeProvider typeProvider, BinaryExpre
ssion node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanOrEqua
lValid(typeProvider, node, this); |
| 1265 if (value == null) { | 1423 |
| 1266 return valueOf4("null"); | 1424 EvaluationResultImpl integerDivide(TypeProvider typeProvider, BinaryExpression
node, EvaluationResultImpl rightOperand) => rightOperand.integerDivideValid(typ
eProvider, node, this); |
| 1267 } else if (value is bool) { | 1425 |
| 1268 return valueOf4((value as bool).toString()); | 1426 /** |
| 1269 } else if (value is int) { | 1427 * Return `true` if this object represents an object whose type is 'bool'. |
| 1270 return valueOf4((value as int).toString()); | 1428 * |
| 1271 } else if (value is double) { | 1429 * @return `true` if this object represents a boolean value |
| 1272 return valueOf4((value as double).toString()); | 1430 */ |
| 1273 } else if (value is String) { | 1431 bool get isBool => value.isBool; |
| 1274 return this; | 1432 |
| 1275 } else if (isSomeBool) { | 1433 /** |
| 1276 return valueOf4("<some bool>"); | 1434 * Return `true` if this object represents an object whose type is either 'boo
l', 'num', |
| 1277 } else if (isSomeInt) { | 1435 * 'String', or 'Null'. |
| 1278 return valueOf4("<some int>"); | 1436 * |
| 1279 } else if (isSomeNum) { | 1437 * @return `true` if this object represents either a boolean, numeric, string
or null value |
| 1280 return valueOf4("<some num>"); | 1438 */ |
| 1439 bool get isBoolNumStringOrNull => value.isBoolNumStringOrNull; |
| 1440 |
| 1441 /** |
| 1442 * Return `true` if this result represents the value 'false'. |
| 1443 * |
| 1444 * @return `true` if this result represents the value 'false' |
| 1445 */ |
| 1446 bool get isFalse => value.isFalse; |
| 1447 |
| 1448 /** |
| 1449 * Return `true` if this result represents the value 'null'. |
| 1450 * |
| 1451 * @return `true` if this result represents the value 'null' |
| 1452 */ |
| 1453 bool get isNull => value.isNull; |
| 1454 |
| 1455 /** |
| 1456 * Return `true` if this result represents the value 'true'. |
| 1457 * |
| 1458 * @return `true` if this result represents the value 'true' |
| 1459 */ |
| 1460 bool get isTrue => value.isTrue; |
| 1461 |
| 1462 /** |
| 1463 * Return `true` if this object represents an instance of a user-defined class
. |
| 1464 * |
| 1465 * @return `true` if this object represents an instance of a user-defined clas
s |
| 1466 */ |
| 1467 bool get isUserDefinedObject => value.isUserDefinedObject; |
| 1468 |
| 1469 EvaluationResultImpl lessThan(TypeProvider typeProvider, BinaryExpression node
, EvaluationResultImpl rightOperand) => rightOperand.lessThanValid(typeProvider,
node, this); |
| 1470 |
| 1471 EvaluationResultImpl lessThanOrEqual(TypeProvider typeProvider, BinaryExpressi
on node, EvaluationResultImpl rightOperand) => rightOperand.lessThanOrEqualValid
(typeProvider, node, this); |
| 1472 |
| 1473 EvaluationResultImpl logicalAnd(TypeProvider typeProvider, BinaryExpression no
de, EvaluationResultImpl rightOperand) => rightOperand.logicalAndValid(typeProvi
der, node, this); |
| 1474 |
| 1475 EvaluationResultImpl logicalNot(TypeProvider typeProvider, Expression node) { |
| 1476 try { |
| 1477 return valueOf(value.logicalNot(typeProvider)); |
| 1478 } on EvaluationException catch (exception) { |
| 1479 return error(node, exception.errorCode); |
| 1281 } | 1480 } |
| 1282 return error(node); | |
| 1283 } | 1481 } |
| 1284 | 1482 |
| 1285 EvaluationResultImpl remainder(BinaryExpression node, EvaluationResultImpl rig
htOperand) => rightOperand.remainderValid(node, this); | 1483 EvaluationResultImpl logicalOr(TypeProvider typeProvider, BinaryExpression nod
e, EvaluationResultImpl rightOperand) => rightOperand.logicalOrValid(typeProvide
r, node, this); |
| 1286 | 1484 |
| 1287 EvaluationResultImpl shiftLeft(BinaryExpression node, EvaluationResultImpl rig
htOperand) => rightOperand.shiftLeftValid(node, this); | 1485 EvaluationResultImpl minus(TypeProvider typeProvider, BinaryExpression node, E
valuationResultImpl rightOperand) => rightOperand.minusValid(typeProvider, node,
this); |
| 1288 | 1486 |
| 1289 EvaluationResultImpl shiftRight(BinaryExpression node, EvaluationResultImpl ri
ghtOperand) => rightOperand.shiftRightValid(node, this); | 1487 EvaluationResultImpl negated(TypeProvider typeProvider, Expression node) { |
| 1488 try { |
| 1489 return valueOf(value.negated(typeProvider)); |
| 1490 } on EvaluationException catch (exception) { |
| 1491 return error(node, exception.errorCode); |
| 1492 } |
| 1493 } |
| 1290 | 1494 |
| 1291 EvaluationResultImpl times(BinaryExpression node, EvaluationResultImpl rightOp
erand) => rightOperand.timesValid(node, this); | 1495 EvaluationResultImpl notEqual(TypeProvider typeProvider, BinaryExpression node
, EvaluationResultImpl rightOperand) => rightOperand.notEqualValid(typeProvider,
node, this); |
| 1496 |
| 1497 EvaluationResultImpl performToString(TypeProvider typeProvider, ASTNode node)
{ |
| 1498 try { |
| 1499 return valueOf(value.performToString(typeProvider)); |
| 1500 } on EvaluationException catch (exception) { |
| 1501 return error(node, exception.errorCode); |
| 1502 } |
| 1503 } |
| 1504 |
| 1505 EvaluationResultImpl remainder(TypeProvider typeProvider, BinaryExpression nod
e, EvaluationResultImpl rightOperand) => rightOperand.remainderValid(typeProvide
r, node, this); |
| 1506 |
| 1507 EvaluationResultImpl shiftLeft(TypeProvider typeProvider, BinaryExpression nod
e, EvaluationResultImpl rightOperand) => rightOperand.shiftLeftValid(typeProvide
r, node, this); |
| 1508 |
| 1509 EvaluationResultImpl shiftRight(TypeProvider typeProvider, BinaryExpression no
de, EvaluationResultImpl rightOperand) => rightOperand.shiftRightValid(typeProvi
der, node, this); |
| 1510 |
| 1511 EvaluationResultImpl times(TypeProvider typeProvider, BinaryExpression node, E
valuationResultImpl rightOperand) => rightOperand.timesValid(typeProvider, node,
this); |
| 1292 | 1512 |
| 1293 String toString() { | 1513 String toString() { |
| 1294 if (value == null) { | 1514 if (value == null) { |
| 1295 return "null"; | 1515 return "null"; |
| 1296 } | 1516 } |
| 1297 return value.toString(); | 1517 return value.toString(); |
| 1298 } | 1518 } |
| 1299 | 1519 |
| 1300 EvaluationResultImpl addToError(BinaryExpression node, ErrorResult leftOperand
) => leftOperand; | 1520 EvaluationResultImpl addToError(BinaryExpression node, ErrorResult leftOperand
) => leftOperand; |
| 1301 | 1521 |
| 1302 EvaluationResultImpl addToValid(BinaryExpression node, ValidResult leftOperand
) { | 1522 EvaluationResultImpl addToValid(TypeProvider typeProvider, BinaryExpression no
de, ValidResult leftOperand) { |
| 1303 if (!isAnyNum || !leftOperand.isAnyNum) { | 1523 try { |
| 1304 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM); | 1524 return valueOf(leftOperand.value.add(typeProvider, value)); |
| 1525 } on EvaluationException catch (exception) { |
| 1526 return error(node, exception.errorCode); |
| 1305 } | 1527 } |
| 1306 if (isSomeInt || leftOperand.isSomeInt) { | |
| 1307 return RESULT_INT; | |
| 1308 } else if (isSomeNum || leftOperand.isSomeNum) { | |
| 1309 return RESULT_NUM; | |
| 1310 } | |
| 1311 Object leftValue = leftOperand.value; | |
| 1312 if (leftValue == null) { | |
| 1313 return error(node.leftOperand); | |
| 1314 } else if (value == null) { | |
| 1315 return error(node.rightOperand); | |
| 1316 } else if (leftValue is int) { | |
| 1317 if (value is int) { | |
| 1318 return valueOf((leftValue as int) + (value as int)); | |
| 1319 } else if (value is double) { | |
| 1320 return valueOf3((leftValue as int).toDouble() + (value as double)); | |
| 1321 } | |
| 1322 } else if (leftValue is double) { | |
| 1323 if (value is int) { | |
| 1324 return valueOf3((leftValue as double) + (value as int).toDouble()); | |
| 1325 } else if (value is double) { | |
| 1326 return valueOf3((leftValue as double) + (value as double)); | |
| 1327 } | |
| 1328 } else if (leftValue is String) { | |
| 1329 if (value is String) { | |
| 1330 return valueOf4("${(leftValue as String)}${(value as String)}"); | |
| 1331 } | |
| 1332 } | |
| 1333 return error(node); | |
| 1334 } | 1528 } |
| 1335 | 1529 |
| 1336 EvaluationResultImpl bitAndError(BinaryExpression node, ErrorResult leftOperan
d) => leftOperand; | 1530 EvaluationResultImpl bitAndError(BinaryExpression node, ErrorResult leftOperan
d) => leftOperand; |
| 1337 | 1531 |
| 1338 EvaluationResultImpl bitAndValid(BinaryExpression node, ValidResult leftOperan
d) { | 1532 EvaluationResultImpl bitAndValid(TypeProvider typeProvider, BinaryExpression n
ode, ValidResult leftOperand) { |
| 1339 if (!isAnyInt || !leftOperand.isAnyInt) { | 1533 try { |
| 1340 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT); | 1534 return valueOf(leftOperand.value.bitAnd(typeProvider, value)); |
| 1535 } on EvaluationException catch (exception) { |
| 1536 return error(node, exception.errorCode); |
| 1341 } | 1537 } |
| 1342 if (isSomeInt || leftOperand.isSomeInt) { | |
| 1343 return RESULT_INT; | |
| 1344 } | |
| 1345 Object leftValue = leftOperand.value; | |
| 1346 if (leftValue == null) { | |
| 1347 return error(node.leftOperand); | |
| 1348 } else if (value == null) { | |
| 1349 return error(node.rightOperand); | |
| 1350 } else if (leftValue is int) { | |
| 1351 if (value is int) { | |
| 1352 return valueOf((leftValue as int) & (value as int)); | |
| 1353 } | |
| 1354 return error(node.leftOperand); | |
| 1355 } | |
| 1356 if (value is int) { | |
| 1357 return error(node.rightOperand); | |
| 1358 } | |
| 1359 return union(error(node.leftOperand), error(node.rightOperand)); | |
| 1360 } | 1538 } |
| 1361 | 1539 |
| 1362 EvaluationResultImpl bitOrError(BinaryExpression node, ErrorResult leftOperand
) => leftOperand; | 1540 EvaluationResultImpl bitOrError(BinaryExpression node, ErrorResult leftOperand
) => leftOperand; |
| 1363 | 1541 |
| 1364 EvaluationResultImpl bitOrValid(BinaryExpression node, ValidResult leftOperand
) { | 1542 EvaluationResultImpl bitOrValid(TypeProvider typeProvider, BinaryExpression no
de, ValidResult leftOperand) { |
| 1365 if (!isAnyInt || !leftOperand.isAnyInt) { | 1543 try { |
| 1366 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT); | 1544 return valueOf(leftOperand.value.bitOr(typeProvider, value)); |
| 1545 } on EvaluationException catch (exception) { |
| 1546 return error(node, exception.errorCode); |
| 1367 } | 1547 } |
| 1368 if (isSomeInt || leftOperand.isSomeInt) { | |
| 1369 return RESULT_INT; | |
| 1370 } | |
| 1371 Object leftValue = leftOperand.value; | |
| 1372 if (leftValue == null) { | |
| 1373 return error(node.leftOperand); | |
| 1374 } else if (value == null) { | |
| 1375 return error(node.rightOperand); | |
| 1376 } else if (leftValue is int) { | |
| 1377 if (value is int) { | |
| 1378 return valueOf((leftValue as int) | (value as int)); | |
| 1379 } | |
| 1380 return error(node.leftOperand); | |
| 1381 } | |
| 1382 if (value is int) { | |
| 1383 return error(node.rightOperand); | |
| 1384 } | |
| 1385 return union(error(node.leftOperand), error(node.rightOperand)); | |
| 1386 } | 1548 } |
| 1387 | 1549 |
| 1388 EvaluationResultImpl bitXorError(BinaryExpression node, ErrorResult leftOperan
d) => leftOperand; | 1550 EvaluationResultImpl bitXorError(BinaryExpression node, ErrorResult leftOperan
d) => leftOperand; |
| 1389 | 1551 |
| 1390 EvaluationResultImpl bitXorValid(BinaryExpression node, ValidResult leftOperan
d) { | 1552 EvaluationResultImpl bitXorValid(TypeProvider typeProvider, BinaryExpression n
ode, ValidResult leftOperand) { |
| 1391 if (!isAnyInt || !leftOperand.isAnyInt) { | 1553 try { |
| 1392 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT); | 1554 return valueOf(leftOperand.value.bitXor(typeProvider, value)); |
| 1555 } on EvaluationException catch (exception) { |
| 1556 return error(node, exception.errorCode); |
| 1393 } | 1557 } |
| 1394 if (isSomeInt || leftOperand.isSomeInt) { | |
| 1395 return RESULT_INT; | |
| 1396 } | |
| 1397 Object leftValue = leftOperand.value; | |
| 1398 if (leftValue == null) { | |
| 1399 return error(node.leftOperand); | |
| 1400 } else if (value == null) { | |
| 1401 return error(node.rightOperand); | |
| 1402 } else if (leftValue is int) { | |
| 1403 if (value is int) { | |
| 1404 return valueOf((leftValue as int) ^ (value as int)); | |
| 1405 } | |
| 1406 return error(node.leftOperand); | |
| 1407 } | |
| 1408 if (value is int) { | |
| 1409 return error(node.rightOperand); | |
| 1410 } | |
| 1411 return union(error(node.leftOperand), error(node.rightOperand)); | |
| 1412 } | 1558 } |
| 1413 | 1559 |
| 1414 EvaluationResultImpl concatenateError(Expression node, ErrorResult leftOperand
) => leftOperand; | 1560 EvaluationResultImpl concatenateError(Expression node, ErrorResult leftOperand
) => leftOperand; |
| 1415 | 1561 |
| 1416 EvaluationResultImpl concatenateValid(Expression node, ValidResult leftOperand
) { | 1562 EvaluationResultImpl concatenateValid(TypeProvider typeProvider, Expression no
de, ValidResult leftOperand) { |
| 1417 Object leftValue = leftOperand.value; | 1563 try { |
| 1418 if (leftValue is String && value is String) { | 1564 return valueOf(leftOperand.value.concatenate(typeProvider, value)); |
| 1419 return valueOf4("${(leftValue as String)}${(value as String)}"); | 1565 } on EvaluationException catch (exception) { |
| 1566 return error(node, exception.errorCode); |
| 1420 } | 1567 } |
| 1421 return error(node); | |
| 1422 } | 1568 } |
| 1423 | 1569 |
| 1424 EvaluationResultImpl divideError(BinaryExpression node, ErrorResult leftOperan
d) => leftOperand; | 1570 EvaluationResultImpl divideError(BinaryExpression node, ErrorResult leftOperan
d) => leftOperand; |
| 1425 | 1571 |
| 1426 EvaluationResultImpl divideValid(BinaryExpression node, ValidResult leftOperan
d) { | 1572 EvaluationResultImpl divideValid(TypeProvider typeProvider, BinaryExpression n
ode, ValidResult leftOperand) { |
| 1427 if (!isAnyNum || !leftOperand.isAnyNum) { | 1573 try { |
| 1428 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM); | 1574 return valueOf(leftOperand.value.divide(typeProvider, value)); |
| 1575 } on EvaluationException catch (exception) { |
| 1576 return error(node, exception.errorCode); |
| 1429 } | 1577 } |
| 1430 if (isSomeNum || leftOperand.isSomeNum) { | |
| 1431 return RESULT_NUM; | |
| 1432 } | |
| 1433 Object leftValue = leftOperand.value; | |
| 1434 if (leftValue == null) { | |
| 1435 return error(node.leftOperand); | |
| 1436 } else if (value == null) { | |
| 1437 return error(node.rightOperand); | |
| 1438 } else if (leftValue is int) { | |
| 1439 if (value is int) { | |
| 1440 if ((value as int) == 0) { | |
| 1441 return valueOf3((leftValue as int).toDouble() / (value as int).toDoubl
e()); | |
| 1442 } | |
| 1443 return valueOf((leftValue as int) ~/ (value as int)); | |
| 1444 } else if (value is double) { | |
| 1445 return valueOf3((leftValue as int).toDouble() / (value as double)); | |
| 1446 } | |
| 1447 } else if (leftValue is double) { | |
| 1448 if (value is int) { | |
| 1449 return valueOf3((leftValue as double) / (value as int).toDouble()); | |
| 1450 } else if (value is double) { | |
| 1451 return valueOf3((leftValue as double) / (value as double)); | |
| 1452 } | |
| 1453 } | |
| 1454 return error(node); | |
| 1455 } | 1578 } |
| 1456 | 1579 |
| 1457 EvaluationResultImpl equalEqualError(Expression node, ErrorResult leftOperand)
=> leftOperand; | 1580 EvaluationResultImpl equalEqualError(Expression node, ErrorResult leftOperand)
=> leftOperand; |
| 1458 | 1581 |
| 1459 EvaluationResultImpl equalEqualValid(Expression node, ValidResult leftOperand)
{ | 1582 EvaluationResultImpl equalEqualValid(TypeProvider typeProvider, Expression nod
e, ValidResult leftOperand) { |
| 1460 if (node is BinaryExpression) { | 1583 try { |
| 1461 if (!isAnyNullBoolNumString || !leftOperand.isAnyNullBoolNumString) { | 1584 return valueOf(leftOperand.value.equalEqual(typeProvider, value)); |
| 1462 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING
); | 1585 } on EvaluationException catch (exception) { |
| 1463 } | 1586 return error(node, exception.errorCode); |
| 1464 } | |
| 1465 Object leftValue = leftOperand.value; | |
| 1466 if (leftValue == null) { | |
| 1467 return valueOf2(value == null); | |
| 1468 } else if (leftValue is int) { | |
| 1469 if (value is int) { | |
| 1470 return valueOf2((leftValue as int) == value); | |
| 1471 } else if (value is double) { | |
| 1472 return valueOf2(toDouble(leftValue as int) == value); | |
| 1473 } | |
| 1474 return RESULT_FALSE; | |
| 1475 } else if (leftValue is double) { | |
| 1476 if (value is int) { | |
| 1477 return valueOf2((leftValue as double) == toDouble(value as int)); | |
| 1478 } else if (value is double) { | |
| 1479 return valueOf2((leftValue as double) == value); | |
| 1480 } | |
| 1481 return RESULT_FALSE; | |
| 1482 } else { | |
| 1483 return valueOf2(leftValue == value); | |
| 1484 } | 1587 } |
| 1485 } | 1588 } |
| 1486 | 1589 |
| 1487 EvaluationResultImpl greaterThanError(BinaryExpression node, ErrorResult leftO
perand) => leftOperand; | 1590 EvaluationResultImpl greaterThanError(BinaryExpression node, ErrorResult leftO
perand) => leftOperand; |
| 1488 | 1591 |
| 1489 EvaluationResultImpl greaterThanOrEqualError(BinaryExpression node, ErrorResul
t leftOperand) => leftOperand; | 1592 EvaluationResultImpl greaterThanOrEqualError(BinaryExpression node, ErrorResul
t leftOperand) => leftOperand; |
| 1490 | 1593 |
| 1491 EvaluationResultImpl greaterThanOrEqualValid(BinaryExpression node, ValidResul
t leftOperand) { | 1594 EvaluationResultImpl greaterThanOrEqualValid(TypeProvider typeProvider, Binary
Expression node, ValidResult leftOperand) { |
| 1492 if (!isAnyNum || !leftOperand.isAnyNum) { | 1595 try { |
| 1493 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM); | 1596 return valueOf(leftOperand.value.greaterThanOrEqual(typeProvider, value)); |
| 1597 } on EvaluationException catch (exception) { |
| 1598 return error(node, exception.errorCode); |
| 1494 } | 1599 } |
| 1495 if (isSomeNum || leftOperand.isSomeNum) { | |
| 1496 return RESULT_BOOL; | |
| 1497 } | |
| 1498 Object leftValue = leftOperand.value; | |
| 1499 if (leftValue == null) { | |
| 1500 return error(node.leftOperand); | |
| 1501 } else if (value == null) { | |
| 1502 return error(node.rightOperand); | |
| 1503 } else if (leftValue is int) { | |
| 1504 if (value is int) { | |
| 1505 return valueOf2((leftValue as int).compareTo(value as int) >= 0); | |
| 1506 } else if (value is double) { | |
| 1507 return valueOf2((leftValue as int).toDouble() >= (value as double)); | |
| 1508 } | |
| 1509 } else if (leftValue is double) { | |
| 1510 if (value is int) { | |
| 1511 return valueOf2((leftValue as double) >= (value as int).toDouble()); | |
| 1512 } else if (value is double) { | |
| 1513 return valueOf2((leftValue as double) >= (value as double)); | |
| 1514 } | |
| 1515 } | |
| 1516 return error(node); | |
| 1517 } | 1600 } |
| 1518 | 1601 |
| 1519 EvaluationResultImpl greaterThanValid(BinaryExpression node, ValidResult leftO
perand) { | 1602 EvaluationResultImpl greaterThanValid(TypeProvider typeProvider, BinaryExpress
ion node, ValidResult leftOperand) { |
| 1520 if (!isAnyNum || !leftOperand.isAnyNum) { | 1603 try { |
| 1521 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM); | 1604 return valueOf(leftOperand.value.greaterThan(typeProvider, value)); |
| 1605 } on EvaluationException catch (exception) { |
| 1606 return error(node, exception.errorCode); |
| 1522 } | 1607 } |
| 1523 if (isSomeNum || leftOperand.isSomeNum) { | |
| 1524 return RESULT_BOOL; | |
| 1525 } | |
| 1526 Object leftValue = leftOperand.value; | |
| 1527 if (leftValue == null) { | |
| 1528 return error(node.leftOperand); | |
| 1529 } else if (value == null) { | |
| 1530 return error(node.rightOperand); | |
| 1531 } else if (leftValue is int) { | |
| 1532 if (value is int) { | |
| 1533 return valueOf2((leftValue as int).compareTo(value as int) > 0); | |
| 1534 } else if (value is double) { | |
| 1535 return valueOf2((leftValue as int).toDouble() > (value as double)); | |
| 1536 } | |
| 1537 } else if (leftValue is double) { | |
| 1538 if (value is int) { | |
| 1539 return valueOf2((leftValue as double) > (value as int).toDouble()); | |
| 1540 } else if (value is double) { | |
| 1541 return valueOf2((leftValue as double) > (value as double)); | |
| 1542 } | |
| 1543 } | |
| 1544 return error(node); | |
| 1545 } | 1608 } |
| 1546 | 1609 |
| 1547 EvaluationResultImpl integerDivideError(BinaryExpression node, ErrorResult lef
tOperand) => leftOperand; | 1610 EvaluationResultImpl integerDivideError(BinaryExpression node, ErrorResult lef
tOperand) => leftOperand; |
| 1548 | 1611 |
| 1549 EvaluationResultImpl integerDivideValid(BinaryExpression node, ValidResult lef
tOperand) { | 1612 EvaluationResultImpl integerDivideValid(TypeProvider typeProvider, BinaryExpre
ssion node, ValidResult leftOperand) { |
| 1550 if (!isAnyNum || !leftOperand.isAnyNum) { | 1613 try { |
| 1551 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM); | 1614 return valueOf(leftOperand.value.integerDivide(typeProvider, value)); |
| 1615 } on EvaluationException catch (exception) { |
| 1616 return error(node, exception.errorCode); |
| 1552 } | 1617 } |
| 1553 if (isSomeNum || leftOperand.isSomeNum) { | |
| 1554 return RESULT_INT; | |
| 1555 } | |
| 1556 Object leftValue = leftOperand.value; | |
| 1557 if (leftValue == null) { | |
| 1558 return error(node.leftOperand); | |
| 1559 } else if (value == null) { | |
| 1560 return error(node.rightOperand); | |
| 1561 } else if (leftValue is int) { | |
| 1562 if (value is int) { | |
| 1563 if ((value as int) == 0) { | |
| 1564 return error2(node, CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE); | |
| 1565 } | |
| 1566 return valueOf((leftValue as int) ~/ (value as int)); | |
| 1567 } else if (value is double) { | |
| 1568 double result = (leftValue as int).toDouble() / (value as double); | |
| 1569 return valueOf(result.toInt()); | |
| 1570 } | |
| 1571 } else if (leftValue is double) { | |
| 1572 if (value is int) { | |
| 1573 double result = (leftValue as double) / (value as int).toDouble(); | |
| 1574 return valueOf(result.toInt()); | |
| 1575 } else if (value is double) { | |
| 1576 double result = (leftValue as double) / (value as double); | |
| 1577 return valueOf(result.toInt()); | |
| 1578 } | |
| 1579 } | |
| 1580 return error(node); | |
| 1581 } | 1618 } |
| 1582 | 1619 |
| 1583 EvaluationResultImpl lessThanError(BinaryExpression node, ErrorResult leftOper
and) => leftOperand; | 1620 EvaluationResultImpl lessThanError(BinaryExpression node, ErrorResult leftOper
and) => leftOperand; |
| 1584 | 1621 |
| 1585 EvaluationResultImpl lessThanOrEqualError(BinaryExpression node, ErrorResult l
eftOperand) => leftOperand; | 1622 EvaluationResultImpl lessThanOrEqualError(BinaryExpression node, ErrorResult l
eftOperand) => leftOperand; |
| 1586 | 1623 |
| 1587 EvaluationResultImpl lessThanOrEqualValid(BinaryExpression node, ValidResult l
eftOperand) { | 1624 EvaluationResultImpl lessThanOrEqualValid(TypeProvider typeProvider, BinaryExp
ression node, ValidResult leftOperand) { |
| 1588 if (!isAnyNum || !leftOperand.isAnyNum) { | 1625 try { |
| 1589 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM); | 1626 return valueOf(leftOperand.value.lessThanOrEqual(typeProvider, value)); |
| 1627 } on EvaluationException catch (exception) { |
| 1628 return error(node, exception.errorCode); |
| 1590 } | 1629 } |
| 1591 if (isSomeNum || leftOperand.isSomeNum) { | |
| 1592 return RESULT_BOOL; | |
| 1593 } | |
| 1594 Object leftValue = leftOperand.value; | |
| 1595 if (leftValue == null) { | |
| 1596 return error(node.leftOperand); | |
| 1597 } else if (value == null) { | |
| 1598 return error(node.rightOperand); | |
| 1599 } else if (leftValue is int) { | |
| 1600 if (value is int) { | |
| 1601 return valueOf2((leftValue as int).compareTo(value as int) <= 0); | |
| 1602 } else if (value is double) { | |
| 1603 return valueOf2((leftValue as int).toDouble() <= (value as double)); | |
| 1604 } | |
| 1605 } else if (leftValue is double) { | |
| 1606 if (value is int) { | |
| 1607 return valueOf2((leftValue as double) <= (value as int).toDouble()); | |
| 1608 } else if (value is double) { | |
| 1609 return valueOf2((leftValue as double) <= (value as double)); | |
| 1610 } | |
| 1611 } | |
| 1612 return error(node); | |
| 1613 } | 1630 } |
| 1614 | 1631 |
| 1615 EvaluationResultImpl lessThanValid(BinaryExpression node, ValidResult leftOper
and) { | 1632 EvaluationResultImpl lessThanValid(TypeProvider typeProvider, BinaryExpression
node, ValidResult leftOperand) { |
| 1616 if (!isAnyNum || !leftOperand.isAnyNum) { | 1633 try { |
| 1617 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM); | 1634 return valueOf(leftOperand.value.lessThan(typeProvider, value)); |
| 1635 } on EvaluationException catch (exception) { |
| 1636 return error(node, exception.errorCode); |
| 1618 } | 1637 } |
| 1619 if (isSomeNum || leftOperand.isSomeNum) { | |
| 1620 return RESULT_BOOL; | |
| 1621 } | |
| 1622 Object leftValue = leftOperand.value; | |
| 1623 if (leftValue == null) { | |
| 1624 return error(node.leftOperand); | |
| 1625 } else if (value == null) { | |
| 1626 return error(node.rightOperand); | |
| 1627 } else if (leftValue is int) { | |
| 1628 if (value is int) { | |
| 1629 return valueOf2((leftValue as int).compareTo(value as int) < 0); | |
| 1630 } else if (value is double) { | |
| 1631 return valueOf2((leftValue as int).toDouble() < (value as double)); | |
| 1632 } | |
| 1633 } else if (leftValue is double) { | |
| 1634 if (value is int) { | |
| 1635 return valueOf2((leftValue as double) < (value as int).toDouble()); | |
| 1636 } else if (value is double) { | |
| 1637 return valueOf2((leftValue as double) < (value as double)); | |
| 1638 } | |
| 1639 } | |
| 1640 return error(node); | |
| 1641 } | 1638 } |
| 1642 | 1639 |
| 1643 EvaluationResultImpl logicalAndError(BinaryExpression node, ErrorResult leftOp
erand) => leftOperand; | 1640 EvaluationResultImpl logicalAndError(BinaryExpression node, ErrorResult leftOp
erand) => leftOperand; |
| 1644 | 1641 |
| 1645 EvaluationResultImpl logicalAndValid(BinaryExpression node, ValidResult leftOp
erand) { | 1642 EvaluationResultImpl logicalAndValid(TypeProvider typeProvider, BinaryExpressi
on node, ValidResult leftOperand) { |
| 1646 if (!isAnyBool || !leftOperand.isAnyBool) { | 1643 try { |
| 1647 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL); | 1644 return valueOf(leftOperand.value.logicalAnd(typeProvider, value)); |
| 1645 } on EvaluationException catch (exception) { |
| 1646 return error(node, exception.errorCode); |
| 1648 } | 1647 } |
| 1649 if (isSomeBool || leftOperand.isSomeBool) { | |
| 1650 return RESULT_BOOL; | |
| 1651 } | |
| 1652 Object leftValue = leftOperand.value; | |
| 1653 if (leftValue is bool) { | |
| 1654 if (leftValue as bool) { | |
| 1655 return booleanConversion(node.rightOperand, value); | |
| 1656 } | |
| 1657 return RESULT_FALSE; | |
| 1658 } | |
| 1659 return error(node); | |
| 1660 } | 1648 } |
| 1661 | 1649 |
| 1662 EvaluationResultImpl logicalOrError(BinaryExpression node, ErrorResult leftOpe
rand) => leftOperand; | 1650 EvaluationResultImpl logicalOrError(BinaryExpression node, ErrorResult leftOpe
rand) => leftOperand; |
| 1663 | 1651 |
| 1664 EvaluationResultImpl logicalOrValid(BinaryExpression node, ValidResult leftOpe
rand) { | 1652 EvaluationResultImpl logicalOrValid(TypeProvider typeProvider, BinaryExpressio
n node, ValidResult leftOperand) { |
| 1665 if (!isAnyBool || !leftOperand.isAnyBool) { | 1653 try { |
| 1666 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL); | 1654 return valueOf(leftOperand.value.logicalOr(typeProvider, value)); |
| 1655 } on EvaluationException catch (exception) { |
| 1656 return error(node, exception.errorCode); |
| 1667 } | 1657 } |
| 1668 if (isSomeBool || leftOperand.isSomeBool) { | |
| 1669 return RESULT_BOOL; | |
| 1670 } | |
| 1671 Object leftValue = leftOperand.value; | |
| 1672 if (leftValue is bool && (leftValue as bool)) { | |
| 1673 return RESULT_TRUE; | |
| 1674 } | |
| 1675 return booleanConversion(node.rightOperand, value); | |
| 1676 } | 1658 } |
| 1677 | 1659 |
| 1678 EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand
) => leftOperand; | 1660 EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand
) => leftOperand; |
| 1679 | 1661 |
| 1680 EvaluationResultImpl minusValid(BinaryExpression node, ValidResult leftOperand
) { | 1662 EvaluationResultImpl minusValid(TypeProvider typeProvider, BinaryExpression no
de, ValidResult leftOperand) { |
| 1681 if (!isAnyNum || !leftOperand.isAnyNum) { | 1663 try { |
| 1682 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM); | 1664 return valueOf(leftOperand.value.minus(typeProvider, value)); |
| 1665 } on EvaluationException catch (exception) { |
| 1666 return error(node, exception.errorCode); |
| 1683 } | 1667 } |
| 1684 if (isSomeInt || leftOperand.isSomeInt) { | |
| 1685 return RESULT_INT; | |
| 1686 } else if (isSomeNum || leftOperand.isSomeNum) { | |
| 1687 return RESULT_NUM; | |
| 1688 } | |
| 1689 Object leftValue = leftOperand.value; | |
| 1690 if (leftValue == null) { | |
| 1691 return error(node.leftOperand); | |
| 1692 } else if (value == null) { | |
| 1693 return error(node.rightOperand); | |
| 1694 } else if (leftValue is int) { | |
| 1695 if (value is int) { | |
| 1696 return valueOf((leftValue as int) - (value as int)); | |
| 1697 } else if (value is double) { | |
| 1698 return valueOf3((leftValue as int).toDouble() - (value as double)); | |
| 1699 } | |
| 1700 } else if (leftValue is double) { | |
| 1701 if (value is int) { | |
| 1702 return valueOf3((leftValue as double) - (value as int).toDouble()); | |
| 1703 } else if (value is double) { | |
| 1704 return valueOf3((leftValue as double) - (value as double)); | |
| 1705 } | |
| 1706 } | |
| 1707 return error(node); | |
| 1708 } | 1668 } |
| 1709 | 1669 |
| 1710 EvaluationResultImpl notEqualError(BinaryExpression node, ErrorResult leftOper
and) => leftOperand; | 1670 EvaluationResultImpl notEqualError(BinaryExpression node, ErrorResult leftOper
and) => leftOperand; |
| 1711 | 1671 |
| 1712 EvaluationResultImpl notEqualValid(BinaryExpression node, ValidResult leftOper
and) { | 1672 EvaluationResultImpl notEqualValid(TypeProvider typeProvider, BinaryExpression
node, ValidResult leftOperand) { |
| 1713 if (!isAnyNullBoolNumString || !leftOperand.isAnyNullBoolNumString) { | 1673 try { |
| 1714 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING); | 1674 return valueOf(leftOperand.value.notEqual(typeProvider, value)); |
| 1675 } on EvaluationException catch (exception) { |
| 1676 return error(node, exception.errorCode); |
| 1715 } | 1677 } |
| 1716 Object leftValue = leftOperand.value; | |
| 1717 if (leftValue == null) { | |
| 1718 return valueOf2(value != null); | |
| 1719 } else if (leftValue is bool) { | |
| 1720 if (value is bool) { | |
| 1721 return valueOf2((leftValue as bool) != (value as bool)); | |
| 1722 } | |
| 1723 return RESULT_TRUE; | |
| 1724 } else if (leftValue is int) { | |
| 1725 if (value is int) { | |
| 1726 return valueOf2((leftValue as int) != value); | |
| 1727 } else if (value is double) { | |
| 1728 return valueOf2(toDouble(leftValue as int) != value); | |
| 1729 } | |
| 1730 return RESULT_TRUE; | |
| 1731 } else if (leftValue is double) { | |
| 1732 if (value is int) { | |
| 1733 return valueOf2((leftValue as double) != toDouble(value as int)); | |
| 1734 } else if (value is double) { | |
| 1735 return valueOf2((leftValue as double) != value); | |
| 1736 } | |
| 1737 return RESULT_TRUE; | |
| 1738 } else if (leftValue is String) { | |
| 1739 if (value is String) { | |
| 1740 return valueOf2((leftValue as String) != value); | |
| 1741 } | |
| 1742 return RESULT_TRUE; | |
| 1743 } | |
| 1744 return RESULT_TRUE; | |
| 1745 } | 1678 } |
| 1746 | 1679 |
| 1747 EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOpe
rand) => leftOperand; | 1680 EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOpe
rand) => leftOperand; |
| 1748 | 1681 |
| 1749 EvaluationResultImpl remainderValid(BinaryExpression node, ValidResult leftOpe
rand) { | 1682 EvaluationResultImpl remainderValid(TypeProvider typeProvider, BinaryExpressio
n node, ValidResult leftOperand) { |
| 1750 if (!isAnyNum || !leftOperand.isAnyNum) { | 1683 try { |
| 1751 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM); | 1684 return valueOf(leftOperand.value.remainder(typeProvider, value)); |
| 1685 } on EvaluationException catch (exception) { |
| 1686 return error(node, exception.errorCode); |
| 1752 } | 1687 } |
| 1753 if (isSomeInt || leftOperand.isSomeInt) { | |
| 1754 return RESULT_INT; | |
| 1755 } else if (isSomeNum || leftOperand.isSomeNum) { | |
| 1756 return RESULT_NUM; | |
| 1757 } | |
| 1758 Object leftValue = leftOperand.value; | |
| 1759 if (leftValue == null) { | |
| 1760 return error(node.leftOperand); | |
| 1761 } else if (value == null) { | |
| 1762 return error(node.rightOperand); | |
| 1763 } else if (leftValue is int) { | |
| 1764 if (value is int) { | |
| 1765 if ((value as int) == 0) { | |
| 1766 return valueOf3((leftValue as int).toDouble() % (value as int).toDoubl
e()); | |
| 1767 } | |
| 1768 return valueOf((leftValue as int).remainder(value as int)); | |
| 1769 } else if (value is double) { | |
| 1770 return valueOf3((leftValue as int).toDouble() % (value as double)); | |
| 1771 } | |
| 1772 } else if (leftValue is double) { | |
| 1773 if (value is int) { | |
| 1774 return valueOf3((leftValue as double) % (value as int).toDouble()); | |
| 1775 } else if (value is double) { | |
| 1776 return valueOf3((leftValue as double) % (value as double)); | |
| 1777 } | |
| 1778 } | |
| 1779 return error(node); | |
| 1780 } | 1688 } |
| 1781 | 1689 |
| 1782 EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOpe
rand) => leftOperand; | 1690 EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOpe
rand) => leftOperand; |
| 1783 | 1691 |
| 1784 EvaluationResultImpl shiftLeftValid(BinaryExpression node, ValidResult leftOpe
rand) { | 1692 EvaluationResultImpl shiftLeftValid(TypeProvider typeProvider, BinaryExpressio
n node, ValidResult leftOperand) { |
| 1785 if (!isAnyInt || !leftOperand.isAnyInt) { | 1693 try { |
| 1786 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT); | 1694 return valueOf(leftOperand.value.shiftLeft(typeProvider, value)); |
| 1695 } on EvaluationException catch (exception) { |
| 1696 return error(node, exception.errorCode); |
| 1787 } | 1697 } |
| 1788 if (isSomeInt || leftOperand.isSomeInt) { | |
| 1789 return RESULT_INT; | |
| 1790 } | |
| 1791 Object leftValue = leftOperand.value; | |
| 1792 if (leftValue == null) { | |
| 1793 return error(node.leftOperand); | |
| 1794 } else if (value == null) { | |
| 1795 return error(node.rightOperand); | |
| 1796 } else if (leftValue is int) { | |
| 1797 if (value is int) { | |
| 1798 return RESULT_INT; | |
| 1799 } | |
| 1800 return error(node.rightOperand); | |
| 1801 } | |
| 1802 if (value is int) { | |
| 1803 return error(node.leftOperand); | |
| 1804 } | |
| 1805 return union(error(node.leftOperand), error(node.rightOperand)); | |
| 1806 } | 1698 } |
| 1807 | 1699 |
| 1808 EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOp
erand) => leftOperand; | 1700 EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOp
erand) => leftOperand; |
| 1809 | 1701 |
| 1810 EvaluationResultImpl shiftRightValid(BinaryExpression node, ValidResult leftOp
erand) { | 1702 EvaluationResultImpl shiftRightValid(TypeProvider typeProvider, BinaryExpressi
on node, ValidResult leftOperand) { |
| 1811 if (!isAnyInt || !leftOperand.isAnyInt) { | 1703 try { |
| 1812 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT); | 1704 return valueOf(leftOperand.value.shiftRight(typeProvider, value)); |
| 1705 } on EvaluationException catch (exception) { |
| 1706 return error(node, exception.errorCode); |
| 1813 } | 1707 } |
| 1814 if (isSomeInt || leftOperand.isSomeInt) { | |
| 1815 return RESULT_INT; | |
| 1816 } | |
| 1817 Object leftValue = leftOperand.value; | |
| 1818 if (leftValue == null) { | |
| 1819 return error(node.leftOperand); | |
| 1820 } else if (value == null) { | |
| 1821 return error(node.rightOperand); | |
| 1822 } else if (leftValue is int) { | |
| 1823 if (value is int) { | |
| 1824 return valueOf((leftValue as int) >> (value as int)); | |
| 1825 } | |
| 1826 return error(node.rightOperand); | |
| 1827 } | |
| 1828 if (value is int) { | |
| 1829 return error(node.leftOperand); | |
| 1830 } | |
| 1831 return union(error(node.leftOperand), error(node.rightOperand)); | |
| 1832 } | 1708 } |
| 1833 | 1709 |
| 1834 EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand
) => leftOperand; | 1710 EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand
) => leftOperand; |
| 1835 | 1711 |
| 1836 EvaluationResultImpl timesValid(BinaryExpression node, ValidResult leftOperand
) { | 1712 EvaluationResultImpl timesValid(TypeProvider typeProvider, BinaryExpression no
de, ValidResult leftOperand) { |
| 1837 if (!isAnyNum || !leftOperand.isAnyNum) { | 1713 try { |
| 1838 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM); | 1714 return valueOf(leftOperand.value.times(typeProvider, value)); |
| 1715 } on EvaluationException catch (exception) { |
| 1716 return error(node, exception.errorCode); |
| 1839 } | 1717 } |
| 1840 if (isSomeInt || leftOperand.isSomeInt) { | |
| 1841 return RESULT_INT; | |
| 1842 } else if (isSomeNum || leftOperand.isSomeNum) { | |
| 1843 return RESULT_NUM; | |
| 1844 } | |
| 1845 Object leftValue = leftOperand.value; | |
| 1846 if (leftValue == null) { | |
| 1847 return error(node.leftOperand); | |
| 1848 } else if (value == null) { | |
| 1849 return error(node.rightOperand); | |
| 1850 } else if (leftValue is int) { | |
| 1851 if (value is int) { | |
| 1852 return valueOf((leftValue as int) * (value as int)); | |
| 1853 } else if (value is double) { | |
| 1854 return valueOf3((leftValue as int).toDouble() * (value as double)); | |
| 1855 } | |
| 1856 } else if (leftValue is double) { | |
| 1857 if (value is int) { | |
| 1858 return valueOf3((leftValue as double) * (value as int).toDouble()); | |
| 1859 } else if (value is double) { | |
| 1860 return valueOf3((leftValue as double) * (value as double)); | |
| 1861 } | |
| 1862 } | |
| 1863 return error(node); | |
| 1864 } | 1718 } |
| 1865 | 1719 |
| 1866 bool get isNull => identical(this, RESULT_NULL); | |
| 1867 | |
| 1868 /** | |
| 1869 * Return the result of applying boolean conversion to the given value. | |
| 1870 * | |
| 1871 * @param node the node against which errors should be reported | |
| 1872 * @param value the value to be converted to a boolean | |
| 1873 * @return the result of applying boolean conversion to the given value | |
| 1874 */ | |
| 1875 EvaluationResultImpl booleanConversion(ASTNode node, Object value) { | |
| 1876 if (value is bool) { | |
| 1877 if (value as bool) { | |
| 1878 return RESULT_TRUE; | |
| 1879 } else { | |
| 1880 return RESULT_FALSE; | |
| 1881 } | |
| 1882 } | |
| 1883 return error(node); | |
| 1884 } | |
| 1885 | |
| 1886 ErrorResult error(ASTNode node) => error2(node, CompileTimeErrorCode.INVALID_C
ONSTANT); | |
| 1887 | |
| 1888 /** | 1720 /** |
| 1889 * Return a result object representing an error associated with the given node
. | 1721 * Return a result object representing an error associated with the given node
. |
| 1890 * | 1722 * |
| 1891 * @param node the AST node associated with the error | 1723 * @param node the AST node associated with the error |
| 1892 * @param code the error code indicating the nature of the error | 1724 * @param code the error code indicating the nature of the error |
| 1893 * @return a result object representing an error associated with the given nod
e | 1725 * @return a result object representing an error associated with the given nod
e |
| 1894 */ | 1726 */ |
| 1895 ErrorResult error2(ASTNode node, ErrorCode code) => new ErrorResult.con1(node,
code); | 1727 ErrorResult error(ASTNode node, ErrorCode code) => new ErrorResult.con1(node,
code); |
| 1896 | |
| 1897 /** | |
| 1898 * Checks if this result has type "bool", with known or unknown value. | |
| 1899 */ | |
| 1900 bool get isAnyBool => isSomeBool || identical(this, RESULT_TRUE) || identical(
this, RESULT_FALSE); | |
| 1901 | |
| 1902 /** | |
| 1903 * Checks if this result has type "int", with known or unknown value. | |
| 1904 */ | |
| 1905 bool get isAnyInt => identical(this, RESULT_INT) || value is int; | |
| 1906 | |
| 1907 /** | |
| 1908 * Checks if this result has one of the types - "bool", "num" or "string"; or
may be `null`. | |
| 1909 */ | |
| 1910 bool get isAnyNullBoolNumString => isNull || isAnyBool || isAnyNum || value is
String; | |
| 1911 | |
| 1912 /** | |
| 1913 * Checks if this result has type "num", with known or unknown value. | |
| 1914 */ | |
| 1915 bool get isAnyNum => isSomeNum || value is num; | |
| 1916 | |
| 1917 /** | |
| 1918 * Checks if this result has type "bool", exact value of which we don't know. | |
| 1919 */ | |
| 1920 bool get isSomeBool => identical(this, RESULT_BOOL); | |
| 1921 | |
| 1922 /** | |
| 1923 * Checks if this result has type "int", exact value of which we don't know. | |
| 1924 */ | |
| 1925 bool get isSomeInt => identical(this, RESULT_INT); | |
| 1926 | |
| 1927 /** | |
| 1928 * Checks if this result has type "num" (or "int"), exact value of which we do
n't know. | |
| 1929 */ | |
| 1930 bool get isSomeNum => identical(this, RESULT_DYNAMIC) || identical(this, RESUL
T_INT) || identical(this, RESULT_NUM); | |
| 1931 | |
| 1932 double toDouble(int value) => value.toDouble(); | |
| 1933 | |
| 1934 /** | |
| 1935 * Return an error result that is the union of the two given error results. | |
| 1936 * | |
| 1937 * @param firstError the first error to be combined | |
| 1938 * @param secondError the second error to be combined | |
| 1939 * @return an error result that is the union of the two given error results | |
| 1940 */ | |
| 1941 ErrorResult union(ErrorResult firstError, ErrorResult secondError) => new Erro
rResult.con2(firstError, secondError); | |
| 1942 | 1728 |
| 1943 /** | 1729 /** |
| 1944 * Return a result object representing the given value. | 1730 * Return a result object representing the given value. |
| 1945 * | 1731 * |
| 1946 * @param value the value to be represented as a result object | 1732 * @param value the value to be represented as a result object |
| 1947 * @return a result object representing the given value | 1733 * @return a result object representing the given value |
| 1948 */ | 1734 */ |
| 1949 ValidResult valueOf(int value) => new ValidResult(value); | 1735 ValidResult valueOf(DartObjectImpl value) => new ValidResult(value); |
| 1950 | 1736 } |
| 1951 /** | 1737 |
| 1952 * Return a result object representing the given value. | 1738 /** |
| 1953 * | 1739 * Instances of the class `BoolState` represent the state of an object represent
ing a boolean |
| 1954 * @param value the value to be represented as a result object | 1740 * value. |
| 1955 * @return a result object representing the given value | 1741 */ |
| 1956 */ | 1742 class BoolState extends InstanceState { |
| 1957 ValidResult valueOf2(bool value) => value ? RESULT_TRUE : RESULT_FALSE; | 1743 /** |
| 1958 | 1744 * The value of this instance. |
| 1959 /** | 1745 */ |
| 1960 * Return a result object representing the given value. | 1746 final bool value; |
| 1961 * | 1747 |
| 1962 * @param value the value to be represented as a result object | 1748 /** |
| 1963 * @return a result object representing the given value | 1749 * An instance representing the boolean value 'false'. |
| 1964 */ | 1750 */ |
| 1965 ValidResult valueOf3(double value) => new ValidResult(value); | 1751 static BoolState FALSE_STATE = new BoolState(false); |
| 1966 | 1752 |
| 1967 /** | 1753 /** |
| 1968 * Return a result object representing the given value. | 1754 * An instance representing the boolean value 'true'. |
| 1969 * | 1755 */ |
| 1970 * @param value the value to be represented as a result object | 1756 static BoolState TRUE_STATE = new BoolState(true); |
| 1971 * @return a result object representing the given value | 1757 |
| 1972 */ | 1758 /** |
| 1973 ValidResult valueOf4(String value) => new ValidResult(value); | 1759 * A state that can be used to represent a boolean whose value is not known. |
| 1760 */ |
| 1761 static BoolState UNKNOWN_VALUE = new BoolState(null); |
| 1762 |
| 1763 /** |
| 1764 * Return the boolean state representing the given boolean value. |
| 1765 * |
| 1766 * @param value the value to be represented |
| 1767 * @return the boolean state representing the given boolean value |
| 1768 */ |
| 1769 static BoolState from(bool value) => value ? BoolState.TRUE_STATE : BoolState.
FALSE_STATE; |
| 1770 |
| 1771 /** |
| 1772 * Initialize a newly created state to represent the given value. |
| 1773 * |
| 1774 * @param value the value of this instance |
| 1775 */ |
| 1776 BoolState(this.value); |
| 1777 |
| 1778 BoolState convertToBool() => this; |
| 1779 |
| 1780 StringState convertToString() { |
| 1781 if (value == null) { |
| 1782 return StringState.UNKNOWN_VALUE; |
| 1783 } |
| 1784 return new StringState(value ? "true" : "false"); |
| 1785 } |
| 1786 |
| 1787 BoolState equalEqual(InstanceState rightOperand) { |
| 1788 assertBoolNumStringOrNull(rightOperand); |
| 1789 if (value == null) { |
| 1790 return UNKNOWN_VALUE; |
| 1791 } |
| 1792 if (rightOperand is BoolState) { |
| 1793 bool rightValue = (rightOperand as BoolState).value; |
| 1794 if (rightValue == null) { |
| 1795 return UNKNOWN_VALUE; |
| 1796 } |
| 1797 return BoolState.from(identical(value, rightValue)); |
| 1798 } else if (rightOperand is DynamicState) { |
| 1799 return UNKNOWN_VALUE; |
| 1800 } |
| 1801 return FALSE_STATE; |
| 1802 } |
| 1803 |
| 1804 bool operator ==(Object object) => object is BoolState && identical(value, (ob
ject as BoolState).value); |
| 1805 |
| 1806 String get typeName => "bool"; |
| 1807 |
| 1808 int get hashCode => value == null ? 0 : (value ? 2 : 3); |
| 1809 |
| 1810 /** |
| 1811 * Return `true` if this object represents an object whose type is 'bool'. |
| 1812 * |
| 1813 * @return `true` if this object represents a boolean value |
| 1814 */ |
| 1815 bool get isBool => true; |
| 1816 |
| 1817 bool get isBoolNumStringOrNull => true; |
| 1818 |
| 1819 BoolState logicalAnd(InstanceState rightOperand) { |
| 1820 assertBool(rightOperand); |
| 1821 if (value == null) { |
| 1822 return UNKNOWN_VALUE; |
| 1823 } |
| 1824 return value ? rightOperand.convertToBool() : FALSE_STATE; |
| 1825 } |
| 1826 |
| 1827 BoolState logicalNot() { |
| 1828 if (value == null) { |
| 1829 return UNKNOWN_VALUE; |
| 1830 } |
| 1831 return value ? FALSE_STATE : TRUE_STATE; |
| 1832 } |
| 1833 |
| 1834 BoolState logicalOr(InstanceState rightOperand) { |
| 1835 assertBool(rightOperand); |
| 1836 if (value == null) { |
| 1837 return UNKNOWN_VALUE; |
| 1838 } |
| 1839 return value ? TRUE_STATE : rightOperand.convertToBool(); |
| 1840 } |
| 1841 |
| 1842 String toString() => value == null ? "-unknown-" : (value ? "true" : "false"); |
| 1843 } |
| 1844 |
| 1845 /** |
| 1846 * Instances of the class `DartObjectImpl` represent an instance of a Dart class
. |
| 1847 */ |
| 1848 class DartObjectImpl implements DartObject { |
| 1849 /** |
| 1850 * The run-time type of this object. |
| 1851 */ |
| 1852 final InterfaceType type; |
| 1853 |
| 1854 /** |
| 1855 * The state of the object. |
| 1856 */ |
| 1857 InstanceState _state; |
| 1858 |
| 1859 /** |
| 1860 * Initialize a newly created object to have the given type and state. |
| 1861 * |
| 1862 * @param type the run-time type of this object |
| 1863 * @param state the state of the object |
| 1864 */ |
| 1865 DartObjectImpl(this.type, InstanceState state) { |
| 1866 this._state = state; |
| 1867 } |
| 1868 |
| 1869 /** |
| 1870 * Return the result of invoking the '+' operator on this object with the give
n argument. |
| 1871 * |
| 1872 * @param typeProvider the type provider used to find known types |
| 1873 * @param rightOperand the right-hand operand of the operation |
| 1874 * @return the result of invoking the '+' operator on this object with the giv
en argument |
| 1875 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 1876 */ |
| 1877 DartObjectImpl add(TypeProvider typeProvider, DartObjectImpl rightOperand) { |
| 1878 InstanceState result = _state.add(rightOperand._state); |
| 1879 if (result is IntState) { |
| 1880 return new DartObjectImpl(typeProvider.intType, result); |
| 1881 } else if (result is DoubleState) { |
| 1882 return new DartObjectImpl(typeProvider.doubleType, result); |
| 1883 } else if (result is NumState) { |
| 1884 return new DartObjectImpl(typeProvider.numType, result); |
| 1885 } |
| 1886 throw new IllegalStateException("add returned a ${result.runtimeType.toStrin
g()}"); |
| 1887 } |
| 1888 |
| 1889 /** |
| 1890 * Return the result of invoking the '&' operator on this object with the give
n argument. |
| 1891 * |
| 1892 * @param typeProvider the type provider used to find known types |
| 1893 * @param rightOperand the right-hand operand of the operation |
| 1894 * @return the result of invoking the '&' operator on this object with the giv
en argument |
| 1895 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 1896 */ |
| 1897 DartObjectImpl bitAnd(TypeProvider typeProvider, DartObjectImpl rightOperand)
=> new DartObjectImpl(typeProvider.intType, _state.bitAnd(rightOperand._state)); |
| 1898 |
| 1899 /** |
| 1900 * Return the result of invoking the '~' operator on this object. |
| 1901 * |
| 1902 * @param typeProvider the type provider used to find known types |
| 1903 * @return the result of invoking the '~' operator on this object |
| 1904 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 1905 */ |
| 1906 DartObjectImpl bitNot(TypeProvider typeProvider) => new DartObjectImpl(typePro
vider.intType, _state.bitNot()); |
| 1907 |
| 1908 /** |
| 1909 * Return the result of invoking the '|' operator on this object with the give
n argument. |
| 1910 * |
| 1911 * @param typeProvider the type provider used to find known types |
| 1912 * @param rightOperand the right-hand operand of the operation |
| 1913 * @return the result of invoking the '|' operator on this object with the giv
en argument |
| 1914 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 1915 */ |
| 1916 DartObjectImpl bitOr(TypeProvider typeProvider, DartObjectImpl rightOperand) =
> new DartObjectImpl(typeProvider.intType, _state.bitOr(rightOperand._state)); |
| 1917 |
| 1918 /** |
| 1919 * Return the result of invoking the '^' operator on this object with the give
n argument. |
| 1920 * |
| 1921 * @param typeProvider the type provider used to find known types |
| 1922 * @param rightOperand the right-hand operand of the operation |
| 1923 * @return the result of invoking the '^' operator on this object with the giv
en argument |
| 1924 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 1925 */ |
| 1926 DartObjectImpl bitXor(TypeProvider typeProvider, DartObjectImpl rightOperand)
=> new DartObjectImpl(typeProvider.intType, _state.bitXor(rightOperand._state)); |
| 1927 |
| 1928 /** |
| 1929 * Return the result of invoking the ' ' operator on this object with the give
n argument. |
| 1930 * |
| 1931 * @param typeProvider the type provider used to find known types |
| 1932 * @param rightOperand the right-hand operand of the operation |
| 1933 * @return the result of invoking the ' ' operator on this object with the giv
en argument |
| 1934 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 1935 */ |
| 1936 DartObjectImpl concatenate(TypeProvider typeProvider, DartObjectImpl rightOper
and) => new DartObjectImpl(typeProvider.stringType, _state.concatenate(rightOper
and._state)); |
| 1937 |
| 1938 /** |
| 1939 * Return the result of applying boolean conversion to this object. |
| 1940 * |
| 1941 * @param typeProvider the type provider used to find known types |
| 1942 * @return the result of applying boolean conversion to this object |
| 1943 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 1944 */ |
| 1945 DartObjectImpl convertToBool(TypeProvider typeProvider) { |
| 1946 InterfaceType boolType = typeProvider.boolType; |
| 1947 if (identical(type, boolType)) { |
| 1948 return this; |
| 1949 } |
| 1950 return new DartObjectImpl(boolType, _state.convertToBool()); |
| 1951 } |
| 1952 |
| 1953 /** |
| 1954 * Return the result of invoking the '/' operator on this object with the give
n argument. |
| 1955 * |
| 1956 * @param typeProvider the type provider used to find known types |
| 1957 * @param rightOperand the right-hand operand of the operation |
| 1958 * @return the result of invoking the '/' operator on this object with the giv
en argument |
| 1959 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 1960 */ |
| 1961 DartObjectImpl divide(TypeProvider typeProvider, DartObjectImpl rightOperand)
{ |
| 1962 InstanceState result = _state.divide(rightOperand._state); |
| 1963 if (result is IntState) { |
| 1964 return new DartObjectImpl(typeProvider.intType, result); |
| 1965 } else if (result is DoubleState) { |
| 1966 return new DartObjectImpl(typeProvider.doubleType, result); |
| 1967 } else if (result is NumState) { |
| 1968 return new DartObjectImpl(typeProvider.numType, result); |
| 1969 } |
| 1970 throw new IllegalStateException("divide returned a ${result.runtimeType.toSt
ring()}"); |
| 1971 } |
| 1972 |
| 1973 /** |
| 1974 * Return the result of invoking the '==' operator on this object with the giv
en argument. |
| 1975 * |
| 1976 * @param typeProvider the type provider used to find known types |
| 1977 * @param rightOperand the right-hand operand of the operation |
| 1978 * @return the result of invoking the '==' operator on this object with the gi
ven argument |
| 1979 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 1980 */ |
| 1981 DartObjectImpl equalEqual(TypeProvider typeProvider, DartObjectImpl rightOpera
nd) { |
| 1982 if (type != rightOperand.type) { |
| 1983 String typeName = type.name; |
| 1984 if (!(typeName == "bool" || typeName == "double" || typeName == "int" || t
ypeName == "num" || typeName == "String" || typeName == "Null" || type.isDynamic
)) { |
| 1985 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_
NUM_STRING); |
| 1986 } |
| 1987 } |
| 1988 return new DartObjectImpl(typeProvider.boolType, _state.equalEqual(rightOper
and._state)); |
| 1989 } |
| 1990 |
| 1991 bool operator ==(Object object) { |
| 1992 if (object is! DartObjectImpl) { |
| 1993 return false; |
| 1994 } |
| 1995 DartObjectImpl dartObject = object as DartObjectImpl; |
| 1996 return type == dartObject.type && _state == dartObject._state; |
| 1997 } |
| 1998 |
| 1999 Object get boolValue { |
| 2000 if (_state is BoolState) { |
| 2001 return (_state as BoolState).value; |
| 2002 } |
| 2003 return null; |
| 2004 } |
| 2005 |
| 2006 double get doubleValue { |
| 2007 if (_state is DoubleState) { |
| 2008 return (_state as DoubleState).value; |
| 2009 } |
| 2010 return null; |
| 2011 } |
| 2012 |
| 2013 int get intValue { |
| 2014 if (_state is IntState) { |
| 2015 return (_state as IntState).value; |
| 2016 } |
| 2017 return null; |
| 2018 } |
| 2019 |
| 2020 String get stringValue { |
| 2021 if (_state is StringState) { |
| 2022 return (_state as StringState).value; |
| 2023 } |
| 2024 return null; |
| 2025 } |
| 2026 |
| 2027 /** |
| 2028 * Return the result of invoking the '>' operator on this object with the g
iven argument. |
| 2029 * |
| 2030 * @param typeProvider the type provider used to find known types |
| 2031 * @param rightOperand the right-hand operand of the operation |
| 2032 * @return the result of invoking the '>' operator on this object with the
given argument |
| 2033 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 2034 */ |
| 2035 DartObjectImpl greaterThan(TypeProvider typeProvider, DartObjectImpl rightOper
and) => new DartObjectImpl(typeProvider.boolType, _state.greaterThan(rightOperan
d._state)); |
| 2036 |
| 2037 /** |
| 2038 * Return the result of invoking the '>=' operator on this object with the
given argument. |
| 2039 * |
| 2040 * @param typeProvider the type provider used to find known types |
| 2041 * @param rightOperand the right-hand operand of the operation |
| 2042 * @return the result of invoking the '>=' operator on this object with the
given argument |
| 2043 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 2044 */ |
| 2045 DartObjectImpl greaterThanOrEqual(TypeProvider typeProvider, DartObjectImpl ri
ghtOperand) => new DartObjectImpl(typeProvider.boolType, _state.greaterThanOrEqu
al(rightOperand._state)); |
| 2046 |
| 2047 int get hashCode => ObjectUtilities.combineHashCodes(type.hashCode, _state.has
hCode); |
| 2048 |
| 2049 /** |
| 2050 * Return the result of invoking the '~/' operator on this object with the giv
en argument. |
| 2051 * |
| 2052 * @param typeProvider the type provider used to find known types |
| 2053 * @param rightOperand the right-hand operand of the operation |
| 2054 * @return the result of invoking the '~/' operator on this object with the gi
ven argument |
| 2055 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 2056 */ |
| 2057 DartObjectImpl integerDivide(TypeProvider typeProvider, DartObjectImpl rightOp
erand) => new DartObjectImpl(typeProvider.intType, _state.integerDivide(rightOpe
rand._state)); |
| 2058 |
| 2059 /** |
| 2060 * Return `true` if this object represents an object whose type is 'bool'. |
| 2061 * |
| 2062 * @return `true` if this object represents a boolean value |
| 2063 */ |
| 2064 bool get isBool => _state.isBool; |
| 2065 |
| 2066 /** |
| 2067 * Return `true` if this object represents an object whose type is either 'boo
l', 'num', |
| 2068 * 'String', or 'Null'. |
| 2069 * |
| 2070 * @return `true` if this object represents either a boolean, numeric, string
or null value |
| 2071 */ |
| 2072 bool get isBoolNumStringOrNull => _state.isBoolNumStringOrNull; |
| 2073 |
| 2074 bool get isFalse => _state is BoolState && identical((_state as BoolState).val
ue, false); |
| 2075 |
| 2076 bool get isNull => _state is NullState; |
| 2077 |
| 2078 bool get isTrue => _state is BoolState && identical((_state as BoolState).valu
e, true); |
| 2079 |
| 2080 /** |
| 2081 * Return `true` if this object represents an instance of a user-defined class
. |
| 2082 * |
| 2083 * @return `true` if this object represents an instance of a user-defined clas
s |
| 2084 */ |
| 2085 bool get isUserDefinedObject => _state is GenericState; |
| 2086 |
| 2087 /** |
| 2088 * Return the result of invoking the '<' operator on this object with the g
iven argument. |
| 2089 * |
| 2090 * @param typeProvider the type provider used to find known types |
| 2091 * @param rightOperand the right-hand operand of the operation |
| 2092 * @return the result of invoking the '<' operator on this object with the
given argument |
| 2093 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 2094 */ |
| 2095 DartObjectImpl lessThan(TypeProvider typeProvider, DartObjectImpl rightOperand
) => new DartObjectImpl(typeProvider.boolType, _state.lessThan(rightOperand._sta
te)); |
| 2096 |
| 2097 /** |
| 2098 * Return the result of invoking the '<=' operator on this object with the
given argument. |
| 2099 * |
| 2100 * @param typeProvider the type provider used to find known types |
| 2101 * @param rightOperand the right-hand operand of the operation |
| 2102 * @return the result of invoking the '<=' operator on this object with the
given argument |
| 2103 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 2104 */ |
| 2105 DartObjectImpl lessThanOrEqual(TypeProvider typeProvider, DartObjectImpl right
Operand) => new DartObjectImpl(typeProvider.boolType, _state.lessThanOrEqual(rig
htOperand._state)); |
| 2106 |
| 2107 /** |
| 2108 * Return the result of invoking the '&&' operator on this object with the giv
en argument. |
| 2109 * |
| 2110 * @param typeProvider the type provider used to find known types |
| 2111 * @param rightOperand the right-hand operand of the operation |
| 2112 * @return the result of invoking the '&&' operator on this object with the gi
ven argument |
| 2113 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 2114 */ |
| 2115 DartObjectImpl logicalAnd(TypeProvider typeProvider, DartObjectImpl rightOpera
nd) => new DartObjectImpl(typeProvider.boolType, _state.logicalAnd(rightOperand.
_state)); |
| 2116 |
| 2117 /** |
| 2118 * Return the result of invoking the '!' operator on this object. |
| 2119 * |
| 2120 * @param typeProvider the type provider used to find known types |
| 2121 * @return the result of invoking the '!' operator on this object |
| 2122 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 2123 */ |
| 2124 DartObjectImpl logicalNot(TypeProvider typeProvider) => new DartObjectImpl(typ
eProvider.boolType, _state.logicalNot()); |
| 2125 |
| 2126 /** |
| 2127 * Return the result of invoking the '||' operator on this object with the giv
en argument. |
| 2128 * |
| 2129 * @param typeProvider the type provider used to find known types |
| 2130 * @param rightOperand the right-hand operand of the operation |
| 2131 * @return the result of invoking the '||' operator on this object with the gi
ven argument |
| 2132 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 2133 */ |
| 2134 DartObjectImpl logicalOr(TypeProvider typeProvider, DartObjectImpl rightOperan
d) => new DartObjectImpl(typeProvider.boolType, _state.logicalOr(rightOperand._s
tate)); |
| 2135 |
| 2136 /** |
| 2137 * Return the result of invoking the '-' operator on this object with the give
n argument. |
| 2138 * |
| 2139 * @param typeProvider the type provider used to find known types |
| 2140 * @param rightOperand the right-hand operand of the operation |
| 2141 * @return the result of invoking the '-' operator on this object with the giv
en argument |
| 2142 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 2143 */ |
| 2144 DartObjectImpl minus(TypeProvider typeProvider, DartObjectImpl rightOperand) { |
| 2145 InstanceState result = _state.minus(rightOperand._state); |
| 2146 if (result is IntState) { |
| 2147 return new DartObjectImpl(typeProvider.intType, result); |
| 2148 } else if (result is DoubleState) { |
| 2149 return new DartObjectImpl(typeProvider.doubleType, result); |
| 2150 } else if (result is NumState) { |
| 2151 return new DartObjectImpl(typeProvider.numType, result); |
| 2152 } |
| 2153 throw new IllegalStateException("minus returned a ${result.runtimeType.toStr
ing()}"); |
| 2154 } |
| 2155 |
| 2156 /** |
| 2157 * Return the result of invoking the '-' operator on this object. |
| 2158 * |
| 2159 * @param typeProvider the type provider used to find known types |
| 2160 * @return the result of invoking the '-' operator on this object |
| 2161 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 2162 */ |
| 2163 DartObjectImpl negated(TypeProvider typeProvider) { |
| 2164 InstanceState result = _state.negated(); |
| 2165 if (result is IntState) { |
| 2166 return new DartObjectImpl(typeProvider.intType, result); |
| 2167 } else if (result is DoubleState) { |
| 2168 return new DartObjectImpl(typeProvider.doubleType, result); |
| 2169 } else if (result is NumState) { |
| 2170 return new DartObjectImpl(typeProvider.numType, result); |
| 2171 } |
| 2172 throw new IllegalStateException("negated returned a ${result.runtimeType.toS
tring()}"); |
| 2173 } |
| 2174 |
| 2175 /** |
| 2176 * Return the result of invoking the '!=' operator on this object with the giv
en argument. |
| 2177 * |
| 2178 * @param typeProvider the type provider used to find known types |
| 2179 * @param rightOperand the right-hand operand of the operation |
| 2180 * @return the result of invoking the '!=' operator on this object with the gi
ven argument |
| 2181 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 2182 */ |
| 2183 DartObjectImpl notEqual(TypeProvider typeProvider, DartObjectImpl rightOperand
) { |
| 2184 if (type != rightOperand.type) { |
| 2185 String typeName = type.name; |
| 2186 if (typeName != "bool" && typeName != "double" && typeName != "int" && typ
eName != "num" && typeName != "String") { |
| 2187 return new DartObjectImpl(typeProvider.boolType, BoolState.TRUE_STATE); |
| 2188 } |
| 2189 } |
| 2190 return new DartObjectImpl(typeProvider.boolType, _state.equalEqual(rightOper
and._state).logicalNot()); |
| 2191 } |
| 2192 |
| 2193 /** |
| 2194 * Return the result of converting this object to a String. |
| 2195 * |
| 2196 * @param typeProvider the type provider used to find known types |
| 2197 * @return the result of converting this object to a String |
| 2198 * @throws EvaluationException if the object cannot be converted to a String |
| 2199 */ |
| 2200 DartObjectImpl performToString(TypeProvider typeProvider) { |
| 2201 InterfaceType stringType = typeProvider.stringType; |
| 2202 if (identical(type, stringType)) { |
| 2203 return this; |
| 2204 } |
| 2205 return new DartObjectImpl(stringType, _state.convertToString()); |
| 2206 } |
| 2207 |
| 2208 /** |
| 2209 * Return the result of invoking the '%' operator on this object with the give
n argument. |
| 2210 * |
| 2211 * @param typeProvider the type provider used to find known types |
| 2212 * @param rightOperand the right-hand operand of the operation |
| 2213 * @return the result of invoking the '%' operator on this object with the giv
en argument |
| 2214 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 2215 */ |
| 2216 DartObjectImpl remainder(TypeProvider typeProvider, DartObjectImpl rightOperan
d) { |
| 2217 InstanceState result = _state.remainder(rightOperand._state); |
| 2218 if (result is IntState) { |
| 2219 return new DartObjectImpl(typeProvider.intType, result); |
| 2220 } else if (result is DoubleState) { |
| 2221 return new DartObjectImpl(typeProvider.doubleType, result); |
| 2222 } else if (result is NumState) { |
| 2223 return new DartObjectImpl(typeProvider.numType, result); |
| 2224 } |
| 2225 throw new IllegalStateException("remainder returned a ${result.runtimeType.t
oString()}"); |
| 2226 } |
| 2227 |
| 2228 /** |
| 2229 * Return the result of invoking the '<<' operator on this object with t
he given argument. |
| 2230 * |
| 2231 * @param typeProvider the type provider used to find known types |
| 2232 * @param rightOperand the right-hand operand of the operation |
| 2233 * @return the result of invoking the '<<' operator on this object with
the given argument |
| 2234 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 2235 */ |
| 2236 DartObjectImpl shiftLeft(TypeProvider typeProvider, DartObjectImpl rightOperan
d) => new DartObjectImpl(typeProvider.intType, _state.shiftLeft(rightOperand._st
ate)); |
| 2237 |
| 2238 /** |
| 2239 * Return the result of invoking the '>>' operator on this object with t
he given argument. |
| 2240 * |
| 2241 * @param typeProvider the type provider used to find known types |
| 2242 * @param rightOperand the right-hand operand of the operation |
| 2243 * @return the result of invoking the '>>' operator on this object with
the given argument |
| 2244 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 2245 */ |
| 2246 DartObjectImpl shiftRight(TypeProvider typeProvider, DartObjectImpl rightOpera
nd) => new DartObjectImpl(typeProvider.intType, _state.shiftRight(rightOperand._
state)); |
| 2247 |
| 2248 /** |
| 2249 * Return the result of invoking the '*' operator on this object with the give
n argument. |
| 2250 * |
| 2251 * @param typeProvider the type provider used to find known types |
| 2252 * @param rightOperand the right-hand operand of the operation |
| 2253 * @return the result of invoking the '*' operator on this object with the giv
en argument |
| 2254 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 2255 */ |
| 2256 DartObjectImpl times(TypeProvider typeProvider, DartObjectImpl rightOperand) { |
| 2257 InstanceState result = _state.times(rightOperand._state); |
| 2258 if (result is IntState) { |
| 2259 return new DartObjectImpl(typeProvider.intType, result); |
| 2260 } else if (result is DoubleState) { |
| 2261 return new DartObjectImpl(typeProvider.doubleType, result); |
| 2262 } else if (result is NumState) { |
| 2263 return new DartObjectImpl(typeProvider.numType, result); |
| 2264 } |
| 2265 throw new IllegalStateException("times returned a ${result.runtimeType.toStr
ing()}"); |
| 2266 } |
| 2267 |
| 2268 String toString() => "${type.displayName} (${_state.toString()})"; |
| 2269 } |
| 2270 |
| 2271 /** |
| 2272 * Instances of the class `DoubleState` represent the state of an object represe
nting a |
| 2273 * double. |
| 2274 */ |
| 2275 class DoubleState extends NumState { |
| 2276 /** |
| 2277 * The value of this instance. |
| 2278 */ |
| 2279 final double value; |
| 2280 |
| 2281 /** |
| 2282 * A state that can be used to represent a double whose value is not known. |
| 2283 */ |
| 2284 static DoubleState UNKNOWN_VALUE = new DoubleState(null); |
| 2285 |
| 2286 /** |
| 2287 * Initialize a newly created state to represent a double with the given value
. |
| 2288 * |
| 2289 * @param value the value of this instance |
| 2290 */ |
| 2291 DoubleState(this.value); |
| 2292 |
| 2293 NumState add(InstanceState rightOperand) { |
| 2294 assertNumOrNull(rightOperand); |
| 2295 if (value == null) { |
| 2296 return UNKNOWN_VALUE; |
| 2297 } |
| 2298 if (rightOperand is IntState) { |
| 2299 int rightValue = (rightOperand as IntState).value; |
| 2300 if (rightValue == null) { |
| 2301 return UNKNOWN_VALUE; |
| 2302 } |
| 2303 return new DoubleState(value + rightValue.toDouble()); |
| 2304 } else if (rightOperand is DoubleState) { |
| 2305 double rightValue = (rightOperand as DoubleState).value; |
| 2306 if (rightValue == null) { |
| 2307 return UNKNOWN_VALUE; |
| 2308 } |
| 2309 return new DoubleState(value + rightValue); |
| 2310 } else if (rightOperand is DynamicState || rightOperand is NumState) { |
| 2311 return UNKNOWN_VALUE; |
| 2312 } |
| 2313 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI
ON); |
| 2314 } |
| 2315 |
| 2316 StringState convertToString() { |
| 2317 if (value == null) { |
| 2318 return StringState.UNKNOWN_VALUE; |
| 2319 } |
| 2320 return new StringState(value.toString()); |
| 2321 } |
| 2322 |
| 2323 NumState divide(InstanceState rightOperand) { |
| 2324 assertNumOrNull(rightOperand); |
| 2325 if (value == null) { |
| 2326 return UNKNOWN_VALUE; |
| 2327 } |
| 2328 if (rightOperand is IntState) { |
| 2329 int rightValue = (rightOperand as IntState).value; |
| 2330 if (rightValue == null) { |
| 2331 return UNKNOWN_VALUE; |
| 2332 } |
| 2333 return new DoubleState(value / rightValue.toDouble()); |
| 2334 } else if (rightOperand is DoubleState) { |
| 2335 double rightValue = (rightOperand as DoubleState).value; |
| 2336 if (rightValue == null) { |
| 2337 return UNKNOWN_VALUE; |
| 2338 } |
| 2339 return new DoubleState(value / rightValue); |
| 2340 } else if (rightOperand is DynamicState || rightOperand is NumState) { |
| 2341 return UNKNOWN_VALUE; |
| 2342 } |
| 2343 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI
ON); |
| 2344 } |
| 2345 |
| 2346 bool operator ==(Object object) => object is DoubleState && (value == (object
as DoubleState).value); |
| 2347 |
| 2348 BoolState equalEqual(InstanceState rightOperand) { |
| 2349 assertBoolNumStringOrNull(rightOperand); |
| 2350 if (value == null) { |
| 2351 return BoolState.UNKNOWN_VALUE; |
| 2352 } |
| 2353 if (rightOperand is DoubleState) { |
| 2354 double rightValue = (rightOperand as DoubleState).value; |
| 2355 if (rightValue == null) { |
| 2356 return BoolState.UNKNOWN_VALUE; |
| 2357 } |
| 2358 return BoolState.from(value == rightValue); |
| 2359 } else if (rightOperand is IntState) { |
| 2360 int rightValue = (rightOperand as IntState).value; |
| 2361 if (rightValue == null) { |
| 2362 return BoolState.UNKNOWN_VALUE; |
| 2363 } |
| 2364 return BoolState.from(value == rightValue.toDouble()); |
| 2365 } else if (rightOperand is DynamicState || rightOperand is NumState) { |
| 2366 return BoolState.UNKNOWN_VALUE; |
| 2367 } |
| 2368 return BoolState.FALSE_STATE; |
| 2369 } |
| 2370 |
| 2371 String get typeName => "double"; |
| 2372 |
| 2373 BoolState greaterThan(InstanceState rightOperand) { |
| 2374 assertNumOrNull(rightOperand); |
| 2375 if (value == null) { |
| 2376 return BoolState.UNKNOWN_VALUE; |
| 2377 } |
| 2378 if (rightOperand is IntState) { |
| 2379 int rightValue = (rightOperand as IntState).value; |
| 2380 if (rightValue == null) { |
| 2381 return BoolState.UNKNOWN_VALUE; |
| 2382 } |
| 2383 return BoolState.from(value > rightValue.toDouble()); |
| 2384 } else if (rightOperand is DoubleState) { |
| 2385 double rightValue = (rightOperand as DoubleState).value; |
| 2386 if (rightValue == null) { |
| 2387 return BoolState.UNKNOWN_VALUE; |
| 2388 } |
| 2389 return BoolState.from(value > rightValue); |
| 2390 } else if (rightOperand is DynamicState || rightOperand is NumState) { |
| 2391 return BoolState.UNKNOWN_VALUE; |
| 2392 } |
| 2393 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI
ON); |
| 2394 } |
| 2395 |
| 2396 BoolState greaterThanOrEqual(InstanceState rightOperand) { |
| 2397 assertNumOrNull(rightOperand); |
| 2398 if (value == null) { |
| 2399 return BoolState.UNKNOWN_VALUE; |
| 2400 } |
| 2401 if (rightOperand is IntState) { |
| 2402 int rightValue = (rightOperand as IntState).value; |
| 2403 if (rightValue == null) { |
| 2404 return BoolState.UNKNOWN_VALUE; |
| 2405 } |
| 2406 return BoolState.from(value >= rightValue.toDouble()); |
| 2407 } else if (rightOperand is DoubleState) { |
| 2408 double rightValue = (rightOperand as DoubleState).value; |
| 2409 if (rightValue == null) { |
| 2410 return BoolState.UNKNOWN_VALUE; |
| 2411 } |
| 2412 return BoolState.from(value >= rightValue); |
| 2413 } else if (rightOperand is DynamicState || rightOperand is NumState) { |
| 2414 return BoolState.UNKNOWN_VALUE; |
| 2415 } |
| 2416 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI
ON); |
| 2417 } |
| 2418 |
| 2419 int get hashCode => value == null ? 0 : value.hashCode; |
| 2420 |
| 2421 IntState integerDivide(InstanceState rightOperand) { |
| 2422 assertNumOrNull(rightOperand); |
| 2423 if (value == null) { |
| 2424 return IntState.UNKNOWN_VALUE; |
| 2425 } |
| 2426 if (rightOperand is IntState) { |
| 2427 int rightValue = (rightOperand as IntState).value; |
| 2428 if (rightValue == null) { |
| 2429 return IntState.UNKNOWN_VALUE; |
| 2430 } |
| 2431 double result = value / rightValue.toDouble(); |
| 2432 return new IntState(result.toInt()); |
| 2433 } else if (rightOperand is DoubleState) { |
| 2434 double rightValue = (rightOperand as DoubleState).value; |
| 2435 if (rightValue == null) { |
| 2436 return IntState.UNKNOWN_VALUE; |
| 2437 } |
| 2438 double result = value / rightValue; |
| 2439 return new IntState(result.toInt()); |
| 2440 } else if (rightOperand is DynamicState || rightOperand is NumState) { |
| 2441 return IntState.UNKNOWN_VALUE; |
| 2442 } |
| 2443 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI
ON); |
| 2444 } |
| 2445 |
| 2446 bool get isBoolNumStringOrNull => true; |
| 2447 |
| 2448 BoolState lessThan(InstanceState rightOperand) { |
| 2449 assertNumOrNull(rightOperand); |
| 2450 if (value == null) { |
| 2451 return BoolState.UNKNOWN_VALUE; |
| 2452 } |
| 2453 if (rightOperand is IntState) { |
| 2454 int rightValue = (rightOperand as IntState).value; |
| 2455 if (rightValue == null) { |
| 2456 return BoolState.UNKNOWN_VALUE; |
| 2457 } |
| 2458 return BoolState.from(value < rightValue.toDouble()); |
| 2459 } else if (rightOperand is DoubleState) { |
| 2460 double rightValue = (rightOperand as DoubleState).value; |
| 2461 if (rightValue == null) { |
| 2462 return BoolState.UNKNOWN_VALUE; |
| 2463 } |
| 2464 return BoolState.from(value < rightValue); |
| 2465 } else if (rightOperand is DynamicState || rightOperand is NumState) { |
| 2466 return BoolState.UNKNOWN_VALUE; |
| 2467 } |
| 2468 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI
ON); |
| 2469 } |
| 2470 |
| 2471 BoolState lessThanOrEqual(InstanceState rightOperand) { |
| 2472 assertNumOrNull(rightOperand); |
| 2473 if (value == null) { |
| 2474 return BoolState.UNKNOWN_VALUE; |
| 2475 } |
| 2476 if (rightOperand is IntState) { |
| 2477 int rightValue = (rightOperand as IntState).value; |
| 2478 if (rightValue == null) { |
| 2479 return BoolState.UNKNOWN_VALUE; |
| 2480 } |
| 2481 return BoolState.from(value <= rightValue.toDouble()); |
| 2482 } else if (rightOperand is DoubleState) { |
| 2483 double rightValue = (rightOperand as DoubleState).value; |
| 2484 if (rightValue == null) { |
| 2485 return BoolState.UNKNOWN_VALUE; |
| 2486 } |
| 2487 return BoolState.from(value <= rightValue); |
| 2488 } else if (rightOperand is DynamicState || rightOperand is NumState) { |
| 2489 return BoolState.UNKNOWN_VALUE; |
| 2490 } |
| 2491 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI
ON); |
| 2492 } |
| 2493 |
| 2494 NumState minus(InstanceState rightOperand) { |
| 2495 assertNumOrNull(rightOperand); |
| 2496 if (value == null) { |
| 2497 return UNKNOWN_VALUE; |
| 2498 } |
| 2499 if (rightOperand is IntState) { |
| 2500 int rightValue = (rightOperand as IntState).value; |
| 2501 if (rightValue == null) { |
| 2502 return UNKNOWN_VALUE; |
| 2503 } |
| 2504 return new DoubleState(value - rightValue.toDouble()); |
| 2505 } else if (rightOperand is DoubleState) { |
| 2506 double rightValue = (rightOperand as DoubleState).value; |
| 2507 if (rightValue == null) { |
| 2508 return UNKNOWN_VALUE; |
| 2509 } |
| 2510 return new DoubleState(value - rightValue); |
| 2511 } else if (rightOperand is DynamicState || rightOperand is NumState) { |
| 2512 return UNKNOWN_VALUE; |
| 2513 } |
| 2514 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI
ON); |
| 2515 } |
| 2516 |
| 2517 NumState negated() { |
| 2518 if (value == null) { |
| 2519 return UNKNOWN_VALUE; |
| 2520 } |
| 2521 return new DoubleState(-(value)); |
| 2522 } |
| 2523 |
| 2524 NumState remainder(InstanceState rightOperand) { |
| 2525 assertNumOrNull(rightOperand); |
| 2526 if (value == null) { |
| 2527 return UNKNOWN_VALUE; |
| 2528 } |
| 2529 if (rightOperand is IntState) { |
| 2530 int rightValue = (rightOperand as IntState).value; |
| 2531 if (rightValue == null) { |
| 2532 return UNKNOWN_VALUE; |
| 2533 } |
| 2534 return new DoubleState(value % rightValue.toDouble()); |
| 2535 } else if (rightOperand is DoubleState) { |
| 2536 double rightValue = (rightOperand as DoubleState).value; |
| 2537 if (rightValue == null) { |
| 2538 return UNKNOWN_VALUE; |
| 2539 } |
| 2540 return new DoubleState(value % rightValue); |
| 2541 } else if (rightOperand is DynamicState || rightOperand is NumState) { |
| 2542 return UNKNOWN_VALUE; |
| 2543 } |
| 2544 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI
ON); |
| 2545 } |
| 2546 |
| 2547 NumState times(InstanceState rightOperand) { |
| 2548 assertNumOrNull(rightOperand); |
| 2549 if (value == null) { |
| 2550 return UNKNOWN_VALUE; |
| 2551 } |
| 2552 if (rightOperand is IntState) { |
| 2553 int rightValue = (rightOperand as IntState).value; |
| 2554 if (rightValue == null) { |
| 2555 return UNKNOWN_VALUE; |
| 2556 } |
| 2557 return new DoubleState(value * rightValue.toDouble()); |
| 2558 } else if (rightOperand is DoubleState) { |
| 2559 double rightValue = (rightOperand as DoubleState).value; |
| 2560 if (rightValue == null) { |
| 2561 return UNKNOWN_VALUE; |
| 2562 } |
| 2563 return new DoubleState(value * rightValue); |
| 2564 } else if (rightOperand is DynamicState || rightOperand is NumState) { |
| 2565 return UNKNOWN_VALUE; |
| 2566 } |
| 2567 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI
ON); |
| 2568 } |
| 2569 |
| 2570 String toString() => value == null ? "-unknown-" : value.toString(); |
| 2571 } |
| 2572 |
| 2573 /** |
| 2574 * Instances of the class `DynamicState` represent the state of an object repres
enting a Dart |
| 2575 * object for which there is no type information. |
| 2576 */ |
| 2577 class DynamicState extends InstanceState { |
| 2578 /** |
| 2579 * The unique instance of this class. |
| 2580 */ |
| 2581 static DynamicState DYNAMIC_STATE = new DynamicState(); |
| 2582 |
| 2583 NumState add(InstanceState rightOperand) { |
| 2584 assertNumOrNull(rightOperand); |
| 2585 return unknownNum(rightOperand); |
| 2586 } |
| 2587 |
| 2588 IntState bitAnd(InstanceState rightOperand) { |
| 2589 assertIntOrNull(rightOperand); |
| 2590 return IntState.UNKNOWN_VALUE; |
| 2591 } |
| 2592 |
| 2593 IntState bitNot() => IntState.UNKNOWN_VALUE; |
| 2594 |
| 2595 IntState bitOr(InstanceState rightOperand) { |
| 2596 assertIntOrNull(rightOperand); |
| 2597 return IntState.UNKNOWN_VALUE; |
| 2598 } |
| 2599 |
| 2600 IntState bitXor(InstanceState rightOperand) { |
| 2601 assertIntOrNull(rightOperand); |
| 2602 return IntState.UNKNOWN_VALUE; |
| 2603 } |
| 2604 |
| 2605 StringState concatenate(InstanceState rightOperand) { |
| 2606 assertString(rightOperand); |
| 2607 return StringState.UNKNOWN_VALUE; |
| 2608 } |
| 2609 |
| 2610 BoolState convertToBool() => BoolState.UNKNOWN_VALUE; |
| 2611 |
| 2612 StringState convertToString() => StringState.UNKNOWN_VALUE; |
| 2613 |
| 2614 NumState divide(InstanceState rightOperand) { |
| 2615 assertNumOrNull(rightOperand); |
| 2616 return unknownNum(rightOperand); |
| 2617 } |
| 2618 |
| 2619 BoolState equalEqual(InstanceState rightOperand) { |
| 2620 assertBoolNumStringOrNull(rightOperand); |
| 2621 return BoolState.UNKNOWN_VALUE; |
| 2622 } |
| 2623 |
| 2624 String get typeName => "dynamic"; |
| 2625 |
| 2626 BoolState greaterThan(InstanceState rightOperand) { |
| 2627 assertNumOrNull(rightOperand); |
| 2628 return BoolState.UNKNOWN_VALUE; |
| 2629 } |
| 2630 |
| 2631 BoolState greaterThanOrEqual(InstanceState rightOperand) { |
| 2632 assertNumOrNull(rightOperand); |
| 2633 return BoolState.UNKNOWN_VALUE; |
| 2634 } |
| 2635 |
| 2636 IntState integerDivide(InstanceState rightOperand) { |
| 2637 assertNumOrNull(rightOperand); |
| 2638 return IntState.UNKNOWN_VALUE; |
| 2639 } |
| 2640 |
| 2641 bool get isBool => true; |
| 2642 |
| 2643 bool get isBoolNumStringOrNull => true; |
| 2644 |
| 2645 BoolState lessThan(InstanceState rightOperand) { |
| 2646 assertNumOrNull(rightOperand); |
| 2647 return BoolState.UNKNOWN_VALUE; |
| 2648 } |
| 2649 |
| 2650 BoolState lessThanOrEqual(InstanceState rightOperand) { |
| 2651 assertNumOrNull(rightOperand); |
| 2652 return BoolState.UNKNOWN_VALUE; |
| 2653 } |
| 2654 |
| 2655 BoolState logicalAnd(InstanceState rightOperand) { |
| 2656 assertBool(rightOperand); |
| 2657 return BoolState.UNKNOWN_VALUE; |
| 2658 } |
| 2659 |
| 2660 BoolState logicalNot() => BoolState.UNKNOWN_VALUE; |
| 2661 |
| 2662 BoolState logicalOr(InstanceState rightOperand) { |
| 2663 assertBool(rightOperand); |
| 2664 return rightOperand.convertToBool(); |
| 2665 } |
| 2666 |
| 2667 NumState minus(InstanceState rightOperand) { |
| 2668 assertNumOrNull(rightOperand); |
| 2669 return unknownNum(rightOperand); |
| 2670 } |
| 2671 |
| 2672 NumState negated() => NumState.UNKNOWN_VALUE; |
| 2673 |
| 2674 NumState remainder(InstanceState rightOperand) { |
| 2675 assertNumOrNull(rightOperand); |
| 2676 return unknownNum(rightOperand); |
| 2677 } |
| 2678 |
| 2679 IntState shiftLeft(InstanceState rightOperand) { |
| 2680 assertIntOrNull(rightOperand); |
| 2681 return IntState.UNKNOWN_VALUE; |
| 2682 } |
| 2683 |
| 2684 IntState shiftRight(InstanceState rightOperand) { |
| 2685 assertIntOrNull(rightOperand); |
| 2686 return IntState.UNKNOWN_VALUE; |
| 2687 } |
| 2688 |
| 2689 NumState times(InstanceState rightOperand) { |
| 2690 assertNumOrNull(rightOperand); |
| 2691 return unknownNum(rightOperand); |
| 2692 } |
| 2693 |
| 2694 /** |
| 2695 * Return an object representing an unknown numeric value whose type is based
on the type of the |
| 2696 * right-hand operand. |
| 2697 * |
| 2698 * @param rightOperand the operand whose type will determine the type of the r
esult |
| 2699 * @return an object representing an unknown numeric value |
| 2700 */ |
| 2701 NumState unknownNum(InstanceState rightOperand) { |
| 2702 if (rightOperand is IntState) { |
| 2703 return IntState.UNKNOWN_VALUE; |
| 2704 } else if (rightOperand is DoubleState) { |
| 2705 return DoubleState.UNKNOWN_VALUE; |
| 2706 } |
| 2707 return NumState.UNKNOWN_VALUE; |
| 2708 } |
| 2709 } |
| 2710 |
| 2711 /** |
| 2712 * Instances of the class `EvaluationException` represent a run-time exception t
hat would be |
| 2713 * thrown during the evaluation of Dart code. |
| 2714 */ |
| 2715 class EvaluationException extends JavaException { |
| 2716 /** |
| 2717 * The error code associated with the exception. |
| 2718 */ |
| 2719 final ErrorCode errorCode; |
| 2720 |
| 2721 /** |
| 2722 * Initialize a newly created exception to have the given error code. |
| 2723 * |
| 2724 * @param errorCode the error code associated with the exception |
| 2725 */ |
| 2726 EvaluationException(this.errorCode); |
| 2727 } |
| 2728 |
| 2729 /** |
| 2730 * Instances of the class `FunctionState` represent the state of an object repre
senting a |
| 2731 * function. |
| 2732 */ |
| 2733 class FunctionState extends InstanceState { |
| 2734 /** |
| 2735 * The element representing the function being modeled. |
| 2736 */ |
| 2737 ExecutableElement _element; |
| 2738 |
| 2739 /** |
| 2740 * Initialize a newly created state to represent the given function. |
| 2741 * |
| 2742 * @param element the element representing the function being modeled |
| 2743 */ |
| 2744 FunctionState(ExecutableElement element) { |
| 2745 this._element = element; |
| 2746 } |
| 2747 |
| 2748 StringState convertToString() { |
| 2749 if (_element == null) { |
| 2750 return StringState.UNKNOWN_VALUE; |
| 2751 } |
| 2752 return new StringState(_element.name); |
| 2753 } |
| 2754 |
| 2755 bool operator ==(Object object) => object is FunctionState && (_element == (ob
ject as FunctionState)._element); |
| 2756 |
| 2757 BoolState equalEqual(InstanceState rightOperand) { |
| 2758 if (_element == null) { |
| 2759 return BoolState.UNKNOWN_VALUE; |
| 2760 } |
| 2761 if (rightOperand is FunctionState) { |
| 2762 ExecutableElement rightElement = (rightOperand as FunctionState)._element; |
| 2763 if (rightElement == null) { |
| 2764 return BoolState.UNKNOWN_VALUE; |
| 2765 } |
| 2766 return BoolState.from(_element == rightElement); |
| 2767 } else if (rightOperand is DynamicState) { |
| 2768 return BoolState.UNKNOWN_VALUE; |
| 2769 } |
| 2770 return BoolState.FALSE_STATE; |
| 2771 } |
| 2772 |
| 2773 String get typeName => "Function"; |
| 2774 |
| 2775 int get hashCode => _element == null ? 0 : _element.hashCode; |
| 2776 |
| 2777 String toString() => _element == null ? "-unknown-" : _element.name; |
| 2778 } |
| 2779 |
| 2780 /** |
| 2781 * Instances of the class `GenericState` represent the state of an object repres
enting a Dart |
| 2782 * object for which there is no more specific state. |
| 2783 */ |
| 2784 class GenericState extends InstanceState { |
| 2785 /** |
| 2786 * The values of the fields of this instance. |
| 2787 */ |
| 2788 Map<String, DartObjectImpl> _fieldMap = new Map<String, DartObjectImpl>(); |
| 2789 |
| 2790 /** |
| 2791 * A state that can be used to represent an object whose state is not known. |
| 2792 */ |
| 2793 static GenericState UNKNOWN_VALUE = new GenericState(new Map<String, DartObjec
tImpl>()); |
| 2794 |
| 2795 /** |
| 2796 * Initialize a newly created state to represent a newly created object. |
| 2797 * |
| 2798 * @param fieldMap the values of the fields of this instance |
| 2799 */ |
| 2800 GenericState(Map<String, DartObjectImpl> fieldMap) { |
| 2801 this._fieldMap = fieldMap; |
| 2802 } |
| 2803 |
| 2804 StringState convertToString() => StringState.UNKNOWN_VALUE; |
| 2805 |
| 2806 bool operator ==(Object object) { |
| 2807 if (object is! GenericState) { |
| 2808 return false; |
| 2809 } |
| 2810 GenericState state = object as GenericState; |
| 2811 Set<String> otherFields = new Set<String>(); |
| 2812 for (String fieldName in _fieldMap.keys.toSet()) { |
| 2813 if (_fieldMap[fieldName] != state._fieldMap[fieldName]) { |
| 2814 return false; |
| 2815 } |
| 2816 otherFields.remove(fieldName); |
| 2817 } |
| 2818 for (String fieldName in otherFields) { |
| 2819 if (state._fieldMap[fieldName] != _fieldMap[fieldName]) { |
| 2820 return false; |
| 2821 } |
| 2822 } |
| 2823 return true; |
| 2824 } |
| 2825 |
| 2826 BoolState equalEqual(InstanceState rightOperand) { |
| 2827 assertBoolNumStringOrNull(rightOperand); |
| 2828 if (rightOperand is DynamicState) { |
| 2829 return BoolState.UNKNOWN_VALUE; |
| 2830 } |
| 2831 return BoolState.from(this == rightOperand); |
| 2832 } |
| 2833 |
| 2834 String get typeName => "user defined type"; |
| 2835 |
| 2836 int get hashCode { |
| 2837 int hashCode = 0; |
| 2838 for (DartObjectImpl value in _fieldMap.values) { |
| 2839 hashCode += value.hashCode; |
| 2840 } |
| 2841 return hashCode; |
| 2842 } |
| 2843 } |
| 2844 |
| 2845 /** |
| 2846 * The class `InstanceState` defines the behavior of objects representing the st
ate of a Dart |
| 2847 * object. |
| 2848 */ |
| 2849 abstract class InstanceState { |
| 2850 /** |
| 2851 * Return the result of invoking the '+' operator on this object with the give
n argument. |
| 2852 * |
| 2853 * @param rightOperand the right-hand operand of the operation |
| 2854 * @return the result of invoking the '+' operator on this object with the giv
en argument |
| 2855 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 2856 */ |
| 2857 NumState add(InstanceState rightOperand) { |
| 2858 assertNumOrNull(this); |
| 2859 assertNumOrNull(rightOperand); |
| 2860 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); |
| 2861 } |
| 2862 |
| 2863 /** |
| 2864 * Return the result of invoking the '&' operator on this object with the give
n argument. |
| 2865 * |
| 2866 * @param rightOperand the right-hand operand of the operation |
| 2867 * @return the result of invoking the '&' operator on this object with the giv
en argument |
| 2868 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 2869 */ |
| 2870 IntState bitAnd(InstanceState rightOperand) { |
| 2871 assertIntOrNull(this); |
| 2872 assertIntOrNull(rightOperand); |
| 2873 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); |
| 2874 } |
| 2875 |
| 2876 /** |
| 2877 * Return the result of invoking the '~' operator on this object. |
| 2878 * |
| 2879 * @return the result of invoking the '~' operator on this object |
| 2880 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 2881 */ |
| 2882 IntState bitNot() { |
| 2883 assertIntOrNull(this); |
| 2884 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); |
| 2885 } |
| 2886 |
| 2887 /** |
| 2888 * Return the result of invoking the '|' operator on this object with the give
n argument. |
| 2889 * |
| 2890 * @param rightOperand the right-hand operand of the operation |
| 2891 * @return the result of invoking the '|' operator on this object with the giv
en argument |
| 2892 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 2893 */ |
| 2894 IntState bitOr(InstanceState rightOperand) { |
| 2895 assertIntOrNull(this); |
| 2896 assertIntOrNull(rightOperand); |
| 2897 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); |
| 2898 } |
| 2899 |
| 2900 /** |
| 2901 * Return the result of invoking the '^' operator on this object with the give
n argument. |
| 2902 * |
| 2903 * @param rightOperand the right-hand operand of the operation |
| 2904 * @return the result of invoking the '^' operator on this object with the giv
en argument |
| 2905 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 2906 */ |
| 2907 IntState bitXor(InstanceState rightOperand) { |
| 2908 assertIntOrNull(this); |
| 2909 assertIntOrNull(rightOperand); |
| 2910 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); |
| 2911 } |
| 2912 |
| 2913 /** |
| 2914 * Return the result of invoking the ' ' operator on this object with the give
n argument. |
| 2915 * |
| 2916 * @param rightOperand the right-hand operand of the operation |
| 2917 * @return the result of invoking the ' ' operator on this object with the giv
en argument |
| 2918 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 2919 */ |
| 2920 StringState concatenate(InstanceState rightOperand) { |
| 2921 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); |
| 2922 } |
| 2923 |
| 2924 /** |
| 2925 * Return the result of applying boolean conversion to this object. |
| 2926 * |
| 2927 * @param typeProvider the type provider used to find known types |
| 2928 * @return the result of applying boolean conversion to this object |
| 2929 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 2930 */ |
| 2931 BoolState convertToBool() => BoolState.FALSE_STATE; |
| 2932 |
| 2933 /** |
| 2934 * Return the result of converting this object to a String. |
| 2935 * |
| 2936 * @return the result of converting this object to a String |
| 2937 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 2938 */ |
| 2939 StringState convertToString(); |
| 2940 |
| 2941 /** |
| 2942 * Return the result of invoking the '/' operator on this object with the give
n argument. |
| 2943 * |
| 2944 * @param rightOperand the right-hand operand of the operation |
| 2945 * @return the result of invoking the '/' operator on this object with the giv
en argument |
| 2946 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 2947 */ |
| 2948 NumState divide(InstanceState rightOperand) { |
| 2949 assertNumOrNull(this); |
| 2950 assertNumOrNull(rightOperand); |
| 2951 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); |
| 2952 } |
| 2953 |
| 2954 /** |
| 2955 * Return the result of invoking the '==' operator on this object with the giv
en argument. |
| 2956 * |
| 2957 * @param rightOperand the right-hand operand of the operation |
| 2958 * @return the result of invoking the '==' operator on this object with the gi
ven argument |
| 2959 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 2960 */ |
| 2961 BoolState equalEqual(InstanceState rightOperand); |
| 2962 |
| 2963 /** |
| 2964 * Return the name of the type of this value. |
| 2965 * |
| 2966 * @return the name of the type of this value |
| 2967 */ |
| 2968 String get typeName; |
| 2969 |
| 2970 /** |
| 2971 * Return the result of invoking the '>' operator on this object with the g
iven argument. |
| 2972 * |
| 2973 * @param rightOperand the right-hand operand of the operation |
| 2974 * @return the result of invoking the '>' operator on this object with the
given argument |
| 2975 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 2976 */ |
| 2977 BoolState greaterThan(InstanceState rightOperand) { |
| 2978 assertNumOrNull(this); |
| 2979 assertNumOrNull(rightOperand); |
| 2980 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); |
| 2981 } |
| 2982 |
| 2983 /** |
| 2984 * Return the result of invoking the '>=' operator on this object with the
given argument. |
| 2985 * |
| 2986 * @param rightOperand the right-hand operand of the operation |
| 2987 * @return the result of invoking the '>=' operator on this object with the
given argument |
| 2988 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 2989 */ |
| 2990 BoolState greaterThanOrEqual(InstanceState rightOperand) { |
| 2991 assertNumOrNull(this); |
| 2992 assertNumOrNull(rightOperand); |
| 2993 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); |
| 2994 } |
| 2995 |
| 2996 /** |
| 2997 * Return the result of invoking the '~/' operator on this object with the giv
en argument. |
| 2998 * |
| 2999 * @param rightOperand the right-hand operand of the operation |
| 3000 * @return the result of invoking the '~/' operator on this object with the gi
ven argument |
| 3001 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 3002 */ |
| 3003 IntState integerDivide(InstanceState rightOperand) { |
| 3004 assertNumOrNull(this); |
| 3005 assertNumOrNull(rightOperand); |
| 3006 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); |
| 3007 } |
| 3008 |
| 3009 /** |
| 3010 * Return `true` if this object represents an object whose type is 'bool'. |
| 3011 * |
| 3012 * @return `true` if this object represents a boolean value |
| 3013 */ |
| 3014 bool get isBool => false; |
| 3015 |
| 3016 /** |
| 3017 * Return `true` if this object represents an object whose type is either 'boo
l', 'num', |
| 3018 * 'String', or 'Null'. |
| 3019 * |
| 3020 * @return `true` if this object represents either a boolean, numeric, string
or null value |
| 3021 */ |
| 3022 bool get isBoolNumStringOrNull => false; |
| 3023 |
| 3024 /** |
| 3025 * Return the result of invoking the '<' operator on this object with the g
iven argument. |
| 3026 * |
| 3027 * @param rightOperand the right-hand operand of the operation |
| 3028 * @return the result of invoking the '<' operator on this object with the
given argument |
| 3029 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 3030 */ |
| 3031 BoolState lessThan(InstanceState rightOperand) { |
| 3032 assertNumOrNull(this); |
| 3033 assertNumOrNull(rightOperand); |
| 3034 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); |
| 3035 } |
| 3036 |
| 3037 /** |
| 3038 * Return the result of invoking the '<=' operator on this object with the
given argument. |
| 3039 * |
| 3040 * @param rightOperand the right-hand operand of the operation |
| 3041 * @return the result of invoking the '<=' operator on this object with the
given argument |
| 3042 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 3043 */ |
| 3044 BoolState lessThanOrEqual(InstanceState rightOperand) { |
| 3045 assertNumOrNull(this); |
| 3046 assertNumOrNull(rightOperand); |
| 3047 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); |
| 3048 } |
| 3049 |
| 3050 /** |
| 3051 * Return the result of invoking the '&&' operator on this object with the giv
en argument. |
| 3052 * |
| 3053 * @param rightOperand the right-hand operand of the operation |
| 3054 * @return the result of invoking the '&&' operator on this object with the gi
ven argument |
| 3055 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 3056 */ |
| 3057 BoolState logicalAnd(InstanceState rightOperand) { |
| 3058 assertBool(this); |
| 3059 assertBool(rightOperand); |
| 3060 return BoolState.FALSE_STATE; |
| 3061 } |
| 3062 |
| 3063 /** |
| 3064 * Return the result of invoking the '!' operator on this object. |
| 3065 * |
| 3066 * @return the result of invoking the '!' operator on this object |
| 3067 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 3068 */ |
| 3069 BoolState logicalNot() { |
| 3070 assertBool(this); |
| 3071 return BoolState.TRUE_STATE; |
| 3072 } |
| 3073 |
| 3074 /** |
| 3075 * Return the result of invoking the '||' operator on this object with the giv
en argument. |
| 3076 * |
| 3077 * @param rightOperand the right-hand operand of the operation |
| 3078 * @return the result of invoking the '||' operator on this object with the gi
ven argument |
| 3079 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 3080 */ |
| 3081 BoolState logicalOr(InstanceState rightOperand) { |
| 3082 assertBool(this); |
| 3083 assertBool(rightOperand); |
| 3084 return rightOperand.convertToBool(); |
| 3085 } |
| 3086 |
| 3087 /** |
| 3088 * Return the result of invoking the '-' operator on this object with the give
n argument. |
| 3089 * |
| 3090 * @param rightOperand the right-hand operand of the operation |
| 3091 * @return the result of invoking the '-' operator on this object with the giv
en argument |
| 3092 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 3093 */ |
| 3094 NumState minus(InstanceState rightOperand) { |
| 3095 assertNumOrNull(this); |
| 3096 assertNumOrNull(rightOperand); |
| 3097 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); |
| 3098 } |
| 3099 |
| 3100 /** |
| 3101 * Return the result of invoking the '-' operator on this object. |
| 3102 * |
| 3103 * @return the result of invoking the '-' operator on this object |
| 3104 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 3105 */ |
| 3106 NumState negated() { |
| 3107 assertNumOrNull(this); |
| 3108 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); |
| 3109 } |
| 3110 |
| 3111 /** |
| 3112 * Return the result of invoking the '%' operator on this object with the give
n argument. |
| 3113 * |
| 3114 * @param rightOperand the right-hand operand of the operation |
| 3115 * @return the result of invoking the '%' operator on this object with the giv
en argument |
| 3116 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 3117 */ |
| 3118 NumState remainder(InstanceState rightOperand) { |
| 3119 assertNumOrNull(this); |
| 3120 assertNumOrNull(rightOperand); |
| 3121 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); |
| 3122 } |
| 3123 |
| 3124 /** |
| 3125 * Return the result of invoking the '<<' operator on this object with t
he given argument. |
| 3126 * |
| 3127 * @param rightOperand the right-hand operand of the operation |
| 3128 * @return the result of invoking the '<<' operator on this object with
the given argument |
| 3129 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 3130 */ |
| 3131 IntState shiftLeft(InstanceState rightOperand) { |
| 3132 assertIntOrNull(this); |
| 3133 assertIntOrNull(rightOperand); |
| 3134 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); |
| 3135 } |
| 3136 |
| 3137 /** |
| 3138 * Return the result of invoking the '>>' operator on this object with t
he given argument. |
| 3139 * |
| 3140 * @param rightOperand the right-hand operand of the operation |
| 3141 * @return the result of invoking the '>>' operator on this object with
the given argument |
| 3142 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 3143 */ |
| 3144 IntState shiftRight(InstanceState rightOperand) { |
| 3145 assertIntOrNull(this); |
| 3146 assertIntOrNull(rightOperand); |
| 3147 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); |
| 3148 } |
| 3149 |
| 3150 /** |
| 3151 * Return the result of invoking the '*' operator on this object with the give
n argument. |
| 3152 * |
| 3153 * @param rightOperand the right-hand operand of the operation |
| 3154 * @return the result of invoking the '*' operator on this object with the giv
en argument |
| 3155 * @throws EvaluationException if the operator is not appropriate for an objec
t of this kind |
| 3156 */ |
| 3157 NumState times(InstanceState rightOperand) { |
| 3158 assertNumOrNull(this); |
| 3159 assertNumOrNull(rightOperand); |
| 3160 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); |
| 3161 } |
| 3162 |
| 3163 /** |
| 3164 * Throw an exception if the given state does not represent a boolean value. |
| 3165 * |
| 3166 * @param state the state being tested |
| 3167 * @throws EvaluationException if the given state does not represent a boolean
value |
| 3168 */ |
| 3169 void assertBool(InstanceState state) { |
| 3170 if (!(state is BoolState || state is DynamicState)) { |
| 3171 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL); |
| 3172 } |
| 3173 } |
| 3174 |
| 3175 /** |
| 3176 * Throw an exception if the given state does not represent a boolean, numeric
, string or null |
| 3177 * value. |
| 3178 * |
| 3179 * @param state the state being tested |
| 3180 * @throws EvaluationException if the given state does not represent a boolean
, numeric, string or |
| 3181 * null value |
| 3182 */ |
| 3183 void assertBoolNumStringOrNull(InstanceState state) { |
| 3184 if (!(state is BoolState || state is DoubleState || state is IntState || sta
te is NumState || state is StringState || state is NullState || state is Dynamic
State)) { |
| 3185 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NU
M_STRING); |
| 3186 } |
| 3187 } |
| 3188 |
| 3189 /** |
| 3190 * Throw an exception if the given state does not represent an integer or null
value. |
| 3191 * |
| 3192 * @param state the state being tested |
| 3193 * @throws EvaluationException if the given state does not represent an intege
r or null value |
| 3194 */ |
| 3195 void assertIntOrNull(InstanceState state) { |
| 3196 if (!(state is IntState || state is NumState || state is NullState || state
is DynamicState)) { |
| 3197 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_INT); |
| 3198 } |
| 3199 } |
| 3200 |
| 3201 /** |
| 3202 * Throw an exception if the given state does not represent a boolean, numeric
, string or null |
| 3203 * value. |
| 3204 * |
| 3205 * @param state the state being tested |
| 3206 * @throws EvaluationException if the given state does not represent a boolean
, numeric, string or |
| 3207 * null value |
| 3208 */ |
| 3209 void assertNumOrNull(InstanceState state) { |
| 3210 if (!(state is DoubleState || state is IntState || state is NumState || stat
e is NullState || state is DynamicState)) { |
| 3211 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_NUM); |
| 3212 } |
| 3213 } |
| 3214 |
| 3215 /** |
| 3216 * Throw an exception if the given state does not represent a String value. |
| 3217 * |
| 3218 * @param state the state being tested |
| 3219 * @throws EvaluationException if the given state does not represent a String
value |
| 3220 */ |
| 3221 void assertString(InstanceState state) { |
| 3222 if (!(state is StringState || state is DynamicState)) { |
| 3223 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL); |
| 3224 } |
| 3225 } |
| 3226 } |
| 3227 |
| 3228 /** |
| 3229 * Instances of the class `IntState` represent the state of an object representi
ng an int. |
| 3230 */ |
| 3231 class IntState extends NumState { |
| 3232 /** |
| 3233 * The value of this instance. |
| 3234 */ |
| 3235 final int value; |
| 3236 |
| 3237 /** |
| 3238 * A state that can be used to represent an int whose value is not known. |
| 3239 */ |
| 3240 static IntState UNKNOWN_VALUE = new IntState(null); |
| 3241 |
| 3242 /** |
| 3243 * Initialize a newly created state to represent an int with the given value. |
| 3244 * |
| 3245 * @param value the value of this instance |
| 3246 */ |
| 3247 IntState(this.value); |
| 3248 |
| 3249 NumState add(InstanceState rightOperand) { |
| 3250 assertNumOrNull(rightOperand); |
| 3251 if (value == null) { |
| 3252 if (rightOperand is DoubleState) { |
| 3253 return DoubleState.UNKNOWN_VALUE; |
| 3254 } |
| 3255 return UNKNOWN_VALUE; |
| 3256 } |
| 3257 if (rightOperand is IntState) { |
| 3258 int rightValue = (rightOperand as IntState).value; |
| 3259 if (rightValue == null) { |
| 3260 return UNKNOWN_VALUE; |
| 3261 } |
| 3262 return new IntState(value + rightValue); |
| 3263 } else if (rightOperand is DoubleState) { |
| 3264 double rightValue = (rightOperand as DoubleState).value; |
| 3265 if (rightValue == null) { |
| 3266 return DoubleState.UNKNOWN_VALUE; |
| 3267 } |
| 3268 return new DoubleState(value.toDouble() + rightValue); |
| 3269 } else if (rightOperand is DynamicState || rightOperand is NumState) { |
| 3270 return UNKNOWN_VALUE; |
| 3271 } |
| 3272 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI
ON); |
| 3273 } |
| 3274 |
| 3275 IntState bitAnd(InstanceState rightOperand) { |
| 3276 assertIntOrNull(rightOperand); |
| 3277 if (value == null) { |
| 3278 return UNKNOWN_VALUE; |
| 3279 } |
| 3280 if (rightOperand is IntState) { |
| 3281 int rightValue = (rightOperand as IntState).value; |
| 3282 if (rightValue == null) { |
| 3283 return UNKNOWN_VALUE; |
| 3284 } |
| 3285 return new IntState(value & rightValue); |
| 3286 } else if (rightOperand is DynamicState || rightOperand is NumState) { |
| 3287 return UNKNOWN_VALUE; |
| 3288 } |
| 3289 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI
ON); |
| 3290 } |
| 3291 |
| 3292 IntState bitNot() { |
| 3293 if (value == null) { |
| 3294 return UNKNOWN_VALUE; |
| 3295 } |
| 3296 return new IntState(~value); |
| 3297 } |
| 3298 |
| 3299 IntState bitOr(InstanceState rightOperand) { |
| 3300 assertIntOrNull(rightOperand); |
| 3301 if (value == null) { |
| 3302 return UNKNOWN_VALUE; |
| 3303 } |
| 3304 if (rightOperand is IntState) { |
| 3305 int rightValue = (rightOperand as IntState).value; |
| 3306 if (rightValue == null) { |
| 3307 return UNKNOWN_VALUE; |
| 3308 } |
| 3309 return new IntState(value | rightValue); |
| 3310 } else if (rightOperand is DynamicState || rightOperand is NumState) { |
| 3311 return UNKNOWN_VALUE; |
| 3312 } |
| 3313 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI
ON); |
| 3314 } |
| 3315 |
| 3316 IntState bitXor(InstanceState rightOperand) { |
| 3317 assertIntOrNull(rightOperand); |
| 3318 if (value == null) { |
| 3319 return UNKNOWN_VALUE; |
| 3320 } |
| 3321 if (rightOperand is IntState) { |
| 3322 int rightValue = (rightOperand as IntState).value; |
| 3323 if (rightValue == null) { |
| 3324 return UNKNOWN_VALUE; |
| 3325 } |
| 3326 return new IntState(value ^ rightValue); |
| 3327 } else if (rightOperand is DynamicState || rightOperand is NumState) { |
| 3328 return UNKNOWN_VALUE; |
| 3329 } |
| 3330 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI
ON); |
| 3331 } |
| 3332 |
| 3333 StringState convertToString() { |
| 3334 if (value == null) { |
| 3335 return StringState.UNKNOWN_VALUE; |
| 3336 } |
| 3337 return new StringState(value.toString()); |
| 3338 } |
| 3339 |
| 3340 NumState divide(InstanceState rightOperand) { |
| 3341 assertNumOrNull(rightOperand); |
| 3342 if (value == null) { |
| 3343 if (rightOperand is DoubleState) { |
| 3344 return DoubleState.UNKNOWN_VALUE; |
| 3345 } |
| 3346 return UNKNOWN_VALUE; |
| 3347 } |
| 3348 if (rightOperand is IntState) { |
| 3349 int rightValue = (rightOperand as IntState).value; |
| 3350 if (rightValue == null) { |
| 3351 return UNKNOWN_VALUE; |
| 3352 } else if (rightValue == 0) { |
| 3353 return new DoubleState(value.toDouble() / rightValue.toDouble()); |
| 3354 } |
| 3355 return new IntState(value ~/ rightValue); |
| 3356 } else if (rightOperand is DoubleState) { |
| 3357 double rightValue = (rightOperand as DoubleState).value; |
| 3358 if (rightValue == null) { |
| 3359 return DoubleState.UNKNOWN_VALUE; |
| 3360 } |
| 3361 return new DoubleState(value.toDouble() / rightValue); |
| 3362 } else if (rightOperand is DynamicState || rightOperand is NumState) { |
| 3363 return UNKNOWN_VALUE; |
| 3364 } |
| 3365 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI
ON); |
| 3366 } |
| 3367 |
| 3368 bool operator ==(Object object) => object is IntState && (value == (object as
IntState).value); |
| 3369 |
| 3370 BoolState equalEqual(InstanceState rightOperand) { |
| 3371 assertBoolNumStringOrNull(rightOperand); |
| 3372 if (value == null) { |
| 3373 return BoolState.UNKNOWN_VALUE; |
| 3374 } |
| 3375 if (rightOperand is IntState) { |
| 3376 int rightValue = (rightOperand as IntState).value; |
| 3377 if (rightValue == null) { |
| 3378 return BoolState.UNKNOWN_VALUE; |
| 3379 } |
| 3380 return BoolState.from(value == rightValue); |
| 3381 } else if (rightOperand is DoubleState) { |
| 3382 double rightValue = (rightOperand as DoubleState).value; |
| 3383 if (rightValue == null) { |
| 3384 return BoolState.UNKNOWN_VALUE; |
| 3385 } |
| 3386 return BoolState.from(rightValue == value.toDouble()); |
| 3387 } else if (rightOperand is DynamicState || rightOperand is NumState) { |
| 3388 return BoolState.UNKNOWN_VALUE; |
| 3389 } |
| 3390 return BoolState.FALSE_STATE; |
| 3391 } |
| 3392 |
| 3393 String get typeName => "int"; |
| 3394 |
| 3395 BoolState greaterThan(InstanceState rightOperand) { |
| 3396 assertNumOrNull(rightOperand); |
| 3397 if (value == null) { |
| 3398 return BoolState.UNKNOWN_VALUE; |
| 3399 } |
| 3400 if (rightOperand is IntState) { |
| 3401 int rightValue = (rightOperand as IntState).value; |
| 3402 if (rightValue == null) { |
| 3403 return BoolState.UNKNOWN_VALUE; |
| 3404 } |
| 3405 return BoolState.from(value.compareTo(rightValue) > 0); |
| 3406 } else if (rightOperand is DoubleState) { |
| 3407 double rightValue = (rightOperand as DoubleState).value; |
| 3408 if (rightValue == null) { |
| 3409 return BoolState.UNKNOWN_VALUE; |
| 3410 } |
| 3411 return BoolState.from(value.toDouble() > rightValue); |
| 3412 } else if (rightOperand is DynamicState || rightOperand is NumState) { |
| 3413 return BoolState.UNKNOWN_VALUE; |
| 3414 } |
| 3415 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI
ON); |
| 3416 } |
| 3417 |
| 3418 BoolState greaterThanOrEqual(InstanceState rightOperand) { |
| 3419 assertNumOrNull(rightOperand); |
| 3420 if (value == null) { |
| 3421 return BoolState.UNKNOWN_VALUE; |
| 3422 } |
| 3423 if (rightOperand is IntState) { |
| 3424 int rightValue = (rightOperand as IntState).value; |
| 3425 if (rightValue == null) { |
| 3426 return BoolState.UNKNOWN_VALUE; |
| 3427 } |
| 3428 return BoolState.from(value.compareTo(rightValue) >= 0); |
| 3429 } else if (rightOperand is DoubleState) { |
| 3430 double rightValue = (rightOperand as DoubleState).value; |
| 3431 if (rightValue == null) { |
| 3432 return BoolState.UNKNOWN_VALUE; |
| 3433 } |
| 3434 return BoolState.from(value.toDouble() >= rightValue); |
| 3435 } else if (rightOperand is DynamicState || rightOperand is NumState) { |
| 3436 return BoolState.UNKNOWN_VALUE; |
| 3437 } |
| 3438 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI
ON); |
| 3439 } |
| 3440 |
| 3441 int get hashCode => value == null ? 0 : value.hashCode; |
| 3442 |
| 3443 IntState integerDivide(InstanceState rightOperand) { |
| 3444 assertNumOrNull(rightOperand); |
| 3445 if (value == null) { |
| 3446 return UNKNOWN_VALUE; |
| 3447 } |
| 3448 if (rightOperand is IntState) { |
| 3449 int rightValue = (rightOperand as IntState).value; |
| 3450 if (rightValue == null) { |
| 3451 return UNKNOWN_VALUE; |
| 3452 } else if (rightValue == 0) { |
| 3453 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_IDB
ZE); |
| 3454 } |
| 3455 return new IntState(value ~/ rightValue); |
| 3456 } else if (rightOperand is DoubleState) { |
| 3457 double rightValue = (rightOperand as DoubleState).value; |
| 3458 if (rightValue == null) { |
| 3459 return UNKNOWN_VALUE; |
| 3460 } |
| 3461 double result = value.toDouble() / rightValue; |
| 3462 return new IntState(result.toInt()); |
| 3463 } else if (rightOperand is DynamicState || rightOperand is NumState) { |
| 3464 return UNKNOWN_VALUE; |
| 3465 } |
| 3466 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI
ON); |
| 3467 } |
| 3468 |
| 3469 bool get isBoolNumStringOrNull => true; |
| 3470 |
| 3471 BoolState lessThan(InstanceState rightOperand) { |
| 3472 assertNumOrNull(rightOperand); |
| 3473 if (value == null) { |
| 3474 return BoolState.UNKNOWN_VALUE; |
| 3475 } |
| 3476 if (rightOperand is IntState) { |
| 3477 int rightValue = (rightOperand as IntState).value; |
| 3478 if (rightValue == null) { |
| 3479 return BoolState.UNKNOWN_VALUE; |
| 3480 } |
| 3481 return BoolState.from(value.compareTo(rightValue) < 0); |
| 3482 } else if (rightOperand is DoubleState) { |
| 3483 double rightValue = (rightOperand as DoubleState).value; |
| 3484 if (rightValue == null) { |
| 3485 return BoolState.UNKNOWN_VALUE; |
| 3486 } |
| 3487 return BoolState.from(value.toDouble() < rightValue); |
| 3488 } else if (rightOperand is DynamicState || rightOperand is NumState) { |
| 3489 return BoolState.UNKNOWN_VALUE; |
| 3490 } |
| 3491 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI
ON); |
| 3492 } |
| 3493 |
| 3494 BoolState lessThanOrEqual(InstanceState rightOperand) { |
| 3495 assertNumOrNull(rightOperand); |
| 3496 if (value == null) { |
| 3497 return BoolState.UNKNOWN_VALUE; |
| 3498 } |
| 3499 if (rightOperand is IntState) { |
| 3500 int rightValue = (rightOperand as IntState).value; |
| 3501 if (rightValue == null) { |
| 3502 return BoolState.UNKNOWN_VALUE; |
| 3503 } |
| 3504 return BoolState.from(value.compareTo(rightValue) <= 0); |
| 3505 } else if (rightOperand is DoubleState) { |
| 3506 double rightValue = (rightOperand as DoubleState).value; |
| 3507 if (rightValue == null) { |
| 3508 return BoolState.UNKNOWN_VALUE; |
| 3509 } |
| 3510 return BoolState.from(value.toDouble() <= rightValue); |
| 3511 } else if (rightOperand is DynamicState || rightOperand is NumState) { |
| 3512 return BoolState.UNKNOWN_VALUE; |
| 3513 } |
| 3514 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI
ON); |
| 3515 } |
| 3516 |
| 3517 NumState minus(InstanceState rightOperand) { |
| 3518 assertNumOrNull(rightOperand); |
| 3519 if (value == null) { |
| 3520 if (rightOperand is DoubleState) { |
| 3521 return DoubleState.UNKNOWN_VALUE; |
| 3522 } |
| 3523 return UNKNOWN_VALUE; |
| 3524 } |
| 3525 if (rightOperand is IntState) { |
| 3526 int rightValue = (rightOperand as IntState).value; |
| 3527 if (rightValue == null) { |
| 3528 return UNKNOWN_VALUE; |
| 3529 } |
| 3530 return new IntState(value - rightValue); |
| 3531 } else if (rightOperand is DoubleState) { |
| 3532 double rightValue = (rightOperand as DoubleState).value; |
| 3533 if (rightValue == null) { |
| 3534 return DoubleState.UNKNOWN_VALUE; |
| 3535 } |
| 3536 return new DoubleState(value.toDouble() - rightValue); |
| 3537 } else if (rightOperand is DynamicState || rightOperand is NumState) { |
| 3538 return UNKNOWN_VALUE; |
| 3539 } |
| 3540 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI
ON); |
| 3541 } |
| 3542 |
| 3543 NumState negated() { |
| 3544 if (value == null) { |
| 3545 return UNKNOWN_VALUE; |
| 3546 } |
| 3547 return new IntState(-value); |
| 3548 } |
| 3549 |
| 3550 NumState remainder(InstanceState rightOperand) { |
| 3551 assertNumOrNull(rightOperand); |
| 3552 if (value == null) { |
| 3553 if (rightOperand is DoubleState) { |
| 3554 return DoubleState.UNKNOWN_VALUE; |
| 3555 } |
| 3556 return UNKNOWN_VALUE; |
| 3557 } |
| 3558 if (rightOperand is IntState) { |
| 3559 int rightValue = (rightOperand as IntState).value; |
| 3560 if (rightValue == null) { |
| 3561 return UNKNOWN_VALUE; |
| 3562 } else if (rightValue == 0) { |
| 3563 return new DoubleState(value.toDouble() % rightValue.toDouble()); |
| 3564 } |
| 3565 return new IntState(value.remainder(rightValue)); |
| 3566 } else if (rightOperand is DoubleState) { |
| 3567 double rightValue = (rightOperand as DoubleState).value; |
| 3568 if (rightValue == null) { |
| 3569 return DoubleState.UNKNOWN_VALUE; |
| 3570 } |
| 3571 return new DoubleState(value.toDouble() % rightValue); |
| 3572 } else if (rightOperand is DynamicState || rightOperand is NumState) { |
| 3573 return UNKNOWN_VALUE; |
| 3574 } |
| 3575 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI
ON); |
| 3576 } |
| 3577 |
| 3578 IntState shiftLeft(InstanceState rightOperand) { |
| 3579 assertIntOrNull(rightOperand); |
| 3580 if (value == null) { |
| 3581 return UNKNOWN_VALUE; |
| 3582 } |
| 3583 if (rightOperand is IntState) { |
| 3584 int rightValue = (rightOperand as IntState).value; |
| 3585 if (rightValue == null) { |
| 3586 return UNKNOWN_VALUE; |
| 3587 } else if (rightValue.bitLength > 31) { |
| 3588 return UNKNOWN_VALUE; |
| 3589 } |
| 3590 return new IntState(value << rightValue); |
| 3591 } else if (rightOperand is DynamicState || rightOperand is NumState) { |
| 3592 return UNKNOWN_VALUE; |
| 3593 } |
| 3594 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI
ON); |
| 3595 } |
| 3596 |
| 3597 IntState shiftRight(InstanceState rightOperand) { |
| 3598 assertIntOrNull(rightOperand); |
| 3599 if (value == null) { |
| 3600 return UNKNOWN_VALUE; |
| 3601 } |
| 3602 if (rightOperand is IntState) { |
| 3603 int rightValue = (rightOperand as IntState).value; |
| 3604 if (rightValue == null) { |
| 3605 return UNKNOWN_VALUE; |
| 3606 } else if (rightValue.bitLength > 31) { |
| 3607 return UNKNOWN_VALUE; |
| 3608 } |
| 3609 return new IntState(value >> rightValue); |
| 3610 } else if (rightOperand is DynamicState || rightOperand is NumState) { |
| 3611 return UNKNOWN_VALUE; |
| 3612 } |
| 3613 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI
ON); |
| 3614 } |
| 3615 |
| 3616 NumState times(InstanceState rightOperand) { |
| 3617 assertNumOrNull(rightOperand); |
| 3618 if (value == null) { |
| 3619 if (rightOperand is DoubleState) { |
| 3620 return DoubleState.UNKNOWN_VALUE; |
| 3621 } |
| 3622 return UNKNOWN_VALUE; |
| 3623 } |
| 3624 if (rightOperand is IntState) { |
| 3625 int rightValue = (rightOperand as IntState).value; |
| 3626 if (rightValue == null) { |
| 3627 return UNKNOWN_VALUE; |
| 3628 } |
| 3629 return new IntState(value * rightValue); |
| 3630 } else if (rightOperand is DoubleState) { |
| 3631 double rightValue = (rightOperand as DoubleState).value; |
| 3632 if (rightValue == null) { |
| 3633 return DoubleState.UNKNOWN_VALUE; |
| 3634 } |
| 3635 return new DoubleState(value.toDouble() * rightValue); |
| 3636 } else if (rightOperand is DynamicState || rightOperand is NumState) { |
| 3637 return UNKNOWN_VALUE; |
| 3638 } |
| 3639 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI
ON); |
| 3640 } |
| 3641 |
| 3642 String toString() => value == null ? "-unknown-" : value.toString(); |
| 3643 } |
| 3644 |
| 3645 /** |
| 3646 * The unique instance of the class `ListState` represents the state of an objec
t representing |
| 3647 * a list. |
| 3648 */ |
| 3649 class ListState extends InstanceState { |
| 3650 /** |
| 3651 * The elements of the list. |
| 3652 */ |
| 3653 List<DartObjectImpl> _elements; |
| 3654 |
| 3655 /** |
| 3656 * Initialize a newly created state to represent a list with the given element
s. |
| 3657 * |
| 3658 * @param elements the elements of the list |
| 3659 */ |
| 3660 ListState(List<DartObjectImpl> elements) { |
| 3661 this._elements = elements; |
| 3662 } |
| 3663 |
| 3664 StringState convertToString() => StringState.UNKNOWN_VALUE; |
| 3665 |
| 3666 bool operator ==(Object object) { |
| 3667 if (object is! ListState) { |
| 3668 return false; |
| 3669 } |
| 3670 List<DartObjectImpl> otherElements = (object as ListState)._elements; |
| 3671 int count = _elements.length; |
| 3672 if (otherElements.length != count) { |
| 3673 return false; |
| 3674 } else if (count == 0) { |
| 3675 return true; |
| 3676 } |
| 3677 for (int i = 0; i < count; i++) { |
| 3678 if (_elements[i] != otherElements[i]) { |
| 3679 return false; |
| 3680 } |
| 3681 } |
| 3682 return true; |
| 3683 } |
| 3684 |
| 3685 BoolState equalEqual(InstanceState rightOperand) { |
| 3686 assertBoolNumStringOrNull(rightOperand); |
| 3687 if (rightOperand is DynamicState) { |
| 3688 return BoolState.UNKNOWN_VALUE; |
| 3689 } |
| 3690 return BoolState.from(this == rightOperand); |
| 3691 } |
| 3692 |
| 3693 String get typeName => "List"; |
| 3694 |
| 3695 int get hashCode { |
| 3696 int value = 0; |
| 3697 int count = _elements.length; |
| 3698 for (int i = 0; i < count; i++) { |
| 3699 value = (value << 3) ^ _elements[i].hashCode; |
| 3700 } |
| 3701 return value; |
| 3702 } |
| 3703 } |
| 3704 |
| 3705 /** |
| 3706 * The unique instance of the class `ListState` represents the state of an objec
t representing |
| 3707 * a map. |
| 3708 */ |
| 3709 class MapState extends InstanceState { |
| 3710 /** |
| 3711 * The entries in the map. |
| 3712 */ |
| 3713 Map<DartObjectImpl, DartObjectImpl> _entries; |
| 3714 |
| 3715 /** |
| 3716 * Initialize a newly created state to represent a map with the given entries. |
| 3717 * |
| 3718 * @param entries the entries in the map |
| 3719 */ |
| 3720 MapState(Map<DartObjectImpl, DartObjectImpl> entries) { |
| 3721 this._entries = entries; |
| 3722 } |
| 3723 |
| 3724 StringState convertToString() => StringState.UNKNOWN_VALUE; |
| 3725 |
| 3726 bool operator ==(Object object) { |
| 3727 if (object is! MapState) { |
| 3728 return false; |
| 3729 } |
| 3730 Map<DartObjectImpl, DartObjectImpl> otherElements = (object as MapState)._en
tries; |
| 3731 int count = _entries.length; |
| 3732 if (otherElements.length != count) { |
| 3733 return false; |
| 3734 } else if (count == 0) { |
| 3735 return true; |
| 3736 } |
| 3737 for (MapEntry<DartObjectImpl, DartObjectImpl> entry in getMapEntrySet(_entri
es)) { |
| 3738 DartObjectImpl key = entry.getKey(); |
| 3739 DartObjectImpl value = entry.getValue(); |
| 3740 DartObjectImpl otherValue = otherElements[key]; |
| 3741 if (value != otherValue) { |
| 3742 return false; |
| 3743 } |
| 3744 } |
| 3745 return true; |
| 3746 } |
| 3747 |
| 3748 BoolState equalEqual(InstanceState rightOperand) { |
| 3749 assertBoolNumStringOrNull(rightOperand); |
| 3750 if (rightOperand is DynamicState) { |
| 3751 return BoolState.UNKNOWN_VALUE; |
| 3752 } |
| 3753 return BoolState.from(this == rightOperand); |
| 3754 } |
| 3755 |
| 3756 String get typeName => "Map"; |
| 3757 |
| 3758 int get hashCode { |
| 3759 int value = 0; |
| 3760 for (DartObjectImpl key in _entries.keys.toSet()) { |
| 3761 value = (value << 3) ^ key.hashCode; |
| 3762 } |
| 3763 return value; |
| 3764 } |
| 3765 } |
| 3766 |
| 3767 /** |
| 3768 * The unique instance of the class `NullState` represents the state of the valu
e 'null'. |
| 3769 */ |
| 3770 class NullState extends InstanceState { |
| 3771 /** |
| 3772 * An instance representing the boolean value 'true'. |
| 3773 */ |
| 3774 static NullState NULL_STATE = new NullState(); |
| 3775 |
| 3776 BoolState convertToBool() { |
| 3777 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI
ON); |
| 3778 } |
| 3779 |
| 3780 StringState convertToString() => new StringState("null"); |
| 3781 |
| 3782 BoolState equalEqual(InstanceState rightOperand) { |
| 3783 assertBoolNumStringOrNull(rightOperand); |
| 3784 if (rightOperand is DynamicState) { |
| 3785 return BoolState.UNKNOWN_VALUE; |
| 3786 } |
| 3787 return BoolState.from(rightOperand is NullState); |
| 3788 } |
| 3789 |
| 3790 bool operator ==(Object object) => object is NullState; |
| 3791 |
| 3792 String get typeName => "Null"; |
| 3793 |
| 3794 int get hashCode => 0; |
| 3795 |
| 3796 bool get isBoolNumStringOrNull => true; |
| 3797 |
| 3798 BoolState logicalNot() { |
| 3799 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI
ON); |
| 3800 } |
| 3801 |
| 3802 String toString() => "null"; |
| 3803 } |
| 3804 |
| 3805 /** |
| 3806 * Instances of the class `NumState` represent the state of an object representi
ng a number of |
| 3807 * an unknown type (a 'num'). |
| 3808 */ |
| 3809 class NumState extends InstanceState { |
| 3810 /** |
| 3811 * A state that can be used to represent a number whose value is not known. |
| 3812 */ |
| 3813 static NumState UNKNOWN_VALUE = new NumState(); |
| 3814 |
| 3815 NumState add(InstanceState rightOperand) { |
| 3816 assertNumOrNull(rightOperand); |
| 3817 return UNKNOWN_VALUE; |
| 3818 } |
| 3819 |
| 3820 StringState convertToString() => StringState.UNKNOWN_VALUE; |
| 3821 |
| 3822 NumState divide(InstanceState rightOperand) { |
| 3823 assertNumOrNull(rightOperand); |
| 3824 return UNKNOWN_VALUE; |
| 3825 } |
| 3826 |
| 3827 bool operator ==(Object object) => object is NumState; |
| 3828 |
| 3829 BoolState equalEqual(InstanceState rightOperand) { |
| 3830 assertBoolNumStringOrNull(rightOperand); |
| 3831 return BoolState.UNKNOWN_VALUE; |
| 3832 } |
| 3833 |
| 3834 String get typeName => "num"; |
| 3835 |
| 3836 BoolState greaterThan(InstanceState rightOperand) { |
| 3837 assertNumOrNull(rightOperand); |
| 3838 return BoolState.UNKNOWN_VALUE; |
| 3839 } |
| 3840 |
| 3841 BoolState greaterThanOrEqual(InstanceState rightOperand) { |
| 3842 assertNumOrNull(rightOperand); |
| 3843 return BoolState.UNKNOWN_VALUE; |
| 3844 } |
| 3845 |
| 3846 int get hashCode => 7; |
| 3847 |
| 3848 IntState integerDivide(InstanceState rightOperand) { |
| 3849 assertNumOrNull(rightOperand); |
| 3850 if (rightOperand is IntState) { |
| 3851 int rightValue = (rightOperand as IntState).value; |
| 3852 if (rightValue == null) { |
| 3853 return IntState.UNKNOWN_VALUE; |
| 3854 } else if (rightValue == 0) { |
| 3855 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_IDB
ZE); |
| 3856 } |
| 3857 } else if (rightOperand is DynamicState) { |
| 3858 return IntState.UNKNOWN_VALUE; |
| 3859 } |
| 3860 return IntState.UNKNOWN_VALUE; |
| 3861 } |
| 3862 |
| 3863 bool get isBoolNumStringOrNull => true; |
| 3864 |
| 3865 BoolState lessThan(InstanceState rightOperand) { |
| 3866 assertNumOrNull(rightOperand); |
| 3867 return BoolState.UNKNOWN_VALUE; |
| 3868 } |
| 3869 |
| 3870 BoolState lessThanOrEqual(InstanceState rightOperand) { |
| 3871 assertNumOrNull(rightOperand); |
| 3872 return BoolState.UNKNOWN_VALUE; |
| 3873 } |
| 3874 |
| 3875 NumState minus(InstanceState rightOperand) { |
| 3876 assertNumOrNull(rightOperand); |
| 3877 return UNKNOWN_VALUE; |
| 3878 } |
| 3879 |
| 3880 NumState negated() => UNKNOWN_VALUE; |
| 3881 |
| 3882 NumState remainder(InstanceState rightOperand) { |
| 3883 assertNumOrNull(rightOperand); |
| 3884 return UNKNOWN_VALUE; |
| 3885 } |
| 3886 |
| 3887 NumState times(InstanceState rightOperand) { |
| 3888 assertNumOrNull(rightOperand); |
| 3889 return UNKNOWN_VALUE; |
| 3890 } |
| 3891 |
| 3892 String toString() => "-unknown-"; |
| 3893 } |
| 3894 |
| 3895 /** |
| 3896 * Instances of the class `StringState` represent the state of an object represe
nting a |
| 3897 * string. |
| 3898 */ |
| 3899 class StringState extends InstanceState { |
| 3900 /** |
| 3901 * The value of this instance. |
| 3902 */ |
| 3903 final String value; |
| 3904 |
| 3905 /** |
| 3906 * A state that can be used to represent a double whose value is not known. |
| 3907 */ |
| 3908 static StringState UNKNOWN_VALUE = new StringState(null); |
| 3909 |
| 3910 /** |
| 3911 * Initialize a newly created state to represent the given value. |
| 3912 * |
| 3913 * @param value the value of this instance |
| 3914 */ |
| 3915 StringState(this.value); |
| 3916 |
| 3917 StringState concatenate(InstanceState rightOperand) { |
| 3918 if (value == null) { |
| 3919 return UNKNOWN_VALUE; |
| 3920 } |
| 3921 if (rightOperand is StringState) { |
| 3922 String rightValue = (rightOperand as StringState).value; |
| 3923 if (rightValue == null) { |
| 3924 return UNKNOWN_VALUE; |
| 3925 } |
| 3926 return new StringState("${value}${rightValue}"); |
| 3927 } else if (rightOperand is DynamicState) { |
| 3928 return UNKNOWN_VALUE; |
| 3929 } |
| 3930 return super.concatenate(rightOperand); |
| 3931 } |
| 3932 |
| 3933 StringState convertToString() => this; |
| 3934 |
| 3935 bool operator ==(Object object) => object is StringState && (value == (object
as StringState).value); |
| 3936 |
| 3937 BoolState equalEqual(InstanceState rightOperand) { |
| 3938 assertBoolNumStringOrNull(rightOperand); |
| 3939 if (value == null) { |
| 3940 return BoolState.UNKNOWN_VALUE; |
| 3941 } |
| 3942 if (rightOperand is StringState) { |
| 3943 String rightValue = (rightOperand as StringState).value; |
| 3944 if (rightValue == null) { |
| 3945 return BoolState.UNKNOWN_VALUE; |
| 3946 } |
| 3947 return BoolState.from(value == rightValue); |
| 3948 } else if (rightOperand is DynamicState) { |
| 3949 return BoolState.UNKNOWN_VALUE; |
| 3950 } |
| 3951 return BoolState.FALSE_STATE; |
| 3952 } |
| 3953 |
| 3954 String get typeName => "String"; |
| 3955 |
| 3956 int get hashCode => value == null ? 0 : value.hashCode; |
| 3957 |
| 3958 bool get isBoolNumStringOrNull => true; |
| 3959 |
| 3960 String toString() => value == null ? "-unknown-" : "'${value}'"; |
| 3961 } |
| 3962 |
| 3963 /** |
| 3964 * Instances of the class `StringState` represent the state of an object represe
nting a |
| 3965 * symbol. |
| 3966 */ |
| 3967 class SymbolState extends InstanceState { |
| 3968 /** |
| 3969 * The value of this instance. |
| 3970 */ |
| 3971 final String value; |
| 3972 |
| 3973 /** |
| 3974 * Initialize a newly created state to represent the given value. |
| 3975 * |
| 3976 * @param value the value of this instance |
| 3977 */ |
| 3978 SymbolState(this.value); |
| 3979 |
| 3980 StringState convertToString() { |
| 3981 if (value == null) { |
| 3982 return StringState.UNKNOWN_VALUE; |
| 3983 } |
| 3984 return new StringState(value); |
| 3985 } |
| 3986 |
| 3987 bool operator ==(Object object) => object is SymbolState && (value == (object
as SymbolState).value); |
| 3988 |
| 3989 BoolState equalEqual(InstanceState rightOperand) { |
| 3990 assertBoolNumStringOrNull(rightOperand); |
| 3991 if (value == null) { |
| 3992 return BoolState.UNKNOWN_VALUE; |
| 3993 } |
| 3994 if (rightOperand is SymbolState) { |
| 3995 String rightValue = (rightOperand as SymbolState).value; |
| 3996 if (rightValue == null) { |
| 3997 return BoolState.UNKNOWN_VALUE; |
| 3998 } |
| 3999 return BoolState.from(value == rightValue); |
| 4000 } else if (rightOperand is DynamicState) { |
| 4001 return BoolState.UNKNOWN_VALUE; |
| 4002 } |
| 4003 return BoolState.FALSE_STATE; |
| 4004 } |
| 4005 |
| 4006 String get typeName => "Symbol"; |
| 4007 |
| 4008 int get hashCode => value == null ? 0 : value.hashCode; |
| 4009 |
| 4010 String toString() => value == null ? "-unknown-" : "#${value}"; |
| 4011 } |
| 4012 |
| 4013 /** |
| 4014 * Instances of the class `TypeState` represent the state of an object represent
ing a type. |
| 4015 */ |
| 4016 class TypeState extends InstanceState { |
| 4017 /** |
| 4018 * The element representing the type being modeled. |
| 4019 */ |
| 4020 Element _element; |
| 4021 |
| 4022 /** |
| 4023 * Initialize a newly created state to represent the given value. |
| 4024 * |
| 4025 * @param element the element representing the type being modeled |
| 4026 */ |
| 4027 TypeState(Element element) { |
| 4028 this._element = element; |
| 4029 } |
| 4030 |
| 4031 StringState convertToString() { |
| 4032 if (_element == null) { |
| 4033 return StringState.UNKNOWN_VALUE; |
| 4034 } |
| 4035 return new StringState(_element.name); |
| 4036 } |
| 4037 |
| 4038 bool operator ==(Object object) => object is TypeState && (_element == (object
as TypeState)._element); |
| 4039 |
| 4040 BoolState equalEqual(InstanceState rightOperand) { |
| 4041 assertBoolNumStringOrNull(rightOperand); |
| 4042 if (_element == null) { |
| 4043 return BoolState.UNKNOWN_VALUE; |
| 4044 } |
| 4045 if (rightOperand is TypeState) { |
| 4046 Element rightElement = (rightOperand as TypeState)._element; |
| 4047 if (rightElement == null) { |
| 4048 return BoolState.UNKNOWN_VALUE; |
| 4049 } |
| 4050 return BoolState.from(_element == rightElement); |
| 4051 } else if (rightOperand is DynamicState) { |
| 4052 return BoolState.UNKNOWN_VALUE; |
| 4053 } |
| 4054 return BoolState.FALSE_STATE; |
| 4055 } |
| 4056 |
| 4057 String get typeName => "Type"; |
| 4058 |
| 4059 int get hashCode => _element == null ? 0 : _element.hashCode; |
| 4060 |
| 4061 String toString() => _element == null ? "-unknown-" : _element.name; |
| 1974 } | 4062 } |
| OLD | NEW |