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

Side by Side Diff: pkg/analyzer/lib/src/generated/constant.dart

Issue 123763002: New analyzer snapshot. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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> &amp;&amp; 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> &amp; 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 * &gt;&gt; e<sub>2</sub></i> or <i>e<sub>1</sub> &lt;&lt; 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> &lt; e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;=
53 * e<sub>2</sub></i>, <i>e<sub>1</sub> &lt;= 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
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
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> &amp;&amp; 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> &amp; 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 * &gt;&gt; e<sub>2</sub></i> or <i>e<sub>1</sub> &lt;&lt; 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> &lt; e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;=
398 * e<sub>2</sub></i>, <i>e<sub>1</sub> &lt;= 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
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
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 '&gt;' 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 '&gt;' 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 '&gt;=' 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 '&gt;=' 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 '&lt;' 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 '&lt;' 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 '&lt;=' 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 '&lt;=' 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 '&lt;&lt;' 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 '&lt;&lt;' 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 '&gt;&gt;' 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 '&gt;&gt;' 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 '&gt;' 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 '&gt;' 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 '&gt;=' 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 '&gt;=' 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 '&lt;' 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 '&lt;' 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 '&lt;=' 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 '&lt;=' 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 '&lt;&lt;' 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 '&lt;&lt;' 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 '&gt;&gt;' 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 '&gt;&gt;' 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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698