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

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

Issue 1017633003: Clean up comments in constants.dart (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 9 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 // This code was auto-generated, is not intended to be edited, and is subject to 5 // This code was auto-generated, is not intended to be edited, and is subject to
6 // significant change. Please see the README file for more information. 6 // significant change. Please see the README file for more information.
7 7
8 library engine.constant; 8 library engine.constant;
9 9
10 import 'dart:collection'; 10 import 'dart:collection';
11 11
12 import 'package:analyzer/src/generated/utilities_general.dart'; 12 import 'package:analyzer/src/generated/utilities_general.dart';
13 13
14 import 'ast.dart'; 14 import 'ast.dart';
15 import 'element.dart'; 15 import 'element.dart';
16 import 'engine.dart' show AnalysisEngine, RecordingErrorListener; 16 import 'engine.dart' show AnalysisEngine, RecordingErrorListener;
17 import 'error.dart'; 17 import 'error.dart';
18 import 'java_core.dart'; 18 import 'java_core.dart';
19 import 'resolver.dart' show TypeProvider; 19 import 'resolver.dart' show TypeProvider;
20 import 'scanner.dart' show Token, TokenType; 20 import 'scanner.dart' show Token, TokenType;
21 import 'source.dart' show Source; 21 import 'source.dart' show Source;
22 import 'utilities_collection.dart'; 22 import 'utilities_collection.dart';
23 import 'utilities_dart.dart' show ParameterKind; 23 import 'utilities_dart.dart' show ParameterKind;
24 24
25 /** 25 /**
26 * Instances of the class `BoolState` represent the state of an object represent ing a boolean 26 * The state of an object representing a boolean value.
27 * value.
28 */ 27 */
29 class BoolState extends InstanceState { 28 class BoolState extends InstanceState {
30 /** 29 /**
31 * An instance representing the boolean value 'false'. 30 * An instance representing the boolean value 'false'.
32 */ 31 */
33 static BoolState FALSE_STATE = new BoolState(false); 32 static BoolState FALSE_STATE = new BoolState(false);
34 33
35 /** 34 /**
36 * An instance representing the boolean value 'true'. 35 * An instance representing the boolean value 'true'.
37 */ 36 */
38 static BoolState TRUE_STATE = new BoolState(true); 37 static BoolState TRUE_STATE = new BoolState(true);
39 38
40 /** 39 /**
41 * A state that can be used to represent a boolean whose value is not known. 40 * A state that can be used to represent a boolean whose value is not known.
42 */ 41 */
43 static BoolState UNKNOWN_VALUE = new BoolState(null); 42 static BoolState UNKNOWN_VALUE = new BoolState(null);
44 43
45 /** 44 /**
46 * The value of this instance. 45 * The value of this instance.
47 */ 46 */
48 final bool value; 47 final bool value;
49 48
50 /** 49 /**
51 * Initialize a newly created state to represent the given value. 50 * Initialize a newly created state to represent the given [value].
52 *
53 * @param value the value of this instance
54 */ 51 */
55 BoolState(this.value); 52 BoolState(this.value);
56 53
57 @override 54 @override
58 bool get hasExactValue => true; 55 bool get hasExactValue => true;
59 56
60 @override 57 @override
61 int get hashCode => value == null ? 0 : (value ? 2 : 3); 58 int get hashCode => value == null ? 0 : (value ? 2 : 3);
62 59
63 /**
64 * Return `true` if this object represents an object whose type is 'bool'.
65 *
66 * @return `true` if this object represents a boolean value
67 */
68 @override 60 @override
69 bool get isBool => true; 61 bool get isBool => true;
70 62
71 @override 63 @override
72 bool get isBoolNumStringOrNull => true; 64 bool get isBoolNumStringOrNull => true;
73 65
74 @override 66 @override
75 bool get isUnknown => value == null; 67 bool get isUnknown => value == null;
76 68
77 @override 69 @override
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 if (value == null) { 130 if (value == null) {
139 return UNKNOWN_VALUE; 131 return UNKNOWN_VALUE;
140 } 132 }
141 return value ? TRUE_STATE : rightOperand.convertToBool(); 133 return value ? TRUE_STATE : rightOperand.convertToBool();
142 } 134 }
143 135
144 @override 136 @override
145 String toString() => value == null ? "-unknown-" : (value ? "true" : "false"); 137 String toString() => value == null ? "-unknown-" : (value ? "true" : "false");
146 138
147 /** 139 /**
148 * Return the boolean state representing the given boolean value. 140 * Return the boolean state representing the given boolean [value].
149 *
150 * @param value the value to be represented
151 * @return the boolean state representing the given boolean value
152 */ 141 */
153 static BoolState from(bool value) => 142 static BoolState from(bool value) =>
154 value ? BoolState.TRUE_STATE : BoolState.FALSE_STATE; 143 value ? BoolState.TRUE_STATE : BoolState.FALSE_STATE;
155 } 144 }
156 145
157 /** 146 /**
158 * Instances of the class `ConstantEvaluator` evaluate constant expressions to p roduce their 147 * Instances of the class `ConstantEvaluator` evaluate constant expressions to
159 * compile-time value. According to the Dart Language Specification: <blockquote > A constant 148 * produce their compile-time value. According to the Dart Language
160 * expression is one of the following: 149 * Specification:
150 * <blockquote>
151 * A constant expression is one of the following:
161 * * A literal number. 152 * * A literal number.
162 * * A literal boolean. 153 * * A literal boolean.
163 * * A literal string where any interpolated expression is a compile-time consta nt that evaluates 154 * * A literal string where any interpolated expression is a compile-time
164 * to a numeric, string or boolean value or to <b>null</b>. 155 * constant that evaluates to a numeric, string or boolean value or to
156 * <b>null</b>.
165 * * A literal symbol. 157 * * A literal symbol.
166 * * <b>null</b>. 158 * * <b>null</b>.
167 * * A qualified reference to a static constant variable. 159 * * A qualified reference to a static constant variable.
168 * * An identifier expression that denotes a constant variable, class or type al ias. 160 * * An identifier expression that denotes a constant variable, class or type
161 * alias.
169 * * A constant constructor invocation. 162 * * A constant constructor invocation.
170 * * A constant list literal. 163 * * A constant list literal.
171 * * A constant map literal. 164 * * A constant map literal.
172 * * A simple or qualified identifier denoting a top-level function or a static method. 165 * * A simple or qualified identifier denoting a top-level function or a static
173 * * A parenthesized expression <i>(e)</i> where <i>e</i> is a constant expressi on. 166 * method.
174 * * An expression of the form <i>identical(e<sub>1</sub>, e<sub>2</sub>)</i> wh ere 167 * * A parenthesized expression <i>(e)</i> where <i>e</i> is a constant
175 * <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant expressions and <i >identical()</i> is 168 * expression.
176 * statically bound to the predefined dart function <i>identical()</i> discussed above. 169 * * An expression of the form <i>identical(e<sub>1</sub>, e<sub>2</sub>)</i>
177 * * An expression of one of the forms <i>e<sub>1</sub> == e<sub>2</sub></i> or <i>e<sub>1</sub> 170 * where <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant
178 * != e<sub>2</sub></i> where <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant expressions 171 * expressions and <i>identical()</i> is statically bound to the predefined
179 * that evaluate to a numeric, string or boolean value. 172 * dart function <i>identical()</i> discussed above.
180 * * An expression of one of the forms <i>!e</i>, <i>e<sub>1</sub> &amp;&amp; e< sub>2</sub></i> or 173 * * An expression of one of the forms <i>e<sub>1</sub> == e<sub>2</sub></i> or
181 * <i>e<sub>1</sub> || e<sub>2</sub></i>, where <i>e</i>, <i>e1</sub></i> and <i >e2</sub></i> are 174 * <i>e<sub>1</sub> != e<sub>2</sub></i> where <i>e<sub>1</sub></i> and
182 * constant expressions that evaluate to a boolean value. 175 * <i>e<sub>2</sub></i> are constant expressions that evaluate to a numeric,
183 * * An expression of one of the forms <i>~e</i>, <i>e<sub>1</sub> ^ e<sub>2</su b></i>, 176 * string or boolean value.
184 * <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> 177 * * An expression of one of the forms <i>!e</i>, <i>e<sub>1</sub> &amp;&amp;
185 * &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>, 178 * e<sub>2</sub></i> or <i>e<sub>1</sub> || e<sub>2</sub></i>, where <i>e</i>,
186 * <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant expressions that e valuate to an 179 * <i>e1</sub></i> and <i>e2</sub></i> are constant expressions that evaluate
187 * integer value or to <b>null</b>. 180 * to a boolean value.
188 * * An expression of one of the forms <i>-e</i>, <i>e<sub>1</sub> + e<sub>2</su b></i>, 181 * * An expression of one of the forms <i>~e</i>, <i>e<sub>1</sub> ^
189 * <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> / 182 * e<sub>2</sub></i>, <i>e<sub>1</sub> &amp; e<sub>2</sub></i>,
190 * e<sub>2</sub></i>, <i>e<sub>1</sub> ~/ e<sub>2</sub></i>, <i>e<sub>1</sub> &g t; 183 * <i>e<sub>1</sub> | e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;&gt;
191 * e<sub>2</sub></i>, <i>e<sub>1</sub> &lt; e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;= 184 * e<sub>2</sub></i> or <i>e<sub>1</sub> &lt;&lt; e<sub>2</sub></i>, where
192 * e<sub>2</sub></i>, <i>e<sub>1</sub> &lt;= e<sub>2</sub></i> or <i>e<sub>1</su b> % 185 * <i>e</i>, <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant
193 * e<sub>2</sub></i>, where <i>e</i>, <i>e<sub>1</sub></i> and <i>e<sub>2</sub>< /i> are constant 186 * expressions that evaluate to an integer value or to <b>null</b>.
194 * expressions that evaluate to a numeric value or to <b>null</b>. 187 * * An expression of one of the forms <i>-e</i>, <i>e<sub>1</sub> +
195 * * An expression of the form <i>e<sub>1</sub> ? e<sub>2</sub> : e<sub>3</sub>< /i> where 188 * e<sub>2</sub></i>, <i>e<sub>1</sub> -e<sub>2</sub></i>, <i>e<sub>1</sub> *
196 * <i>e<sub>1</sub></i>, <i>e<sub>2</sub></i> and <i>e<sub>3</sub></i> are const ant expressions, and 189 * e<sub>2</sub></i>, <i>e<sub>1</sub> / e<sub>2</sub></i>, <i>e<sub>1</sub>
197 * <i>e<sub>1</sub></i> evaluates to a boolean value. 190 * ~/ e<sub>2</sub></i>, <i>e<sub>1</sub> &gt; e<sub>2</sub></i>,
191 * <i>e<sub>1</sub> &lt; e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;=
192 * e<sub>2</sub></i>, <i>e<sub>1</sub> &lt;= e<sub>2</sub></i> or
193 * <i>e<sub>1</sub> % e<sub>2</sub></i>, where <i>e</i>, <i>e<sub>1</sub></i>
194 * and <i>e<sub>2</sub></i> are constant expressions that evaluate to a
195 * numeric value or to <b>null</b>.
196 * * An expression of the form <i>e<sub>1</sub> ? e<sub>2</sub> :
197 * e<sub>3</sub></i> where <i>e<sub>1</sub></i>, <i>e<sub>2</sub></i> and
198 * <i>e<sub>3</sub></i> are constant expressions, and <i>e<sub>1</sub></i>
199 * evaluates to a boolean value.
198 * </blockquote> 200 * </blockquote>
199 */ 201 */
200 class ConstantEvaluator { 202 class ConstantEvaluator {
201 /** 203 /**
202 * The source containing the expression(s) that will be evaluated. 204 * The source containing the expression(s) that will be evaluated.
203 */ 205 */
204 final Source _source; 206 final Source _source;
205 207
206 /** 208 /**
207 * The type provider used to access the known types. 209 * The type provider used to access the known types.
208 */ 210 */
209 final TypeProvider _typeProvider; 211 final TypeProvider _typeProvider;
210 212
211 /** 213 /**
212 * Initialize a newly created evaluator to evaluate expressions in the given s ource. 214 * Initialize a newly created evaluator to evaluate expressions in the given
213 * 215 * [source]. The [typeProvider] is the type provider used to access known
214 * @param source the source containing the expression(s) that will be evaluate d 216 * types.
215 * @param typeProvider the type provider used to access known types
216 */ 217 */
217 ConstantEvaluator(this._source, this._typeProvider); 218 ConstantEvaluator(this._source, this._typeProvider);
218 219
219 EvaluationResult evaluate(Expression expression) { 220 EvaluationResult evaluate(Expression expression) {
220 RecordingErrorListener errorListener = new RecordingErrorListener(); 221 RecordingErrorListener errorListener = new RecordingErrorListener();
221 ErrorReporter errorReporter = new ErrorReporter(errorListener, _source); 222 ErrorReporter errorReporter = new ErrorReporter(errorListener, _source);
222 DartObjectImpl result = expression 223 DartObjectImpl result = expression
223 .accept(new ConstantVisitor.con1(_typeProvider, errorReporter)); 224 .accept(new ConstantVisitor.con1(_typeProvider, errorReporter));
224 if (result != null) { 225 if (result != null) {
225 return EvaluationResult.forValue(result); 226 return EvaluationResult.forValue(result);
226 } 227 }
227 return EvaluationResult.forErrors(errorListener.errors); 228 return EvaluationResult.forErrors(errorListener.errors);
228 } 229 }
229 } 230 }
230 231
231 /** 232 /**
232 * Instances of the class `ConstantFinder` are used to traverse the AST 233 * A visitor used to traverse the AST structures of all of the compilation units
233 * structures of all of the compilation units being resolved and build tables 234 * being resolved and build tables of the constant variables, constant
234 * of the constant variables, constant constructors, constant constructor 235 * constructors, constant constructor invocations, and annotations found in
235 * invocations, and annotations found in those compilation units. 236 * those compilation units.
236 */ 237 */
237 class ConstantFinder extends RecursiveAstVisitor<Object> { 238 class ConstantFinder extends RecursiveAstVisitor<Object> {
238 /** 239 /**
239 * A table mapping constant variable elements to the declarations of those var iables. 240 * A table mapping constant variable elements to the declarations of those
241 * variables.
240 */ 242 */
241 final HashMap<VariableElement, VariableDeclaration> variableMap = 243 final HashMap<VariableElement, VariableDeclaration> variableMap =
242 new HashMap<VariableElement, VariableDeclaration>(); 244 new HashMap<VariableElement, VariableDeclaration>();
243 245
244 /** 246 /**
245 * A table mapping constant constructors to the declarations of those construc tors. 247 * A table mapping constant constructors to the declarations of those
248 * constructors.
246 */ 249 */
247 final HashMap<ConstructorElement, ConstructorDeclaration> constructorMap = 250 final HashMap<ConstructorElement, ConstructorDeclaration> constructorMap =
248 new HashMap<ConstructorElement, ConstructorDeclaration>(); 251 new HashMap<ConstructorElement, ConstructorDeclaration>();
249 252
250 /** 253 /**
251 * A collection of constant constructor invocations. 254 * A collection of constant constructor invocations.
252 */ 255 */
253 final List<InstanceCreationExpression> constructorInvocations = 256 final List<InstanceCreationExpression> constructorInvocations =
254 new List<InstanceCreationExpression>(); 257 new List<InstanceCreationExpression>();
255 258
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 VariableElement element = node.element; 297 VariableElement element = node.element;
295 if (element != null) { 298 if (element != null) {
296 variableMap[element] = node; 299 variableMap[element] = node;
297 } 300 }
298 } 301 }
299 return null; 302 return null;
300 } 303 }
301 } 304 }
302 305
303 /** 306 /**
304 * Instances of the class `ConstantValueComputer` compute the values of constant variables and 307 * An object used to compute the values of constant variables and constant
305 * constant constructor invocations in one or more compilation units. The expect ed usage pattern is 308 * constructor invocations in one or more compilation units. The expected usage
306 * for the compilation units to be added to this computer using the method 309 * pattern is for the compilation units to be added to this computer using the
307 * [add] and then for the method [computeValues] to be invoked 310 * method [add] and then for the method [computeValues] to be invoked exactly
308 * exactly once. Any use of an instance after invoking the method [computeValues ] will 311 * once. Any use of an instance after invoking the method [computeValues] will
309 * result in unpredictable behavior. 312 * result in unpredictable behavior.
310 */ 313 */
311 class ConstantValueComputer { 314 class ConstantValueComputer {
312 /** 315 /**
313 * Parameter to "fromEnvironment" methods that denotes the default value. 316 * Parameter to "fromEnvironment" methods that denotes the default value.
314 */ 317 */
315 static String _DEFAULT_VALUE_PARAM = "defaultValue"; 318 static String _DEFAULT_VALUE_PARAM = "defaultValue";
316 319
317 /** 320 /**
318 * Source of RegExp matching declarable operator names. From sdk/lib/internal/ symbol.dart. 321 * Source of RegExp matching declarable operator names.
322 * From sdk/lib/internal/symbol.dart.
319 */ 323 */
320 static String _OPERATOR_RE = 324 static String _OPERATOR_RE =
321 "(?:[\\-+*/%&|^]|\\[\\]=?|==|~/?|<[<=]?|>[>=]?|unary-)"; 325 "(?:[\\-+*/%&|^]|\\[\\]=?|==|~/?|<[<=]?|>[>=]?|unary-)";
322 326
323 /** 327 /**
324 * Source of RegExp matching any public identifier. From sdk/lib/internal/symb ol.dart. 328 * Source of RegExp matching any public identifier.
329 * From sdk/lib/internal/symbol.dart.
325 */ 330 */
326 static String _PUBLIC_IDENTIFIER_RE = 331 static String _PUBLIC_IDENTIFIER_RE =
327 "(?!${ConstantValueComputer._RESERVED_WORD_RE}\\b(?!\\\$))[a-zA-Z\$][\\w\$ ]*"; 332 "(?!${ConstantValueComputer._RESERVED_WORD_RE}\\b(?!\\\$))[a-zA-Z\$][\\w\$ ]*";
328 333
329 /** 334 /**
330 * Source of RegExp matching Dart reserved words. From sdk/lib/internal/symbol .dart. 335 * Source of RegExp matching Dart reserved words.
336 * From sdk/lib/internal/symbol.dart.
331 */ 337 */
332 static String _RESERVED_WORD_RE = 338 static String _RESERVED_WORD_RE =
333 "(?:assert|break|c(?:a(?:se|tch)|lass|on(?:st|tinue))|d(?:efault|o)|e(?:ls e|num|xtends)|f(?:alse|inal(?:ly)?|or)|i[fns]|n(?:ew|ull)|ret(?:hrow|urn)|s(?:up er|witch)|t(?:h(?:is|row)|r(?:ue|y))|v(?:ar|oid)|w(?:hile|ith))"; 339 "(?:assert|break|c(?:a(?:se|tch)|lass|on(?:st|tinue))|d(?:efault|o)|e(?:ls e|num|xtends)|f(?:alse|inal(?:ly)?|or)|i[fns]|n(?:ew|ull)|ret(?:hrow|urn)|s(?:up er|witch)|t(?:h(?:is|row)|r(?:ue|y))|v(?:ar|oid)|w(?:hile|ith))";
334 340
335 /** 341 /**
336 * RegExp that validates a non-empty non-private symbol. From sdk/lib/internal /symbol.dart. 342 * RegExp that validates a non-empty non-private symbol.
343 * From sdk/lib/internal/symbol.dart.
337 */ 344 */
338 static RegExp _PUBLIC_SYMBOL_PATTERN = new RegExp( 345 static RegExp _PUBLIC_SYMBOL_PATTERN = new RegExp(
339 "^(?:${ConstantValueComputer._OPERATOR_RE}\$|$_PUBLIC_IDENTIFIER_RE(?:=?\$ |[.](?!\$)))+?\$"); 346 "^(?:${ConstantValueComputer._OPERATOR_RE}\$|$_PUBLIC_IDENTIFIER_RE(?:=?\$ |[.](?!\$)))+?\$");
340 347
341 /** 348 /**
342 * The type provider used to access the known types. 349 * The type provider used to access the known types.
343 */ 350 */
344 TypeProvider typeProvider; 351 TypeProvider typeProvider;
345 352
346 /** 353 /**
347 * The object used to find constant variables and constant constructor invocat ions in the 354 * The object used to find constant variables and constant constructor
348 * compilation units that were added. 355 * invocations in the compilation units that were added.
349 */ 356 */
350 ConstantFinder _constantFinder = new ConstantFinder(); 357 ConstantFinder _constantFinder = new ConstantFinder();
351 358
352 /** 359 /**
353 * A graph in which the nodes are the constants, and the edges are from each c onstant to the other 360 * A graph in which the nodes are the constants, and the edges are from each
354 * constants that are referenced by it. 361 * constant to the other constants that are referenced by it.
355 */ 362 */
356 DirectedGraph<AstNode> referenceGraph = new DirectedGraph<AstNode>(); 363 DirectedGraph<AstNode> referenceGraph = new DirectedGraph<AstNode>();
357 364
358 /** 365 /**
359 * A table mapping constant variables to the declarations of those variables. 366 * A table mapping constant variables to the declarations of those variables.
360 */ 367 */
361 HashMap<VariableElement, VariableDeclaration> _variableDeclarationMap; 368 HashMap<VariableElement, VariableDeclaration> _variableDeclarationMap;
362 369
363 /** 370 /**
364 * A table mapping constant constructors to the declarations of those construc tors. 371 * A table mapping constant constructors to the declarations of those
372 * constructors.
365 */ 373 */
366 HashMap<ConstructorElement, ConstructorDeclaration> constructorDeclarationMap; 374 HashMap<ConstructorElement, ConstructorDeclaration> constructorDeclarationMap;
367 375
368 /** 376 /**
369 * A collection of constant constructor invocations. 377 * A collection of constant constructor invocations.
370 */ 378 */
371 List<InstanceCreationExpression> _constructorInvocations; 379 List<InstanceCreationExpression> _constructorInvocations;
372 380
373 /** 381 /**
374 * A collection of annotations. 382 * A collection of annotations.
375 */ 383 */
376 List<Annotation> _annotations; 384 List<Annotation> _annotations;
377 385
378 /** 386 /**
379 * The set of variables declared on the command line using '-D'. 387 * The set of variables declared on the command line using '-D'.
380 */ 388 */
381 final DeclaredVariables _declaredVariables; 389 final DeclaredVariables _declaredVariables;
382 390
383 /** 391 /**
384 * Initialize a newly created constant value computer. 392 * Initialize a newly created constant value computer. The [typeProvider] is
385 * 393 * the type provider used to access known types. The [declaredVariables] is
386 * @param typeProvider the type provider used to access known types 394 * the set of variables declared on the command line using '-D'.
387 * @param declaredVariables the set of variables declared on the command line using '-D'
388 */ 395 */
389 ConstantValueComputer(TypeProvider typeProvider, this._declaredVariables) { 396 ConstantValueComputer(TypeProvider typeProvider, this._declaredVariables) {
390 this.typeProvider = typeProvider; 397 this.typeProvider = typeProvider;
391 } 398 }
392 399
393 /** 400 /**
394 * Add the constants in the given compilation unit to the list of constants wh ose value needs to 401 * Add the constants in the given compilation [unit] to the list of constants
395 * be computed. 402 * whose value needs to be computed.
396 *
397 * @param unit the compilation unit defining the constants to be added
398 */ 403 */
399 void add(CompilationUnit unit) { 404 void add(CompilationUnit unit) {
400 unit.accept(_constantFinder); 405 unit.accept(_constantFinder);
401 } 406 }
402 407
403 /** 408 /**
404 * This method is called just before computing the constant value associated w ith an AST node. 409 * This method is called just before computing the constant value associated
405 * Unit tests will override this method to introduce additional error checking . 410 * with [constNode]. Unit tests will override this method to introduce
411 * additional error checking.
406 */ 412 */
407 void beforeComputeValue(AstNode constNode) {} 413 void beforeComputeValue(AstNode constNode) {}
408 414
409 /** 415 /**
410 * This method is called just before getting the constant initializers associa ted with a 416 * This method is called just before getting the constant initializers
411 * constructor AST node. Unit tests will override this method to introduce add itional error 417 * associated with the [constructor]. Unit tests will override this method to
412 * checking. 418 * introduce additional error checking.
413 */ 419 */
414 void beforeGetConstantInitializers(ConstructorElement constructor) {} 420 void beforeGetConstantInitializers(ConstructorElement constructor) {}
415 421
416 /** 422 /**
417 * This method is called just before getting a parameter's default value. Unit tests will override 423 * This method is called just before getting a parameter's default value. Unit
418 * this method to introduce additional error checking. 424 * tests will override this method to introduce additional error checking.
419 */ 425 */
420 void beforeGetParameterDefault(ParameterElement parameter) {} 426 void beforeGetParameterDefault(ParameterElement parameter) {}
421 427
422 /** 428 /**
423 * Compute values for all of the constants in the compilation units that were added. 429 * Compute values for all of the constants in the compilation units that were
430 * added.
424 */ 431 */
425 void computeValues() { 432 void computeValues() {
426 _variableDeclarationMap = _constantFinder.variableMap; 433 _variableDeclarationMap = _constantFinder.variableMap;
427 constructorDeclarationMap = _constantFinder.constructorMap; 434 constructorDeclarationMap = _constantFinder.constructorMap;
428 _constructorInvocations = _constantFinder.constructorInvocations; 435 _constructorInvocations = _constantFinder.constructorInvocations;
429 _annotations = _constantFinder.annotations; 436 _annotations = _constantFinder.annotations;
430 _variableDeclarationMap.values.forEach((VariableDeclaration declaration) { 437 _variableDeclarationMap.values.forEach((VariableDeclaration declaration) {
431 ReferenceFinder referenceFinder = new ReferenceFinder(declaration, 438 ReferenceFinder referenceFinder = new ReferenceFinder(declaration,
432 referenceGraph, _variableDeclarationMap, constructorDeclarationMap); 439 referenceGraph, _variableDeclarationMap, constructorDeclarationMap);
433 referenceGraph.addNode(declaration); 440 referenceGraph.addNode(declaration);
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 } 513 }
507 // Since no constant can depend on an annotation, we don't waste time 514 // Since no constant can depend on an annotation, we don't waste time
508 // including them in the topological sort. We just process all the 515 // including them in the topological sort. We just process all the
509 // annotations after all other constants are finished. 516 // annotations after all other constants are finished.
510 for (Annotation annotation in _annotations) { 517 for (Annotation annotation in _annotations) {
511 _computeValueFor(annotation); 518 _computeValueFor(annotation);
512 } 519 }
513 } 520 }
514 521
515 /** 522 /**
516 * Create the ConstantVisitor used to evaluate constants. Unit tests will over ride this method to 523 * Create the ConstantVisitor used to evaluate constants. Unit tests will
517 * introduce additional error checking. 524 * override this method to introduce additional error checking.
518 */ 525 */
519 ConstantVisitor createConstantVisitor(ErrorReporter errorReporter) => 526 ConstantVisitor createConstantVisitor(ErrorReporter errorReporter) =>
520 new ConstantVisitor.con1(typeProvider, errorReporter); 527 new ConstantVisitor.con1(typeProvider, errorReporter);
521 528
522 ConstructorDeclaration findConstructorDeclaration( 529 ConstructorDeclaration findConstructorDeclaration(
523 ConstructorElement constructor) => 530 ConstructorElement constructor) =>
524 constructorDeclarationMap[_getConstructorBase(constructor)]; 531 constructorDeclarationMap[_getConstructorBase(constructor)];
525 532
526 /** 533 /**
527 * Check that the arguments to a call to fromEnvironment() are correct. 534 * Check that the arguments to a call to fromEnvironment() are correct. The
528 * 535 * [arguments] are the AST nodes of the arguments. The [argumentValues] are
529 * @param arguments the AST nodes of the arguments. 536 * the values of the unnamed arguments. The [namedArgumentValues] are the
530 * @param argumentValues the values of the unnamed arguments. 537 * values of the named arguments. The [expectedDefaultValueType] is the
531 * @param namedArgumentValues the values of the named arguments. 538 * allowed type of the "defaultValue" parameter (if present). Note:
532 * @param expectedDefaultValueType the allowed type of the "defaultValue" para meter (if present). 539 * "defaultValue" is always allowed to be null. Return `true` if the arguments
533 * Note: "defaultValue" is always allowed to be null. 540 * are correct, `false` if there is an error.
534 * @return true if the arguments are correct, false if there is an error.
535 */ 541 */
536 bool _checkFromEnvironmentArguments(NodeList<Expression> arguments, 542 bool _checkFromEnvironmentArguments(NodeList<Expression> arguments,
537 List<DartObjectImpl> argumentValues, 543 List<DartObjectImpl> argumentValues,
538 HashMap<String, DartObjectImpl> namedArgumentValues, 544 HashMap<String, DartObjectImpl> namedArgumentValues,
539 InterfaceType expectedDefaultValueType) { 545 InterfaceType expectedDefaultValueType) {
540 int argumentCount = arguments.length; 546 int argumentCount = arguments.length;
541 if (argumentCount < 1 || argumentCount > 2) { 547 if (argumentCount < 1 || argumentCount > 2) {
542 return false; 548 return false;
543 } 549 }
544 if (arguments[0] is NamedExpression) { 550 if (arguments[0] is NamedExpression) {
(...skipping 14 matching lines...) Expand all
559 namedArgumentValues[_DEFAULT_VALUE_PARAM].type; 565 namedArgumentValues[_DEFAULT_VALUE_PARAM].type;
560 if (!(identical(defaultValueType, expectedDefaultValueType) || 566 if (!(identical(defaultValueType, expectedDefaultValueType) ||
561 identical(defaultValueType, typeProvider.nullType))) { 567 identical(defaultValueType, typeProvider.nullType))) {
562 return false; 568 return false;
563 } 569 }
564 } 570 }
565 return true; 571 return true;
566 } 572 }
567 573
568 /** 574 /**
569 * Check that the arguments to a call to Symbol() are correct. 575 * Check that the arguments to a call to Symbol() are correct. The [arguments]
570 * 576 * are the AST nodes of the arguments. The [argumentValues] are the values of
571 * @param arguments the AST nodes of the arguments. 577 * the unnamed arguments. The [namedArgumentValues] are the values of the
572 * @param argumentValues the values of the unnamed arguments. 578 * named arguments. Return `true` if the arguments are correct, `false` if
573 * @param namedArgumentValues the values of the named arguments. 579 * there is an error.
574 * @return true if the arguments are correct, false if there is an error.
575 */ 580 */
576 bool _checkSymbolArguments(NodeList<Expression> arguments, 581 bool _checkSymbolArguments(NodeList<Expression> arguments,
577 List<DartObjectImpl> argumentValues, 582 List<DartObjectImpl> argumentValues,
578 HashMap<String, DartObjectImpl> namedArgumentValues) { 583 HashMap<String, DartObjectImpl> namedArgumentValues) {
579 if (arguments.length != 1) { 584 if (arguments.length != 1) {
580 return false; 585 return false;
581 } 586 }
582 if (arguments[0] is NamedExpression) { 587 if (arguments[0] is NamedExpression) {
583 return false; 588 return false;
584 } 589 }
585 if (!identical(argumentValues[0].type, typeProvider.stringType)) { 590 if (!identical(argumentValues[0].type, typeProvider.stringType)) {
586 return false; 591 return false;
587 } 592 }
588 String name = argumentValues[0].stringValue; 593 String name = argumentValues[0].stringValue;
589 return isValidPublicSymbol(name); 594 return isValidPublicSymbol(name);
590 } 595 }
591 596
592 /** 597 /**
593 * Compute a value for the given constant. 598 * Compute a value for the given [constNode].
594 *
595 * @param constNode the constant for which a value is to be computed
596 */ 599 */
597 void _computeValueFor(AstNode constNode) { 600 void _computeValueFor(AstNode constNode) {
598 beforeComputeValue(constNode); 601 beforeComputeValue(constNode);
599 if (constNode is VariableDeclaration) { 602 if (constNode is VariableDeclaration) {
600 VariableDeclaration declaration = constNode; 603 VariableDeclaration declaration = constNode;
601 VariableElement element = declaration.element; 604 VariableElement element = declaration.element;
602 RecordingErrorListener errorListener = new RecordingErrorListener(); 605 RecordingErrorListener errorListener = new RecordingErrorListener();
603 ErrorReporter errorReporter = 606 ErrorReporter errorReporter =
604 new ErrorReporter(errorListener, element.source); 607 new ErrorReporter(errorListener, element.source);
605 DartObjectImpl dartObject = 608 DartObjectImpl dartObject =
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
694 } 697 }
695 } else { 698 } else {
696 // Should not happen. 699 // Should not happen.
697 AnalysisEngine.instance.logger.logError( 700 AnalysisEngine.instance.logger.logError(
698 "Constant value computer trying to compute the value of a node which i s not a VariableDeclaration, InstanceCreationExpression, FormalParameter, or Con structorDeclaration"); 701 "Constant value computer trying to compute the value of a node which i s not a VariableDeclaration, InstanceCreationExpression, FormalParameter, or Con structorDeclaration");
699 return; 702 return;
700 } 703 }
701 } 704 }
702 705
703 /** 706 /**
704 * Evaluate a call to fromEnvironment() on the bool, int, or String class. 707 * Evaluate a call to fromEnvironment() on the bool, int, or String class. The
705 * 708 * [environmentValue] is the value fetched from the environment. The
706 * @param environmentValue Value fetched from the environment 709 * [builtInDefaultValue] is the value that should be used as the default if no
707 * @param builtInDefaultValue Value that should be used as the default if no " defaultValue" 710 * "defaultValue" argument appears in [namedArgumentValues]. The
708 * argument appears in [namedArgumentValues]. 711 * [namedArgumentValues] are the values of the named parameters passed to
709 * @param namedArgumentValues Named parameters passed to fromEnvironment() 712 * fromEnvironment(). Return a [DartObjectImpl] object corresponding to the
710 * @return A [DartObjectImpl] object corresponding to the evaluated result 713 * evaluated result.
711 */ 714 */
712 DartObjectImpl _computeValueFromEnvironment(DartObject environmentValue, 715 DartObjectImpl _computeValueFromEnvironment(DartObject environmentValue,
713 DartObjectImpl builtInDefaultValue, 716 DartObjectImpl builtInDefaultValue,
714 HashMap<String, DartObjectImpl> namedArgumentValues) { 717 HashMap<String, DartObjectImpl> namedArgumentValues) {
715 DartObjectImpl value = environmentValue as DartObjectImpl; 718 DartObjectImpl value = environmentValue as DartObjectImpl;
716 if (value.isUnknown || value.isNull) { 719 if (value.isUnknown || value.isNull) {
717 // The name either doesn't exist in the environment or we couldn't parse 720 // The name either doesn't exist in the environment or we couldn't parse
718 // the corresponding value. 721 // the corresponding value.
719 // If the code supplied an explicit default, use it. 722 // If the code supplied an explicit default, use it.
720 if (namedArgumentValues.containsKey(_DEFAULT_VALUE_PARAM)) { 723 if (namedArgumentValues.containsKey(_DEFAULT_VALUE_PARAM)) {
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
964 if (superConstructor != null && superConstructor.isConst) { 967 if (superConstructor != null && superConstructor.isConst) {
965 DartObjectImpl evaluationResult = _evaluateConstructorCall(node, 968 DartObjectImpl evaluationResult = _evaluateConstructorCall(node,
966 superArguments, superConstructor, initializerVisitor, errorReporter); 969 superArguments, superConstructor, initializerVisitor, errorReporter);
967 if (evaluationResult != null) { 970 if (evaluationResult != null) {
968 fieldMap[GenericState.SUPERCLASS_FIELD] = evaluationResult; 971 fieldMap[GenericState.SUPERCLASS_FIELD] = evaluationResult;
969 } 972 }
970 } 973 }
971 } 974 }
972 975
973 /** 976 /**
974 * Attempt to follow the chain of factory redirections until a constructor is reached which is not 977 * Attempt to follow the chain of factory redirections until a constructor is
975 * a const factory constructor. 978 * reached which is not a const factory constructor. Return the constant
976 * 979 * constructor which terminates the chain of factory redirections, if the
977 * @return the constant constructor which terminates the chain of factory redi rections, if the 980 * chain terminates. If there is a problem (e.g. a redirection can't be found,
978 * chain terminates. If there is a problem (e.g. a redirection can't b e found, or a cycle 981 * or a cycle is encountered), the chain will be followed as far as possible
979 * is encountered), the chain will be followed as far as possible and then a const factory 982 * and then a const factory constructor will be returned.
980 * constructor will be returned.
981 */ 983 */
982 ConstructorElement _followConstantRedirectionChain( 984 ConstructorElement _followConstantRedirectionChain(
983 ConstructorElement constructor) { 985 ConstructorElement constructor) {
984 HashSet<ConstructorElement> constructorsVisited = 986 HashSet<ConstructorElement> constructorsVisited =
985 new HashSet<ConstructorElement>(); 987 new HashSet<ConstructorElement>();
986 while (constructor.isFactory) { 988 while (constructor.isFactory) {
987 if (identical( 989 if (identical(
988 constructor.enclosingElement.type, typeProvider.symbolType)) { 990 constructor.enclosingElement.type, typeProvider.symbolType)) {
989 // The dart:core.Symbol has a const factory constructor that redirects 991 // The dart:core.Symbol has a const factory constructor that redirects
990 // to dart:_internal.Symbol. That in turn redirects to an external 992 // to dart:_internal.Symbol. That in turn redirects to an external
(...skipping 20 matching lines...) Expand all
1011 // and is checked elsewhere--see 1013 // and is checked elsewhere--see
1012 // [ErrorVerifier.checkForRecursiveFactoryRedirect()]). 1014 // [ErrorVerifier.checkForRecursiveFactoryRedirect()]).
1013 break; 1015 break;
1014 } 1016 }
1015 constructor = redirectedConstructor; 1017 constructor = redirectedConstructor;
1016 } 1018 }
1017 return constructor; 1019 return constructor;
1018 } 1020 }
1019 1021
1020 /** 1022 /**
1021 * Generate an error indicating that the given constant is not a valid compile -time constant 1023 * Generate an error indicating that the given [constant] is not a valid
1022 * because it references at least one of the constants in the given cycle, eac h of which directly 1024 * compile-time constant because it references at least one of the constants
1023 * or indirectly references the constant. 1025 * in the given [cycle], each of which directly or indirectly references the
1024 * 1026 * constant.
1025 * @param constantsInCycle the constants in the cycle that includes the given constant
1026 * @param constant the constant that is not a valid compile-time constant
1027 */ 1027 */
1028 void _generateCycleError(List<AstNode> constantsInCycle, AstNode constant) { 1028 void _generateCycleError(List<AstNode> cycle, AstNode constant) {
1029 // TODO(brianwilkerson) Implement this. 1029 // TODO(brianwilkerson) Implement this.
1030 } 1030 }
1031 1031
1032 ConstructorElement _getConstructorBase(ConstructorElement constructor) { 1032 ConstructorElement _getConstructorBase(ConstructorElement constructor) {
1033 while (constructor is ConstructorMember) { 1033 while (constructor is ConstructorMember) {
1034 constructor = (constructor as ConstructorMember).baseElement; 1034 constructor = (constructor as ConstructorMember).baseElement;
1035 } 1035 }
1036 return constructor; 1036 return constructor;
1037 } 1037 }
1038 1038
1039 /** 1039 /**
1040 * Check if the object [obj] matches the type [type] according 1040 * Check if the object [obj] matches the type [type] according to runtime type
1041 * to runtime type checking rules. 1041 * checking rules.
1042 */ 1042 */
1043 bool _runtimeTypeMatch(DartObjectImpl obj, DartType type) { 1043 bool _runtimeTypeMatch(DartObjectImpl obj, DartType type) {
1044 if (obj.isNull) { 1044 if (obj.isNull) {
1045 return true; 1045 return true;
1046 } 1046 }
1047 if (type.isUndefined) { 1047 if (type.isUndefined) {
1048 return false; 1048 return false;
1049 } 1049 }
1050 return obj.type.isSubtypeOf(type); 1050 return obj.type.isSubtypeOf(type);
1051 } 1051 }
1052 1052
1053 /** 1053 /**
1054 * Determine whether the given string is a valid name for a public symbol (i.e . whether it is 1054 * Determine whether the given string is a valid name for a public symbol
1055 * allowed for a call to the Symbol constructor). 1055 * (i.e. whether it is allowed for a call to the Symbol constructor).
1056 */ 1056 */
1057 static bool isValidPublicSymbol(String name) => name.isEmpty || 1057 static bool isValidPublicSymbol(String name) => name.isEmpty ||
1058 name == "void" || 1058 name == "void" ||
1059 new JavaPatternMatcher(_PUBLIC_SYMBOL_PATTERN, name).matches(); 1059 new JavaPatternMatcher(_PUBLIC_SYMBOL_PATTERN, name).matches();
1060 } 1060 }
1061 1061
1062 /** 1062 /**
1063 * A `ConstantValueComputer_InitializerCloner` is an [AstCloner] that copies the 1063 * An [AstCloner] that copies the necessary information from the AST to allow
1064 * necessary information from the AST to allow const constructor initializers to 1064 * const constructor initializers to be evaluated.
1065 * be evaluated.
1066 */ 1065 */
1067 class ConstantValueComputer_InitializerCloner extends AstCloner { 1066 class ConstantValueComputer_InitializerCloner extends AstCloner {
1068 // TODO(brianwilkerson) Investigate replacing uses of this class with uses of 1067 // TODO(brianwilkerson) Investigate replacing uses of this class with uses of
1069 // AstCloner and ResolutionCopier. 1068 // AstCloner and ResolutionCopier.
1070 1069
1071 ConstantValueComputer_InitializerCloner() : super(true); 1070 ConstantValueComputer_InitializerCloner() : super(true);
1072 1071
1073 @override 1072 @override
1074 InstanceCreationExpression visitInstanceCreationExpression( 1073 InstanceCreationExpression visitInstanceCreationExpression(
1075 InstanceCreationExpression node) { 1074 InstanceCreationExpression node) {
(...skipping 23 matching lines...) Expand all
1099 SuperConstructorInvocation visitSuperConstructorInvocation( 1098 SuperConstructorInvocation visitSuperConstructorInvocation(
1100 SuperConstructorInvocation node) { 1099 SuperConstructorInvocation node) {
1101 SuperConstructorInvocation invocation = 1100 SuperConstructorInvocation invocation =
1102 super.visitSuperConstructorInvocation(node); 1101 super.visitSuperConstructorInvocation(node);
1103 invocation.staticElement = node.staticElement; 1102 invocation.staticElement = node.staticElement;
1104 return invocation; 1103 return invocation;
1105 } 1104 }
1106 } 1105 }
1107 1106
1108 /** 1107 /**
1109 * Instances of the class `ConstantVisitor` evaluate constant expressions to pro duce their 1108 * A visitor used to evaluate constant expressions to produce their compile-time
1110 * compile-time value. According to the Dart Language Specification: <blockquote > A constant 1109 * value. According to the Dart Language Specification: <blockquote> A constant
1111 * expression is one of the following: 1110 * expression is one of the following:
1111 *
1112 * * A literal number. 1112 * * A literal number.
1113 * * A literal boolean. 1113 * * A literal boolean.
1114 * * A literal string where any interpolated expression is a compile-time consta nt that evaluates 1114 * * A literal string where any interpolated expression is a compile-time
1115 * to a numeric, string or boolean value or to <b>null</b>. 1115 * constant that evaluates to a numeric, string or boolean value or to
1116 * <b>null</b>.
1116 * * A literal symbol. 1117 * * A literal symbol.
1117 * * <b>null</b>. 1118 * * <b>null</b>.
1118 * * A qualified reference to a static constant variable. 1119 * * A qualified reference to a static constant variable.
1119 * * An identifier expression that denotes a constant variable, class or type al ias. 1120 * * An identifier expression that denotes a constant variable, class or type
1121 * alias.
1120 * * A constant constructor invocation. 1122 * * A constant constructor invocation.
1121 * * A constant list literal. 1123 * * A constant list literal.
1122 * * A constant map literal. 1124 * * A constant map literal.
1123 * * A simple or qualified identifier denoting a top-level function or a static method. 1125 * * A simple or qualified identifier denoting a top-level function or a static
1124 * * A parenthesized expression <i>(e)</i> where <i>e</i> is a constant expressi on. 1126 * method.
1125 * * An expression of the form <i>identical(e<sub>1</sub>, e<sub>2</sub>)</i> wh ere 1127 * * A parenthesized expression <i>(e)</i> where <i>e</i> is a constant
1126 * <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant expressions and <i >identical()</i> is 1128 * expression.
1127 * statically bound to the predefined dart function <i>identical()</i> discussed above. 1129 * * An expression of the form <i>identical(e<sub>1</sub>, e<sub>2</sub>)</i>
1128 * * An expression of one of the forms <i>e<sub>1</sub> == e<sub>2</sub></i> or <i>e<sub>1</sub> 1130 * where <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant
1129 * != e<sub>2</sub></i> where <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant expressions 1131 * expressions and <i>identical()</i> is statically bound to the predefined
1130 * that evaluate to a numeric, string or boolean value. 1132 * dart function <i>identical()</i> discussed above.
1131 * * An expression of one of the forms <i>!e</i>, <i>e<sub>1</sub> &amp;&amp; e< sub>2</sub></i> or 1133 * * An expression of one of the forms <i>e<sub>1</sub> == e<sub>2</sub></i> or
1132 * <i>e<sub>1</sub> || e<sub>2</sub></i>, where <i>e</i>, <i>e1</sub></i> and <i >e2</sub></i> are 1134 * <i>e<sub>1</sub> != e<sub>2</sub></i> where <i>e<sub>1</sub></i> and
1133 * constant expressions that evaluate to a boolean value. 1135 * <i>e<sub>2</sub></i> are constant expressions that evaluate to a numeric,
1134 * * An expression of one of the forms <i>~e</i>, <i>e<sub>1</sub> ^ e<sub>2</su b></i>, 1136 * string or boolean value.
1135 * <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> 1137 * * An expression of one of the forms <i>!e</i>, <i>e<sub>1</sub> &amp;&amp;
1136 * &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>, 1138 * e<sub>2</sub></i> or <i>e<sub>1</sub> || e<sub>2</sub></i>, where <i>e</i>,
1137 * <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant expressions that e valuate to an 1139 * <i>e1</sub></i> and <i>e2</sub></i> are constant expressions that evaluate
1138 * integer value or to <b>null</b>. 1140 * to a boolean value.
1139 * * An expression of one of the forms <i>-e</i>, <i>e<sub>1</sub> + e<sub>2</su b></i>, 1141 * * An expression of one of the forms <i>~e</i>, <i>e<sub>1</sub> ^
1140 * <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> / 1142 * e<sub>2</sub></i>, <i>e<sub>1</sub> &amp; e<sub>2</sub></i>,
1141 * e<sub>2</sub></i>, <i>e<sub>1</sub> ~/ e<sub>2</sub></i>, <i>e<sub>1</sub> &g t; 1143 * <i>e<sub>1</sub> | e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;&gt;
1142 * e<sub>2</sub></i>, <i>e<sub>1</sub> &lt; e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;= 1144 * e<sub>2</sub></i> or <i>e<sub>1</sub> &lt;&lt; e<sub>2</sub></i>, where
1143 * e<sub>2</sub></i>, <i>e<sub>1</sub> &lt;= e<sub>2</sub></i> or <i>e<sub>1</su b> % 1145 * <i>e</i>, <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant
1144 * e<sub>2</sub></i>, where <i>e</i>, <i>e<sub>1</sub></i> and <i>e<sub>2</sub>< /i> are constant 1146 * expressions that evaluate to an integer value or to <b>null</b>.
1145 * expressions that evaluate to a numeric value or to <b>null</b>. 1147 * * An expression of one of the forms <i>-e</i>, <i>e<sub>1</sub> +
1146 * * An expression of the form <i>e<sub>1</sub> ? e<sub>2</sub> : e<sub>3</sub>< /i> where 1148 * e<sub>2</sub></i>, <i>e<sub>1</sub> - e<sub>2</sub></i>, <i>e<sub>1</sub> *
1147 * <i>e<sub>1</sub></i>, <i>e<sub>2</sub></i> and <i>e<sub>3</sub></i> are const ant expressions, and 1149 * e<sub>2</sub></i>, <i>e<sub>1</sub> / e<sub>2</sub></i>, <i>e<sub>1</sub>
1148 * <i>e<sub>1</sub></i> evaluates to a boolean value. 1150 * ~/ e<sub>2</sub></i>, <i>e<sub>1</sub> &gt; e<sub>2</sub></i>,
1151 * <i>e<sub>1</sub> &lt; e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;=
1152 * e<sub>2</sub></i>, <i>e<sub>1</sub> &lt;= e<sub>2</sub></i> or
1153 * <i>e<sub>1</sub> % e<sub>2</sub></i>, where <i>e</i>, <i>e<sub>1</sub></i>
1154 * and <i>e<sub>2</sub></i> are constant expressions that evaluate to a
1155 * numeric value or to <b>null</b>.
1156 * * An expression of the form <i>e<sub>1</sub> ? e<sub>2</sub> :
1157 * e<sub>3</sub></i> where <i>e<sub>1</sub></i>, <i>e<sub>2</sub></i> and
1158 * <i>e<sub>3</sub></i> are constant expressions, and <i>e<sub>1</sub></i>
1159 * evaluates to a boolean value.
1149 * </blockquote> 1160 * </blockquote>
1150 */ 1161 */
1151 class ConstantVisitor extends UnifyingAstVisitor<DartObjectImpl> { 1162 class ConstantVisitor extends UnifyingAstVisitor<DartObjectImpl> {
1152 /** 1163 /**
1153 * The type provider used to access the known types. 1164 * The type provider used to access the known types.
1154 */ 1165 */
1155 final TypeProvider _typeProvider; 1166 final TypeProvider _typeProvider;
1156 1167
1157 /** 1168 /**
1158 * An shared object representing the value 'null'. 1169 * An shared object representing the value 'null'.
1159 */ 1170 */
1160 DartObjectImpl _nullObject; 1171 DartObjectImpl _nullObject;
1161 1172
1162 HashMap<String, DartObjectImpl> _lexicalEnvironment; 1173 HashMap<String, DartObjectImpl> _lexicalEnvironment;
1163 1174
1164 /** 1175 /**
1165 * Error reporter that we use to report errors accumulated while computing the constant. 1176 * Error reporter that we use to report errors accumulated while computing the
1177 * constant.
1166 */ 1178 */
1167 final ErrorReporter _errorReporter; 1179 final ErrorReporter _errorReporter;
1168 1180
1169 /** 1181 /**
1170 * Helper class used to compute constant values. 1182 * Helper class used to compute constant values.
1171 */ 1183 */
1172 DartObjectComputer _dartObjectComputer; 1184 DartObjectComputer _dartObjectComputer;
1173 1185
1174 /** 1186 /**
1175 * Initialize a newly created constant visitor. 1187 * Initialize a newly created constant visitor. The [_typeProvider] is the
1176 * 1188 * type provider used to access known types. The [_errorReporter] is used to
1177 * @param typeProvider the type provider used to access known types 1189 * report errors found during evaluation.
1178 * @param lexicalEnvironment values which should override simpleIdentifiers, o r null if no
1179 * overriding is necessary.
1180 */ 1190 */
1181 ConstantVisitor.con1(this._typeProvider, this._errorReporter) { 1191 ConstantVisitor.con1(this._typeProvider, this._errorReporter) {
1182 this._lexicalEnvironment = null; 1192 this._lexicalEnvironment = null;
1183 this._dartObjectComputer = 1193 this._dartObjectComputer =
1184 new DartObjectComputer(_errorReporter, _typeProvider); 1194 new DartObjectComputer(_errorReporter, _typeProvider);
1185 } 1195 }
1186 1196
1187 /** 1197 /**
1188 * Initialize a newly created constant visitor. 1198 * Initialize a newly created constant visitor. The [_typeProvider] is the
1189 * 1199 * type provider used to access known types. The [lexicalEnvironment] is a map
1190 * @param typeProvider the type provider used to access known types 1200 * containing values which should override identifiers, or `null` if no
1191 * @param lexicalEnvironment values which should override simpleIdentifiers, o r null if no 1201 * overriding is necessary. The [_errorReporter] is used to report errors
1192 * overriding is necessary. 1202 * found during evaluation.
1193 */ 1203 */
1194 ConstantVisitor.con2(this._typeProvider, 1204 ConstantVisitor.con2(this._typeProvider,
1195 HashMap<String, DartObjectImpl> lexicalEnvironment, this._errorReporter) { 1205 HashMap<String, DartObjectImpl> lexicalEnvironment, this._errorReporter) {
1196 this._lexicalEnvironment = lexicalEnvironment; 1206 this._lexicalEnvironment = lexicalEnvironment;
1197 this._dartObjectComputer = 1207 this._dartObjectComputer =
1198 new DartObjectComputer(_errorReporter, _typeProvider); 1208 new DartObjectComputer(_errorReporter, _typeProvider);
1199 } 1209 }
1200 1210
1201 /** 1211 /**
1202 * Return an object representing the value 'null'. 1212 * Return an object representing the value 'null'.
1203 *
1204 * @return an object representing the value 'null'
1205 */ 1213 */
1206 DartObjectImpl get null2 { 1214 DartObjectImpl get null2 {
1207 if (_nullObject == null) { 1215 if (_nullObject == null) {
1208 _nullObject = 1216 _nullObject =
1209 new DartObjectImpl(_typeProvider.nullType, NullState.NULL_STATE); 1217 new DartObjectImpl(_typeProvider.nullType, NullState.NULL_STATE);
1210 } 1218 }
1211 return _nullObject; 1219 return _nullObject;
1212 } 1220 }
1213 1221
1214 /** 1222 /**
1215 * This method is called just before retrieving an evaluation result from an A ST node. Unit tests 1223 * This method is called just before retrieving an evaluation result from an
1216 * will override it to introduce additional error checking. 1224 * AST node. Unit tests will override it to introduce additional error
1225 * checking.
1217 */ 1226 */
1218 void beforeGetEvaluationResult(AstNode node) {} 1227 void beforeGetEvaluationResult(AstNode node) {}
1219 1228
1220 /** 1229 /**
1221 * Return `true` if the given [element] represents the `length` getter in 1230 * Return `true` if the given [element] represents the `length` getter in
1222 * class [String]. 1231 * class 'String'.
1223 */ 1232 */
1224 bool isStringLength(Element element) { 1233 bool isStringLength(Element element) {
1225 if (element is PropertyAccessorElement) { 1234 if (element is PropertyAccessorElement) {
1226 if (element.isGetter && element.name == 'length') { 1235 if (element.isGetter && element.name == 'length') {
1227 return element.enclosingElement == _typeProvider.stringType.element; 1236 return element.enclosingElement == _typeProvider.stringType.element;
1228 } 1237 }
1229 } 1238 }
1230 return false; 1239 return false;
1231 } 1240 }
1232 1241
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after
1595 if (i > 0) { 1604 if (i > 0) {
1596 buffer.writeCharCode(0x2E); 1605 buffer.writeCharCode(0x2E);
1597 } 1606 }
1598 buffer.write(components[i].lexeme); 1607 buffer.write(components[i].lexeme);
1599 } 1608 }
1600 return new DartObjectImpl( 1609 return new DartObjectImpl(
1601 _typeProvider.symbolType, new SymbolState(buffer.toString())); 1610 _typeProvider.symbolType, new SymbolState(buffer.toString()));
1602 } 1611 }
1603 1612
1604 /** 1613 /**
1605 * Create an error associated with the given node. 1614 * Create an error associated with the given [node]. The error will have the
1606 * 1615 * given error [code].
1607 * @param node the AST node associated with the error
1608 * @param code the error code indicating the nature of the error
1609 */ 1616 */
1610 void _error(AstNode node, ErrorCode code) { 1617 void _error(AstNode node, ErrorCode code) {
1611 _errorReporter.reportErrorForNode( 1618 _errorReporter.reportErrorForNode(
1612 code == null ? CompileTimeErrorCode.INVALID_CONSTANT : code, node); 1619 code == null ? CompileTimeErrorCode.INVALID_CONSTANT : code, node);
1613 } 1620 }
1614 1621
1615 /** 1622 /**
1616 * Return the constant value of the static constant represented by the given e lement. 1623 * Return the constant value of the static constant represented by the given
1617 * 1624 * [element]. The [node] is the node to be used if an error needs to be
1618 * @param node the node to be used if an error needs to be reported 1625 * reported.
1619 * @param element the element whose value is to be returned
1620 * @return the constant value of the static constant
1621 */ 1626 */
1622 DartObjectImpl _getConstantValue(AstNode node, Element element) { 1627 DartObjectImpl _getConstantValue(AstNode node, Element element) {
1623 if (element is PropertyAccessorElement) { 1628 if (element is PropertyAccessorElement) {
1624 element = (element as PropertyAccessorElement).variable; 1629 element = (element as PropertyAccessorElement).variable;
1625 } 1630 }
1626 if (element is VariableElementImpl) { 1631 if (element is VariableElementImpl) {
1627 VariableElementImpl variableElementImpl = element; 1632 VariableElementImpl variableElementImpl = element;
1628 beforeGetEvaluationResult(node); 1633 beforeGetEvaluationResult(node);
1629 EvaluationResultImpl value = variableElementImpl.evaluationResult; 1634 EvaluationResultImpl value = variableElementImpl.evaluationResult;
1630 if (variableElementImpl.isConst && value != null) { 1635 if (variableElementImpl.isConst && value != null) {
(...skipping 26 matching lines...) Expand all
1657 } else if (typeName == "int") { 1662 } else if (typeName == "int") {
1658 return new DartObjectImpl(type, IntState.UNKNOWN_VALUE); 1663 return new DartObjectImpl(type, IntState.UNKNOWN_VALUE);
1659 } else if (typeName == "String") { 1664 } else if (typeName == "String") {
1660 return new DartObjectImpl(type, StringState.UNKNOWN_VALUE); 1665 return new DartObjectImpl(type, StringState.UNKNOWN_VALUE);
1661 } 1666 }
1662 } 1667 }
1663 return new DartObjectImpl(type, GenericState.UNKNOWN_VALUE); 1668 return new DartObjectImpl(type, GenericState.UNKNOWN_VALUE);
1664 } 1669 }
1665 1670
1666 /** 1671 /**
1667 * Return the value of the given expression, or a representation of 'null' if the expression 1672 * Return the value of the given [expression], or a representation of 'null'
1668 * cannot be evaluated. 1673 * if the expression cannot be evaluated.
1669 *
1670 * @param expression the expression whose value is to be returned
1671 * @return the value of the given expression
1672 */ 1674 */
1673 DartObjectImpl _valueOf(Expression expression) { 1675 DartObjectImpl _valueOf(Expression expression) {
1674 DartObjectImpl expressionValue = expression.accept(this); 1676 DartObjectImpl expressionValue = expression.accept(this);
1675 if (expressionValue != null) { 1677 if (expressionValue != null) {
1676 return expressionValue; 1678 return expressionValue;
1677 } 1679 }
1678 return null2; 1680 return null2;
1679 } 1681 }
1680 } 1682 }
1681 1683
1682 /** 1684 /**
1683 * The interface `DartObject` defines the behavior of objects that represent the state of a 1685 * The state of a Dart object.
1684 * Dart object.
1685 */ 1686 */
1686 abstract class DartObject { 1687 abstract class DartObject {
1687 /** 1688 /**
1688 * Return the boolean value of this object, or `null` if either the value of t his object is 1689 * Return the boolean value of this object, or `null` if either the value of
1689 * not known or this object is not of type 'bool'. 1690 * this object is not known or this object is not of type 'bool'.
1690 *
1691 * @return the boolean value of this object
1692 */ 1691 */
1693 bool get boolValue; 1692 bool get boolValue;
1694 1693
1695 /** 1694 /**
1696 * Return the floating point value of this object, or `null` if either the val ue of this 1695 * Return the floating point value of this object, or `null` if either the
1697 * object is not known or this object is not of type 'double'. 1696 * value of this object is not known or this object is not of type 'double'.
1698 *
1699 * @return the floating point value of this object
1700 */ 1697 */
1701 double get doubleValue; 1698 double get doubleValue;
1702 1699
1703 /** 1700 /**
1704 * Return `true` if this object's value can be represented exactly. 1701 * Return `true` if this object's value can be represented exactly.
1705 *
1706 * @return `true` if this object's value can be represented exactly
1707 */ 1702 */
1708 bool get hasExactValue; 1703 bool get hasExactValue;
1709 1704
1710 /** 1705 /**
1711 * Return the integer value of this object, or `null` if either the value of t his object is 1706 * Return the integer value of this object, or `null` if either the value of
1712 * not known or this object is not of type 'int'. 1707 * this object is not known or this object is not of type 'int'.
1713 *
1714 * @return the integer value of this object
1715 */ 1708 */
1716 int get intValue; 1709 int get intValue;
1717 1710
1718 /** 1711 /**
1719 * Return `true` if this object represents the value 'false'. 1712 * Return `true` if this object represents the value 'false'.
1720 *
1721 * @return `true` if this object represents the value 'false'
1722 */ 1713 */
1723 bool get isFalse; 1714 bool get isFalse;
1724 1715
1725 /** 1716 /**
1726 * Return `true` if this object represents the value 'null'. 1717 * Return `true` if this object represents the value 'null'.
1727 *
1728 * @return `true` if this object represents the value 'null'
1729 */ 1718 */
1730 bool get isNull; 1719 bool get isNull;
1731 1720
1732 /** 1721 /**
1733 * Return `true` if this object represents the value 'true'. 1722 * Return `true` if this object represents the value 'true'.
1734 *
1735 * @return `true` if this object represents the value 'true'
1736 */ 1723 */
1737 bool get isTrue; 1724 bool get isTrue;
1738 1725
1739 /** 1726 /**
1740 * Return the string value of this object, or `null` if either the value of th is object is 1727 * Return the string value of this object, or `null` if either the value of
1741 * not known or this object is not of type 'String'. 1728 * this object is not known or this object is not of type 'String'.
1742 *
1743 * @return the string value of this object
1744 */ 1729 */
1745 String get stringValue; 1730 String get stringValue;
1746 1731
1747 /** 1732 /**
1748 * Return the run-time type of this object. 1733 * Return the run-time type of this object.
1749 *
1750 * @return the run-time type of this object
1751 */ 1734 */
1752 ParameterizedType get type; 1735 ParameterizedType get type;
1753 1736
1754 /** 1737 /**
1755 * Return this object's value if it can be represented exactly, or `null` if e ither the 1738 * Return this object's value if it can be represented exactly, or `null` if
1756 * value cannot be represented exactly or if the value is `null`. Clients shou ld use 1739 * either the value cannot be represented exactly or if the value is `null`.
1757 * [hasExactValue] to distinguish between these two cases. 1740 * Clients should use [hasExactValue] to distinguish between these two cases.
1758 *
1759 * @return this object's value
1760 */ 1741 */
1761 Object get value; 1742 Object get value;
1762 } 1743 }
1763 1744
1764 /** 1745 /**
1765 * Instances of the class `DartObjectComputer` contain methods for manipulating instances of a 1746 * A utility class that contains methods for manipulating instances of a Dart
1766 * Dart class and for collecting errors during evaluation. 1747 * class and for collecting errors during evaluation.
1767 */ 1748 */
1768 class DartObjectComputer { 1749 class DartObjectComputer {
1769 /** 1750 /**
1770 * The error reporter that we are using to collect errors. 1751 * The error reporter that we are using to collect errors.
1771 */ 1752 */
1772 final ErrorReporter _errorReporter; 1753 final ErrorReporter _errorReporter;
1773 1754
1774 /** 1755 /**
1775 * The type provider. Used to create objects of the appropriate types, and to identify when an 1756 * The type provider used to create objects of the appropriate types, and to
1776 * object is of a built-in type. 1757 * identify when an object is of a built-in type.
1777 */ 1758 */
1778 final TypeProvider _typeProvider; 1759 final TypeProvider _typeProvider;
1779 1760
1780 DartObjectComputer(this._errorReporter, this._typeProvider); 1761 DartObjectComputer(this._errorReporter, this._typeProvider);
1781 1762
1782 DartObjectImpl add(BinaryExpression node, DartObjectImpl leftOperand, 1763 DartObjectImpl add(BinaryExpression node, DartObjectImpl leftOperand,
1783 DartObjectImpl rightOperand) { 1764 DartObjectImpl rightOperand) {
1784 if (leftOperand != null && rightOperand != null) { 1765 if (leftOperand != null && rightOperand != null) {
1785 try { 1766 try {
1786 return leftOperand.add(_typeProvider, rightOperand); 1767 return leftOperand.add(_typeProvider, rightOperand);
1787 } on EvaluationException catch (exception) { 1768 } on EvaluationException catch (exception) {
1788 _errorReporter.reportErrorForNode(exception.errorCode, node); 1769 _errorReporter.reportErrorForNode(exception.errorCode, node);
1789 return null; 1770 return null;
1790 } 1771 }
1791 } 1772 }
1792 return null; 1773 return null;
1793 } 1774 }
1794 1775
1795 /** 1776 /**
1796 * Return the result of applying boolean conversion to this result. 1777 * Return the result of applying boolean conversion to the [evaluationResult].
1797 * 1778 * The [node] is the node against which errors should be reported.
1798 * @param node the node against which errors should be reported
1799 * @return the result of applying boolean conversion to the given value
1800 */ 1779 */
1801 DartObjectImpl applyBooleanConversion( 1780 DartObjectImpl applyBooleanConversion(
1802 AstNode node, DartObjectImpl evaluationResult) { 1781 AstNode node, DartObjectImpl evaluationResult) {
1803 if (evaluationResult != null) { 1782 if (evaluationResult != null) {
1804 try { 1783 try {
1805 return evaluationResult.convertToBool(_typeProvider); 1784 return evaluationResult.convertToBool(_typeProvider);
1806 } on EvaluationException catch (exception) { 1785 } on EvaluationException catch (exception) {
1807 _errorReporter.reportErrorForNode(exception.errorCode, node); 1786 _errorReporter.reportErrorForNode(exception.errorCode, node);
1808 } 1787 }
1809 } 1788 }
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
2077 try { 2056 try {
2078 return leftOperand.shiftRight(_typeProvider, rightOperand); 2057 return leftOperand.shiftRight(_typeProvider, rightOperand);
2079 } on EvaluationException catch (exception) { 2058 } on EvaluationException catch (exception) {
2080 _errorReporter.reportErrorForNode(exception.errorCode, node); 2059 _errorReporter.reportErrorForNode(exception.errorCode, node);
2081 } 2060 }
2082 } 2061 }
2083 return null; 2062 return null;
2084 } 2063 }
2085 2064
2086 /** 2065 /**
2087 * Return the result of invoking the 'length' getter on this result. 2066 * Return the result of invoking the 'length' getter on the
2088 * 2067 * [evaluationResult]. The [node] is the node against which errors should be
2089 * @param node the node against which errors should be reported 2068 * reported.
2090 * @return the result of invoking the 'length' getter on this result
2091 */ 2069 */
2092 EvaluationResultImpl stringLength( 2070 EvaluationResultImpl stringLength(
2093 Expression node, EvaluationResultImpl evaluationResult) { 2071 Expression node, EvaluationResultImpl evaluationResult) {
2094 if (evaluationResult.value != null) { 2072 if (evaluationResult.value != null) {
2095 try { 2073 try {
2096 return new EvaluationResultImpl.con1( 2074 return new EvaluationResultImpl.con1(
2097 evaluationResult.value.stringLength(_typeProvider)); 2075 evaluationResult.value.stringLength(_typeProvider));
2098 } on EvaluationException catch (exception) { 2076 } on EvaluationException catch (exception) {
2099 _errorReporter.reportErrorForNode(exception.errorCode, node); 2077 _errorReporter.reportErrorForNode(exception.errorCode, node);
2100 } 2078 }
2101 } 2079 }
2102 return new EvaluationResultImpl.con1(null); 2080 return new EvaluationResultImpl.con1(null);
2103 } 2081 }
2104 2082
2105 DartObjectImpl times(BinaryExpression node, DartObjectImpl leftOperand, 2083 DartObjectImpl times(BinaryExpression node, DartObjectImpl leftOperand,
2106 DartObjectImpl rightOperand) { 2084 DartObjectImpl rightOperand) {
2107 if (leftOperand != null && rightOperand != null) { 2085 if (leftOperand != null && rightOperand != null) {
2108 try { 2086 try {
2109 return leftOperand.times(_typeProvider, rightOperand); 2087 return leftOperand.times(_typeProvider, rightOperand);
2110 } on EvaluationException catch (exception) { 2088 } on EvaluationException catch (exception) {
2111 _errorReporter.reportErrorForNode(exception.errorCode, node); 2089 _errorReporter.reportErrorForNode(exception.errorCode, node);
2112 } 2090 }
2113 } 2091 }
2114 return null; 2092 return null;
2115 } 2093 }
2116 } 2094 }
2117 2095
2118 /** 2096 /**
2119 * Instances of the class `DartObjectImpl` represent an instance of a Dart class . 2097 * An instance of a Dart class.
2120 */ 2098 */
2121 class DartObjectImpl implements DartObject { 2099 class DartObjectImpl implements DartObject {
2122 /** 2100 /**
2123 * An empty list of objects. 2101 * An empty list of objects.
2124 */ 2102 */
2125 static const List<DartObjectImpl> EMPTY_LIST = const <DartObjectImpl>[]; 2103 static const List<DartObjectImpl> EMPTY_LIST = const <DartObjectImpl>[];
2126 2104
2127 /** 2105 /**
2128 * The run-time type of this object. 2106 * The run-time type of this object.
2129 */ 2107 */
2130 final ParameterizedType type; 2108 final ParameterizedType type;
2131 2109
2132 /** 2110 /**
2133 * The state of the object. 2111 * The state of the object.
2134 */ 2112 */
2135 final InstanceState _state; 2113 final InstanceState _state;
2136 2114
2137 /** 2115 /**
2138 * Initialize a newly created object to have the given type and state. 2116 * Initialize a newly created object to have the given [type] and [_state].
2139 *
2140 * @param type the run-time type of this object
2141 * @param state the state of the object
2142 */ 2117 */
2143 DartObjectImpl(this.type, this._state); 2118 DartObjectImpl(this.type, this._state);
2144 2119
2145 @override 2120 @override
2146 bool get boolValue { 2121 bool get boolValue {
2147 if (_state is BoolState) { 2122 if (_state is BoolState) {
2148 return (_state as BoolState).value; 2123 return (_state as BoolState).value;
2149 } 2124 }
2150 return null; 2125 return null;
2151 } 2126 }
(...skipping 17 matching lines...) Expand all
2169 @override 2144 @override
2170 int get intValue { 2145 int get intValue {
2171 if (_state is IntState) { 2146 if (_state is IntState) {
2172 return (_state as IntState).value; 2147 return (_state as IntState).value;
2173 } 2148 }
2174 return null; 2149 return null;
2175 } 2150 }
2176 2151
2177 /** 2152 /**
2178 * Return `true` if this object represents an object whose type is 'bool'. 2153 * Return `true` if this object represents an object whose type is 'bool'.
2179 *
2180 * @return `true` if this object represents a boolean value
2181 */ 2154 */
2182 bool get isBool => _state.isBool; 2155 bool get isBool => _state.isBool;
2183 2156
2184 /** 2157 /**
2185 * Return `true` if this object represents an object whose type is either 'boo l', 'num', 2158 * Return `true` if this object represents an object whose type is either
2186 * 'String', or 'Null'. 2159 * 'bool', 'num', 'String', or 'Null'.
2187 *
2188 * @return `true` if this object represents either a boolean, numeric, string or null value
2189 */ 2160 */
2190 bool get isBoolNumStringOrNull => _state.isBoolNumStringOrNull; 2161 bool get isBoolNumStringOrNull => _state.isBoolNumStringOrNull;
2191 2162
2192 @override 2163 @override
2193 bool get isFalse => 2164 bool get isFalse =>
2194 _state is BoolState && identical((_state as BoolState).value, false); 2165 _state is BoolState && identical((_state as BoolState).value, false);
2195 2166
2196 @override 2167 @override
2197 bool get isNull => _state is NullState; 2168 bool get isNull => _state is NullState;
2198 2169
2199 @override 2170 @override
2200 bool get isTrue => 2171 bool get isTrue =>
2201 _state is BoolState && identical((_state as BoolState).value, true); 2172 _state is BoolState && identical((_state as BoolState).value, true);
2202 2173
2203 /** 2174 /**
2204 * Return true if this object represents an unknown value. 2175 * Return `true` if this object represents an unknown value.
2205 */ 2176 */
2206 bool get isUnknown => _state.isUnknown; 2177 bool get isUnknown => _state.isUnknown;
2207 2178
2208 /** 2179 /**
2209 * Return `true` if this object represents an instance of a user-defined class . 2180 * Return `true` if this object represents an instance of a user-defined
2210 * 2181 * class.
2211 * @return `true` if this object represents an instance of a user-defined clas s
2212 */ 2182 */
2213 bool get isUserDefinedObject => _state is GenericState; 2183 bool get isUserDefinedObject => _state is GenericState;
2214 2184
2215 @override 2185 @override
2216 String get stringValue { 2186 String get stringValue {
2217 if (_state is StringState) { 2187 if (_state is StringState) {
2218 return (_state as StringState).value; 2188 return (_state as StringState).value;
2219 } 2189 }
2220 return null; 2190 return null;
2221 } 2191 }
2222 2192
2223 @override 2193 @override
2224 Object get value => _state.value; 2194 Object get value => _state.value;
2225 2195
2226 @override 2196 @override
2227 bool operator ==(Object object) { 2197 bool operator ==(Object object) {
2228 if (object is! DartObjectImpl) { 2198 if (object is! DartObjectImpl) {
2229 return false; 2199 return false;
2230 } 2200 }
2231 DartObjectImpl dartObject = object as DartObjectImpl; 2201 DartObjectImpl dartObject = object as DartObjectImpl;
2232 return type == dartObject.type && _state == dartObject._state; 2202 return type == dartObject.type && _state == dartObject._state;
2233 } 2203 }
2234 2204
2235 /** 2205 /**
2236 * Return the result of invoking the '+' operator on this object with the give n argument. 2206 * Return the result of invoking the '+' operator on this object with the
2207 * given [rightOperand]. The [typeProvider] is the type provider used to find
2208 * known types.
2237 * 2209 *
2238 * @param typeProvider the type provider used to find known types 2210 * Throws an [EvaluationException] if the operator is not appropriate for an
2239 * @param rightOperand the right-hand operand of the operation 2211 * object of this kind.
2240 * @return the result of invoking the '+' operator on this object with the giv en argument
2241 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2242 */ 2212 */
2243 DartObjectImpl add(TypeProvider typeProvider, DartObjectImpl rightOperand) { 2213 DartObjectImpl add(TypeProvider typeProvider, DartObjectImpl rightOperand) {
2244 InstanceState result = _state.add(rightOperand._state); 2214 InstanceState result = _state.add(rightOperand._state);
2245 if (result is IntState) { 2215 if (result is IntState) {
2246 return new DartObjectImpl(typeProvider.intType, result); 2216 return new DartObjectImpl(typeProvider.intType, result);
2247 } else if (result is DoubleState) { 2217 } else if (result is DoubleState) {
2248 return new DartObjectImpl(typeProvider.doubleType, result); 2218 return new DartObjectImpl(typeProvider.doubleType, result);
2249 } else if (result is NumState) { 2219 } else if (result is NumState) {
2250 return new DartObjectImpl(typeProvider.numType, result); 2220 return new DartObjectImpl(typeProvider.numType, result);
2251 } else if (result is StringState) { 2221 } else if (result is StringState) {
2252 return new DartObjectImpl(typeProvider.stringType, result); 2222 return new DartObjectImpl(typeProvider.stringType, result);
2253 } 2223 }
2254 // We should never get here. 2224 // We should never get here.
2255 throw new IllegalStateException("add returned a ${result.runtimeType}"); 2225 throw new IllegalStateException("add returned a ${result.runtimeType}");
2256 } 2226 }
2257 2227
2258 /** 2228 /**
2259 * Return the result of invoking the '&' operator on this object with the give n argument. 2229 * Return the result of invoking the '&' operator on this object with the
2230 * [rightOperand]. The [typeProvider] is the type provider used to find known
2231 * types.
2260 * 2232 *
2261 * @param typeProvider the type provider used to find known types 2233 * Throws an [EvaluationException] if the operator is not appropriate for an
2262 * @param rightOperand the right-hand operand of the operation 2234 * object of this kind.
2263 * @return the result of invoking the '&' operator on this object with the giv en argument
2264 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2265 */ 2235 */
2266 DartObjectImpl bitAnd( 2236 DartObjectImpl bitAnd(
2267 TypeProvider typeProvider, DartObjectImpl rightOperand) => 2237 TypeProvider typeProvider, DartObjectImpl rightOperand) =>
2268 new DartObjectImpl( 2238 new DartObjectImpl(
2269 typeProvider.intType, _state.bitAnd(rightOperand._state)); 2239 typeProvider.intType, _state.bitAnd(rightOperand._state));
2270 2240
2271 /** 2241 /**
2272 * Return the result of invoking the '~' operator on this object. 2242 * Return the result of invoking the '~' operator on this object. The
2243 * [typeProvider] is the type provider used to find known types.
2273 * 2244 *
2274 * @param typeProvider the type provider used to find known types 2245 * Throws an [EvaluationException] if the operator is not appropriate for an
2275 * @return the result of invoking the '~' operator on this object 2246 * object of this kind.
2276 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2277 */ 2247 */
2278 DartObjectImpl bitNot(TypeProvider typeProvider) => 2248 DartObjectImpl bitNot(TypeProvider typeProvider) =>
2279 new DartObjectImpl(typeProvider.intType, _state.bitNot()); 2249 new DartObjectImpl(typeProvider.intType, _state.bitNot());
2280 2250
2281 /** 2251 /**
2282 * Return the result of invoking the '|' operator on this object with the give n argument. 2252 * Return the result of invoking the '|' operator on this object with the
2253 * [rightOperand]. The [typeProvider] is the type provider used to find known
2254 * types.
2283 * 2255 *
2284 * @param typeProvider the type provider used to find known types 2256 * Throws an [EvaluationException] if the operator is not appropriate for an
2285 * @param rightOperand the right-hand operand of the operation 2257 * object of this kind.
2286 * @return the result of invoking the '|' operator on this object with the giv en argument
2287 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2288 */ 2258 */
2289 DartObjectImpl bitOr( 2259 DartObjectImpl bitOr(
2290 TypeProvider typeProvider, DartObjectImpl rightOperand) => 2260 TypeProvider typeProvider, DartObjectImpl rightOperand) =>
2291 new DartObjectImpl( 2261 new DartObjectImpl(
2292 typeProvider.intType, _state.bitOr(rightOperand._state)); 2262 typeProvider.intType, _state.bitOr(rightOperand._state));
2293 2263
2294 /** 2264 /**
2295 * Return the result of invoking the '^' operator on this object with the give n argument. 2265 * Return the result of invoking the '^' operator on this object with the
2266 * [rightOperand]. The [typeProvider] is the type provider used to find known
2267 * types.
2296 * 2268 *
2297 * @param typeProvider the type provider used to find known types 2269 * Throws an [EvaluationException] if the operator is not appropriate for an
2298 * @param rightOperand the right-hand operand of the operation 2270 * object of this kind.
2299 * @return the result of invoking the '^' operator on this object with the giv en argument
2300 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2301 */ 2271 */
2302 DartObjectImpl bitXor( 2272 DartObjectImpl bitXor(
2303 TypeProvider typeProvider, DartObjectImpl rightOperand) => 2273 TypeProvider typeProvider, DartObjectImpl rightOperand) =>
2304 new DartObjectImpl( 2274 new DartObjectImpl(
2305 typeProvider.intType, _state.bitXor(rightOperand._state)); 2275 typeProvider.intType, _state.bitXor(rightOperand._state));
2306 2276
2307 /** 2277 /**
2308 * Return the result of invoking the ' ' operator on this object with the give n argument. 2278 * Return the result of invoking the ' ' operator on this object with the
2279 * [rightOperand]. The [typeProvider] is the type provider used to find known
2280 * types.
2309 * 2281 *
2310 * @param typeProvider the type provider used to find known types 2282 * Throws an [EvaluationException] if the operator is not appropriate for an
2311 * @param rightOperand the right-hand operand of the operation 2283 * object of this kind.
2312 * @return the result of invoking the ' ' operator on this object with the giv en argument
2313 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2314 */ 2284 */
2315 DartObjectImpl concatenate( 2285 DartObjectImpl concatenate(
2316 TypeProvider typeProvider, DartObjectImpl rightOperand) => 2286 TypeProvider typeProvider, DartObjectImpl rightOperand) =>
2317 new DartObjectImpl( 2287 new DartObjectImpl(
2318 typeProvider.stringType, _state.concatenate(rightOperand._state)); 2288 typeProvider.stringType, _state.concatenate(rightOperand._state));
2319 2289
2320 /** 2290 /**
2321 * Return the result of applying boolean conversion to this object. 2291 * Return the result of applying boolean conversion to this object. The
2292 * [typeProvider] is the type provider used to find known types.
2322 * 2293 *
2323 * @param typeProvider the type provider used to find known types 2294 * Throws an [EvaluationException] if the operator is not appropriate for an
2324 * @return the result of applying boolean conversion to this object 2295 * object of this kind.
2325 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2326 */ 2296 */
2327 DartObjectImpl convertToBool(TypeProvider typeProvider) { 2297 DartObjectImpl convertToBool(TypeProvider typeProvider) {
2328 InterfaceType boolType = typeProvider.boolType; 2298 InterfaceType boolType = typeProvider.boolType;
2329 if (identical(type, boolType)) { 2299 if (identical(type, boolType)) {
2330 return this; 2300 return this;
2331 } 2301 }
2332 return new DartObjectImpl(boolType, _state.convertToBool()); 2302 return new DartObjectImpl(boolType, _state.convertToBool());
2333 } 2303 }
2334 2304
2335 /** 2305 /**
2336 * Return the result of invoking the '/' operator on this object with the give n argument. 2306 * Return the result of invoking the '/' operator on this object with the
2307 * [rightOperand]. The [typeProvider] is the type provider used to find known
2308 * types.
2337 * 2309 *
2338 * @param typeProvider the type provider used to find known types 2310 * Throws an [EvaluationException] if the operator is not appropriate for
2339 * @param rightOperand the right-hand operand of the operation 2311 * an object of this kind.
2340 * @return the result of invoking the '/' operator on this object with the giv en argument
2341 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2342 */ 2312 */
2343 DartObjectImpl divide( 2313 DartObjectImpl divide(
2344 TypeProvider typeProvider, DartObjectImpl rightOperand) { 2314 TypeProvider typeProvider, DartObjectImpl rightOperand) {
2345 InstanceState result = _state.divide(rightOperand._state); 2315 InstanceState result = _state.divide(rightOperand._state);
2346 if (result is IntState) { 2316 if (result is IntState) {
2347 return new DartObjectImpl(typeProvider.intType, result); 2317 return new DartObjectImpl(typeProvider.intType, result);
2348 } else if (result is DoubleState) { 2318 } else if (result is DoubleState) {
2349 return new DartObjectImpl(typeProvider.doubleType, result); 2319 return new DartObjectImpl(typeProvider.doubleType, result);
2350 } else if (result is NumState) { 2320 } else if (result is NumState) {
2351 return new DartObjectImpl(typeProvider.numType, result); 2321 return new DartObjectImpl(typeProvider.numType, result);
2352 } 2322 }
2353 // We should never get here. 2323 // We should never get here.
2354 throw new IllegalStateException("divide returned a ${result.runtimeType}"); 2324 throw new IllegalStateException("divide returned a ${result.runtimeType}");
2355 } 2325 }
2356 2326
2357 /** 2327 /**
2358 * Return the result of invoking the '==' operator on this object with the giv en argument. 2328 * Return the result of invoking the '==' operator on this object with the
2329 * [rightOperand]. The [typeProvider] is the type provider used to find known
2330 * types.
2359 * 2331 *
2360 * @param typeProvider the type provider used to find known types 2332 * Throws an [EvaluationException] if the operator is not appropriate for an
2361 * @param rightOperand the right-hand operand of the operation 2333 * object of this kind.
2362 * @return the result of invoking the '==' operator on this object with the gi ven argument
2363 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2364 */ 2334 */
2365 DartObjectImpl equalEqual( 2335 DartObjectImpl equalEqual(
2366 TypeProvider typeProvider, DartObjectImpl rightOperand) { 2336 TypeProvider typeProvider, DartObjectImpl rightOperand) {
2367 if (type != rightOperand.type) { 2337 if (type != rightOperand.type) {
2368 String typeName = type.name; 2338 String typeName = type.name;
2369 if (!(typeName == "bool" || 2339 if (!(typeName == "bool" ||
2370 typeName == "double" || 2340 typeName == "double" ||
2371 typeName == "int" || 2341 typeName == "int" ||
2372 typeName == "num" || 2342 typeName == "num" ||
2373 typeName == "String" || 2343 typeName == "String" ||
2374 typeName == "Null" || 2344 typeName == "Null" ||
2375 type.isDynamic)) { 2345 type.isDynamic)) {
2376 throw new EvaluationException( 2346 throw new EvaluationException(
2377 CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING); 2347 CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING);
2378 } 2348 }
2379 } 2349 }
2380 return new DartObjectImpl( 2350 return new DartObjectImpl(
2381 typeProvider.boolType, _state.equalEqual(rightOperand._state)); 2351 typeProvider.boolType, _state.equalEqual(rightOperand._state));
2382 } 2352 }
2383 2353
2384 /** 2354 /**
2385 * Return the result of invoking the '&gt;' operator on this object with the g iven argument. 2355 * Return the result of invoking the '&gt;' operator on this object with the
2356 * [rightOperand]. The [typeProvider] is the type provider used to find known
2357 * types.
2386 * 2358 *
2387 * @param typeProvider the type provider used to find known types 2359 * Throws an [EvaluationException] if the operator is not appropriate for an
2388 * @param rightOperand the right-hand operand of the operation 2360 * object of this kind.
2389 * @return the result of invoking the '&gt;' operator on this object with the given argument
2390 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2391 */ 2361 */
2392 DartObjectImpl greaterThan( 2362 DartObjectImpl greaterThan(
2393 TypeProvider typeProvider, DartObjectImpl rightOperand) => 2363 TypeProvider typeProvider, DartObjectImpl rightOperand) =>
2394 new DartObjectImpl( 2364 new DartObjectImpl(
2395 typeProvider.boolType, _state.greaterThan(rightOperand._state)); 2365 typeProvider.boolType, _state.greaterThan(rightOperand._state));
2396 2366
2397 /** 2367 /**
2398 * Return the result of invoking the '&gt;=' operator on this object with the given argument. 2368 * Return the result of invoking the '&gt;=' operator on this object with the
2369 * [rightOperand]. The [typeProvider] is the type provider used to find known
2370 * types.
2399 * 2371 *
2400 * @param typeProvider the type provider used to find known types 2372 * Throws an [EvaluationException] if the operator is not appropriate for an
2401 * @param rightOperand the right-hand operand of the operation 2373 * object of this kind.
2402 * @return the result of invoking the '&gt;=' operator on this object with the given argument
2403 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2404 */ 2374 */
2405 DartObjectImpl greaterThanOrEqual(TypeProvider typeProvider, 2375 DartObjectImpl greaterThanOrEqual(TypeProvider typeProvider,
2406 DartObjectImpl rightOperand) => new DartObjectImpl( 2376 DartObjectImpl rightOperand) => new DartObjectImpl(
2407 typeProvider.boolType, _state.greaterThanOrEqual(rightOperand._state)); 2377 typeProvider.boolType, _state.greaterThanOrEqual(rightOperand._state));
2408 2378
2409 /** 2379 /**
2410 * Return the result of invoking the '~/' operator on this object with the giv en argument. 2380 * Return the result of invoking the '~/' operator on this object with the
2381 * [rightOperand]. The [typeProvider] is the type provider used to find known
2382 * types.
2411 * 2383 *
2412 * @param typeProvider the type provider used to find known types 2384 * Throws an [EvaluationException] if the operator is not appropriate for an
2413 * @param rightOperand the right-hand operand of the operation 2385 * object of this kind.
2414 * @return the result of invoking the '~/' operator on this object with the gi ven argument
2415 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2416 */ 2386 */
2417 DartObjectImpl integerDivide( 2387 DartObjectImpl integerDivide(
2418 TypeProvider typeProvider, DartObjectImpl rightOperand) => 2388 TypeProvider typeProvider, DartObjectImpl rightOperand) =>
2419 new DartObjectImpl( 2389 new DartObjectImpl(
2420 typeProvider.intType, _state.integerDivide(rightOperand._state)); 2390 typeProvider.intType, _state.integerDivide(rightOperand._state));
2421 2391
2422 /** 2392 /**
2423 * Return the result of invoking the identical function on this object with 2393 * Return the result of invoking the identical function on this object with
2424 * the given argument. 2394 * the [rightOperand]. The [typeProvider] is the type provider used to find
2425 * 2395 * known types.
2426 * @param typeProvider the type provider used to find known types
2427 * @param rightOperand the right-hand operand of the operation
2428 * @return the result of invoking the identical function on this object with
2429 * the given argument
2430 */ 2396 */
2431 DartObjectImpl isIdentical( 2397 DartObjectImpl isIdentical(
2432 TypeProvider typeProvider, DartObjectImpl rightOperand) { 2398 TypeProvider typeProvider, DartObjectImpl rightOperand) {
2433 return new DartObjectImpl( 2399 return new DartObjectImpl(
2434 typeProvider.boolType, _state.isIdentical(rightOperand._state)); 2400 typeProvider.boolType, _state.isIdentical(rightOperand._state));
2435 } 2401 }
2436 2402
2437 /** 2403 /**
2438 * Return the result of invoking the '&lt;' operator on this object with the g iven argument. 2404 * Return the result of invoking the '&lt;' operator on this object with the
2405 * [rightOperand]. The [typeProvider] is the type provider used to find known
2406 * types.
2439 * 2407 *
2440 * @param typeProvider the type provider used to find known types 2408 * Throws an [EvaluationException] if the operator is not appropriate for an
2441 * @param rightOperand the right-hand operand of the operation 2409 * object of this kind.
2442 * @return the result of invoking the '&lt;' operator on this object with the given argument
2443 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2444 */ 2410 */
2445 DartObjectImpl lessThan( 2411 DartObjectImpl lessThan(
2446 TypeProvider typeProvider, DartObjectImpl rightOperand) => 2412 TypeProvider typeProvider, DartObjectImpl rightOperand) =>
2447 new DartObjectImpl( 2413 new DartObjectImpl(
2448 typeProvider.boolType, _state.lessThan(rightOperand._state)); 2414 typeProvider.boolType, _state.lessThan(rightOperand._state));
2449 2415
2450 /** 2416 /**
2451 * Return the result of invoking the '&lt;=' operator on this object with the given argument. 2417 * Return the result of invoking the '&lt;=' operator on this object with the
2418 * [rightOperand]. The [typeProvider] is the type provider used to find known
2419 * types.
2452 * 2420 *
2453 * @param typeProvider the type provider used to find known types 2421 * Throws an [EvaluationException] if the operator is not appropriate for an
2454 * @param rightOperand the right-hand operand of the operation 2422 * object of this kind.
2455 * @return the result of invoking the '&lt;=' operator on this object with the given argument
2456 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2457 */ 2423 */
2458 DartObjectImpl lessThanOrEqual( 2424 DartObjectImpl lessThanOrEqual(
2459 TypeProvider typeProvider, DartObjectImpl rightOperand) => 2425 TypeProvider typeProvider, DartObjectImpl rightOperand) =>
2460 new DartObjectImpl( 2426 new DartObjectImpl(
2461 typeProvider.boolType, _state.lessThanOrEqual(rightOperand._state)); 2427 typeProvider.boolType, _state.lessThanOrEqual(rightOperand._state));
2462 2428
2463 /** 2429 /**
2464 * Return the result of invoking the '&&' operator on this object with the giv en argument. 2430 * Return the result of invoking the '&&' operator on this object with the
2431 * [rightOperand]. The [typeProvider] is the type provider used to find known
2432 * types.
2465 * 2433 *
2466 * @param typeProvider the type provider used to find known types 2434 * Throws an [EvaluationException] if the operator is not appropriate for an
2467 * @param rightOperand the right-hand operand of the operation 2435 * object of this kind.
2468 * @return the result of invoking the '&&' operator on this object with the gi ven argument
2469 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2470 */ 2436 */
2471 DartObjectImpl logicalAnd( 2437 DartObjectImpl logicalAnd(
2472 TypeProvider typeProvider, DartObjectImpl rightOperand) => 2438 TypeProvider typeProvider, DartObjectImpl rightOperand) =>
2473 new DartObjectImpl( 2439 new DartObjectImpl(
2474 typeProvider.boolType, _state.logicalAnd(rightOperand._state)); 2440 typeProvider.boolType, _state.logicalAnd(rightOperand._state));
2475 2441
2476 /** 2442 /**
2477 * Return the result of invoking the '!' operator on this object. 2443 * Return the result of invoking the '!' operator on this object. The
2444 * [typeProvider] is the type provider used to find known types.
2478 * 2445 *
2479 * @param typeProvider the type provider used to find known types 2446 * Throws an [EvaluationException] if the operator is not appropriate for an
2480 * @return the result of invoking the '!' operator on this object 2447 * object of this kind.
2481 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2482 */ 2448 */
2483 DartObjectImpl logicalNot(TypeProvider typeProvider) => 2449 DartObjectImpl logicalNot(TypeProvider typeProvider) =>
2484 new DartObjectImpl(typeProvider.boolType, _state.logicalNot()); 2450 new DartObjectImpl(typeProvider.boolType, _state.logicalNot());
2485 2451
2486 /** 2452 /**
2487 * Return the result of invoking the '||' operator on this object with the giv en argument. 2453 * Return the result of invoking the '||' operator on this object with the
2454 * [rightOperand]. The [typeProvider] is the type provider used to find known
2455 * types.
2488 * 2456 *
2489 * @param typeProvider the type provider used to find known types 2457 * Throws an [EvaluationException] if the operator is not appropriate for an
2490 * @param rightOperand the right-hand operand of the operation 2458 * object of this kind.
2491 * @return the result of invoking the '||' operator on this object with the gi ven argument
2492 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2493 */ 2459 */
2494 DartObjectImpl logicalOr( 2460 DartObjectImpl logicalOr(
2495 TypeProvider typeProvider, DartObjectImpl rightOperand) => 2461 TypeProvider typeProvider, DartObjectImpl rightOperand) =>
2496 new DartObjectImpl( 2462 new DartObjectImpl(
2497 typeProvider.boolType, _state.logicalOr(rightOperand._state)); 2463 typeProvider.boolType, _state.logicalOr(rightOperand._state));
2498 2464
2499 /** 2465 /**
2500 * Return the result of invoking the '-' operator on this object with the give n argument. 2466 * Return the result of invoking the '-' operator on this object with the
2467 * [rightOperand]. The [typeProvider] is the type provider used to find known
2468 * types.
2501 * 2469 *
2502 * @param typeProvider the type provider used to find known types 2470 * Throws an [EvaluationException] if the operator is not appropriate for an
2503 * @param rightOperand the right-hand operand of the operation 2471 * object of this kind.
2504 * @return the result of invoking the '-' operator on this object with the giv en argument
2505 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2506 */ 2472 */
2507 DartObjectImpl minus(TypeProvider typeProvider, DartObjectImpl rightOperand) { 2473 DartObjectImpl minus(TypeProvider typeProvider, DartObjectImpl rightOperand) {
2508 InstanceState result = _state.minus(rightOperand._state); 2474 InstanceState result = _state.minus(rightOperand._state);
2509 if (result is IntState) { 2475 if (result is IntState) {
2510 return new DartObjectImpl(typeProvider.intType, result); 2476 return new DartObjectImpl(typeProvider.intType, result);
2511 } else if (result is DoubleState) { 2477 } else if (result is DoubleState) {
2512 return new DartObjectImpl(typeProvider.doubleType, result); 2478 return new DartObjectImpl(typeProvider.doubleType, result);
2513 } else if (result is NumState) { 2479 } else if (result is NumState) {
2514 return new DartObjectImpl(typeProvider.numType, result); 2480 return new DartObjectImpl(typeProvider.numType, result);
2515 } 2481 }
2516 // We should never get here. 2482 // We should never get here.
2517 throw new IllegalStateException("minus returned a ${result.runtimeType}"); 2483 throw new IllegalStateException("minus returned a ${result.runtimeType}");
2518 } 2484 }
2519 2485
2520 /** 2486 /**
2521 * Return the result of invoking the '-' operator on this object. 2487 * Return the result of invoking the '-' operator on this object. The
2488 * [typeProvider] is the type provider used to find known types.
2522 * 2489 *
2523 * @param typeProvider the type provider used to find known types 2490 * Throws an [EvaluationException] if the operator is not appropriate for an
2524 * @return the result of invoking the '-' operator on this object 2491 * object of this kind.
2525 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2526 */ 2492 */
2527 DartObjectImpl negated(TypeProvider typeProvider) { 2493 DartObjectImpl negated(TypeProvider typeProvider) {
2528 InstanceState result = _state.negated(); 2494 InstanceState result = _state.negated();
2529 if (result is IntState) { 2495 if (result is IntState) {
2530 return new DartObjectImpl(typeProvider.intType, result); 2496 return new DartObjectImpl(typeProvider.intType, result);
2531 } else if (result is DoubleState) { 2497 } else if (result is DoubleState) {
2532 return new DartObjectImpl(typeProvider.doubleType, result); 2498 return new DartObjectImpl(typeProvider.doubleType, result);
2533 } else if (result is NumState) { 2499 } else if (result is NumState) {
2534 return new DartObjectImpl(typeProvider.numType, result); 2500 return new DartObjectImpl(typeProvider.numType, result);
2535 } 2501 }
2536 // We should never get here. 2502 // We should never get here.
2537 throw new IllegalStateException("negated returned a ${result.runtimeType}"); 2503 throw new IllegalStateException("negated returned a ${result.runtimeType}");
2538 } 2504 }
2539 2505
2540 /** 2506 /**
2541 * Return the result of invoking the '!=' operator on this object with the giv en argument. 2507 * Return the result of invoking the '!=' operator on this object with the
2508 * [rightOperand]. The [typeProvider] is the type provider used to find known
2509 * types.
2542 * 2510 *
2543 * @param typeProvider the type provider used to find known types 2511 * Throws an [EvaluationException] if the operator is not appropriate for an
2544 * @param rightOperand the right-hand operand of the operation 2512 * object of this kind.
2545 * @return the result of invoking the '!=' operator on this object with the gi ven argument
2546 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2547 */ 2513 */
2548 DartObjectImpl notEqual( 2514 DartObjectImpl notEqual(
2549 TypeProvider typeProvider, DartObjectImpl rightOperand) { 2515 TypeProvider typeProvider, DartObjectImpl rightOperand) {
2550 if (type != rightOperand.type) { 2516 if (type != rightOperand.type) {
2551 String typeName = type.name; 2517 String typeName = type.name;
2552 if (typeName != "bool" && 2518 if (typeName != "bool" &&
2553 typeName != "double" && 2519 typeName != "double" &&
2554 typeName != "int" && 2520 typeName != "int" &&
2555 typeName != "num" && 2521 typeName != "num" &&
2556 typeName != "String") { 2522 typeName != "String") {
2557 return new DartObjectImpl(typeProvider.boolType, BoolState.TRUE_STATE); 2523 return new DartObjectImpl(typeProvider.boolType, BoolState.TRUE_STATE);
2558 } 2524 }
2559 } 2525 }
2560 return new DartObjectImpl(typeProvider.boolType, 2526 return new DartObjectImpl(typeProvider.boolType,
2561 _state.equalEqual(rightOperand._state).logicalNot()); 2527 _state.equalEqual(rightOperand._state).logicalNot());
2562 } 2528 }
2563 2529
2564 /** 2530 /**
2565 * Return the result of converting this object to a String. 2531 * Return the result of converting this object to a 'String'. The
2532 * [typeProvider] is the type provider used to find known types.
2566 * 2533 *
2567 * @param typeProvider the type provider used to find known types 2534 * Throws an [EvaluationException] if the object cannot be converted to a
2568 * @return the result of converting this object to a String 2535 * 'String'.
2569 * @throws EvaluationException if the object cannot be converted to a String
2570 */ 2536 */
2571 DartObjectImpl performToString(TypeProvider typeProvider) { 2537 DartObjectImpl performToString(TypeProvider typeProvider) {
2572 InterfaceType stringType = typeProvider.stringType; 2538 InterfaceType stringType = typeProvider.stringType;
2573 if (identical(type, stringType)) { 2539 if (identical(type, stringType)) {
2574 return this; 2540 return this;
2575 } 2541 }
2576 return new DartObjectImpl(stringType, _state.convertToString()); 2542 return new DartObjectImpl(stringType, _state.convertToString());
2577 } 2543 }
2578 2544
2579 /** 2545 /**
2580 * Return the result of invoking the '%' operator on this object with the give n argument. 2546 * Return the result of invoking the '%' operator on this object with the
2547 * [rightOperand]. The [typeProvider] is the type provider used to find known
2548 * types.
2581 * 2549 *
2582 * @param typeProvider the type provider used to find known types 2550 * Throws an [EvaluationException] if the operator is not appropriate for an
2583 * @param rightOperand the right-hand operand of the operation 2551 * object of this kind.
2584 * @return the result of invoking the '%' operator on this object with the giv en argument
2585 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2586 */ 2552 */
2587 DartObjectImpl remainder( 2553 DartObjectImpl remainder(
2588 TypeProvider typeProvider, DartObjectImpl rightOperand) { 2554 TypeProvider typeProvider, DartObjectImpl rightOperand) {
2589 InstanceState result = _state.remainder(rightOperand._state); 2555 InstanceState result = _state.remainder(rightOperand._state);
2590 if (result is IntState) { 2556 if (result is IntState) {
2591 return new DartObjectImpl(typeProvider.intType, result); 2557 return new DartObjectImpl(typeProvider.intType, result);
2592 } else if (result is DoubleState) { 2558 } else if (result is DoubleState) {
2593 return new DartObjectImpl(typeProvider.doubleType, result); 2559 return new DartObjectImpl(typeProvider.doubleType, result);
2594 } else if (result is NumState) { 2560 } else if (result is NumState) {
2595 return new DartObjectImpl(typeProvider.numType, result); 2561 return new DartObjectImpl(typeProvider.numType, result);
2596 } 2562 }
2597 // We should never get here. 2563 // We should never get here.
2598 throw new IllegalStateException( 2564 throw new IllegalStateException(
2599 "remainder returned a ${result.runtimeType}"); 2565 "remainder returned a ${result.runtimeType}");
2600 } 2566 }
2601 2567
2602 /** 2568 /**
2603 * Return the result of invoking the '&lt;&lt;' operator on this object with t he given argument. 2569 * Return the result of invoking the '&lt;&lt;' operator on this object with
2570 * the [rightOperand]. The [typeProvider] is the type provider used to find
2571 * known types.
2604 * 2572 *
2605 * @param typeProvider the type provider used to find known types 2573 * Throws an [EvaluationException] if the operator is not appropriate for an
2606 * @param rightOperand the right-hand operand of the operation 2574 * object of this kind.
2607 * @return the result of invoking the '&lt;&lt;' operator on this object with the given argument
2608 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2609 */ 2575 */
2610 DartObjectImpl shiftLeft( 2576 DartObjectImpl shiftLeft(
2611 TypeProvider typeProvider, DartObjectImpl rightOperand) => 2577 TypeProvider typeProvider, DartObjectImpl rightOperand) =>
2612 new DartObjectImpl( 2578 new DartObjectImpl(
2613 typeProvider.intType, _state.shiftLeft(rightOperand._state)); 2579 typeProvider.intType, _state.shiftLeft(rightOperand._state));
2614 2580
2615 /** 2581 /**
2616 * Return the result of invoking the '&gt;&gt;' operator on this object with t he given argument. 2582 * Return the result of invoking the '&gt;&gt;' operator on this object with
2583 * the [rightOperand]. The [typeProvider] is the type provider used to find
2584 * known types.
2617 * 2585 *
2618 * @param typeProvider the type provider used to find known types 2586 * Throws an [EvaluationException] if the operator is not appropriate for an
2619 * @param rightOperand the right-hand operand of the operation 2587 * object of this kind.
2620 * @return the result of invoking the '&gt;&gt;' operator on this object with the given argument
2621 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2622 */ 2588 */
2623 DartObjectImpl shiftRight( 2589 DartObjectImpl shiftRight(
2624 TypeProvider typeProvider, DartObjectImpl rightOperand) => 2590 TypeProvider typeProvider, DartObjectImpl rightOperand) =>
2625 new DartObjectImpl( 2591 new DartObjectImpl(
2626 typeProvider.intType, _state.shiftRight(rightOperand._state)); 2592 typeProvider.intType, _state.shiftRight(rightOperand._state));
2627 2593
2628 /** 2594 /**
2629 * Return the result of invoking the 'length' getter on this object. 2595 * Return the result of invoking the 'length' getter on this object. The
2596 * [typeProvider] is the type provider used to find known types.
2630 * 2597 *
2631 * @param typeProvider the type provider used to find known types 2598 * Throws an [EvaluationException] if the operator is not appropriate for an
2632 * @return the result of invoking the 'length' getter on this object 2599 * object of this kind.
2633 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2634 */ 2600 */
2635 DartObjectImpl stringLength(TypeProvider typeProvider) => 2601 DartObjectImpl stringLength(TypeProvider typeProvider) =>
2636 new DartObjectImpl(typeProvider.intType, _state.stringLength()); 2602 new DartObjectImpl(typeProvider.intType, _state.stringLength());
2637 2603
2638 /** 2604 /**
2639 * Return the result of invoking the '*' operator on this object with the give n argument. 2605 * Return the result of invoking the '*' operator on this object with the
2606 * [rightOperand]. The [typeProvider] is the type provider used to find known
2607 * types.
2640 * 2608 *
2641 * @param typeProvider the type provider used to find known types 2609 * Throws an [EvaluationException] if the operator is not appropriate for an
2642 * @param rightOperand the right-hand operand of the operation 2610 * object of this kind.
2643 * @return the result of invoking the '*' operator on this object with the giv en argument
2644 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2645 */ 2611 */
2646 DartObjectImpl times(TypeProvider typeProvider, DartObjectImpl rightOperand) { 2612 DartObjectImpl times(TypeProvider typeProvider, DartObjectImpl rightOperand) {
2647 InstanceState result = _state.times(rightOperand._state); 2613 InstanceState result = _state.times(rightOperand._state);
2648 if (result is IntState) { 2614 if (result is IntState) {
2649 return new DartObjectImpl(typeProvider.intType, result); 2615 return new DartObjectImpl(typeProvider.intType, result);
2650 } else if (result is DoubleState) { 2616 } else if (result is DoubleState) {
2651 return new DartObjectImpl(typeProvider.doubleType, result); 2617 return new DartObjectImpl(typeProvider.doubleType, result);
2652 } else if (result is NumState) { 2618 } else if (result is NumState) {
2653 return new DartObjectImpl(typeProvider.numType, result); 2619 return new DartObjectImpl(typeProvider.numType, result);
2654 } 2620 }
2655 // We should never get here. 2621 // We should never get here.
2656 throw new IllegalStateException("times returned a ${result.runtimeType}"); 2622 throw new IllegalStateException("times returned a ${result.runtimeType}");
2657 } 2623 }
2658 2624
2659 @override 2625 @override
2660 String toString() => "${type.displayName} ($_state)"; 2626 String toString() => "${type.displayName} ($_state)";
2661 } 2627 }
2662 2628
2663 /** 2629 /**
2664 * Instances of the class `DeclaredVariables` provide access to the values of va riables that 2630 * An object used to provide access to the values of variables that have been
2665 * have been defined on the command line using the `-D` option. 2631 * defined on the command line using the `-D` option.
2666 */ 2632 */
2667 class DeclaredVariables { 2633 class DeclaredVariables {
2668 /** 2634 /**
2669 * A table mapping the names of declared variables to their values. 2635 * A table mapping the names of declared variables to their values.
2670 */ 2636 */
2671 HashMap<String, String> _declaredVariables = new HashMap<String, String>(); 2637 HashMap<String, String> _declaredVariables = new HashMap<String, String>();
2672 2638
2673 /** 2639 /**
2674 * Define a variable with the given name to have the given value. 2640 * Define a variable with the given [name] to have the given [value].
2675 *
2676 * @param variableName the name of the variable being defined
2677 * @param value the value of the variable
2678 */ 2641 */
2679 void define(String variableName, String value) { 2642 void define(String name, String value) {
2680 _declaredVariables[variableName] = value; 2643 _declaredVariables[name] = value;
2681 } 2644 }
2682 2645
2683 /** 2646 /**
2684 * Return the value of the variable with the given name interpreted as a boole an value. If the 2647 * Return the value of the variable with the given [name] interpreted as a
2685 * variable is not defined (or [variableName] is null), a DartObject represent ing "unknown" 2648 * 'boolean' value. If the variable is not defined (or [name] is `null`), a
2686 * is returned. If the value can't be parsed as a boolean, a DartObject repres enting null is 2649 * DartObject representing "unknown" is returned. If the value cannot be
2687 * returned. 2650 * parsed as a boolean, a DartObject representing 'null' is returned. The
2688 * 2651 * [typeProvider] is the type provider used to find the type 'bool'.
2689 * @param typeProvider the type provider used to find the type 'bool'
2690 * @param variableName the name of the variable whose value is to be returned
2691 */ 2652 */
2692 DartObject getBool(TypeProvider typeProvider, String variableName) { 2653 DartObject getBool(TypeProvider typeProvider, String name) {
2693 String value = _declaredVariables[variableName]; 2654 String value = _declaredVariables[name];
2694 if (value == null) { 2655 if (value == null) {
2695 return new DartObjectImpl(typeProvider.boolType, BoolState.UNKNOWN_VALUE); 2656 return new DartObjectImpl(typeProvider.boolType, BoolState.UNKNOWN_VALUE);
2696 } 2657 }
2697 if (value == "true") { 2658 if (value == "true") {
2698 return new DartObjectImpl(typeProvider.boolType, BoolState.TRUE_STATE); 2659 return new DartObjectImpl(typeProvider.boolType, BoolState.TRUE_STATE);
2699 } else if (value == "false") { 2660 } else if (value == "false") {
2700 return new DartObjectImpl(typeProvider.boolType, BoolState.FALSE_STATE); 2661 return new DartObjectImpl(typeProvider.boolType, BoolState.FALSE_STATE);
2701 } 2662 }
2702 return new DartObjectImpl(typeProvider.nullType, NullState.NULL_STATE); 2663 return new DartObjectImpl(typeProvider.nullType, NullState.NULL_STATE);
2703 } 2664 }
2704 2665
2705 /** 2666 /**
2706 * Return the value of the variable with the given name interpreted as an inte ger value. If the 2667 * Return the value of the variable with the given [name] interpreted as an
2707 * variable is not defined (or [variableName] is null), a DartObject represent ing "unknown" 2668 * integer value. If the variable is not defined (or [name] is `null`), a
2708 * is returned. If the value can't be parsed as an integer, a DartObject repre senting null is 2669 * DartObject representing "unknown" is returned. If the value cannot be
2709 * returned. 2670 * parsed as an integer, a DartObject representing 'null' is returned.
2710 *
2711 * @param typeProvider the type provider used to find the type 'int'
2712 * @param variableName the name of the variable whose value is to be returned
2713 */ 2671 */
2714 DartObject getInt(TypeProvider typeProvider, String variableName) { 2672 DartObject getInt(TypeProvider typeProvider, String name) {
2715 String value = _declaredVariables[variableName]; 2673 String value = _declaredVariables[name];
2716 if (value == null) { 2674 if (value == null) {
2717 return new DartObjectImpl(typeProvider.intType, IntState.UNKNOWN_VALUE); 2675 return new DartObjectImpl(typeProvider.intType, IntState.UNKNOWN_VALUE);
2718 } 2676 }
2719 int bigInteger; 2677 int bigInteger;
2720 try { 2678 try {
2721 bigInteger = int.parse(value); 2679 bigInteger = int.parse(value);
2722 } on FormatException catch (exception) { 2680 } on FormatException catch (exception) {
2723 return new DartObjectImpl(typeProvider.nullType, NullState.NULL_STATE); 2681 return new DartObjectImpl(typeProvider.nullType, NullState.NULL_STATE);
2724 } 2682 }
2725 return new DartObjectImpl(typeProvider.intType, new IntState(bigInteger)); 2683 return new DartObjectImpl(typeProvider.intType, new IntState(bigInteger));
2726 } 2684 }
2727 2685
2728 /** 2686 /**
2729 * Return the value of the variable with the given name interpreted as a Strin g value, or 2687 * Return the value of the variable with the given [name] interpreted as a
2730 * `null` if the variable is not defined. Return the value of the variable wit h the given 2688 * String value, or `null` if the variable is not defined. Return the value of
2731 * name interpreted as a String value. If the variable is not defined (or [var iableName] is 2689 * the variable with the given name interpreted as a String value. If the
2732 * null), a DartObject representing "unknown" is returned. 2690 * variable is not defined (or [name] is `null`), a DartObject representing
2733 * 2691 * "unknown" is returned. The [typeProvider] is the type provider used to find
2734 * @param typeProvider the type provider used to find the type 'String' 2692 * the type 'String'.
2735 * @param variableName the name of the variable whose value is to be returned
2736 */ 2693 */
2737 DartObject getString(TypeProvider typeProvider, String variableName) { 2694 DartObject getString(TypeProvider typeProvider, String name) {
2738 String value = _declaredVariables[variableName]; 2695 String value = _declaredVariables[name];
2739 if (value == null) { 2696 if (value == null) {
2740 return new DartObjectImpl( 2697 return new DartObjectImpl(
2741 typeProvider.stringType, StringState.UNKNOWN_VALUE); 2698 typeProvider.stringType, StringState.UNKNOWN_VALUE);
2742 } 2699 }
2743 return new DartObjectImpl(typeProvider.stringType, new StringState(value)); 2700 return new DartObjectImpl(typeProvider.stringType, new StringState(value));
2744 } 2701 }
2745 } 2702 }
2746 2703
2747 /** 2704 /**
2748 * Instances of the class `DoubleState` represent the state of an object represe nting a 2705 * The state of an object representing a double.
2749 * double.
2750 */ 2706 */
2751 class DoubleState extends NumState { 2707 class DoubleState extends NumState {
2752 /** 2708 /**
2753 * A state that can be used to represent a double whose value is not known. 2709 * A state that can be used to represent a double whose value is not known.
2754 */ 2710 */
2755 static DoubleState UNKNOWN_VALUE = new DoubleState(null); 2711 static DoubleState UNKNOWN_VALUE = new DoubleState(null);
2756 2712
2757 /** 2713 /**
2758 * The value of this instance. 2714 * The value of this instance.
2759 */ 2715 */
2760 final double value; 2716 final double value;
2761 2717
2762 /** 2718 /**
2763 * Initialize a newly created state to represent a double with the given value . 2719 * Initialize a newly created state to represent a double with the given
2764 * 2720 * [value].
2765 * @param value the value of this instance
2766 */ 2721 */
2767 DoubleState(this.value); 2722 DoubleState(this.value);
2768 2723
2769 @override 2724 @override
2770 bool get hasExactValue => true; 2725 bool get hasExactValue => true;
2771 2726
2772 @override 2727 @override
2773 int get hashCode => value == null ? 0 : value.hashCode; 2728 int get hashCode => value == null ? 0 : value.hashCode;
2774 2729
2775 @override 2730 @override
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
3080 } 3035 }
3081 throw new EvaluationException( 3036 throw new EvaluationException(
3082 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION); 3037 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
3083 } 3038 }
3084 3039
3085 @override 3040 @override
3086 String toString() => value == null ? "-unknown-" : value.toString(); 3041 String toString() => value == null ? "-unknown-" : value.toString();
3087 } 3042 }
3088 3043
3089 /** 3044 /**
3090 * Instances of the class `DynamicState` represent the state of an object repres enting a Dart 3045 * The state of an object representing a Dart object for which there is no type
3091 * object for which there is no type information. 3046 * information.
3092 */ 3047 */
3093 class DynamicState extends InstanceState { 3048 class DynamicState extends InstanceState {
3094 /** 3049 /**
3095 * The unique instance of this class. 3050 * The unique instance of this class.
3096 */ 3051 */
3097 static DynamicState DYNAMIC_STATE = new DynamicState(); 3052 static DynamicState DYNAMIC_STATE = new DynamicState();
3098 3053
3099 @override 3054 @override
3100 bool get isBool => true; 3055 bool get isBool => true;
3101 3056
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
3233 return IntState.UNKNOWN_VALUE; 3188 return IntState.UNKNOWN_VALUE;
3234 } 3189 }
3235 3190
3236 @override 3191 @override
3237 NumState times(InstanceState rightOperand) { 3192 NumState times(InstanceState rightOperand) {
3238 assertNumOrNull(rightOperand); 3193 assertNumOrNull(rightOperand);
3239 return _unknownNum(rightOperand); 3194 return _unknownNum(rightOperand);
3240 } 3195 }
3241 3196
3242 /** 3197 /**
3243 * Return an object representing an unknown numeric value whose type is based on the type of the 3198 * Return an object representing an unknown numeric value whose type is based
3244 * right-hand operand. 3199 * on the type of the [rightOperand].
3245 *
3246 * @param rightOperand the operand whose type will determine the type of the r esult
3247 * @return an object representing an unknown numeric value
3248 */ 3200 */
3249 NumState _unknownNum(InstanceState rightOperand) { 3201 NumState _unknownNum(InstanceState rightOperand) {
3250 if (rightOperand is IntState) { 3202 if (rightOperand is IntState) {
3251 return IntState.UNKNOWN_VALUE; 3203 return IntState.UNKNOWN_VALUE;
3252 } else if (rightOperand is DoubleState) { 3204 } else if (rightOperand is DoubleState) {
3253 return DoubleState.UNKNOWN_VALUE; 3205 return DoubleState.UNKNOWN_VALUE;
3254 } 3206 }
3255 return NumState.UNKNOWN_VALUE; 3207 return NumState.UNKNOWN_VALUE;
3256 } 3208 }
3257 } 3209 }
3258 3210
3259 /** 3211 /**
3260 * Instances of the class `EvaluationException` represent a run-time exception t hat would be 3212 * A run-time exception that would be thrown during the evaluation of Dart code.
3261 * thrown during the evaluation of Dart code.
3262 */ 3213 */
3263 class EvaluationException extends JavaException { 3214 class EvaluationException extends JavaException {
3264 /** 3215 /**
3265 * The error code associated with the exception. 3216 * The error code associated with the exception.
3266 */ 3217 */
3267 final ErrorCode errorCode; 3218 final ErrorCode errorCode;
3268 3219
3269 /** 3220 /**
3270 * Initialize a newly created exception to have the given error code. 3221 * Initialize a newly created exception to have the given [errorCode].
3271 *
3272 * @param errorCode the error code associated with the exception
3273 */ 3222 */
3274 EvaluationException(this.errorCode); 3223 EvaluationException(this.errorCode);
3275 } 3224 }
3276 3225
3277 /** 3226 /**
3278 * Instances of the class `EvaluationResult` represent the result of attempting to evaluate an 3227 * The result of attempting to evaluate an expression.
3279 * expression.
3280 */ 3228 */
3281 class EvaluationResult { 3229 class EvaluationResult {
3282 /** 3230 /**
3283 * The value of the expression. 3231 * The value of the expression.
3284 */ 3232 */
3285 final DartObject value; 3233 final DartObject value;
3286 3234
3287 /** 3235 /**
3288 * The errors that should be reported for the expression(s) that were evaluate d. 3236 * The errors that should be reported for the expression(s) that were
3237 * evaluated.
3289 */ 3238 */
3290 final List<AnalysisError> _errors; 3239 final List<AnalysisError> _errors;
3291 3240
3292 /** 3241 /**
3293 * Initialize a newly created result object with the given state. Clients shou ld use one of the 3242 * Initialize a newly created result object with the given [value] and set of
3294 * factory methods: [forErrors] and [forValue]. 3243 * [_errors]. Clients should use one of the factory methods: [forErrors] and
3295 * 3244 * [forValue].
3296 * @param value the value of the expression
3297 * @param errors the errors that should be reported for the expression(s) that were evaluated
3298 */ 3245 */
3299 EvaluationResult(this.value, this._errors); 3246 EvaluationResult(this.value, this._errors);
3300 3247
3301 /** 3248 /**
3302 * Return an array containing the errors that should be reported for the expre ssion(s) that were 3249 * Return a list containing the errors that should be reported for the
3303 * evaluated. If there are no such errors, the array will be empty. The array can be empty even if 3250 * expression(s) that were evaluated. If there are no such errors, the list
3304 * the expression is not a valid compile time constant if the errors would hav e been reported by 3251 * will be empty. The list can be empty even if the expression is not a valid
3305 * other parts of the analysis engine. 3252 * compile time constant if the errors would have been reported by other parts
3253 * of the analysis engine.
3306 */ 3254 */
3307 List<AnalysisError> get errors => 3255 List<AnalysisError> get errors =>
3308 _errors == null ? AnalysisError.NO_ERRORS : _errors; 3256 _errors == null ? AnalysisError.NO_ERRORS : _errors;
3309 3257
3310 /** 3258 /**
3311 * Return `true` if the expression is a compile-time constant expression that would not 3259 * Return `true` if the expression is a compile-time constant expression that
3312 * throw an exception when evaluated. 3260 * would not throw an exception when evaluated.
3313 *
3314 * @return `true` if the expression is a valid compile-time constant expressio n
3315 */ 3261 */
3316 bool get isValid => _errors == null; 3262 bool get isValid => _errors == null;
3317 3263
3318 /** 3264 /**
3319 * Return an evaluation result representing the result of evaluating an expres sion that is not a 3265 * Return an evaluation result representing the result of evaluating an
3320 * compile-time constant because of the given errors. 3266 * expression that is not a compile-time constant because of the given
3321 * 3267 * [errors].
3322 * @param errors the errors that should be reported for the expression(s) that were evaluated
3323 * @return the result of evaluating an expression that is not a compile-time c onstant
3324 */ 3268 */
3325 static EvaluationResult forErrors(List<AnalysisError> errors) => 3269 static EvaluationResult forErrors(List<AnalysisError> errors) =>
3326 new EvaluationResult(null, errors); 3270 new EvaluationResult(null, errors);
3327 3271
3328 /** 3272 /**
3329 * Return an evaluation result representing the result of evaluating an expres sion that is a 3273 * Return an evaluation result representing the result of evaluating an
3330 * compile-time constant that evaluates to the given value. 3274 * expression that is a compile-time constant that evaluates to the given
3331 * 3275 * [value].
3332 * @param value the value of the expression
3333 * @return the result of evaluating an expression that is a compile-time const ant
3334 */ 3276 */
3335 static EvaluationResult forValue(DartObject value) => 3277 static EvaluationResult forValue(DartObject value) =>
3336 new EvaluationResult(value, null); 3278 new EvaluationResult(value, null);
3337 } 3279 }
3338 3280
3339 /** 3281 /**
3340 * Instances of the class `InternalResult` represent the result of attempting to evaluate a 3282 * The result of attempting to evaluate a expression.
3341 * expression.
3342 */ 3283 */
3343 class EvaluationResultImpl { 3284 class EvaluationResultImpl {
3344 /** 3285 /**
3345 * The errors encountered while trying to evaluate the compile time constant. These errors may or 3286 * The errors encountered while trying to evaluate the compile time constant.
3346 * may not have prevented the expression from being a valid compile time const ant. 3287 * These errors may or may not have prevented the expression from being a
3288 * valid compile time constant.
3347 */ 3289 */
3348 List<AnalysisError> _errors; 3290 List<AnalysisError> _errors;
3349 3291
3350 /** 3292 /**
3351 * The value of the expression, or null if the value couldn't be computed due to errors. 3293 * The value of the expression, or `null` if the value couldn't be computed
3294 * due to errors.
3352 */ 3295 */
3353 final DartObjectImpl value; 3296 final DartObjectImpl value;
3354 3297
3355 EvaluationResultImpl.con1(this.value) { 3298 EvaluationResultImpl.con1(this.value) {
3356 this._errors = new List<AnalysisError>(0); 3299 this._errors = new List<AnalysisError>(0);
3357 } 3300 }
3358 3301
3359 EvaluationResultImpl.con2(this.value, List<AnalysisError> errors) { 3302 EvaluationResultImpl.con2(this.value, List<AnalysisError> errors) {
3360 this._errors = errors; 3303 this._errors = errors;
3361 } 3304 }
(...skipping 14 matching lines...) Expand all
3376 @override 3319 @override
3377 String toString() { 3320 String toString() {
3378 if (value == null) { 3321 if (value == null) {
3379 return "error"; 3322 return "error";
3380 } 3323 }
3381 return value.toString(); 3324 return value.toString();
3382 } 3325 }
3383 } 3326 }
3384 3327
3385 /** 3328 /**
3386 * Instances of the class `FunctionState` represent the state of an object repre senting a 3329 * The state of an object representing a function.
3387 * function.
3388 */ 3330 */
3389 class FunctionState extends InstanceState { 3331 class FunctionState extends InstanceState {
3390 /** 3332 /**
3391 * The element representing the function being modeled. 3333 * The element representing the function being modeled.
3392 */ 3334 */
3393 final ExecutableElement _element; 3335 final ExecutableElement _element;
3394 3336
3395 /** 3337 /**
3396 * Initialize a newly created state to represent the given function. 3338 * Initialize a newly created state to represent the function with the given
3397 * 3339 * [element].
3398 * @param element the element representing the function being modeled
3399 */ 3340 */
3400 FunctionState(this._element); 3341 FunctionState(this._element);
3401 3342
3402 @override 3343 @override
3403 int get hashCode => _element == null ? 0 : _element.hashCode; 3344 int get hashCode => _element == null ? 0 : _element.hashCode;
3404 3345
3405 @override 3346 @override
3406 String get typeName => "Function"; 3347 String get typeName => "Function";
3407 3348
3408 @override 3349 @override
(...skipping 28 matching lines...) Expand all
3437 return BoolState.UNKNOWN_VALUE; 3378 return BoolState.UNKNOWN_VALUE;
3438 } 3379 }
3439 return BoolState.FALSE_STATE; 3380 return BoolState.FALSE_STATE;
3440 } 3381 }
3441 3382
3442 @override 3383 @override
3443 String toString() => _element == null ? "-unknown-" : _element.name; 3384 String toString() => _element == null ? "-unknown-" : _element.name;
3444 } 3385 }
3445 3386
3446 /** 3387 /**
3447 * Instances of the class `GenericState` represent the state of an object repres enting a Dart 3388 * The state of an object representing a Dart object for which there is no more
3448 * object for which there is no more specific state. 3389 * specific state.
3449 */ 3390 */
3450 class GenericState extends InstanceState { 3391 class GenericState extends InstanceState {
3451 /** 3392 /**
3452 * Pseudo-field that we use to represent fields in the superclass. 3393 * Pseudo-field that we use to represent fields in the superclass.
3453 */ 3394 */
3454 static String SUPERCLASS_FIELD = "(super)"; 3395 static String SUPERCLASS_FIELD = "(super)";
3455 3396
3456 /** 3397 /**
3457 * A state that can be used to represent an object whose state is not known. 3398 * A state that can be used to represent an object whose state is not known.
3458 */ 3399 */
3459 static GenericState UNKNOWN_VALUE = 3400 static GenericState UNKNOWN_VALUE =
3460 new GenericState(new HashMap<String, DartObjectImpl>()); 3401 new GenericState(new HashMap<String, DartObjectImpl>());
3461 3402
3462 /** 3403 /**
3463 * The values of the fields of this instance. 3404 * The values of the fields of this instance.
3464 */ 3405 */
3465 final HashMap<String, DartObjectImpl> _fieldMap; 3406 final HashMap<String, DartObjectImpl> _fieldMap;
3466 3407
3467 /** 3408 /**
3468 * Initialize a newly created state to represent a newly created object. 3409 * Initialize a newly created state to represent a newly created object. The
3469 * 3410 * [fieldMap] contains the values of the fields of the instance.
3470 * @param fieldMap the values of the fields of this instance
3471 */ 3411 */
3472 GenericState(this._fieldMap); 3412 GenericState(this._fieldMap);
3473 3413
3474 @override 3414 @override
3475 HashMap<String, DartObjectImpl> get fields => _fieldMap; 3415 HashMap<String, DartObjectImpl> get fields => _fieldMap;
3476 3416
3477 @override 3417 @override
3478 int get hashCode { 3418 int get hashCode {
3479 int hashCode = 0; 3419 int hashCode = 0;
3480 for (DartObjectImpl value in _fieldMap.values) { 3420 for (DartObjectImpl value in _fieldMap.values) {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
3542 } 3482 }
3543 buffer.write(fieldName); 3483 buffer.write(fieldName);
3544 buffer.write(' = '); 3484 buffer.write(' = ');
3545 buffer.write(_fieldMap[fieldName]); 3485 buffer.write(_fieldMap[fieldName]);
3546 } 3486 }
3547 return buffer.toString(); 3487 return buffer.toString();
3548 } 3488 }
3549 } 3489 }
3550 3490
3551 /** 3491 /**
3552 * The class `InstanceState` defines the behavior of objects representing the st ate of a Dart 3492 * The state of an object representing a Dart object.
3553 * object.
3554 */ 3493 */
3555 abstract class InstanceState { 3494 abstract class InstanceState {
3556 /** 3495 /**
3557 * If this represents a generic dart object, return a map from its fieldnames to their values. 3496 * If this represents a generic dart object, return a map from its field names
3558 * Otherwise return null. 3497 * to their values. Otherwise return null.
3559 */ 3498 */
3560 HashMap<String, DartObjectImpl> get fields => null; 3499 HashMap<String, DartObjectImpl> get fields => null;
3561 3500
3562 /** 3501 /**
3563 * Return `true` if this object's value can be represented exactly. 3502 * Return `true` if this object's value can be represented exactly.
3564 *
3565 * @return `true` if this object's value can be represented exactly
3566 */ 3503 */
3567 bool get hasExactValue => false; 3504 bool get hasExactValue => false;
3568 3505
3569 /** 3506 /**
3570 * Return `true` if this object represents an object whose type is 'bool'. 3507 * Return `true` if this object represents an object whose type is 'bool'.
3571 *
3572 * @return `true` if this object represents a boolean value
3573 */ 3508 */
3574 bool get isBool => false; 3509 bool get isBool => false;
3575 3510
3576 /** 3511 /**
3577 * Return `true` if this object represents an object whose type is either 'boo l', 'num', 3512 * Return `true` if this object represents an object whose type is either
3578 * 'String', or 'Null'. 3513 * 'bool', 'num', 'String', or 'Null'.
3579 *
3580 * @return `true` if this object represents either a boolean, numeric, string or null value
3581 */ 3514 */
3582 bool get isBoolNumStringOrNull => false; 3515 bool get isBoolNumStringOrNull => false;
3583 3516
3584 /** 3517 /**
3585 * Return true if this object represents an unknown value. 3518 * Return `true` if this object represents an unknown value.
3586 */ 3519 */
3587 bool get isUnknown => false; 3520 bool get isUnknown => false;
3588 3521
3589 /** 3522 /**
3590 * Return the name of the type of this value. 3523 * Return the name of the type of this value.
3591 *
3592 * @return the name of the type of this value
3593 */ 3524 */
3594 String get typeName; 3525 String get typeName;
3595 3526
3596 /** 3527 /**
3597 * Return this object's value if it can be represented exactly, or `null` if e ither the 3528 * Return this object's value if it can be represented exactly, or `null` if
3598 * value cannot be represented exactly or if the value is `null`. Clients shou ld use 3529 * either the value cannot be represented exactly or if the value is `null`.
3599 * [hasExactValue] to distinguish between these two cases. 3530 * Clients should use [hasExactValue] to distinguish between these two cases.
3600 *
3601 * @return this object's value
3602 */ 3531 */
3603 Object get value => null; 3532 Object get value => null;
3604 3533
3605 /** 3534 /**
3606 * Return the result of invoking the '+' operator on this object with the give n argument. 3535 * Return the result of invoking the '+' operator on this object with the
3536 * [rightOperand].
3607 * 3537 *
3608 * @param rightOperand the right-hand operand of the operation 3538 * Throws an [EvaluationException] if the operator is not appropriate for an
3609 * @return the result of invoking the '+' operator on this object with the giv en argument 3539 * object of this kind.
3610 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
3611 */ 3540 */
3612 InstanceState add(InstanceState rightOperand) { 3541 InstanceState add(InstanceState rightOperand) {
3613 if (this is StringState && rightOperand is StringState) { 3542 if (this is StringState && rightOperand is StringState) {
3614 return concatenate(rightOperand); 3543 return concatenate(rightOperand);
3615 } 3544 }
3616 assertNumOrNull(this); 3545 assertNumOrNull(this);
3617 assertNumOrNull(rightOperand); 3546 assertNumOrNull(rightOperand);
3618 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); 3547 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
3619 } 3548 }
3620 3549
3621 /** 3550 /**
3622 * Throw an exception if the given state does not represent a boolean value. 3551 * Throw an exception if the given [state] does not represent a boolean value.
3623 *
3624 * @param state the state being tested
3625 * @throws EvaluationException if the given state does not represent a boolean value
3626 */ 3552 */
3627 void assertBool(InstanceState state) { 3553 void assertBool(InstanceState state) {
3628 if (!(state is BoolState || state is DynamicState)) { 3554 if (!(state is BoolState || state is DynamicState)) {
3629 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL); 3555 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL);
3630 } 3556 }
3631 } 3557 }
3632 3558
3633 /** 3559 /**
3634 * Throw an exception if the given state does not represent a boolean, numeric , string or null 3560 * Throw an exception if the given [state] does not represent a boolean,
3635 * value. 3561 * numeric, string or null value.
3636 *
3637 * @param state the state being tested
3638 * @throws EvaluationException if the given state does not represent a boolean , numeric, string or
3639 * null value
3640 */ 3562 */
3641 void assertBoolNumStringOrNull(InstanceState state) { 3563 void assertBoolNumStringOrNull(InstanceState state) {
3642 if (!(state is BoolState || 3564 if (!(state is BoolState ||
3643 state is DoubleState || 3565 state is DoubleState ||
3644 state is IntState || 3566 state is IntState ||
3645 state is NumState || 3567 state is NumState ||
3646 state is StringState || 3568 state is StringState ||
3647 state is NullState || 3569 state is NullState ||
3648 state is DynamicState)) { 3570 state is DynamicState)) {
3649 throw new EvaluationException( 3571 throw new EvaluationException(
3650 CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING); 3572 CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING);
3651 } 3573 }
3652 } 3574 }
3653 3575
3654 /** 3576 /**
3655 * Throw an exception if the given state does not represent an integer or null value. 3577 * Throw an exception if the given [state] does not represent an integer or
3656 * 3578 * null value.
3657 * @param state the state being tested
3658 * @throws EvaluationException if the given state does not represent an intege r or null value
3659 */ 3579 */
3660 void assertIntOrNull(InstanceState state) { 3580 void assertIntOrNull(InstanceState state) {
3661 if (!(state is IntState || 3581 if (!(state is IntState ||
3662 state is NumState || 3582 state is NumState ||
3663 state is NullState || 3583 state is NullState ||
3664 state is DynamicState)) { 3584 state is DynamicState)) {
3665 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_INT); 3585 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
3666 } 3586 }
3667 } 3587 }
3668 3588
3669 /** 3589 /**
3670 * Throw an exception if the given state does not represent a boolean, numeric , string or null 3590 * Throw an exception if the given [state] does not represent a boolean,
3671 * value. 3591 * numeric, string or null value.
3672 *
3673 * @param state the state being tested
3674 * @throws EvaluationException if the given state does not represent a boolean , numeric, string or
3675 * null value
3676 */ 3592 */
3677 void assertNumOrNull(InstanceState state) { 3593 void assertNumOrNull(InstanceState state) {
3678 if (!(state is DoubleState || 3594 if (!(state is DoubleState ||
3679 state is IntState || 3595 state is IntState ||
3680 state is NumState || 3596 state is NumState ||
3681 state is NullState || 3597 state is NullState ||
3682 state is DynamicState)) { 3598 state is DynamicState)) {
3683 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_NUM); 3599 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
3684 } 3600 }
3685 } 3601 }
3686 3602
3687 /** 3603 /**
3688 * Throw an exception if the given state does not represent a String value. 3604 * Throw an exception if the given [state] does not represent a String value.
3689 *
3690 * @param state the state being tested
3691 * @throws EvaluationException if the given state does not represent a String value
3692 */ 3605 */
3693 void assertString(InstanceState state) { 3606 void assertString(InstanceState state) {
3694 if (!(state is StringState || state is DynamicState)) { 3607 if (!(state is StringState || state is DynamicState)) {
3695 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL); 3608 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL);
3696 } 3609 }
3697 } 3610 }
3698 3611
3699 /** 3612 /**
3700 * Return the result of invoking the '&' operator on this object with the give n argument. 3613 * Return the result of invoking the '&' operator on this object with the
3614 * [rightOperand].
3701 * 3615 *
3702 * @param rightOperand the right-hand operand of the operation 3616 * Throws an [EvaluationException] if the operator is not appropriate for an
3703 * @return the result of invoking the '&' operator on this object with the giv en argument 3617 * object of this kind.
3704 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
3705 */ 3618 */
3706 IntState bitAnd(InstanceState rightOperand) { 3619 IntState bitAnd(InstanceState rightOperand) {
3707 assertIntOrNull(this); 3620 assertIntOrNull(this);
3708 assertIntOrNull(rightOperand); 3621 assertIntOrNull(rightOperand);
3709 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); 3622 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
3710 } 3623 }
3711 3624
3712 /** 3625 /**
3713 * Return the result of invoking the '~' operator on this object. 3626 * Return the result of invoking the '~' operator on this object.
3714 * 3627 *
3715 * @return the result of invoking the '~' operator on this object 3628 * Throws an [EvaluationException] if the operator is not appropriate for an
3716 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 3629 * object of this kind.
3717 */ 3630 */
3718 IntState bitNot() { 3631 IntState bitNot() {
3719 assertIntOrNull(this); 3632 assertIntOrNull(this);
3720 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); 3633 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
3721 } 3634 }
3722 3635
3723 /** 3636 /**
3724 * Return the result of invoking the '|' operator on this object with the give n argument. 3637 * Return the result of invoking the '|' operator on this object with the
3638 * [rightOperand].
3725 * 3639 *
3726 * @param rightOperand the right-hand operand of the operation 3640 * Throws an [EvaluationException] if the operator is not appropriate for an
3727 * @return the result of invoking the '|' operator on this object with the giv en argument 3641 * object of this kind.
3728 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
3729 */ 3642 */
3730 IntState bitOr(InstanceState rightOperand) { 3643 IntState bitOr(InstanceState rightOperand) {
3731 assertIntOrNull(this); 3644 assertIntOrNull(this);
3732 assertIntOrNull(rightOperand); 3645 assertIntOrNull(rightOperand);
3733 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); 3646 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
3734 } 3647 }
3735 3648
3736 /** 3649 /**
3737 * Return the result of invoking the '^' operator on this object with the give n argument. 3650 * Return the result of invoking the '^' operator on this object with the
3651 * [rightOperand].
3738 * 3652 *
3739 * @param rightOperand the right-hand operand of the operation 3653 * Throws an [EvaluationException] if the operator is not appropriate for an
3740 * @return the result of invoking the '^' operator on this object with the giv en argument 3654 * object of this kind.
3741 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
3742 */ 3655 */
3743 IntState bitXor(InstanceState rightOperand) { 3656 IntState bitXor(InstanceState rightOperand) {
3744 assertIntOrNull(this); 3657 assertIntOrNull(this);
3745 assertIntOrNull(rightOperand); 3658 assertIntOrNull(rightOperand);
3746 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); 3659 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
3747 } 3660 }
3748 3661
3749 /** 3662 /**
3750 * Return the result of invoking the ' ' operator on this object with the give n argument. 3663 * Return the result of invoking the ' ' operator on this object with the
3664 * [rightOperand].
3751 * 3665 *
3752 * @param rightOperand the right-hand operand of the operation 3666 * Throws an [EvaluationException] if the operator is not appropriate for an
3753 * @return the result of invoking the ' ' operator on this object with the giv en argument 3667 * object of this kind.
3754 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
3755 */ 3668 */
3756 StringState concatenate(InstanceState rightOperand) { 3669 StringState concatenate(InstanceState rightOperand) {
3757 assertString(rightOperand); 3670 assertString(rightOperand);
3758 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); 3671 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
3759 } 3672 }
3760 3673
3761 /** 3674 /**
3762 * Return the result of applying boolean conversion to this object. 3675 * Return the result of applying boolean conversion to this object.
3763 * 3676 *
3764 * @param typeProvider the type provider used to find known types 3677 * Throws an [EvaluationException] if the operator is not appropriate for an
3765 * @return the result of applying boolean conversion to this object 3678 * object of this kind.
3766 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
3767 */ 3679 */
3768 BoolState convertToBool() => BoolState.FALSE_STATE; 3680 BoolState convertToBool() => BoolState.FALSE_STATE;
3769 3681
3770 /** 3682 /**
3771 * Return the result of converting this object to a String. 3683 * Return the result of converting this object to a String.
3772 * 3684 *
3773 * @return the result of converting this object to a String 3685 * Throws an [EvaluationException] if the operator is not appropriate for an
3774 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 3686 * object of this kind.
3775 */ 3687 */
3776 StringState convertToString(); 3688 StringState convertToString();
3777 3689
3778 /** 3690 /**
3779 * Return the result of invoking the '/' operator on this object with the give n argument. 3691 * Return the result of invoking the '/' operator on this object with the
3692 * [rightOperand].
3780 * 3693 *
3781 * @param rightOperand the right-hand operand of the operation 3694 * Throws an [EvaluationException] if the operator is not appropriate for an
3782 * @return the result of invoking the '/' operator on this object with the giv en argument 3695 * object of this kind.
3783 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
3784 */ 3696 */
3785 NumState divide(InstanceState rightOperand) { 3697 NumState divide(InstanceState rightOperand) {
3786 assertNumOrNull(this); 3698 assertNumOrNull(this);
3787 assertNumOrNull(rightOperand); 3699 assertNumOrNull(rightOperand);
3788 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); 3700 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
3789 } 3701 }
3790 3702
3791 /** 3703 /**
3792 * Return the result of invoking the '==' operator on this object with the giv en argument. 3704 * Return the result of invoking the '==' operator on this object with the
3705 * [rightOperand].
3793 * 3706 *
3794 * @param rightOperand the right-hand operand of the operation 3707 * Throws an [EvaluationException] if the operator is not appropriate for an
3795 * @return the result of invoking the '==' operator on this object with the gi ven argument 3708 * object of this kind.
3796 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
3797 */ 3709 */
3798 BoolState equalEqual(InstanceState rightOperand); 3710 BoolState equalEqual(InstanceState rightOperand);
3799 3711
3800 /** 3712 /**
3801 * Return the result of invoking the '&gt;' operator on this object with the g iven argument. 3713 * Return the result of invoking the '&gt;' operator on this object with the
3714 * [rightOperand].
3802 * 3715 *
3803 * @param rightOperand the right-hand operand of the operation 3716 * Throws an [EvaluationException] if the operator is not appropriate for an
3804 * @return the result of invoking the '&gt;' operator on this object with the given argument 3717 * object of this kind.
3805 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
3806 */ 3718 */
3807 BoolState greaterThan(InstanceState rightOperand) { 3719 BoolState greaterThan(InstanceState rightOperand) {
3808 assertNumOrNull(this); 3720 assertNumOrNull(this);
3809 assertNumOrNull(rightOperand); 3721 assertNumOrNull(rightOperand);
3810 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); 3722 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
3811 } 3723 }
3812 3724
3813 /** 3725 /**
3814 * Return the result of invoking the '&gt;=' operator on this object with the given argument. 3726 * Return the result of invoking the '&gt;=' operator on this object with the
3727 * [rightOperand].
3815 * 3728 *
3816 * @param rightOperand the right-hand operand of the operation 3729 * Throws an [EvaluationException] if the operator is not appropriate for an
3817 * @return the result of invoking the '&gt;=' operator on this object with the given argument 3730 * object of this kind.
3818 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
3819 */ 3731 */
3820 BoolState greaterThanOrEqual(InstanceState rightOperand) { 3732 BoolState greaterThanOrEqual(InstanceState rightOperand) {
3821 assertNumOrNull(this); 3733 assertNumOrNull(this);
3822 assertNumOrNull(rightOperand); 3734 assertNumOrNull(rightOperand);
3823 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); 3735 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
3824 } 3736 }
3825 3737
3826 /** 3738 /**
3827 * Return the result of invoking the '~/' operator on this object with the giv en argument. 3739 * Return the result of invoking the '~/' operator on this object with the
3740 * [rightOperand].
3828 * 3741 *
3829 * @param rightOperand the right-hand operand of the operation 3742 * Throws an [EvaluationException] if the operator is not appropriate for an
3830 * @return the result of invoking the '~/' operator on this object with the gi ven argument 3743 * object of this kind.
3831 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
3832 */ 3744 */
3833 IntState integerDivide(InstanceState rightOperand) { 3745 IntState integerDivide(InstanceState rightOperand) {
3834 assertNumOrNull(this); 3746 assertNumOrNull(this);
3835 assertNumOrNull(rightOperand); 3747 assertNumOrNull(rightOperand);
3836 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); 3748 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
3837 } 3749 }
3838 3750
3839 /** 3751 /**
3840 * Return the result of invoking the identical function on this object with 3752 * Return the result of invoking the identical function on this object with
3841 * the given argument. 3753 * the [rightOperand].
3842 *
3843 * @param rightOperand the right-hand operand of the operation
3844 * @return the result of invoking the identical function on this object with
3845 * the given argument
3846 */ 3754 */
3847 BoolState isIdentical(InstanceState rightOperand); 3755 BoolState isIdentical(InstanceState rightOperand);
3848 3756
3849 /** 3757 /**
3850 * Return the result of invoking the '&lt;' operator on this object with the g iven argument. 3758 * Return the result of invoking the '&lt;' operator on this object with the
3759 * [rightOperand].
3851 * 3760 *
3852 * @param rightOperand the right-hand operand of the operation 3761 * Throws an [EvaluationException] if the operator is not appropriate for an
3853 * @return the result of invoking the '&lt;' operator on this object with the given argument 3762 * object of this kind.
3854 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
3855 */ 3763 */
3856 BoolState lessThan(InstanceState rightOperand) { 3764 BoolState lessThan(InstanceState rightOperand) {
3857 assertNumOrNull(this); 3765 assertNumOrNull(this);
3858 assertNumOrNull(rightOperand); 3766 assertNumOrNull(rightOperand);
3859 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); 3767 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
3860 } 3768 }
3861 3769
3862 /** 3770 /**
3863 * Return the result of invoking the '&lt;=' operator on this object with the given argument. 3771 * Return the result of invoking the '&lt;=' operator on this object with the
3772 * [rightOperand].
3864 * 3773 *
3865 * @param rightOperand the right-hand operand of the operation 3774 * Throws an [EvaluationException] if the operator is not appropriate for an
3866 * @return the result of invoking the '&lt;=' operator on this object with the given argument 3775 * object of this kind.
3867 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
3868 */ 3776 */
3869 BoolState lessThanOrEqual(InstanceState rightOperand) { 3777 BoolState lessThanOrEqual(InstanceState rightOperand) {
3870 assertNumOrNull(this); 3778 assertNumOrNull(this);
3871 assertNumOrNull(rightOperand); 3779 assertNumOrNull(rightOperand);
3872 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); 3780 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
3873 } 3781 }
3874 3782
3875 /** 3783 /**
3876 * Return the result of invoking the '&&' operator on this object with the giv en argument. 3784 * Return the result of invoking the '&&' operator on this object with the
3785 * [rightOperand].
3877 * 3786 *
3878 * @param rightOperand the right-hand operand of the operation 3787 * Throws an [EvaluationException] if the operator is not appropriate for an
3879 * @return the result of invoking the '&&' operator on this object with the gi ven argument 3788 * object of this kind.
3880 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
3881 */ 3789 */
3882 BoolState logicalAnd(InstanceState rightOperand) { 3790 BoolState logicalAnd(InstanceState rightOperand) {
3883 assertBool(this); 3791 assertBool(this);
3884 assertBool(rightOperand); 3792 assertBool(rightOperand);
3885 return BoolState.FALSE_STATE; 3793 return BoolState.FALSE_STATE;
3886 } 3794 }
3887 3795
3888 /** 3796 /**
3889 * Return the result of invoking the '!' operator on this object. 3797 * Return the result of invoking the '!' operator on this object.
3890 * 3798 *
3891 * @return the result of invoking the '!' operator on this object 3799 * Throws an [EvaluationException] if the operator is not appropriate for an
3892 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 3800 * object of this kind.
3893 */ 3801 */
3894 BoolState logicalNot() { 3802 BoolState logicalNot() {
3895 assertBool(this); 3803 assertBool(this);
3896 return BoolState.TRUE_STATE; 3804 return BoolState.TRUE_STATE;
3897 } 3805 }
3898 3806
3899 /** 3807 /**
3900 * Return the result of invoking the '||' operator on this object with the giv en argument. 3808 * Return the result of invoking the '||' operator on this object with the
3809 * [rightOperand].
3901 * 3810 *
3902 * @param rightOperand the right-hand operand of the operation 3811 * Throws an [EvaluationException] if the operator is not appropriate for an
3903 * @return the result of invoking the '||' operator on this object with the gi ven argument 3812 * object of this kind.
3904 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
3905 */ 3813 */
3906 BoolState logicalOr(InstanceState rightOperand) { 3814 BoolState logicalOr(InstanceState rightOperand) {
3907 assertBool(this); 3815 assertBool(this);
3908 assertBool(rightOperand); 3816 assertBool(rightOperand);
3909 return rightOperand.convertToBool(); 3817 return rightOperand.convertToBool();
3910 } 3818 }
3911 3819
3912 /** 3820 /**
3913 * Return the result of invoking the '-' operator on this object with the give n argument. 3821 * Return the result of invoking the '-' operator on this object with the
3822 * [rightOperand].
3914 * 3823 *
3915 * @param rightOperand the right-hand operand of the operation 3824 * Throws an [EvaluationException] if the operator is not appropriate for an
3916 * @return the result of invoking the '-' operator on this object with the giv en argument 3825 * object of this kind.
3917 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
3918 */ 3826 */
3919 NumState minus(InstanceState rightOperand) { 3827 NumState minus(InstanceState rightOperand) {
3920 assertNumOrNull(this); 3828 assertNumOrNull(this);
3921 assertNumOrNull(rightOperand); 3829 assertNumOrNull(rightOperand);
3922 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); 3830 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
3923 } 3831 }
3924 3832
3925 /** 3833 /**
3926 * Return the result of invoking the '-' operator on this object. 3834 * Return the result of invoking the '-' operator on this object.
3927 * 3835 *
3928 * @return the result of invoking the '-' operator on this object 3836 * Throws an [EvaluationException] if the operator is not appropriate for an
3929 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 3837 * object of this kind.
3930 */ 3838 */
3931 NumState negated() { 3839 NumState negated() {
3932 assertNumOrNull(this); 3840 assertNumOrNull(this);
3933 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); 3841 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
3934 } 3842 }
3935 3843
3936 /** 3844 /**
3937 * Return the result of invoking the '%' operator on this object with the give n argument. 3845 * Return the result of invoking the '%' operator on this object with the
3846 * [rightOperand].
3938 * 3847 *
3939 * @param rightOperand the right-hand operand of the operation 3848 * Throws an [EvaluationException] if the operator is not appropriate for an
3940 * @return the result of invoking the '%' operator on this object with the giv en argument 3849 * object of this kind.
3941 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
3942 */ 3850 */
3943 NumState remainder(InstanceState rightOperand) { 3851 NumState remainder(InstanceState rightOperand) {
3944 assertNumOrNull(this); 3852 assertNumOrNull(this);
3945 assertNumOrNull(rightOperand); 3853 assertNumOrNull(rightOperand);
3946 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); 3854 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
3947 } 3855 }
3948 3856
3949 /** 3857 /**
3950 * Return the result of invoking the '&lt;&lt;' operator on this object with t he given argument. 3858 * Return the result of invoking the '&lt;&lt;' operator on this object with
3859 * the [rightOperand].
3951 * 3860 *
3952 * @param rightOperand the right-hand operand of the operation 3861 * Throws an [EvaluationException] if the operator is not appropriate for an
3953 * @return the result of invoking the '&lt;&lt;' operator on this object with the given argument 3862 * object of this kind.
3954 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
3955 */ 3863 */
3956 IntState shiftLeft(InstanceState rightOperand) { 3864 IntState shiftLeft(InstanceState rightOperand) {
3957 assertIntOrNull(this); 3865 assertIntOrNull(this);
3958 assertIntOrNull(rightOperand); 3866 assertIntOrNull(rightOperand);
3959 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); 3867 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
3960 } 3868 }
3961 3869
3962 /** 3870 /**
3963 * Return the result of invoking the '&gt;&gt;' operator on this object with t he given argument. 3871 * Return the result of invoking the '&gt;&gt;' operator on this object with
3872 * the [rightOperand].
3964 * 3873 *
3965 * @param rightOperand the right-hand operand of the operation 3874 * Throws an [EvaluationException] if the operator is not appropriate for an
3966 * @return the result of invoking the '&gt;&gt;' operator on this object with the given argument 3875 * object of this kind.
3967 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
3968 */ 3876 */
3969 IntState shiftRight(InstanceState rightOperand) { 3877 IntState shiftRight(InstanceState rightOperand) {
3970 assertIntOrNull(this); 3878 assertIntOrNull(this);
3971 assertIntOrNull(rightOperand); 3879 assertIntOrNull(rightOperand);
3972 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); 3880 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
3973 } 3881 }
3974 3882
3975 /** 3883 /**
3976 * Return the result of invoking the 'length' getter on this object. 3884 * Return the result of invoking the 'length' getter on this object.
3977 * 3885 *
3978 * @return the result of invoking the 'length' getter on this object 3886 * Throws an [EvaluationException] if the operator is not appropriate for an
3979 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 3887 * object of this kind.
3980 */ 3888 */
3981 IntState stringLength() { 3889 IntState stringLength() {
3982 assertString(this); 3890 assertString(this);
3983 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); 3891 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
3984 } 3892 }
3985 3893
3986 /** 3894 /**
3987 * Return the result of invoking the '*' operator on this object with the give n argument. 3895 * Return the result of invoking the '*' operator on this object with the
3896 * [rightOperand].
3988 * 3897 *
3989 * @param rightOperand the right-hand operand of the operation 3898 * Throws an [EvaluationException] if the operator is not appropriate for an
3990 * @return the result of invoking the '*' operator on this object with the giv en argument 3899 * object of this kind.
3991 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
3992 */ 3900 */
3993 NumState times(InstanceState rightOperand) { 3901 NumState times(InstanceState rightOperand) {
3994 assertNumOrNull(this); 3902 assertNumOrNull(this);
3995 assertNumOrNull(rightOperand); 3903 assertNumOrNull(rightOperand);
3996 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); 3904 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
3997 } 3905 }
3998 } 3906 }
3999 3907
4000 /** 3908 /**
4001 * Instances of the class `IntState` represent the state of an object representi ng an int. 3909 * The state of an object representing an int.
4002 */ 3910 */
4003 class IntState extends NumState { 3911 class IntState extends NumState {
4004 /** 3912 /**
4005 * A state that can be used to represent an int whose value is not known. 3913 * A state that can be used to represent an int whose value is not known.
4006 */ 3914 */
4007 static IntState UNKNOWN_VALUE = new IntState(null); 3915 static IntState UNKNOWN_VALUE = new IntState(null);
4008 3916
4009 /** 3917 /**
4010 * The value of this instance. 3918 * The value of this instance.
4011 */ 3919 */
4012 final int value; 3920 final int value;
4013 3921
4014 /** 3922 /**
4015 * Initialize a newly created state to represent an int with the given value. 3923 * Initialize a newly created state to represent an int with the given
4016 * 3924 * [value].
4017 * @param value the value of this instance
4018 */ 3925 */
4019 IntState(this.value); 3926 IntState(this.value);
4020 3927
4021 @override 3928 @override
4022 bool get hasExactValue => true; 3929 bool get hasExactValue => true;
4023 3930
4024 @override 3931 @override
4025 int get hashCode => value == null ? 0 : value.hashCode; 3932 int get hashCode => value == null ? 0 : value.hashCode;
4026 3933
4027 @override 3934 @override
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after
4460 } 4367 }
4461 throw new EvaluationException( 4368 throw new EvaluationException(
4462 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION); 4369 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
4463 } 4370 }
4464 4371
4465 @override 4372 @override
4466 String toString() => value == null ? "-unknown-" : value.toString(); 4373 String toString() => value == null ? "-unknown-" : value.toString();
4467 } 4374 }
4468 4375
4469 /** 4376 /**
4470 * The unique instance of the class `ListState` represents the state of an objec t representing 4377 * The state of an object representing a list.
4471 * a list.
4472 */ 4378 */
4473 class ListState extends InstanceState { 4379 class ListState extends InstanceState {
4474 /** 4380 /**
4475 * The elements of the list. 4381 * The elements of the list.
4476 */ 4382 */
4477 final List<DartObjectImpl> _elements; 4383 final List<DartObjectImpl> _elements;
4478 4384
4479 /** 4385 /**
4480 * Initialize a newly created state to represent a list with the given element s. 4386 * Initialize a newly created state to represent a list with the given
4481 * 4387 * [elements].
4482 * @param elements the elements of the list
4483 */ 4388 */
4484 ListState(this._elements); 4389 ListState(this._elements);
4485 4390
4486 @override 4391 @override
4487 bool get hasExactValue { 4392 bool get hasExactValue {
4488 int count = _elements.length; 4393 int count = _elements.length;
4489 for (int i = 0; i < count; i++) { 4394 for (int i = 0; i < count; i++) {
4490 if (!_elements[i].hasExactValue) { 4395 if (!_elements[i].hasExactValue) {
4491 return false; 4396 return false;
4492 } 4397 }
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
4570 buffer.write(', '); 4475 buffer.write(', ');
4571 } 4476 }
4572 buffer.write(element); 4477 buffer.write(element);
4573 }); 4478 });
4574 buffer.write(']'); 4479 buffer.write(']');
4575 return buffer.toString(); 4480 return buffer.toString();
4576 } 4481 }
4577 } 4482 }
4578 4483
4579 /** 4484 /**
4580 * The unique instance of the class `ListState` represents the state of an objec t representing 4485 * The state of an object representing a map.
4581 * a map.
4582 */ 4486 */
4583 class MapState extends InstanceState { 4487 class MapState extends InstanceState {
4584 /** 4488 /**
4585 * The entries in the map. 4489 * The entries in the map.
4586 */ 4490 */
4587 final HashMap<DartObjectImpl, DartObjectImpl> _entries; 4491 final HashMap<DartObjectImpl, DartObjectImpl> _entries;
4588 4492
4589 /** 4493 /**
4590 * Initialize a newly created state to represent a map with the given entries. 4494 * Initialize a newly created state to represent a map with the given
4591 * 4495 * [entries].
4592 * @param entries the entries in the map
4593 */ 4496 */
4594 MapState(this._entries); 4497 MapState(this._entries);
4595 4498
4596 @override 4499 @override
4597 bool get hasExactValue { 4500 bool get hasExactValue {
4598 for (DartObjectImpl key in _entries.keys) { 4501 for (DartObjectImpl key in _entries.keys) {
4599 if (!key.hasExactValue || !_entries[key].hasExactValue) { 4502 if (!key.hasExactValue || !_entries[key].hasExactValue) {
4600 return false; 4503 return false;
4601 } 4504 }
4602 } 4505 }
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
4682 buffer.write(key); 4585 buffer.write(key);
4683 buffer.write(' = '); 4586 buffer.write(' = ');
4684 buffer.write(value); 4587 buffer.write(value);
4685 }); 4588 });
4686 buffer.write('}'); 4589 buffer.write('}');
4687 return buffer.toString(); 4590 return buffer.toString();
4688 } 4591 }
4689 } 4592 }
4690 4593
4691 /** 4594 /**
4692 * The unique instance of the class `NullState` represents the state of the valu e 'null'. 4595 * The state of an object representing the value 'null'.
4693 */ 4596 */
4694 class NullState extends InstanceState { 4597 class NullState extends InstanceState {
4695 /** 4598 /**
4696 * An instance representing the boolean value 'true'. 4599 * An instance representing the boolean value 'null'.
4697 */ 4600 */
4698 static NullState NULL_STATE = new NullState(); 4601 static NullState NULL_STATE = new NullState();
4699 4602
4700 @override 4603 @override
4701 bool get hasExactValue => true; 4604 bool get hasExactValue => true;
4702 4605
4703 @override 4606 @override
4704 int get hashCode => 0; 4607 int get hashCode => 0;
4705 4608
4706 @override 4609 @override
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
4739 BoolState logicalNot() { 4642 BoolState logicalNot() {
4740 throw new EvaluationException( 4643 throw new EvaluationException(
4741 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION); 4644 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
4742 } 4645 }
4743 4646
4744 @override 4647 @override
4745 String toString() => "null"; 4648 String toString() => "null";
4746 } 4649 }
4747 4650
4748 /** 4651 /**
4749 * Instances of the class `NumState` represent the state of an object representi ng a number of 4652 * The state of an object representing a number of an unknown type (a 'num').
4750 * an unknown type (a 'num').
4751 */ 4653 */
4752 class NumState extends InstanceState { 4654 class NumState extends InstanceState {
4753 /** 4655 /**
4754 * A state that can be used to represent a number whose value is not known. 4656 * A state that can be used to represent a number whose value is not known.
4755 */ 4657 */
4756 static NumState UNKNOWN_VALUE = new NumState(); 4658 static NumState UNKNOWN_VALUE = new NumState();
4757 4659
4758 @override 4660 @override
4759 int get hashCode => 7; 4661 int get hashCode => 7;
4760 4662
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
4856 NumState times(InstanceState rightOperand) { 4758 NumState times(InstanceState rightOperand) {
4857 assertNumOrNull(rightOperand); 4759 assertNumOrNull(rightOperand);
4858 return UNKNOWN_VALUE; 4760 return UNKNOWN_VALUE;
4859 } 4761 }
4860 4762
4861 @override 4763 @override
4862 String toString() => "-unknown-"; 4764 String toString() => "-unknown-";
4863 } 4765 }
4864 4766
4865 /** 4767 /**
4866 * Instances of the class `ReferenceFinder` add reference information for a give n variable to 4768 * An object used to add reference information for a given variable to the
4867 * the bi-directional mapping used to order the evaluation of constants. 4769 * bi-directional mapping used to order the evaluation of constants.
4868 */ 4770 */
4869 class ReferenceFinder extends RecursiveAstVisitor<Object> { 4771 class ReferenceFinder extends RecursiveAstVisitor<Object> {
4870 /** 4772 /**
4871 * The element representing the construct that will be visited. 4773 * The element representing the construct that will be visited.
4872 */ 4774 */
4873 final AstNode _source; 4775 final AstNode _source;
4874 4776
4875 /** 4777 /**
4876 * A graph in which the nodes are the constant variables and the edges are fro m each variable to 4778 * A graph in which the nodes are the constant variables and the edges are
4877 * the other constant variables that are referenced in the head's initializer. 4779 * from each variable to the other constant variables that are referenced in
4780 * the head's initializer.
4878 */ 4781 */
4879 final DirectedGraph<AstNode> _referenceGraph; 4782 final DirectedGraph<AstNode> _referenceGraph;
4880 4783
4881 /** 4784 /**
4882 * A table mapping constant variables to the declarations of those variables. 4785 * A table mapping constant variables to the declarations of those variables.
4883 */ 4786 */
4884 final HashMap<VariableElement, VariableDeclaration> _variableDeclarationMap; 4787 final HashMap<VariableElement, VariableDeclaration> _variableDeclarationMap;
4885 4788
4886 /** 4789 /**
4887 * A table mapping constant constructors to the declarations of those construc tors. 4790 * A table mapping constant constructors to the declarations of those
4791 * constructors.
4888 */ 4792 */
4889 final HashMap<ConstructorElement, ConstructorDeclaration> _constructorDeclarat ionMap; 4793 final HashMap<ConstructorElement, ConstructorDeclaration> _constructorDeclarat ionMap;
4890 4794
4891 /** 4795 /**
4892 * Initialize a newly created reference finder to find references from the giv en variable to other 4796 * Initialize a newly created reference finder to find references from a given
4893 * variables and to add those references to the given graph. 4797 * variable to other variables and to add those references to the given graph.
4894 * 4798 * The [source] is the element representing the variable whose initializer
4895 * @param source the element representing the variable whose initializer will be visited 4799 * will be visited. The [referenceGraph] is a graph recording which variables
4896 * @param referenceGraph a graph recording which variables (heads) reference w hich other variables 4800 * (heads) reference which other variables (tails) in their initializers. The
4897 * (tails) in their initializers 4801 * [variableDeclarationMap] is a table mapping constant variables to the
4898 * @param variableDeclarationMap A table mapping constant variables to the dec larations of those 4802 * declarations of those variables. The [constructorDeclarationMap] is a table
4899 * variables. 4803 * mapping constant constructors to the declarations of those constructors.
4900 * @param constructorDeclarationMap A table mapping constant constructors to t he declarations of
4901 * those constructors.
4902 */ 4804 */
4903 ReferenceFinder(this._source, this._referenceGraph, 4805 ReferenceFinder(this._source, this._referenceGraph,
4904 this._variableDeclarationMap, this._constructorDeclarationMap); 4806 this._variableDeclarationMap, this._constructorDeclarationMap);
4905 4807
4906 @override 4808 @override
4907 Object visitInstanceCreationExpression(InstanceCreationExpression node) { 4809 Object visitInstanceCreationExpression(InstanceCreationExpression node) {
4908 if (node.isConst) { 4810 if (node.isConst) {
4909 _referenceGraph.addEdge(_source, node); 4811 _referenceGraph.addEdge(_source, node);
4910 } 4812 }
4911 return null; 4813 return null;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
4963 // to check because there's nothing we can do about it at this point. 4865 // to check because there's nothing we can do about it at this point.
4964 if (constructorDeclaration != null) { 4866 if (constructorDeclaration != null) {
4965 _referenceGraph.addEdge(_source, constructorDeclaration); 4867 _referenceGraph.addEdge(_source, constructorDeclaration);
4966 } 4868 }
4967 } 4869 }
4968 return null; 4870 return null;
4969 } 4871 }
4970 } 4872 }
4971 4873
4972 /** 4874 /**
4973 * Instances of the class `StringState` represent the state of an object represe nting a 4875 * The state of an object representing a string.
4974 * string.
4975 */ 4876 */
4976 class StringState extends InstanceState { 4877 class StringState extends InstanceState {
4977 /** 4878 /**
4978 * A state that can be used to represent a double whose value is not known. 4879 * A state that can be used to represent a double whose value is not known.
4979 */ 4880 */
4980 static StringState UNKNOWN_VALUE = new StringState(null); 4881 static StringState UNKNOWN_VALUE = new StringState(null);
4981 4882
4982 /** 4883 /**
4983 * The value of this instance. 4884 * The value of this instance.
4984 */ 4885 */
4985 final String value; 4886 final String value;
4986 4887
4987 /** 4888 /**
4988 * Initialize a newly created state to represent the given value. 4889 * Initialize a newly created state to represent the given [value].
4989 *
4990 * @param value the value of this instance
4991 */ 4890 */
4992 StringState(this.value); 4891 StringState(this.value);
4993 4892
4994 @override 4893 @override
4995 bool get hasExactValue => true; 4894 bool get hasExactValue => true;
4996 4895
4997 @override 4896 @override
4998 int get hashCode => value == null ? 0 : value.hashCode; 4897 int get hashCode => value == null ? 0 : value.hashCode;
4999 4898
5000 @override 4899 @override
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
5059 return IntState.UNKNOWN_VALUE; 4958 return IntState.UNKNOWN_VALUE;
5060 } 4959 }
5061 return new IntState(value.length); 4960 return new IntState(value.length);
5062 } 4961 }
5063 4962
5064 @override 4963 @override
5065 String toString() => value == null ? "-unknown-" : "'$value'"; 4964 String toString() => value == null ? "-unknown-" : "'$value'";
5066 } 4965 }
5067 4966
5068 /** 4967 /**
5069 * Instances of the class `StringState` represent the state of an object represe nting a 4968 * The state of an object representing a symbol.
5070 * symbol.
5071 */ 4969 */
5072 class SymbolState extends InstanceState { 4970 class SymbolState extends InstanceState {
5073 /** 4971 /**
5074 * The value of this instance. 4972 * The value of this instance.
5075 */ 4973 */
5076 final String value; 4974 final String value;
5077 4975
5078 /** 4976 /**
5079 * Initialize a newly created state to represent the given value. 4977 * Initialize a newly created state to represent the given [value].
5080 *
5081 * @param value the value of this instance
5082 */ 4978 */
5083 SymbolState(this.value); 4979 SymbolState(this.value);
5084 4980
5085 @override 4981 @override
5086 bool get hasExactValue => true; 4982 bool get hasExactValue => true;
5087 4983
5088 @override 4984 @override
5089 int get hashCode => value == null ? 0 : value.hashCode; 4985 int get hashCode => value == null ? 0 : value.hashCode;
5090 4986
5091 @override 4987 @override
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
5124 return BoolState.UNKNOWN_VALUE; 5020 return BoolState.UNKNOWN_VALUE;
5125 } 5021 }
5126 return BoolState.FALSE_STATE; 5022 return BoolState.FALSE_STATE;
5127 } 5023 }
5128 5024
5129 @override 5025 @override
5130 String toString() => value == null ? "-unknown-" : "#$value"; 5026 String toString() => value == null ? "-unknown-" : "#$value";
5131 } 5027 }
5132 5028
5133 /** 5029 /**
5134 * Instances of the class `TypeState` represent the state of an object represent ing a type. 5030 * The state of an object representing a type.
5135 */ 5031 */
5136 class TypeState extends InstanceState { 5032 class TypeState extends InstanceState {
5137 /** 5033 /**
5138 * The element representing the type being modeled. 5034 * The element representing the type being modeled.
5139 */ 5035 */
5140 final Element _element; 5036 final Element _element;
5141 5037
5142 /** 5038 /**
5143 * Initialize a newly created state to represent the given value. 5039 * Initialize a newly created state to represent the given [value].
5144 *
5145 * @param element the element representing the type being modeled
5146 */ 5040 */
5147 TypeState(this._element); 5041 TypeState(this._element);
5148 5042
5149 @override 5043 @override
5150 int get hashCode => _element == null ? 0 : _element.hashCode; 5044 int get hashCode => _element == null ? 0 : _element.hashCode;
5151 5045
5152 @override 5046 @override
5153 String get typeName => "Type"; 5047 String get typeName => "Type";
5154 5048
5155 @override 5049 @override
(...skipping 27 matching lines...) Expand all
5183 return BoolState.from(_element == rightElement); 5077 return BoolState.from(_element == rightElement);
5184 } else if (rightOperand is DynamicState) { 5078 } else if (rightOperand is DynamicState) {
5185 return BoolState.UNKNOWN_VALUE; 5079 return BoolState.UNKNOWN_VALUE;
5186 } 5080 }
5187 return BoolState.FALSE_STATE; 5081 return BoolState.FALSE_STATE;
5188 } 5082 }
5189 5083
5190 @override 5084 @override
5191 String toString() => _element == null ? "-unknown-" : _element.name; 5085 String toString() => _element == null ? "-unknown-" : _element.name;
5192 } 5086 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698