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

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

Issue 725143004: Format and sort analyzer and analysis_server packages. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month 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 | « pkg/analyzer/lib/src/generated/ast.dart ('k') | pkg/analyzer/lib/src/generated/element.dart » ('j') | 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
12 import 'ast.dart';
13 import 'element.dart';
14 import 'engine.dart' show AnalysisEngine, RecordingErrorListener;
15 import 'error.dart';
11 import 'java_core.dart'; 16 import 'java_core.dart';
12 import 'java_engine.dart' show ObjectUtilities; 17 import 'java_engine.dart' show ObjectUtilities;
18 import 'resolver.dart' show TypeProvider;
19 import 'scanner.dart' show Token, TokenType;
13 import 'source.dart' show Source; 20 import 'source.dart' show Source;
14 import 'error.dart'; 21 import 'utilities_collection.dart';
15 import 'scanner.dart' show Token, TokenType;
16 import 'ast.dart';
17 import 'element.dart';
18 import 'resolver.dart' show TypeProvider;
19 import 'engine.dart' show AnalysisEngine, RecordingErrorListener;
20 import 'utilities_dart.dart' show ParameterKind; 22 import 'utilities_dart.dart' show ParameterKind;
21 import 'utilities_collection.dart';
22 23
23 /** 24 /**
24 * Instances of the class `BoolState` represent the state of an object represent ing a boolean 25 * Instances of the class `BoolState` represent the state of an object represent ing a boolean
25 * value. 26 * value.
26 */ 27 */
27 class BoolState extends InstanceState { 28 class BoolState extends InstanceState {
28 /** 29 /**
29 * The value of this instance.
30 */
31 final bool value;
32
33 /**
34 * An instance representing the boolean value 'false'. 30 * An instance representing the boolean value 'false'.
35 */ 31 */
36 static BoolState FALSE_STATE = new BoolState(false); 32 static BoolState FALSE_STATE = new BoolState(false);
37 33
38 /** 34 /**
39 * An instance representing the boolean value 'true'. 35 * An instance representing the boolean value 'true'.
40 */ 36 */
41 static BoolState TRUE_STATE = new BoolState(true); 37 static BoolState TRUE_STATE = new BoolState(true);
42 38
43 /** 39 /**
44 * 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.
45 */ 41 */
46 static BoolState UNKNOWN_VALUE = new BoolState(null); 42 static BoolState UNKNOWN_VALUE = new BoolState(null);
47 43
48 /** 44 /**
49 * Return the boolean state representing the given boolean value. 45 * The value of this instance.
50 *
51 * @param value the value to be represented
52 * @return the boolean state representing the given boolean value
53 */ 46 */
54 static BoolState from(bool value) => value ? BoolState.TRUE_STATE : BoolState. FALSE_STATE; 47 final bool value;
55 48
56 /** 49 /**
57 * Initialize a newly created state to represent the given value. 50 * Initialize a newly created state to represent the given value.
58 * 51 *
59 * @param value the value of this instance 52 * @param value the value of this instance
60 */ 53 */
61 BoolState(this.value); 54 BoolState(this.value);
62 55
63 @override 56 @override
57 bool get hasExactValue => true;
58
59 @override
60 int get hashCode => value == null ? 0 : (value ? 2 : 3);
61
62 /**
63 * Return `true` if this object represents an object whose type is 'bool'.
64 *
65 * @return `true` if this object represents a boolean value
66 */
67 @override
68 bool get isBool => true;
69
70 @override
71 bool get isBoolNumStringOrNull => true;
72
73 @override
74 bool get isUnknown => value == null;
75
76 @override
77 String get typeName => "bool";
78
79 @override
80 bool operator ==(Object object) =>
81 object is BoolState && identical(value, object.value);
82
83 @override
64 BoolState convertToBool() => this; 84 BoolState convertToBool() => this;
65 85
66 @override 86 @override
67 StringState convertToString() { 87 StringState convertToString() {
68 if (value == null) { 88 if (value == null) {
69 return StringState.UNKNOWN_VALUE; 89 return StringState.UNKNOWN_VALUE;
70 } 90 }
71 return new StringState(value ? "true" : "false"); 91 return new StringState(value ? "true" : "false");
72 } 92 }
73 93
(...skipping 14 matching lines...) Expand all
88 return UNKNOWN_VALUE; 108 return UNKNOWN_VALUE;
89 } 109 }
90 return BoolState.from(identical(value, rightValue)); 110 return BoolState.from(identical(value, rightValue));
91 } else if (rightOperand is DynamicState) { 111 } else if (rightOperand is DynamicState) {
92 return UNKNOWN_VALUE; 112 return UNKNOWN_VALUE;
93 } 113 }
94 return FALSE_STATE; 114 return FALSE_STATE;
95 } 115 }
96 116
97 @override 117 @override
98 bool operator ==(Object object) => object is BoolState && identical(value, obj ect.value);
99
100 @override
101 String get typeName => "bool";
102
103 @override
104 bool get hasExactValue => true;
105
106 @override
107 int get hashCode => value == null ? 0 : (value ? 2 : 3);
108
109 /**
110 * Return `true` if this object represents an object whose type is 'bool'.
111 *
112 * @return `true` if this object represents a boolean value
113 */
114 @override
115 bool get isBool => true;
116
117 @override
118 bool get isBoolNumStringOrNull => true;
119
120 @override
121 bool get isUnknown => value == null;
122
123 @override
124 BoolState logicalAnd(InstanceState rightOperand) { 118 BoolState logicalAnd(InstanceState rightOperand) {
125 assertBool(rightOperand); 119 assertBool(rightOperand);
126 if (value == null) { 120 if (value == null) {
127 return UNKNOWN_VALUE; 121 return UNKNOWN_VALUE;
128 } 122 }
129 return value ? rightOperand.convertToBool() : FALSE_STATE; 123 return value ? rightOperand.convertToBool() : FALSE_STATE;
130 } 124 }
131 125
132 @override 126 @override
133 BoolState logicalNot() { 127 BoolState logicalNot() {
134 if (value == null) { 128 if (value == null) {
135 return UNKNOWN_VALUE; 129 return UNKNOWN_VALUE;
136 } 130 }
137 return value ? FALSE_STATE : TRUE_STATE; 131 return value ? FALSE_STATE : TRUE_STATE;
138 } 132 }
139 133
140 @override 134 @override
141 BoolState logicalOr(InstanceState rightOperand) { 135 BoolState logicalOr(InstanceState rightOperand) {
142 assertBool(rightOperand); 136 assertBool(rightOperand);
143 if (value == null) { 137 if (value == null) {
144 return UNKNOWN_VALUE; 138 return UNKNOWN_VALUE;
145 } 139 }
146 return value ? TRUE_STATE : rightOperand.convertToBool(); 140 return value ? TRUE_STATE : rightOperand.convertToBool();
147 } 141 }
148 142
149 @override 143 @override
150 String toString() => value == null ? "-unknown-" : (value ? "true" : "false"); 144 String toString() => value == null ? "-unknown-" : (value ? "true" : "false");
145
146 /**
147 * Return the boolean state representing the given boolean value.
148 *
149 * @param value the value to be represented
150 * @return the boolean state representing the given boolean value
151 */
152 static BoolState from(bool value) =>
153 value ? BoolState.TRUE_STATE : BoolState.FALSE_STATE;
151 } 154 }
152 155
153 /** 156 /**
154 * Instances of the class `ConstantEvaluator` evaluate constant expressions to p roduce their 157 * Instances of the class `ConstantEvaluator` evaluate constant expressions to p roduce their
155 * compile-time value. According to the Dart Language Specification: <blockquote > A constant 158 * compile-time value. According to the Dart Language Specification: <blockquote > A constant
156 * expression is one of the following: 159 * expression is one of the following:
157 * * A literal number. 160 * * A literal number.
158 * * A literal boolean. 161 * * A literal boolean.
159 * * A literal string where any interpolated expression is a compile-time consta nt that evaluates 162 * * A literal string where any interpolated expression is a compile-time consta nt that evaluates
160 * to a numeric, string or boolean value or to <b>null</b>. 163 * to a numeric, string or boolean value or to <b>null</b>.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 * Initialize a newly created evaluator to evaluate expressions in the given s ource. 211 * Initialize a newly created evaluator to evaluate expressions in the given s ource.
209 * 212 *
210 * @param source the source containing the expression(s) that will be evaluate d 213 * @param source the source containing the expression(s) that will be evaluate d
211 * @param typeProvider the type provider used to access known types 214 * @param typeProvider the type provider used to access known types
212 */ 215 */
213 ConstantEvaluator(this._source, this._typeProvider); 216 ConstantEvaluator(this._source, this._typeProvider);
214 217
215 EvaluationResult evaluate(Expression expression) { 218 EvaluationResult evaluate(Expression expression) {
216 RecordingErrorListener errorListener = new RecordingErrorListener(); 219 RecordingErrorListener errorListener = new RecordingErrorListener();
217 ErrorReporter errorReporter = new ErrorReporter(errorListener, _source); 220 ErrorReporter errorReporter = new ErrorReporter(errorListener, _source);
218 DartObjectImpl result = expression.accept(new ConstantVisitor.con1(_typeProv ider, errorReporter)); 221 DartObjectImpl result =
222 expression.accept(new ConstantVisitor.con1(_typeProvider, errorReporter) );
219 if (result != null) { 223 if (result != null) {
220 return EvaluationResult.forValue(result); 224 return EvaluationResult.forValue(result);
221 } 225 }
222 return EvaluationResult.forErrors(errorListener.errors); 226 return EvaluationResult.forErrors(errorListener.errors);
223 } 227 }
224 } 228 }
225 229
226 /** 230 /**
227 * Instances of the class `ConstantFinder` are used to traverse the AST structur es of all of 231 * Instances of the class `ConstantFinder` are used to traverse the AST structur es of all of
228 * the compilation units being resolved and build a table mapping constant varia ble elements to the 232 * the compilation units being resolved and build a table mapping constant varia ble elements to the
229 * declarations of those variables. 233 * declarations of those variables.
230 */ 234 */
231 class ConstantFinder extends RecursiveAstVisitor<Object> { 235 class ConstantFinder extends RecursiveAstVisitor<Object> {
232 /** 236 /**
233 * A table mapping constant variable elements to the declarations of those var iables. 237 * A table mapping constant variable elements to the declarations of those var iables.
234 */ 238 */
235 final HashMap<VariableElement, VariableDeclaration> variableMap = new HashMap< VariableElement, VariableDeclaration>(); 239 final HashMap<VariableElement, VariableDeclaration> variableMap =
240 new HashMap<VariableElement, VariableDeclaration>();
236 241
237 /** 242 /**
238 * A table mapping constant constructors to the declarations of those construc tors. 243 * A table mapping constant constructors to the declarations of those construc tors.
239 */ 244 */
240 final HashMap<ConstructorElement, ConstructorDeclaration> constructorMap = new HashMap<ConstructorElement, ConstructorDeclaration>(); 245 final HashMap<ConstructorElement, ConstructorDeclaration> constructorMap =
246 new HashMap<ConstructorElement, ConstructorDeclaration>();
241 247
242 /** 248 /**
243 * A collection of constant constructor invocations. 249 * A collection of constant constructor invocations.
244 */ 250 */
245 final List<InstanceCreationExpression> constructorInvocations = new List<Insta nceCreationExpression>(); 251 final List<InstanceCreationExpression> constructorInvocations =
252 new List<InstanceCreationExpression>();
246 253
247 @override 254 @override
248 Object visitConstructorDeclaration(ConstructorDeclaration node) { 255 Object visitConstructorDeclaration(ConstructorDeclaration node) {
249 super.visitConstructorDeclaration(node); 256 super.visitConstructorDeclaration(node);
250 if (node.constKeyword != null) { 257 if (node.constKeyword != null) {
251 ConstructorElement element = node.element; 258 ConstructorElement element = node.element;
252 if (element != null) { 259 if (element != null) {
253 constructorMap[element] = node; 260 constructorMap[element] = node;
254 } 261 }
255 } 262 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 */ 296 */
290 class ConstantValueComputer { 297 class ConstantValueComputer {
291 /** 298 /**
292 * Parameter to "fromEnvironment" methods that denotes the default value. 299 * Parameter to "fromEnvironment" methods that denotes the default value.
293 */ 300 */
294 static String _DEFAULT_VALUE_PARAM = "defaultValue"; 301 static String _DEFAULT_VALUE_PARAM = "defaultValue";
295 302
296 /** 303 /**
297 * Source of RegExp matching declarable operator names. From sdk/lib/internal/ symbol.dart. 304 * Source of RegExp matching declarable operator names. From sdk/lib/internal/ symbol.dart.
298 */ 305 */
299 static String _OPERATOR_RE = "(?:[\\-+*/%&|^]|\\[\\]=?|==|~/?|<[<=]?|>[>=]?|un ary-)"; 306 static String _OPERATOR_RE =
307 "(?:[\\-+*/%&|^]|\\[\\]=?|==|~/?|<[<=]?|>[>=]?|unary-)";
300 308
301 /** 309 /**
302 * Source of RegExp matching any public identifier. From sdk/lib/internal/symb ol.dart. 310 * Source of RegExp matching any public identifier. From sdk/lib/internal/symb ol.dart.
303 */ 311 */
304 static String _PUBLIC_IDENTIFIER_RE = "(?!${ConstantValueComputer._RESERVED_WO RD_RE}\\b(?!\\\$))[a-zA-Z\$][\\w\$]*"; 312 static String _PUBLIC_IDENTIFIER_RE =
313 "(?!${ConstantValueComputer._RESERVED_WORD_RE}\\b(?!\\\$))[a-zA-Z\$][\\w\$ ]*";
305 314
306 /** 315 /**
307 * Source of RegExp matching Dart reserved words. From sdk/lib/internal/symbol .dart. 316 * Source of RegExp matching Dart reserved words. From sdk/lib/internal/symbol .dart.
308 */ 317 */
309 static String _RESERVED_WORD_RE = "(?:assert|break|c(?:a(?:se|tch)|lass|on(?:s t|tinue))|d(?:efault|o)|e(?:lse|num|xtends)|f(?:alse|inal(?:ly)?|or)|i[fns]|n(?: ew|ull)|ret(?:hrow|urn)|s(?:uper|witch)|t(?:h(?:is|row)|r(?:ue|y))|v(?:ar|oid)|w (?:hile|ith))"; 318 static String _RESERVED_WORD_RE =
319 "(?: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))";
310 320
311 /** 321 /**
312 * RegExp that validates a non-empty non-private symbol. From sdk/lib/internal /symbol.dart. 322 * RegExp that validates a non-empty non-private symbol. From sdk/lib/internal /symbol.dart.
313 */ 323 */
314 static RegExp _PUBLIC_SYMBOL_PATTERN = new RegExp("^(?:${ConstantValueComputer ._OPERATOR_RE}\$|$_PUBLIC_IDENTIFIER_RE(?:=?\$|[.](?!\$)))+?\$"); 324 static RegExp _PUBLIC_SYMBOL_PATTERN = new RegExp(
315 325 "^(?:${ConstantValueComputer._OPERATOR_RE}\$|$_PUBLIC_IDENTIFIER_RE(?:=?\$ |[.](?!\$)))+?\$");
316 /**
317 * Determine whether the given string is a valid name for a public symbol (i.e . whether it is
318 * allowed for a call to the Symbol constructor).
319 */
320 static bool isValidPublicSymbol(String name) => name.isEmpty || name == "void" || new JavaPatternMatcher(_PUBLIC_SYMBOL_PATTERN, name).matches();
321 326
322 /** 327 /**
323 * The type provider used to access the known types. 328 * The type provider used to access the known types.
324 */ 329 */
325 TypeProvider typeProvider; 330 TypeProvider typeProvider;
326 331
327 /** 332 /**
328 * The object used to find constant variables and constant constructor invocat ions in the 333 * The object used to find constant variables and constant constructor invocat ions in the
329 * compilation units that were added. 334 * compilation units that were added.
330 */ 335 */
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 * Add the constants in the given compilation unit to the list of constants wh ose value needs to 375 * Add the constants in the given compilation unit to the list of constants wh ose value needs to
371 * be computed. 376 * be computed.
372 * 377 *
373 * @param unit the compilation unit defining the constants to be added 378 * @param unit the compilation unit defining the constants to be added
374 */ 379 */
375 void add(CompilationUnit unit) { 380 void add(CompilationUnit unit) {
376 unit.accept(_constantFinder); 381 unit.accept(_constantFinder);
377 } 382 }
378 383
379 /** 384 /**
385 * This method is called just before computing the constant value associated w ith an AST node.
386 * Unit tests will override this method to introduce additional error checking .
387 */
388 void beforeComputeValue(AstNode constNode) {
389 }
390
391 /**
392 * This method is called just before getting the constant initializers associa ted with a
393 * constructor AST node. Unit tests will override this method to introduce add itional error
394 * checking.
395 */
396 void beforeGetConstantInitializers(ConstructorElement constructor) {
397 }
398
399 /**
400 * This method is called just before getting a parameter's default value. Unit tests will override
401 * this method to introduce additional error checking.
402 */
403 void beforeGetParameterDefault(ParameterElement parameter) {
404 }
405
406 /**
380 * Compute values for all of the constants in the compilation units that were added. 407 * Compute values for all of the constants in the compilation units that were added.
381 */ 408 */
382 void computeValues() { 409 void computeValues() {
383 _variableDeclarationMap = _constantFinder.variableMap; 410 _variableDeclarationMap = _constantFinder.variableMap;
384 constructorDeclarationMap = _constantFinder.constructorMap; 411 constructorDeclarationMap = _constantFinder.constructorMap;
385 _constructorInvocations = _constantFinder.constructorInvocations; 412 _constructorInvocations = _constantFinder.constructorInvocations;
386 _variableDeclarationMap.values.forEach((VariableDeclaration declaration) { 413 _variableDeclarationMap.values.forEach((VariableDeclaration declaration) {
387 ReferenceFinder referenceFinder = new ReferenceFinder(declaration, referen ceGraph, _variableDeclarationMap, constructorDeclarationMap); 414 ReferenceFinder referenceFinder = new ReferenceFinder(
415 declaration,
416 referenceGraph,
417 _variableDeclarationMap,
418 constructorDeclarationMap);
388 referenceGraph.addNode(declaration); 419 referenceGraph.addNode(declaration);
389 declaration.initializer.accept(referenceFinder); 420 declaration.initializer.accept(referenceFinder);
390 }); 421 });
391 constructorDeclarationMap.forEach((ConstructorElement element, ConstructorDe claration declaration) { 422 constructorDeclarationMap.forEach(
392 ReferenceFinder referenceFinder = new ReferenceFinder(declaration, referen ceGraph, _variableDeclarationMap, constructorDeclarationMap); 423 (ConstructorElement element, ConstructorDeclaration declaration) {
424 ReferenceFinder referenceFinder = new ReferenceFinder(
425 declaration,
426 referenceGraph,
427 _variableDeclarationMap,
428 constructorDeclarationMap);
393 referenceGraph.addNode(declaration); 429 referenceGraph.addNode(declaration);
394 bool superInvocationFound = false; 430 bool superInvocationFound = false;
395 NodeList<ConstructorInitializer> initializers = declaration.initializers; 431 NodeList<ConstructorInitializer> initializers = declaration.initializers;
396 for (ConstructorInitializer initializer in initializers) { 432 for (ConstructorInitializer initializer in initializers) {
397 if (initializer is SuperConstructorInvocation) { 433 if (initializer is SuperConstructorInvocation) {
398 superInvocationFound = true; 434 superInvocationFound = true;
399 } 435 }
400 initializer.accept(referenceFinder); 436 initializer.accept(referenceFinder);
401 } 437 }
402 if (!superInvocationFound) { 438 if (!superInvocationFound) {
403 // No explicit superconstructor invocation found, so we need to manually insert 439 // No explicit superconstructor invocation found, so we need to
404 // a reference to the implicit superconstructor. 440 // manually insert a reference to the implicit superconstructor.
405 InterfaceType superclass = (element.returnType as InterfaceType).supercl ass; 441 InterfaceType superclass =
442 (element.returnType as InterfaceType).superclass;
406 if (superclass != null && !superclass.isObject) { 443 if (superclass != null && !superclass.isObject) {
407 ConstructorElement unnamedConstructor = superclass.element.unnamedCons tructor; 444 ConstructorElement unnamedConstructor =
408 ConstructorDeclaration superConstructorDeclaration = findConstructorDe claration(unnamedConstructor); 445 superclass.element.unnamedConstructor;
446 ConstructorDeclaration superConstructorDeclaration =
447 findConstructorDeclaration(unnamedConstructor);
409 if (superConstructorDeclaration != null) { 448 if (superConstructorDeclaration != null) {
410 referenceGraph.addEdge(declaration, superConstructorDeclaration); 449 referenceGraph.addEdge(declaration, superConstructorDeclaration);
411 } 450 }
412 } 451 }
413 } 452 }
414 for (FormalParameter parameter in declaration.parameters.parameters) { 453 for (FormalParameter parameter in declaration.parameters.parameters) {
415 referenceGraph.addNode(parameter); 454 referenceGraph.addNode(parameter);
416 referenceGraph.addEdge(declaration, parameter); 455 referenceGraph.addEdge(declaration, parameter);
417 if (parameter is DefaultFormalParameter) { 456 if (parameter is DefaultFormalParameter) {
418 Expression defaultValue = parameter.defaultValue; 457 Expression defaultValue = parameter.defaultValue;
419 if (defaultValue != null) { 458 if (defaultValue != null) {
420 ReferenceFinder parameterReferenceFinder = new ReferenceFinder(param eter, referenceGraph, _variableDeclarationMap, constructorDeclarationMap); 459 ReferenceFinder parameterReferenceFinder = new ReferenceFinder(
460 parameter,
461 referenceGraph,
462 _variableDeclarationMap,
463 constructorDeclarationMap);
421 defaultValue.accept(parameterReferenceFinder); 464 defaultValue.accept(parameterReferenceFinder);
422 } 465 }
423 } 466 }
424 } 467 }
425 }); 468 });
426 for (InstanceCreationExpression expression in _constructorInvocations) { 469 for (InstanceCreationExpression expression in _constructorInvocations) {
427 referenceGraph.addNode(expression); 470 referenceGraph.addNode(expression);
428 ConstructorElement constructor = expression.staticElement; 471 ConstructorElement constructor = expression.staticElement;
429 if (constructor == null) { 472 if (constructor == null) {
430 continue; 473 continue;
431 } 474 }
432 constructor = _followConstantRedirectionChain(constructor); 475 constructor = _followConstantRedirectionChain(constructor);
433 ConstructorDeclaration declaration = findConstructorDeclaration(constructo r); 476 ConstructorDeclaration declaration =
434 // An instance creation expression depends both on the constructor and the arguments passed 477 findConstructorDeclaration(constructor);
435 // to it. 478 // An instance creation expression depends both on the constructor and
436 ReferenceFinder referenceFinder = new ReferenceFinder(expression, referenc eGraph, _variableDeclarationMap, constructorDeclarationMap); 479 // the arguments passed to it.
480 ReferenceFinder referenceFinder = new ReferenceFinder(
481 expression,
482 referenceGraph,
483 _variableDeclarationMap,
484 constructorDeclarationMap);
437 if (declaration != null) { 485 if (declaration != null) {
438 referenceGraph.addEdge(expression, declaration); 486 referenceGraph.addEdge(expression, declaration);
439 } 487 }
440 expression.argumentList.accept(referenceFinder); 488 expression.argumentList.accept(referenceFinder);
441 } 489 }
442 List<List<AstNode>> topologicalSort = referenceGraph.computeTopologicalSort( ); 490 List<List<AstNode>> topologicalSort =
491 referenceGraph.computeTopologicalSort();
443 for (List<AstNode> constantsInCycle in topologicalSort) { 492 for (List<AstNode> constantsInCycle in topologicalSort) {
444 if (constantsInCycle.length == 1) { 493 if (constantsInCycle.length == 1) {
445 _computeValueFor(constantsInCycle[0]); 494 _computeValueFor(constantsInCycle[0]);
446 } else { 495 } else {
447 for (AstNode constant in constantsInCycle) { 496 for (AstNode constant in constantsInCycle) {
448 _generateCycleError(constantsInCycle, constant); 497 _generateCycleError(constantsInCycle, constant);
449 } 498 }
450 } 499 }
451 } 500 }
452 } 501 }
453 502
454 /** 503 /**
455 * This method is called just before computing the constant value associated w ith an AST node.
456 * Unit tests will override this method to introduce additional error checking .
457 */
458 void beforeComputeValue(AstNode constNode) {
459 }
460
461 /**
462 * This method is called just before getting the constant initializers associa ted with a
463 * constructor AST node. Unit tests will override this method to introduce add itional error
464 * checking.
465 */
466 void beforeGetConstantInitializers(ConstructorElement constructor) {
467 }
468
469 /**
470 * This method is called just before getting a parameter's default value. Unit tests will override
471 * this method to introduce additional error checking.
472 */
473 void beforeGetParameterDefault(ParameterElement parameter) {
474 }
475
476 /**
477 * Create the ConstantVisitor used to evaluate constants. Unit tests will over ride this method to 504 * Create the ConstantVisitor used to evaluate constants. Unit tests will over ride this method to
478 * introduce additional error checking. 505 * introduce additional error checking.
479 */ 506 */
480 ConstantVisitor createConstantVisitor(ErrorReporter errorReporter) => new Cons tantVisitor.con1(typeProvider, errorReporter); 507 ConstantVisitor createConstantVisitor(ErrorReporter errorReporter) =>
508 new ConstantVisitor.con1(typeProvider, errorReporter);
481 509
482 ConstructorDeclaration findConstructorDeclaration(ConstructorElement construct or) => constructorDeclarationMap[_getConstructorBase(constructor)]; 510 ConstructorDeclaration
511 findConstructorDeclaration(ConstructorElement constructor) =>
512 constructorDeclarationMap[_getConstructorBase(constructor)];
483 513
484 /** 514 /**
485 * Check that the arguments to a call to fromEnvironment() are correct. 515 * Check that the arguments to a call to fromEnvironment() are correct.
486 * 516 *
487 * @param arguments the AST nodes of the arguments. 517 * @param arguments the AST nodes of the arguments.
488 * @param argumentValues the values of the unnamed arguments. 518 * @param argumentValues the values of the unnamed arguments.
489 * @param namedArgumentValues the values of the named arguments. 519 * @param namedArgumentValues the values of the named arguments.
490 * @param expectedDefaultValueType the allowed type of the "defaultValue" para meter (if present). 520 * @param expectedDefaultValueType the allowed type of the "defaultValue" para meter (if present).
491 * Note: "defaultValue" is always allowed to be null. 521 * Note: "defaultValue" is always allowed to be null.
492 * @return true if the arguments are correct, false if there is an error. 522 * @return true if the arguments are correct, false if there is an error.
493 */ 523 */
494 bool _checkFromEnvironmentArguments(NodeList<Expression> arguments, List<DartO bjectImpl> argumentValues, HashMap<String, DartObjectImpl> namedArgumentValues, InterfaceType expectedDefaultValueType) { 524 bool _checkFromEnvironmentArguments(NodeList<Expression> arguments,
525 List<DartObjectImpl> argumentValues, HashMap<String,
526 DartObjectImpl> namedArgumentValues, InterfaceType expectedDefaultValueTyp e) {
495 int argumentCount = arguments.length; 527 int argumentCount = arguments.length;
496 if (argumentCount < 1 || argumentCount > 2) { 528 if (argumentCount < 1 || argumentCount > 2) {
497 return false; 529 return false;
498 } 530 }
499 if (arguments[0] is NamedExpression) { 531 if (arguments[0] is NamedExpression) {
500 return false; 532 return false;
501 } 533 }
502 if (!identical(argumentValues[0].type, typeProvider.stringType)) { 534 if (!identical(argumentValues[0].type, typeProvider.stringType)) {
503 return false; 535 return false;
504 } 536 }
505 if (argumentCount == 2) { 537 if (argumentCount == 2) {
506 if (arguments[1] is! NamedExpression) { 538 if (arguments[1] is! NamedExpression) {
507 return false; 539 return false;
508 } 540 }
509 if (!((arguments[1] as NamedExpression).name.label.name == _DEFAULT_VALUE_ PARAM)) { 541 if (!((arguments[1] as NamedExpression).name.label.name ==
542 _DEFAULT_VALUE_PARAM)) {
510 return false; 543 return false;
511 } 544 }
512 ParameterizedType defaultValueType = namedArgumentValues[_DEFAULT_VALUE_PA RAM].type; 545 ParameterizedType defaultValueType =
513 if (!(identical(defaultValueType, expectedDefaultValueType) || identical(d efaultValueType, typeProvider.nullType))) { 546 namedArgumentValues[_DEFAULT_VALUE_PARAM].type;
547 if (!(identical(defaultValueType, expectedDefaultValueType) ||
548 identical(defaultValueType, typeProvider.nullType))) {
514 return false; 549 return false;
515 } 550 }
516 } 551 }
517 return true; 552 return true;
518 } 553 }
519 554
520 /** 555 /**
521 * Check that the arguments to a call to Symbol() are correct. 556 * Check that the arguments to a call to Symbol() are correct.
522 * 557 *
523 * @param arguments the AST nodes of the arguments. 558 * @param arguments the AST nodes of the arguments.
524 * @param argumentValues the values of the unnamed arguments. 559 * @param argumentValues the values of the unnamed arguments.
525 * @param namedArgumentValues the values of the named arguments. 560 * @param namedArgumentValues the values of the named arguments.
526 * @return true if the arguments are correct, false if there is an error. 561 * @return true if the arguments are correct, false if there is an error.
527 */ 562 */
528 bool _checkSymbolArguments(NodeList<Expression> arguments, List<DartObjectImpl > argumentValues, HashMap<String, DartObjectImpl> namedArgumentValues) { 563 bool _checkSymbolArguments(NodeList<Expression> arguments,
564 List<DartObjectImpl> argumentValues, HashMap<String,
565 DartObjectImpl> namedArgumentValues) {
529 if (arguments.length != 1) { 566 if (arguments.length != 1) {
530 return false; 567 return false;
531 } 568 }
532 if (arguments[0] is NamedExpression) { 569 if (arguments[0] is NamedExpression) {
533 return false; 570 return false;
534 } 571 }
535 if (!identical(argumentValues[0].type, typeProvider.stringType)) { 572 if (!identical(argumentValues[0].type, typeProvider.stringType)) {
536 return false; 573 return false;
537 } 574 }
538 String name = argumentValues[0].stringValue; 575 String name = argumentValues[0].stringValue;
539 return isValidPublicSymbol(name); 576 return isValidPublicSymbol(name);
540 } 577 }
541 578
542 /** 579 /**
543 * Compute a value for the given constant. 580 * Compute a value for the given constant.
544 * 581 *
545 * @param constNode the constant for which a value is to be computed 582 * @param constNode the constant for which a value is to be computed
546 */ 583 */
547 void _computeValueFor(AstNode constNode) { 584 void _computeValueFor(AstNode constNode) {
548 beforeComputeValue(constNode); 585 beforeComputeValue(constNode);
549 if (constNode is VariableDeclaration) { 586 if (constNode is VariableDeclaration) {
550 VariableDeclaration declaration = constNode; 587 VariableDeclaration declaration = constNode;
551 VariableElement element = declaration.element; 588 VariableElement element = declaration.element;
552 RecordingErrorListener errorListener = new RecordingErrorListener(); 589 RecordingErrorListener errorListener = new RecordingErrorListener();
553 ErrorReporter errorReporter = new ErrorReporter(errorListener, element.sou rce); 590 ErrorReporter errorReporter =
554 DartObjectImpl dartObject = declaration.initializer.accept(createConstantV isitor(errorReporter)); 591 new ErrorReporter(errorListener, element.source);
592 DartObjectImpl dartObject =
593 declaration.initializer.accept(createConstantVisitor(errorReporter));
555 if (dartObject != null) { 594 if (dartObject != null) {
556 if (!_runtimeTypeMatch(dartObject, element.type)) { 595 if (!_runtimeTypeMatch(dartObject, element.type)) {
557 errorReporter.reportErrorForNode( 596 errorReporter.reportErrorForNode(
558 CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH, 597 CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH,
559 declaration, [dartObject.type, element.type]); 598 declaration,
599 [dartObject.type, element.type]);
560 } 600 }
561 } 601 }
562 (element as VariableElementImpl).evaluationResult = new EvaluationResultIm pl.con2(dartObject, errorListener.errors); 602 (element as VariableElementImpl).evaluationResult =
603 new EvaluationResultImpl.con2(dartObject, errorListener.errors);
563 } else if (constNode is InstanceCreationExpression) { 604 } else if (constNode is InstanceCreationExpression) {
564 InstanceCreationExpression expression = constNode; 605 InstanceCreationExpression expression = constNode;
565 ConstructorElement constructor = expression.staticElement; 606 ConstructorElement constructor = expression.staticElement;
566 if (constructor == null) { 607 if (constructor == null) {
567 // Couldn't resolve the constructor so we can't compute a value. No pro blem--the error 608 // Couldn't resolve the constructor so we can't compute a value.
568 // has already been reported. But we still need to store an evaluation result. 609 // No problem - the error has already been reported.
610 // But we still need to store an evaluation result.
569 expression.evaluationResult = new EvaluationResultImpl.con1(null); 611 expression.evaluationResult = new EvaluationResultImpl.con1(null);
570 return; 612 return;
571 } 613 }
572 RecordingErrorListener errorListener = new RecordingErrorListener(); 614 RecordingErrorListener errorListener = new RecordingErrorListener();
573 CompilationUnit sourceCompilationUnit = expression.getAncestor((node) => n ode is CompilationUnit); 615 CompilationUnit sourceCompilationUnit =
574 ErrorReporter errorReporter = new ErrorReporter(errorListener, sourceCompi lationUnit.element.source); 616 expression.getAncestor((node) => node is CompilationUnit);
617 ErrorReporter errorReporter =
618 new ErrorReporter(errorListener, sourceCompilationUnit.element.source) ;
575 ConstantVisitor constantVisitor = createConstantVisitor(errorReporter); 619 ConstantVisitor constantVisitor = createConstantVisitor(errorReporter);
576 DartObjectImpl result = _evaluateConstructorCall(constNode, expression.arg umentList.arguments, constructor, constantVisitor, errorReporter); 620 DartObjectImpl result = _evaluateConstructorCall(
577 expression.evaluationResult = new EvaluationResultImpl.con2(result, errorL istener.errors); 621 constNode,
622 expression.argumentList.arguments,
623 constructor,
624 constantVisitor,
625 errorReporter);
626 expression.evaluationResult =
627 new EvaluationResultImpl.con2(result, errorListener.errors);
578 } else if (constNode is ConstructorDeclaration) { 628 } else if (constNode is ConstructorDeclaration) {
579 ConstructorDeclaration declaration = constNode; 629 ConstructorDeclaration declaration = constNode;
580 NodeList<ConstructorInitializer> initializers = declaration.initializers; 630 NodeList<ConstructorInitializer> initializers = declaration.initializers;
581 ConstructorElementImpl constructor = declaration.element as ConstructorEle mentImpl; 631 ConstructorElementImpl constructor =
582 constructor.constantInitializers = new ConstantValueComputer_InitializerCl oner().cloneNodeList(initializers); 632 declaration.element as ConstructorElementImpl;
633 constructor.constantInitializers =
634 new ConstantValueComputer_InitializerCloner().cloneNodeList(initialize rs);
583 } else if (constNode is FormalParameter) { 635 } else if (constNode is FormalParameter) {
584 if (constNode is DefaultFormalParameter) { 636 if (constNode is DefaultFormalParameter) {
585 DefaultFormalParameter parameter = constNode; 637 DefaultFormalParameter parameter = constNode;
586 ParameterElement element = parameter.element; 638 ParameterElement element = parameter.element;
587 Expression defaultValue = parameter.defaultValue; 639 Expression defaultValue = parameter.defaultValue;
588 if (defaultValue != null) { 640 if (defaultValue != null) {
589 RecordingErrorListener errorListener = new RecordingErrorListener(); 641 RecordingErrorListener errorListener = new RecordingErrorListener();
590 ErrorReporter errorReporter = new ErrorReporter(errorListener, element .source); 642 ErrorReporter errorReporter =
591 DartObjectImpl dartObject = defaultValue.accept(createConstantVisitor( errorReporter)); 643 new ErrorReporter(errorListener, element.source);
592 (element as ParameterElementImpl).evaluationResult = new EvaluationRes ultImpl.con2(dartObject, errorListener.errors); 644 DartObjectImpl dartObject =
645 defaultValue.accept(createConstantVisitor(errorReporter));
646 (element as ParameterElementImpl).evaluationResult =
647 new EvaluationResultImpl.con2(dartObject, errorListener.errors);
593 } 648 }
594 } 649 }
595 } else { 650 } else {
596 // Should not happen. 651 // Should not happen.
597 AnalysisEngine.instance.logger.logError("Constant value computer trying to compute the value of a node which is not a VariableDeclaration, InstanceCreatio nExpression, FormalParameter, or ConstructorDeclaration"); 652 AnalysisEngine.instance.logger.logError(
653 "Constant value computer trying to compute the value of a node which i s not a VariableDeclaration, InstanceCreationExpression, FormalParameter, or Con structorDeclaration");
598 return; 654 return;
599 } 655 }
600 } 656 }
601 657
602 /** 658 /**
603 * Evaluate a call to fromEnvironment() on the bool, int, or String class. 659 * Evaluate a call to fromEnvironment() on the bool, int, or String class.
604 * 660 *
605 * @param environmentValue Value fetched from the environment 661 * @param environmentValue Value fetched from the environment
606 * @param builtInDefaultValue Value that should be used as the default if no " defaultValue" 662 * @param builtInDefaultValue Value that should be used as the default if no " defaultValue"
607 * argument appears in [namedArgumentValues]. 663 * argument appears in [namedArgumentValues].
608 * @param namedArgumentValues Named parameters passed to fromEnvironment() 664 * @param namedArgumentValues Named parameters passed to fromEnvironment()
609 * @return A [DartObjectImpl] object corresponding to the evaluated result 665 * @return A [DartObjectImpl] object corresponding to the evaluated result
610 */ 666 */
611 DartObjectImpl _computeValueFromEnvironment(DartObject environmentValue, DartO bjectImpl builtInDefaultValue, HashMap<String, DartObjectImpl> namedArgumentValu es) { 667 DartObjectImpl _computeValueFromEnvironment(DartObject environmentValue,
668 DartObjectImpl builtInDefaultValue, HashMap<String,
669 DartObjectImpl> namedArgumentValues) {
612 DartObjectImpl value = environmentValue as DartObjectImpl; 670 DartObjectImpl value = environmentValue as DartObjectImpl;
613 if (value.isUnknown || value.isNull) { 671 if (value.isUnknown || value.isNull) {
614 // The name either doesn't exist in the environment or we couldn't parse t he corresponding 672 // The name either doesn't exist in the environment or we couldn't parse
615 // value. If the code supplied an explicit default, use it. 673 // the corresponding value.
674 // If the code supplied an explicit default, use it.
616 if (namedArgumentValues.containsKey(_DEFAULT_VALUE_PARAM)) { 675 if (namedArgumentValues.containsKey(_DEFAULT_VALUE_PARAM)) {
617 value = namedArgumentValues[_DEFAULT_VALUE_PARAM]; 676 value = namedArgumentValues[_DEFAULT_VALUE_PARAM];
618 } else if (value.isNull) { 677 } else if (value.isNull) {
619 // The code didn't supply an explicit default. The name exists in the e nvironment but 678 // The code didn't supply an explicit default.
620 // we couldn't parse the corresponding value. So use the built-in defau lt value, because 679 // The name exists in the environment but we couldn't parse the
621 // this is what the VM does. 680 // corresponding value.
681 // So use the built-in default value, because this is what the VM does.
622 value = builtInDefaultValue; 682 value = builtInDefaultValue;
623 } else { 683 } else {
624 // The code didn't supply an explicit default. The name doesn't exist i n the environment. 684 // The code didn't supply an explicit default.
625 // The VM would use the built-in default value, but we don't want to do that for analysis 685 // The name doesn't exist in the environment.
626 // because it's likely to lead to cascading errors. So just leave [valu e] in the unknown 686 // The VM would use the built-in default value, but we don't want to do
627 // state. 687 // that for analysis because it's likely to lead to cascading errors.
688 // So just leave [value] in the unknown state.
628 } 689 }
629 } 690 }
630 return value; 691 return value;
631 } 692 }
632 693
633 DartObjectImpl _evaluateConstructorCall(AstNode node, NodeList<Expression> arg uments, ConstructorElement constructor, ConstantVisitor constantVisitor, ErrorRe porter errorReporter) { 694 DartObjectImpl _evaluateConstructorCall(AstNode node,
695 NodeList<Expression> arguments, ConstructorElement constructor,
696 ConstantVisitor constantVisitor, ErrorReporter errorReporter) {
634 int argumentCount = arguments.length; 697 int argumentCount = arguments.length;
635 List<DartObjectImpl> argumentValues = new List<DartObjectImpl>(argumentCount ); 698 List<DartObjectImpl> argumentValues =
699 new List<DartObjectImpl>(argumentCount);
636 List<Expression> argumentNodes = new List<Expression>(argumentCount); 700 List<Expression> argumentNodes = new List<Expression>(argumentCount);
637 HashMap<String, DartObjectImpl> namedArgumentValues = new HashMap<String, Da rtObjectImpl>(); 701 HashMap<String, DartObjectImpl> namedArgumentValues =
702 new HashMap<String, DartObjectImpl>();
638 HashMap<String, NamedExpression> namedArgumentNodes = 703 HashMap<String, NamedExpression> namedArgumentNodes =
639 new HashMap<String, NamedExpression>(); 704 new HashMap<String, NamedExpression>();
640 for (int i = 0; i < argumentCount; i++) { 705 for (int i = 0; i < argumentCount; i++) {
641 Expression argument = arguments[i]; 706 Expression argument = arguments[i];
642 if (argument is NamedExpression) { 707 if (argument is NamedExpression) {
643 String name = argument.name.label.name; 708 String name = argument.name.label.name;
644 namedArgumentValues[name] = constantVisitor._valueOf(argument.expression ); 709 namedArgumentValues[name] =
710 constantVisitor._valueOf(argument.expression);
645 namedArgumentNodes[name] = argument; 711 namedArgumentNodes[name] = argument;
646 argumentValues[i] = constantVisitor.null2; 712 argumentValues[i] = constantVisitor.null2;
647 } else { 713 } else {
648 argumentValues[i] = constantVisitor._valueOf(argument); 714 argumentValues[i] = constantVisitor._valueOf(argument);
649 argumentNodes[i] = argument; 715 argumentNodes[i] = argument;
650 } 716 }
651 } 717 }
652 constructor = _followConstantRedirectionChain(constructor); 718 constructor = _followConstantRedirectionChain(constructor);
653 InterfaceType definingClass = constructor.returnType as InterfaceType; 719 InterfaceType definingClass = constructor.returnType as InterfaceType;
654 if (constructor.isFactory) { 720 if (constructor.isFactory) {
655 // We couldn't find a non-factory constructor. See if it's because we rea ched an external 721 // We couldn't find a non-factory constructor.
656 // const factory constructor that we can emulate. 722 // See if it's because we reached an external const factory constructor
723 // that we can emulate.
657 if (constructor.name == "fromEnvironment") { 724 if (constructor.name == "fromEnvironment") {
658 if (!_checkFromEnvironmentArguments(arguments, argumentValues, namedArgu mentValues, definingClass)) { 725 if (!_checkFromEnvironmentArguments(
659 errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_EVAL_THROW S_EXCEPTION, node); 726 arguments,
727 argumentValues,
728 namedArgumentValues,
729 definingClass)) {
730 errorReporter.reportErrorForNode(
731 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
732 node);
660 return null; 733 return null;
661 } 734 }
662 String variableName = argumentCount < 1 ? null : argumentValues[0].strin gValue; 735 String variableName =
736 argumentCount < 1 ? null : argumentValues[0].stringValue;
663 if (identical(definingClass, typeProvider.boolType)) { 737 if (identical(definingClass, typeProvider.boolType)) {
664 DartObject valueFromEnvironment; 738 DartObject valueFromEnvironment;
665 valueFromEnvironment = _declaredVariables.getBool(typeProvider, variab leName); 739 valueFromEnvironment =
666 return _computeValueFromEnvironment(valueFromEnvironment, new DartObje ctImpl(typeProvider.boolType, BoolState.FALSE_STATE), namedArgumentValues); 740 _declaredVariables.getBool(typeProvider, variableName);
741 return _computeValueFromEnvironment(
742 valueFromEnvironment,
743 new DartObjectImpl(typeProvider.boolType, BoolState.FALSE_STATE),
744 namedArgumentValues);
667 } else if (identical(definingClass, typeProvider.intType)) { 745 } else if (identical(definingClass, typeProvider.intType)) {
668 DartObject valueFromEnvironment; 746 DartObject valueFromEnvironment;
669 valueFromEnvironment = _declaredVariables.getInt(typeProvider, variabl eName); 747 valueFromEnvironment =
670 return _computeValueFromEnvironment(valueFromEnvironment, new DartObje ctImpl(typeProvider.nullType, NullState.NULL_STATE), namedArgumentValues); 748 _declaredVariables.getInt(typeProvider, variableName);
749 return _computeValueFromEnvironment(
750 valueFromEnvironment,
751 new DartObjectImpl(typeProvider.nullType, NullState.NULL_STATE),
752 namedArgumentValues);
671 } else if (identical(definingClass, typeProvider.stringType)) { 753 } else if (identical(definingClass, typeProvider.stringType)) {
672 DartObject valueFromEnvironment; 754 DartObject valueFromEnvironment;
673 valueFromEnvironment = _declaredVariables.getString(typeProvider, vari ableName); 755 valueFromEnvironment =
674 return _computeValueFromEnvironment(valueFromEnvironment, new DartObje ctImpl(typeProvider.nullType, NullState.NULL_STATE), namedArgumentValues); 756 _declaredVariables.getString(typeProvider, variableName);
757 return _computeValueFromEnvironment(
758 valueFromEnvironment,
759 new DartObjectImpl(typeProvider.nullType, NullState.NULL_STATE),
760 namedArgumentValues);
675 } 761 }
676 } else if (constructor.name == "" && identical(definingClass, typeProvider .symbolType) && argumentCount == 1) { 762 } else if (constructor.name == "" &&
677 if (!_checkSymbolArguments(arguments, argumentValues, namedArgumentValue s)) { 763 identical(definingClass, typeProvider.symbolType) &&
678 errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_EVAL_THROW S_EXCEPTION, node); 764 argumentCount == 1) {
765 if (!_checkSymbolArguments(
766 arguments,
767 argumentValues,
768 namedArgumentValues)) {
769 errorReporter.reportErrorForNode(
770 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
771 node);
679 return null; 772 return null;
680 } 773 }
681 String argumentValue = argumentValues[0].stringValue; 774 String argumentValue = argumentValues[0].stringValue;
682 return new DartObjectImpl(definingClass, new SymbolState(argumentValue)) ; 775 return new DartObjectImpl(
776 definingClass,
777 new SymbolState(argumentValue));
683 } 778 }
684 // Either it's an external const factory constructor that we can't emulate , or an error 779 // Either it's an external const factory constructor that we can't
685 // occurred (a cycle, or a const constructor trying to delegate to a non-c onst constructor). 780 // emulate, or an error occurred (a cycle, or a const constructor trying
686 // In the former case, the best we can do is consider it an unknown value. In the latter 781 // to delegate to a non-const constructor).
687 // case, the error has already been reported, so considering it an unknown value will 782 // In the former case, the best we can do is consider it an unknown value.
688 // suppress further errors. 783 // In the latter case, the error has already been reported, so considering
784 // it an unknown value will suppress further errors.
689 return constantVisitor._validWithUnknownValue(definingClass); 785 return constantVisitor._validWithUnknownValue(definingClass);
690 } 786 }
691 beforeGetConstantInitializers(constructor); 787 beforeGetConstantInitializers(constructor);
692 ConstructorElementImpl constructorBase = _getConstructorBase(constructor) as ConstructorElementImpl; 788 ConstructorElementImpl constructorBase =
693 List<ConstructorInitializer> initializers = constructorBase.constantInitiali zers; 789 _getConstructorBase(constructor) as ConstructorElementImpl;
790 List<ConstructorInitializer> initializers =
791 constructorBase.constantInitializers;
694 if (initializers == null) { 792 if (initializers == null) {
695 // This can happen in some cases where there are compile errors in the cod e being analyzed 793 // This can happen in some cases where there are compile errors in the
696 // (for example if the code is trying to create a const instance using a n on-const 794 // code being analyzed (for example if the code is trying to create a
697 // constructor, or the node we're visiting is involved in a cycle). The e rror has already 795 // const instance using a non-const constructor, or the node we're
698 // been reported, so consider it an unknown value to suppress further erro rs. 796 // visiting is involved in a cycle). The error has already been reported,
797 // so consider it an unknown value to suppress further errors.
699 return constantVisitor._validWithUnknownValue(definingClass); 798 return constantVisitor._validWithUnknownValue(definingClass);
700 } 799 }
701 HashMap<String, DartObjectImpl> fieldMap = new HashMap<String, DartObjectImp l>(); 800 HashMap<String, DartObjectImpl> fieldMap =
702 HashMap<String, DartObjectImpl> parameterMap = new HashMap<String, DartObjec tImpl>(); 801 new HashMap<String, DartObjectImpl>();
802 HashMap<String, DartObjectImpl> parameterMap =
803 new HashMap<String, DartObjectImpl>();
703 List<ParameterElement> parameters = constructor.parameters; 804 List<ParameterElement> parameters = constructor.parameters;
704 int parameterCount = parameters.length; 805 int parameterCount = parameters.length;
705 for (int i = 0; i < parameterCount; i++) { 806 for (int i = 0; i < parameterCount; i++) {
706 ParameterElement parameter = parameters[i]; 807 ParameterElement parameter = parameters[i];
707 ParameterElement baseParameter = parameter; 808 ParameterElement baseParameter = parameter;
708 while (baseParameter is ParameterMember) { 809 while (baseParameter is ParameterMember) {
709 baseParameter = (baseParameter as ParameterMember).baseElement; 810 baseParameter = (baseParameter as ParameterMember).baseElement;
710 } 811 }
711 DartObjectImpl argumentValue = null; 812 DartObjectImpl argumentValue = null;
712 AstNode errorTarget = null; 813 AstNode errorTarget = null;
713 if (baseParameter.parameterKind == ParameterKind.NAMED) { 814 if (baseParameter.parameterKind == ParameterKind.NAMED) {
714 argumentValue = namedArgumentValues[baseParameter.name]; 815 argumentValue = namedArgumentValues[baseParameter.name];
715 errorTarget = namedArgumentNodes[baseParameter.name]; 816 errorTarget = namedArgumentNodes[baseParameter.name];
716 } else if (i < argumentCount) { 817 } else if (i < argumentCount) {
717 argumentValue = argumentValues[i]; 818 argumentValue = argumentValues[i];
718 errorTarget = argumentNodes[i]; 819 errorTarget = argumentNodes[i];
719 } 820 }
720 if (errorTarget == null) { 821 if (errorTarget == null) {
721 // No argument node that we can direct error messages to, because we 822 // No argument node that we can direct error messages to, because we
722 // are handling an optional parameter that wasn't specified. So just 823 // are handling an optional parameter that wasn't specified. So just
723 // direct error messages to the constructor call. 824 // direct error messages to the constructor call.
724 errorTarget = node; 825 errorTarget = node;
725 } 826 }
726 if (argumentValue == null && baseParameter is ParameterElementImpl) { 827 if (argumentValue == null && baseParameter is ParameterElementImpl) {
727 // The parameter is an optional positional parameter for which no value was provided, so 828 // The parameter is an optional positional parameter for which no value
728 // use the default value. 829 // was provided, so use the default value.
729 beforeGetParameterDefault(baseParameter); 830 beforeGetParameterDefault(baseParameter);
730 EvaluationResultImpl evaluationResult = (baseParameter as ParameterEleme ntImpl).evaluationResult; 831 EvaluationResultImpl evaluationResult =
832 (baseParameter as ParameterElementImpl).evaluationResult;
731 if (evaluationResult == null) { 833 if (evaluationResult == null) {
732 // No default was provided, so the default value is null. 834 // No default was provided, so the default value is null.
733 argumentValue = constantVisitor.null2; 835 argumentValue = constantVisitor.null2;
734 } else if (evaluationResult.value != null) { 836 } else if (evaluationResult.value != null) {
735 argumentValue = evaluationResult.value; 837 argumentValue = evaluationResult.value;
736 } 838 }
737 } 839 }
738 if (argumentValue != null) { 840 if (argumentValue != null) {
739 if (!_runtimeTypeMatch(argumentValue, parameter.type)) { 841 if (!_runtimeTypeMatch(argumentValue, parameter.type)) {
740 errorReporter.reportErrorForNode( 842 errorReporter.reportErrorForNode(
(...skipping 18 matching lines...) Expand all
759 } 861 }
760 String fieldName = field.name; 862 String fieldName = field.name;
761 fieldMap[fieldName] = argumentValue; 863 fieldMap[fieldName] = argumentValue;
762 } 864 }
763 } else { 865 } else {
764 String name = baseParameter.name; 866 String name = baseParameter.name;
765 parameterMap[name] = argumentValue; 867 parameterMap[name] = argumentValue;
766 } 868 }
767 } 869 }
768 } 870 }
769 ConstantVisitor initializerVisitor = new ConstantVisitor.con2(typeProvider, parameterMap, errorReporter); 871 ConstantVisitor initializerVisitor =
872 new ConstantVisitor.con2(typeProvider, parameterMap, errorReporter);
770 String superName = null; 873 String superName = null;
771 NodeList<Expression> superArguments = null; 874 NodeList<Expression> superArguments = null;
772 for (ConstructorInitializer initializer in initializers) { 875 for (ConstructorInitializer initializer in initializers) {
773 if (initializer is ConstructorFieldInitializer) { 876 if (initializer is ConstructorFieldInitializer) {
774 ConstructorFieldInitializer constructorFieldInitializer = initializer; 877 ConstructorFieldInitializer constructorFieldInitializer = initializer;
775 Expression initializerExpression = constructorFieldInitializer.expressio n; 878 Expression initializerExpression =
776 DartObjectImpl evaluationResult = initializerExpression.accept(initializ erVisitor); 879 constructorFieldInitializer.expression;
880 DartObjectImpl evaluationResult =
881 initializerExpression.accept(initializerVisitor);
777 if (evaluationResult != null) { 882 if (evaluationResult != null) {
778 String fieldName = constructorFieldInitializer.fieldName.name; 883 String fieldName = constructorFieldInitializer.fieldName.name;
779 fieldMap[fieldName] = evaluationResult; 884 fieldMap[fieldName] = evaluationResult;
780 PropertyAccessorElement getter = definingClass.getGetter(fieldName); 885 PropertyAccessorElement getter = definingClass.getGetter(fieldName);
781 if (getter != null) { 886 if (getter != null) {
782 PropertyInducingElement field = getter.variable; 887 PropertyInducingElement field = getter.variable;
783 if (!_runtimeTypeMatch(evaluationResult, field.type)) { 888 if (!_runtimeTypeMatch(evaluationResult, field.type)) {
784 errorReporter.reportErrorForNode( 889 errorReporter.reportErrorForNode(
785 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_M ISMATCH, 890 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_M ISMATCH,
786 node, [evaluationResult.type, fieldName, field.type]); 891 node,
892 [evaluationResult.type, fieldName, field.type]);
787 } 893 }
788 } 894 }
789 } 895 }
790 } else if (initializer is SuperConstructorInvocation) { 896 } else if (initializer is SuperConstructorInvocation) {
791 SuperConstructorInvocation superConstructorInvocation = initializer; 897 SuperConstructorInvocation superConstructorInvocation = initializer;
792 SimpleIdentifier name = superConstructorInvocation.constructorName; 898 SimpleIdentifier name = superConstructorInvocation.constructorName;
793 if (name != null) { 899 if (name != null) {
794 superName = name.name; 900 superName = name.name;
795 } 901 }
796 superArguments = superConstructorInvocation.argumentList.arguments; 902 superArguments = superConstructorInvocation.argumentList.arguments;
797 } else if (initializer is RedirectingConstructorInvocation) { 903 } else if (initializer is RedirectingConstructorInvocation) {
798 // This is a redirecting constructor, so just evaluate the constructor 904 // This is a redirecting constructor, so just evaluate the constructor
799 // it redirects to. 905 // it redirects to.
800 ConstructorElement constructor = initializer.staticElement; 906 ConstructorElement constructor = initializer.staticElement;
801 if (constructor != null && constructor.isConst) { 907 if (constructor != null && constructor.isConst) {
802 return _evaluateConstructorCall( 908 return _evaluateConstructorCall(
803 node, initializer.argumentList.arguments, constructor, 909 node,
804 initializerVisitor, errorReporter); 910 initializer.argumentList.arguments,
911 constructor,
912 initializerVisitor,
913 errorReporter);
805 } 914 }
806 } 915 }
807 } 916 }
808 // Evaluate explicit or implicit call to super(). 917 // Evaluate explicit or implicit call to super().
809 InterfaceType superclass = definingClass.superclass; 918 InterfaceType superclass = definingClass.superclass;
810 if (superclass != null && !superclass.isObject) { 919 if (superclass != null && !superclass.isObject) {
811 ConstructorElement superConstructor = superclass.lookUpConstructor(superNa me, constructor.library); 920 ConstructorElement superConstructor =
921 superclass.lookUpConstructor(superName, constructor.library);
812 if (superConstructor != null) { 922 if (superConstructor != null) {
813 if (superArguments == null) { 923 if (superArguments == null) {
814 superArguments = new NodeList<Expression>(null); 924 superArguments = new NodeList<Expression>(null);
815 } 925 }
816 _evaluateSuperConstructorCall(node, fieldMap, superConstructor, superArg uments, initializerVisitor, errorReporter); 926 _evaluateSuperConstructorCall(
927 node,
928 fieldMap,
929 superConstructor,
930 superArguments,
931 initializerVisitor,
932 errorReporter);
817 } 933 }
818 } 934 }
819 return new DartObjectImpl(definingClass, new GenericState(fieldMap)); 935 return new DartObjectImpl(definingClass, new GenericState(fieldMap));
820 } 936 }
821 937
822 void _evaluateSuperConstructorCall(AstNode node, HashMap<String, DartObjectImp l> fieldMap, ConstructorElement superConstructor, NodeList<Expression> superArgu ments, ConstantVisitor initializerVisitor, ErrorReporter errorReporter) { 938 void _evaluateSuperConstructorCall(AstNode node, HashMap<String,
939 DartObjectImpl> fieldMap, ConstructorElement superConstructor,
940 NodeList<Expression> superArguments, ConstantVisitor initializerVisitor,
941 ErrorReporter errorReporter) {
823 if (superConstructor != null && superConstructor.isConst) { 942 if (superConstructor != null && superConstructor.isConst) {
824 DartObjectImpl evaluationResult = _evaluateConstructorCall(node, superArgu ments, superConstructor, initializerVisitor, errorReporter); 943 DartObjectImpl evaluationResult = _evaluateConstructorCall(
944 node,
945 superArguments,
946 superConstructor,
947 initializerVisitor,
948 errorReporter);
825 if (evaluationResult != null) { 949 if (evaluationResult != null) {
826 fieldMap[GenericState.SUPERCLASS_FIELD] = evaluationResult; 950 fieldMap[GenericState.SUPERCLASS_FIELD] = evaluationResult;
827 } 951 }
828 } 952 }
829 } 953 }
830 954
831 /** 955 /**
832 * Attempt to follow the chain of factory redirections until a constructor is reached which is not 956 * Attempt to follow the chain of factory redirections until a constructor is reached which is not
833 * a const factory constructor. 957 * a const factory constructor.
834 * 958 *
835 * @return the constant constructor which terminates the chain of factory redi rections, if the 959 * @return the constant constructor which terminates the chain of factory redi rections, if the
836 * chain terminates. If there is a problem (e.g. a redirection can't b e found, or a cycle 960 * chain terminates. If there is a problem (e.g. a redirection can't b e found, or a cycle
837 * is encountered), the chain will be followed as far as possible and then a const factory 961 * is encountered), the chain will be followed as far as possible and then a const factory
838 * constructor will be returned. 962 * constructor will be returned.
839 */ 963 */
840 ConstructorElement _followConstantRedirectionChain(ConstructorElement construc tor) { 964 ConstructorElement
841 HashSet<ConstructorElement> constructorsVisited = new HashSet<ConstructorEle ment>(); 965 _followConstantRedirectionChain(ConstructorElement constructor) {
966 HashSet<ConstructorElement> constructorsVisited =
967 new HashSet<ConstructorElement>();
842 while (constructor.isFactory) { 968 while (constructor.isFactory) {
843 if (identical(constructor.enclosingElement.type, typeProvider.symbolType)) { 969 if (identical(
844 // The dart:core.Symbol has a const factory constructor that redirects t o 970 constructor.enclosingElement.type,
845 // dart:_internal.Symbol. That in turn redirects to an external const c onstructor, which 971 typeProvider.symbolType)) {
846 // we won't be able to evaluate. So stop following the chain of redirec tions at 972 // The dart:core.Symbol has a const factory constructor that redirects
847 // dart:core.Symbol, and let [evaluateInstanceCreationExpression] handle it specially. 973 // to dart:_internal.Symbol. That in turn redirects to an external
974 // const constructor, which we won't be able to evaluate.
975 // So stop following the chain of redirections at dart:core.Symbol, and
976 // let [evaluateInstanceCreationExpression] handle it specially.
848 break; 977 break;
849 } 978 }
850 constructorsVisited.add(constructor); 979 constructorsVisited.add(constructor);
851 ConstructorElement redirectedConstructor = constructor.redirectedConstruct or; 980 ConstructorElement redirectedConstructor =
981 constructor.redirectedConstructor;
852 if (redirectedConstructor == null) { 982 if (redirectedConstructor == null) {
853 // This can happen if constructor is an external factory constructor. 983 // This can happen if constructor is an external factory constructor.
854 break; 984 break;
855 } 985 }
856 if (!redirectedConstructor.isConst) { 986 if (!redirectedConstructor.isConst) {
857 // Delegating to a non-const constructor--this is not allowed (and 987 // Delegating to a non-const constructor--this is not allowed (and
858 // is checked elsewhere--see [ErrorVerifier.checkForRedirectToNonConstCo nstructor()]). 988 // is checked elsewhere--see
989 // [ErrorVerifier.checkForRedirectToNonConstConstructor()]).
859 break; 990 break;
860 } 991 }
861 if (constructorsVisited.contains(redirectedConstructor)) { 992 if (constructorsVisited.contains(redirectedConstructor)) {
862 // Cycle in redirecting factory constructors--this is not allowed 993 // Cycle in redirecting factory constructors--this is not allowed
863 // and is checked elsewhere--see [ErrorVerifier.checkForRecursiveFactory Redirect()]). 994 // and is checked elsewhere--see
995 // [ErrorVerifier.checkForRecursiveFactoryRedirect()]).
864 break; 996 break;
865 } 997 }
866 constructor = redirectedConstructor; 998 constructor = redirectedConstructor;
867 } 999 }
868 return constructor; 1000 return constructor;
869 } 1001 }
870 1002
871 /** 1003 /**
872 * Generate an error indicating that the given constant is not a valid compile -time constant 1004 * Generate an error indicating that the given constant is not a valid compile -time constant
873 * because it references at least one of the constants in the given cycle, eac h of which directly 1005 * because it references at least one of the constants in the given cycle, eac h of which directly
(...skipping 19 matching lines...) Expand all
893 */ 1025 */
894 bool _runtimeTypeMatch(DartObjectImpl obj, DartType type) { 1026 bool _runtimeTypeMatch(DartObjectImpl obj, DartType type) {
895 if (obj.isNull) { 1027 if (obj.isNull) {
896 return true; 1028 return true;
897 } 1029 }
898 if (type.isUndefined) { 1030 if (type.isUndefined) {
899 return false; 1031 return false;
900 } 1032 }
901 return obj.type.isSubtypeOf(type); 1033 return obj.type.isSubtypeOf(type);
902 } 1034 }
1035
1036 /**
1037 * Determine whether the given string is a valid name for a public symbol (i.e . whether it is
1038 * allowed for a call to the Symbol constructor).
1039 */
1040 static bool isValidPublicSymbol(String name) =>
1041 name.isEmpty ||
1042 name == "void" ||
1043 new JavaPatternMatcher(_PUBLIC_SYMBOL_PATTERN, name).matches();
903 } 1044 }
904 1045
905 /** 1046 /**
906 * A `ConstantValueComputer_InitializerCloner` is an [AstCloner] that copies the 1047 * A `ConstantValueComputer_InitializerCloner` is an [AstCloner] that copies the
907 * necessary information from the AST to allow const constructor initializers to 1048 * necessary information from the AST to allow const constructor initializers to
908 * be evaluated. 1049 * be evaluated.
909 */ 1050 */
910 class ConstantValueComputer_InitializerCloner extends AstCloner { 1051 class ConstantValueComputer_InitializerCloner extends AstCloner {
911 // TODO(brianwilkerson) Investigate replacing uses of this class with uses of 1052 // TODO(brianwilkerson) Investigate replacing uses of this class with uses of
912 // AstCloner and ResolutionCopier. 1053 // AstCloner and ResolutionCopier.
913 1054
914 ConstantValueComputer_InitializerCloner() : super(true); 1055 ConstantValueComputer_InitializerCloner() : super(true);
915 1056
916 @override 1057 @override
917 InstanceCreationExpression visitInstanceCreationExpression(InstanceCreationExp ression node) { 1058 InstanceCreationExpression
918 InstanceCreationExpression expression = super.visitInstanceCreationExpressio n(node); 1059 visitInstanceCreationExpression(InstanceCreationExpression node) {
1060 InstanceCreationExpression expression =
1061 super.visitInstanceCreationExpression(node);
919 expression.evaluationResult = node.evaluationResult; 1062 expression.evaluationResult = node.evaluationResult;
920 return expression; 1063 return expression;
921 } 1064 }
922 1065
923 @override 1066 @override
1067 RedirectingConstructorInvocation
1068 visitRedirectingConstructorInvocation(RedirectingConstructorInvocation nod e) {
1069 RedirectingConstructorInvocation invocation =
1070 super.visitRedirectingConstructorInvocation(node);
1071 invocation.staticElement = node.staticElement;
1072 return invocation;
1073 }
1074
1075 @override
924 SimpleIdentifier visitSimpleIdentifier(SimpleIdentifier node) { 1076 SimpleIdentifier visitSimpleIdentifier(SimpleIdentifier node) {
925 SimpleIdentifier identifier = super.visitSimpleIdentifier(node); 1077 SimpleIdentifier identifier = super.visitSimpleIdentifier(node);
926 identifier.staticElement = node.staticElement; 1078 identifier.staticElement = node.staticElement;
927 return identifier; 1079 return identifier;
928 } 1080 }
929 1081
930 @override 1082 @override
931 SuperConstructorInvocation visitSuperConstructorInvocation(SuperConstructorInv ocation node) { 1083 SuperConstructorInvocation
932 SuperConstructorInvocation invocation = super.visitSuperConstructorInvocatio n(node); 1084 visitSuperConstructorInvocation(SuperConstructorInvocation node) {
1085 SuperConstructorInvocation invocation =
1086 super.visitSuperConstructorInvocation(node);
933 invocation.staticElement = node.staticElement; 1087 invocation.staticElement = node.staticElement;
934 return invocation; 1088 return invocation;
935 } 1089 }
936
937 @override
938 RedirectingConstructorInvocation visitRedirectingConstructorInvocation(
939 RedirectingConstructorInvocation node) {
940 RedirectingConstructorInvocation invocation =
941 super.visitRedirectingConstructorInvocation(node);
942 invocation.staticElement = node.staticElement;
943 return invocation;
944 }
945 } 1090 }
946 1091
947 /** 1092 /**
948 * Instances of the class `ConstantVisitor` evaluate constant expressions to pro duce their 1093 * Instances of the class `ConstantVisitor` evaluate constant expressions to pro duce their
949 * compile-time value. According to the Dart Language Specification: <blockquote > A constant 1094 * compile-time value. According to the Dart Language Specification: <blockquote > A constant
950 * expression is one of the following: 1095 * expression is one of the following:
951 * * A literal number. 1096 * * A literal number.
952 * * A literal boolean. 1097 * * A literal boolean.
953 * * A literal string where any interpolated expression is a compile-time consta nt that evaluates 1098 * * A literal string where any interpolated expression is a compile-time consta nt that evaluates
954 * to a numeric, string or boolean value or to <b>null</b>. 1099 * to a numeric, string or boolean value or to <b>null</b>.
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1012 1157
1013 /** 1158 /**
1014 * Initialize a newly created constant visitor. 1159 * Initialize a newly created constant visitor.
1015 * 1160 *
1016 * @param typeProvider the type provider used to access known types 1161 * @param typeProvider the type provider used to access known types
1017 * @param lexicalEnvironment values which should override simpleIdentifiers, o r null if no 1162 * @param lexicalEnvironment values which should override simpleIdentifiers, o r null if no
1018 * overriding is necessary. 1163 * overriding is necessary.
1019 */ 1164 */
1020 ConstantVisitor.con1(this._typeProvider, this._errorReporter) { 1165 ConstantVisitor.con1(this._typeProvider, this._errorReporter) {
1021 this._lexicalEnvironment = null; 1166 this._lexicalEnvironment = null;
1022 this._dartObjectComputer = new DartObjectComputer(_errorReporter, _typeProvi der); 1167 this._dartObjectComputer =
1168 new DartObjectComputer(_errorReporter, _typeProvider);
1023 } 1169 }
1024 1170
1025 /** 1171 /**
1026 * Initialize a newly created constant visitor. 1172 * Initialize a newly created constant visitor.
1027 * 1173 *
1028 * @param typeProvider the type provider used to access known types 1174 * @param typeProvider the type provider used to access known types
1029 * @param lexicalEnvironment values which should override simpleIdentifiers, o r null if no 1175 * @param lexicalEnvironment values which should override simpleIdentifiers, o r null if no
1030 * overriding is necessary. 1176 * overriding is necessary.
1031 */ 1177 */
1032 ConstantVisitor.con2(this._typeProvider, HashMap<String, DartObjectImpl> lexic alEnvironment, this._errorReporter) { 1178 ConstantVisitor.con2(this._typeProvider, HashMap<String,
1179 DartObjectImpl> lexicalEnvironment, this._errorReporter) {
1033 this._lexicalEnvironment = lexicalEnvironment; 1180 this._lexicalEnvironment = lexicalEnvironment;
1034 this._dartObjectComputer = new DartObjectComputer(_errorReporter, _typeProvi der); 1181 this._dartObjectComputer =
1182 new DartObjectComputer(_errorReporter, _typeProvider);
1183 }
1184
1185 /**
1186 * Return an object representing the value 'null'.
1187 *
1188 * @return an object representing the value 'null'
1189 */
1190 DartObjectImpl get null2 {
1191 if (_nullObject == null) {
1192 _nullObject =
1193 new DartObjectImpl(_typeProvider.nullType, NullState.NULL_STATE);
1194 }
1195 return _nullObject;
1196 }
1197
1198 /**
1199 * This method is called just before retrieving an evaluation result from an A ST node. Unit tests
1200 * will override it to introduce additional error checking.
1201 */
1202 void beforeGetEvaluationResult(AstNode node) {
1035 } 1203 }
1036 1204
1037 @override 1205 @override
1038 DartObjectImpl visitAdjacentStrings(AdjacentStrings node) { 1206 DartObjectImpl visitAdjacentStrings(AdjacentStrings node) {
1039 DartObjectImpl result = null; 1207 DartObjectImpl result = null;
1040 for (StringLiteral string in node.strings) { 1208 for (StringLiteral string in node.strings) {
1041 if (result == null) { 1209 if (result == null) {
1042 result = string.accept(this); 1210 result = string.accept(this);
1043 } else { 1211 } else {
1044 result = _dartObjectComputer.concatenate(node, result, string.accept(thi s)); 1212 result =
1213 _dartObjectComputer.concatenate(node, result, string.accept(this));
1045 } 1214 }
1046 } 1215 }
1047 return result; 1216 return result;
1048 } 1217 }
1049 1218
1050 @override 1219 @override
1051 DartObjectImpl visitBinaryExpression(BinaryExpression node) { 1220 DartObjectImpl visitBinaryExpression(BinaryExpression node) {
1052 DartObjectImpl leftResult = node.leftOperand.accept(this); 1221 DartObjectImpl leftResult = node.leftOperand.accept(this);
1053 DartObjectImpl rightResult = node.rightOperand.accept(this); 1222 DartObjectImpl rightResult = node.rightOperand.accept(this);
1054 TokenType operatorType = node.operator.type; 1223 TokenType operatorType = node.operator.type;
1055 // 'null' is almost never good operand 1224 // 'null' is almost never good operand
1056 if (operatorType != TokenType.BANG_EQ && operatorType != TokenType.EQ_EQ) { 1225 if (operatorType != TokenType.BANG_EQ && operatorType != TokenType.EQ_EQ) {
1057 if (leftResult != null && leftResult.isNull || rightResult != null && righ tResult.isNull) { 1226 if (leftResult != null && leftResult.isNull ||
1227 rightResult != null && rightResult.isNull) {
1058 _error(node, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION); 1228 _error(node, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
1059 return null; 1229 return null;
1060 } 1230 }
1061 } 1231 }
1062 // evaluate operator 1232 // evaluate operator
1063 while (true) { 1233 while (true) {
1064 if (operatorType == TokenType.AMPERSAND) { 1234 if (operatorType == TokenType.AMPERSAND) {
1065 return _dartObjectComputer.bitAnd(node, leftResult, rightResult); 1235 return _dartObjectComputer.bitAnd(node, leftResult, rightResult);
1066 } else if (operatorType == TokenType.AMPERSAND_AMPERSAND) { 1236 } else if (operatorType == TokenType.AMPERSAND_AMPERSAND) {
1067 return _dartObjectComputer.logicalAnd(node, leftResult, rightResult); 1237 return _dartObjectComputer.logicalAnd(node, leftResult, rightResult);
1068 } else if (operatorType == TokenType.BANG_EQ) { 1238 } else if (operatorType == TokenType.BANG_EQ) {
1069 return _dartObjectComputer.notEqual(node, leftResult, rightResult); 1239 return _dartObjectComputer.notEqual(node, leftResult, rightResult);
1070 } else if (operatorType == TokenType.BAR) { 1240 } else if (operatorType == TokenType.BAR) {
1071 return _dartObjectComputer.bitOr(node, leftResult, rightResult); 1241 return _dartObjectComputer.bitOr(node, leftResult, rightResult);
1072 } else if (operatorType == TokenType.BAR_BAR) { 1242 } else if (operatorType == TokenType.BAR_BAR) {
1073 return _dartObjectComputer.logicalOr(node, leftResult, rightResult); 1243 return _dartObjectComputer.logicalOr(node, leftResult, rightResult);
1074 } else if (operatorType == TokenType.CARET) { 1244 } else if (operatorType == TokenType.CARET) {
1075 return _dartObjectComputer.bitXor(node, leftResult, rightResult); 1245 return _dartObjectComputer.bitXor(node, leftResult, rightResult);
1076 } else if (operatorType == TokenType.EQ_EQ) { 1246 } else if (operatorType == TokenType.EQ_EQ) {
1077 return _dartObjectComputer.equalEqual(node, leftResult, rightResult); 1247 return _dartObjectComputer.equalEqual(node, leftResult, rightResult);
1078 } else if (operatorType == TokenType.GT) { 1248 } else if (operatorType == TokenType.GT) {
1079 return _dartObjectComputer.greaterThan(node, leftResult, rightResult); 1249 return _dartObjectComputer.greaterThan(node, leftResult, rightResult);
1080 } else if (operatorType == TokenType.GT_EQ) { 1250 } else if (operatorType == TokenType.GT_EQ) {
1081 return _dartObjectComputer.greaterThanOrEqual(node, leftResult, rightRes ult); 1251 return _dartObjectComputer.greaterThanOrEqual(
1252 node,
1253 leftResult,
1254 rightResult);
1082 } else if (operatorType == TokenType.GT_GT) { 1255 } else if (operatorType == TokenType.GT_GT) {
1083 return _dartObjectComputer.shiftRight(node, leftResult, rightResult); 1256 return _dartObjectComputer.shiftRight(node, leftResult, rightResult);
1084 } else if (operatorType == TokenType.LT) { 1257 } else if (operatorType == TokenType.LT) {
1085 return _dartObjectComputer.lessThan(node, leftResult, rightResult); 1258 return _dartObjectComputer.lessThan(node, leftResult, rightResult);
1086 } else if (operatorType == TokenType.LT_EQ) { 1259 } else if (operatorType == TokenType.LT_EQ) {
1087 return _dartObjectComputer.lessThanOrEqual(node, leftResult, rightResult ); 1260 return _dartObjectComputer.lessThanOrEqual(
1261 node,
1262 leftResult,
1263 rightResult);
1088 } else if (operatorType == TokenType.LT_LT) { 1264 } else if (operatorType == TokenType.LT_LT) {
1089 return _dartObjectComputer.shiftLeft(node, leftResult, rightResult); 1265 return _dartObjectComputer.shiftLeft(node, leftResult, rightResult);
1090 } else if (operatorType == TokenType.MINUS) { 1266 } else if (operatorType == TokenType.MINUS) {
1091 return _dartObjectComputer.minus(node, leftResult, rightResult); 1267 return _dartObjectComputer.minus(node, leftResult, rightResult);
1092 } else if (operatorType == TokenType.PERCENT) { 1268 } else if (operatorType == TokenType.PERCENT) {
1093 return _dartObjectComputer.remainder(node, leftResult, rightResult); 1269 return _dartObjectComputer.remainder(node, leftResult, rightResult);
1094 } else if (operatorType == TokenType.PLUS) { 1270 } else if (operatorType == TokenType.PLUS) {
1095 return _dartObjectComputer.add(node, leftResult, rightResult); 1271 return _dartObjectComputer.add(node, leftResult, rightResult);
1096 } else if (operatorType == TokenType.STAR) { 1272 } else if (operatorType == TokenType.STAR) {
1097 return _dartObjectComputer.times(node, leftResult, rightResult); 1273 return _dartObjectComputer.times(node, leftResult, rightResult);
1098 } else if (operatorType == TokenType.SLASH) { 1274 } else if (operatorType == TokenType.SLASH) {
1099 return _dartObjectComputer.divide(node, leftResult, rightResult); 1275 return _dartObjectComputer.divide(node, leftResult, rightResult);
1100 } else if (operatorType == TokenType.TILDE_SLASH) { 1276 } else if (operatorType == TokenType.TILDE_SLASH) {
1101 return _dartObjectComputer.integerDivide(node, leftResult, rightResult); 1277 return _dartObjectComputer.integerDivide(node, leftResult, rightResult);
1102 } else { 1278 } else {
1103 // TODO(brianwilkerson) Figure out which error to report. 1279 // TODO(brianwilkerson) Figure out which error to report.
1104 _error(node, null); 1280 _error(node, null);
1105 return null; 1281 return null;
1106 } 1282 }
1107 break; 1283 break;
1108 } 1284 }
1109 } 1285 }
1110 1286
1111 @override 1287 @override
1112 DartObjectImpl visitBooleanLiteral(BooleanLiteral node) => new DartObjectImpl( _typeProvider.boolType, BoolState.from(node.value)); 1288 DartObjectImpl visitBooleanLiteral(BooleanLiteral node) =>
1289 new DartObjectImpl(_typeProvider.boolType, BoolState.from(node.value));
1113 1290
1114 @override 1291 @override
1115 DartObjectImpl visitConditionalExpression(ConditionalExpression node) { 1292 DartObjectImpl visitConditionalExpression(ConditionalExpression node) {
1116 Expression condition = node.condition; 1293 Expression condition = node.condition;
1117 DartObjectImpl conditionResult = condition.accept(this); 1294 DartObjectImpl conditionResult = condition.accept(this);
1118 DartObjectImpl thenResult = node.thenExpression.accept(this); 1295 DartObjectImpl thenResult = node.thenExpression.accept(this);
1119 DartObjectImpl elseResult = node.elseExpression.accept(this); 1296 DartObjectImpl elseResult = node.elseExpression.accept(this);
1120 if (conditionResult == null) { 1297 if (conditionResult == null) {
1121 return conditionResult; 1298 return conditionResult;
1122 } else if (!conditionResult.isBool) { 1299 } else if (!conditionResult.isBool) {
1123 _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_EVAL_TYPE_BOO L, condition); 1300 _errorReporter.reportErrorForNode(
1301 CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL,
1302 condition);
1124 return null; 1303 return null;
1125 } else if (thenResult == null) { 1304 } else if (thenResult == null) {
1126 return thenResult; 1305 return thenResult;
1127 } else if (elseResult == null) { 1306 } else if (elseResult == null) {
1128 return elseResult; 1307 return elseResult;
1129 } 1308 }
1130 conditionResult = _dartObjectComputer.applyBooleanConversion(condition, cond itionResult); 1309 conditionResult =
1310 _dartObjectComputer.applyBooleanConversion(condition, conditionResult);
1131 if (conditionResult == null) { 1311 if (conditionResult == null) {
1132 return conditionResult; 1312 return conditionResult;
1133 } 1313 }
1134 if (conditionResult.isTrue) { 1314 if (conditionResult.isTrue) {
1135 return thenResult; 1315 return thenResult;
1136 } else if (conditionResult.isFalse) { 1316 } else if (conditionResult.isFalse) {
1137 return elseResult; 1317 return elseResult;
1138 } 1318 }
1139 ParameterizedType thenType = thenResult.type; 1319 ParameterizedType thenType = thenResult.type;
1140 ParameterizedType elseType = elseResult.type; 1320 ParameterizedType elseType = elseResult.type;
1141 return _validWithUnknownValue(thenType.getLeastUpperBound(elseType) as Inter faceType); 1321 return _validWithUnknownValue(
1322 thenType.getLeastUpperBound(elseType) as InterfaceType);
1142 } 1323 }
1143 1324
1144 @override 1325 @override
1145 DartObjectImpl visitDoubleLiteral(DoubleLiteral node) => new DartObjectImpl(_t ypeProvider.doubleType, new DoubleState(node.value)); 1326 DartObjectImpl visitDoubleLiteral(DoubleLiteral node) =>
1327 new DartObjectImpl(_typeProvider.doubleType, new DoubleState(node.value));
1146 1328
1147 @override 1329 @override
1148 DartObjectImpl visitInstanceCreationExpression(InstanceCreationExpression node ) { 1330 DartObjectImpl
1331 visitInstanceCreationExpression(InstanceCreationExpression node) {
1149 if (!node.isConst) { 1332 if (!node.isConst) {
1150 // TODO(brianwilkerson) Figure out which error to report. 1333 // TODO(brianwilkerson) Figure out which error to report.
1151 _error(node, null); 1334 _error(node, null);
1152 return null; 1335 return null;
1153 } 1336 }
1154 beforeGetEvaluationResult(node); 1337 beforeGetEvaluationResult(node);
1155 EvaluationResultImpl result = node.evaluationResult; 1338 EvaluationResultImpl result = node.evaluationResult;
1156 if (result != null) { 1339 if (result != null) {
1157 return result.value; 1340 return result.value;
1158 } 1341 }
1159 // TODO(brianwilkerson) Figure out which error to report. 1342 // TODO(brianwilkerson) Figure out which error to report.
1160 _error(node, null); 1343 _error(node, null);
1161 return null; 1344 return null;
1162 } 1345 }
1163 1346
1164 @override 1347 @override
1165 DartObjectImpl visitIntegerLiteral(IntegerLiteral node) => new DartObjectImpl( _typeProvider.intType, new IntState(node.value)); 1348 DartObjectImpl visitIntegerLiteral(IntegerLiteral node) =>
1349 new DartObjectImpl(_typeProvider.intType, new IntState(node.value));
1166 1350
1167 @override 1351 @override
1168 DartObjectImpl visitInterpolationExpression(InterpolationExpression node) { 1352 DartObjectImpl visitInterpolationExpression(InterpolationExpression node) {
1169 DartObjectImpl result = node.expression.accept(this); 1353 DartObjectImpl result = node.expression.accept(this);
1170 if (result != null && !result.isBoolNumStringOrNull) { 1354 if (result != null && !result.isBoolNumStringOrNull) {
1171 _error(node, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING); 1355 _error(node, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING);
1172 return null; 1356 return null;
1173 } 1357 }
1174 return _dartObjectComputer.performToString(node, result); 1358 return _dartObjectComputer.performToString(node, result);
1175 } 1359 }
1176 1360
1177 @override 1361 @override
1178 DartObjectImpl visitInterpolationString(InterpolationString node) => new DartO bjectImpl(_typeProvider.stringType, new StringState(node.value)); 1362 DartObjectImpl visitInterpolationString(InterpolationString node) =>
1363 new DartObjectImpl(_typeProvider.stringType, new StringState(node.value));
1179 1364
1180 @override 1365 @override
1181 DartObjectImpl visitListLiteral(ListLiteral node) { 1366 DartObjectImpl visitListLiteral(ListLiteral node) {
1182 if (node.constKeyword == null) { 1367 if (node.constKeyword == null) {
1183 _errorReporter.reportErrorForNode(CompileTimeErrorCode.MISSING_CONST_IN_LI ST_LITERAL, node); 1368 _errorReporter.reportErrorForNode(
1369 CompileTimeErrorCode.MISSING_CONST_IN_LIST_LITERAL,
1370 node);
1184 return null; 1371 return null;
1185 } 1372 }
1186 bool errorOccurred = false; 1373 bool errorOccurred = false;
1187 List<DartObjectImpl> elements = new List<DartObjectImpl>(); 1374 List<DartObjectImpl> elements = new List<DartObjectImpl>();
1188 for (Expression element in node.elements) { 1375 for (Expression element in node.elements) {
1189 DartObjectImpl elementResult = element.accept(this); 1376 DartObjectImpl elementResult = element.accept(this);
1190 if (elementResult == null) { 1377 if (elementResult == null) {
1191 errorOccurred = true; 1378 errorOccurred = true;
1192 } else { 1379 } else {
1193 elements.add(elementResult); 1380 elements.add(elementResult);
1194 } 1381 }
1195 } 1382 }
1196 if (errorOccurred) { 1383 if (errorOccurred) {
1197 return null; 1384 return null;
1198 } 1385 }
1199 DartType elementType = _typeProvider.dynamicType; 1386 DartType elementType = _typeProvider.dynamicType;
1200 if (node.typeArguments != null && node.typeArguments.arguments.length == 1) { 1387 if (node.typeArguments != null &&
1388 node.typeArguments.arguments.length == 1) {
1201 DartType type = node.typeArguments.arguments[0].type; 1389 DartType type = node.typeArguments.arguments[0].type;
1202 if (type != null) { 1390 if (type != null) {
1203 elementType = type; 1391 elementType = type;
1204 } 1392 }
1205 } 1393 }
1206 InterfaceType listType = _typeProvider.listType.substitute4([elementType]); 1394 InterfaceType listType = _typeProvider.listType.substitute4([elementType]);
1207 return new DartObjectImpl(listType, new ListState(elements)); 1395 return new DartObjectImpl(listType, new ListState(elements));
1208 } 1396 }
1209 1397
1210 @override 1398 @override
1211 DartObjectImpl visitMapLiteral(MapLiteral node) { 1399 DartObjectImpl visitMapLiteral(MapLiteral node) {
1212 if (node.constKeyword == null) { 1400 if (node.constKeyword == null) {
1213 _errorReporter.reportErrorForNode(CompileTimeErrorCode.MISSING_CONST_IN_MA P_LITERAL, node); 1401 _errorReporter.reportErrorForNode(
1402 CompileTimeErrorCode.MISSING_CONST_IN_MAP_LITERAL,
1403 node);
1214 return null; 1404 return null;
1215 } 1405 }
1216 bool errorOccurred = false; 1406 bool errorOccurred = false;
1217 HashMap<DartObjectImpl, DartObjectImpl> map = new HashMap<DartObjectImpl, Da rtObjectImpl>(); 1407 HashMap<DartObjectImpl, DartObjectImpl> map =
1408 new HashMap<DartObjectImpl, DartObjectImpl>();
1218 for (MapLiteralEntry entry in node.entries) { 1409 for (MapLiteralEntry entry in node.entries) {
1219 DartObjectImpl keyResult = entry.key.accept(this); 1410 DartObjectImpl keyResult = entry.key.accept(this);
1220 DartObjectImpl valueResult = entry.value.accept(this); 1411 DartObjectImpl valueResult = entry.value.accept(this);
1221 if (keyResult == null || valueResult == null) { 1412 if (keyResult == null || valueResult == null) {
1222 errorOccurred = true; 1413 errorOccurred = true;
1223 } else { 1414 } else {
1224 map[keyResult] = valueResult; 1415 map[keyResult] = valueResult;
1225 } 1416 }
1226 } 1417 }
1227 if (errorOccurred) { 1418 if (errorOccurred) {
1228 return null; 1419 return null;
1229 } 1420 }
1230 DartType keyType = _typeProvider.dynamicType; 1421 DartType keyType = _typeProvider.dynamicType;
1231 DartType valueType = _typeProvider.dynamicType; 1422 DartType valueType = _typeProvider.dynamicType;
1232 if (node.typeArguments != null && node.typeArguments.arguments.length == 2) { 1423 if (node.typeArguments != null &&
1424 node.typeArguments.arguments.length == 2) {
1233 DartType keyTypeCandidate = node.typeArguments.arguments[0].type; 1425 DartType keyTypeCandidate = node.typeArguments.arguments[0].type;
1234 if (keyTypeCandidate != null) { 1426 if (keyTypeCandidate != null) {
1235 keyType = keyTypeCandidate; 1427 keyType = keyTypeCandidate;
1236 } 1428 }
1237 DartType valueTypeCandidate = node.typeArguments.arguments[1].type; 1429 DartType valueTypeCandidate = node.typeArguments.arguments[1].type;
1238 if (valueTypeCandidate != null) { 1430 if (valueTypeCandidate != null) {
1239 valueType = valueTypeCandidate; 1431 valueType = valueTypeCandidate;
1240 } 1432 }
1241 } 1433 }
1242 InterfaceType mapType = _typeProvider.mapType.substitute4( 1434 InterfaceType mapType =
1243 [keyType, valueType]); 1435 _typeProvider.mapType.substitute4([keyType, valueType]);
1244 return new DartObjectImpl(mapType, new MapState(map)); 1436 return new DartObjectImpl(mapType, new MapState(map));
1245 } 1437 }
1246 1438
1247 @override 1439 @override
1248 DartObjectImpl visitMethodInvocation(MethodInvocation node) { 1440 DartObjectImpl visitMethodInvocation(MethodInvocation node) {
1249 Element element = node.methodName.staticElement; 1441 Element element = node.methodName.staticElement;
1250 if (element is FunctionElement) { 1442 if (element is FunctionElement) {
1251 FunctionElement function = element; 1443 FunctionElement function = element;
1252 if (function.name == "identical") { 1444 if (function.name == "identical") {
1253 NodeList<Expression> arguments = node.argumentList.arguments; 1445 NodeList<Expression> arguments = node.argumentList.arguments;
1254 if (arguments.length == 2) { 1446 if (arguments.length == 2) {
1255 Element enclosingElement = function.enclosingElement; 1447 Element enclosingElement = function.enclosingElement;
1256 if (enclosingElement is CompilationUnitElement) { 1448 if (enclosingElement is CompilationUnitElement) {
1257 LibraryElement library = enclosingElement.library; 1449 LibraryElement library = enclosingElement.library;
1258 if (library.isDartCore) { 1450 if (library.isDartCore) {
1259 DartObjectImpl leftArgument = arguments[0].accept(this); 1451 DartObjectImpl leftArgument = arguments[0].accept(this);
1260 DartObjectImpl rightArgument = arguments[1].accept(this); 1452 DartObjectImpl rightArgument = arguments[1].accept(this);
1261 return _dartObjectComputer.isIdentical(node, leftArgument, 1453 return _dartObjectComputer.isIdentical(
1454 node,
1455 leftArgument,
1262 rightArgument); 1456 rightArgument);
1263 } 1457 }
1264 } 1458 }
1265 } 1459 }
1266 } 1460 }
1267 } 1461 }
1268 // TODO(brianwilkerson) Figure out which error to report. 1462 // TODO(brianwilkerson) Figure out which error to report.
1269 _error(node, null); 1463 _error(node, null);
1270 return null; 1464 return null;
1271 } 1465 }
1272 1466
1273 @override 1467 @override
1274 DartObjectImpl visitNamedExpression(NamedExpression node) => node.expression.a ccept(this); 1468 DartObjectImpl visitNamedExpression(NamedExpression node) =>
1469 node.expression.accept(this);
1275 1470
1276 @override 1471 @override
1277 DartObjectImpl visitNode(AstNode node) { 1472 DartObjectImpl visitNode(AstNode node) {
1278 // TODO(brianwilkerson) Figure out which error to report. 1473 // TODO(brianwilkerson) Figure out which error to report.
1279 _error(node, null); 1474 _error(node, null);
1280 return null; 1475 return null;
1281 } 1476 }
1282 1477
1283 @override 1478 @override
1284 DartObjectImpl visitNullLiteral(NullLiteral node) => null2; 1479 DartObjectImpl visitNullLiteral(NullLiteral node) => null2;
1285 1480
1286 @override 1481 @override
1287 DartObjectImpl visitParenthesizedExpression(ParenthesizedExpression node) => n ode.expression.accept(this); 1482 DartObjectImpl visitParenthesizedExpression(ParenthesizedExpression node) =>
1483 node.expression.accept(this);
1288 1484
1289 @override 1485 @override
1290 DartObjectImpl visitPrefixedIdentifier(PrefixedIdentifier node) { 1486 DartObjectImpl visitPrefixedIdentifier(PrefixedIdentifier node) {
1291 // TODO(brianwilkerson) Uncomment the lines below when the new constant supp ort can be added. 1487 // TODO(brianwilkerson) Uncomment the lines below when the new constant
1488 // support can be added.
1292 // Element element = node.getStaticElement(); 1489 // Element element = node.getStaticElement();
1293 // if (isStringLength(element)) { 1490 // if (isStringLength(element)) {
1294 // EvaluationResultImpl target = node.getPrefix().accept(this); 1491 // EvaluationResultImpl target = node.getPrefix().accept(this);
1295 // return target.stringLength(typeProvider, node); 1492 // return target.stringLength(typeProvider, node);
1296 // } 1493 // }
1297 SimpleIdentifier prefixNode = node.prefix; 1494 SimpleIdentifier prefixNode = node.prefix;
1298 Element prefixElement = prefixNode.staticElement; 1495 Element prefixElement = prefixNode.staticElement;
1299 if (prefixElement is! PrefixElement) { 1496 if (prefixElement is! PrefixElement) {
1300 DartObjectImpl prefixResult = prefixNode.accept(this); 1497 DartObjectImpl prefixResult = prefixNode.accept(this);
1301 if (prefixResult == null) { 1498 if (prefixResult == null) {
(...skipping 24 matching lines...) Expand all
1326 _error(node, null); 1523 _error(node, null);
1327 return null; 1524 return null;
1328 } 1525 }
1329 break; 1526 break;
1330 } 1527 }
1331 } 1528 }
1332 1529
1333 @override 1530 @override
1334 DartObjectImpl visitPropertyAccess(PropertyAccess node) { 1531 DartObjectImpl visitPropertyAccess(PropertyAccess node) {
1335 Element element = node.propertyName.staticElement; 1532 Element element = node.propertyName.staticElement;
1336 // TODO(brianwilkerson) Uncomment the lines below when the new constant supp ort can be added. 1533 // TODO(brianwilkerson) Uncomment the lines below when the new constant
1534 // support can be added.
1337 // if (isStringLength(element)) { 1535 // if (isStringLength(element)) {
1338 // EvaluationResultImpl target = node.getRealTarget().accept(this); 1536 // EvaluationResultImpl target = node.getRealTarget().accept(this);
1339 // return target.stringLength(typeProvider, node); 1537 // return target.stringLength(typeProvider, node);
1340 // } 1538 // }
1341 return _getConstantValue(node, element); 1539 return _getConstantValue(node, element);
1342 } 1540 }
1343 1541
1344 @override 1542 @override
1345 DartObjectImpl visitSimpleIdentifier(SimpleIdentifier node) { 1543 DartObjectImpl visitSimpleIdentifier(SimpleIdentifier node) {
1346 if (_lexicalEnvironment != null && _lexicalEnvironment.containsKey(node.name )) { 1544 if (_lexicalEnvironment != null &&
1545 _lexicalEnvironment.containsKey(node.name)) {
1347 return _lexicalEnvironment[node.name]; 1546 return _lexicalEnvironment[node.name];
1348 } 1547 }
1349 return _getConstantValue(node, node.staticElement); 1548 return _getConstantValue(node, node.staticElement);
1350 } 1549 }
1351 1550
1352 @override 1551 @override
1353 DartObjectImpl visitSimpleStringLiteral(SimpleStringLiteral node) => new DartO bjectImpl(_typeProvider.stringType, new StringState(node.value)); 1552 DartObjectImpl visitSimpleStringLiteral(SimpleStringLiteral node) =>
1553 new DartObjectImpl(_typeProvider.stringType, new StringState(node.value));
1354 1554
1355 @override 1555 @override
1356 DartObjectImpl visitStringInterpolation(StringInterpolation node) { 1556 DartObjectImpl visitStringInterpolation(StringInterpolation node) {
1357 DartObjectImpl result = null; 1557 DartObjectImpl result = null;
1358 bool first = true; 1558 bool first = true;
1359 for (InterpolationElement element in node.elements) { 1559 for (InterpolationElement element in node.elements) {
1360 if (first) { 1560 if (first) {
1361 result = element.accept(this); 1561 result = element.accept(this);
1362 first = false; 1562 first = false;
1363 } else { 1563 } else {
1364 result = _dartObjectComputer.concatenate(node, result, element.accept(th is)); 1564 result =
1565 _dartObjectComputer.concatenate(node, result, element.accept(this));
1365 } 1566 }
1366 } 1567 }
1367 return result; 1568 return result;
1368 } 1569 }
1369 1570
1370 @override 1571 @override
1371 DartObjectImpl visitSymbolLiteral(SymbolLiteral node) { 1572 DartObjectImpl visitSymbolLiteral(SymbolLiteral node) {
1372 StringBuffer buffer = new StringBuffer(); 1573 StringBuffer buffer = new StringBuffer();
1373 List<Token> components = node.components; 1574 List<Token> components = node.components;
1374 for (int i = 0; i < components.length; i++) { 1575 for (int i = 0; i < components.length; i++) {
1375 if (i > 0) { 1576 if (i > 0) {
1376 buffer.writeCharCode(0x2E); 1577 buffer.writeCharCode(0x2E);
1377 } 1578 }
1378 buffer.write(components[i].lexeme); 1579 buffer.write(components[i].lexeme);
1379 } 1580 }
1380 return new DartObjectImpl(_typeProvider.symbolType, new SymbolState(buffer.t oString())); 1581 return new DartObjectImpl(
1582 _typeProvider.symbolType,
1583 new SymbolState(buffer.toString()));
1381 } 1584 }
1382 1585
1383 /** 1586 /**
1384 * This method is called just before retrieving an evaluation result from an A ST node. Unit tests
1385 * will override it to introduce additional error checking.
1386 */
1387 void beforeGetEvaluationResult(AstNode node) {
1388 }
1389
1390 /**
1391 * Return an object representing the value 'null'.
1392 *
1393 * @return an object representing the value 'null'
1394 */
1395 DartObjectImpl get null2 {
1396 if (_nullObject == null) {
1397 _nullObject = new DartObjectImpl(_typeProvider.nullType, NullState.NULL_ST ATE);
1398 }
1399 return _nullObject;
1400 }
1401
1402 DartObjectImpl _validWithUnknownValue(InterfaceType type) {
1403 if (type.element.library.isDartCore) {
1404 String typeName = type.name;
1405 if (typeName == "bool") {
1406 return new DartObjectImpl(type, BoolState.UNKNOWN_VALUE);
1407 } else if (typeName == "double") {
1408 return new DartObjectImpl(type, DoubleState.UNKNOWN_VALUE);
1409 } else if (typeName == "int") {
1410 return new DartObjectImpl(type, IntState.UNKNOWN_VALUE);
1411 } else if (typeName == "String") {
1412 return new DartObjectImpl(type, StringState.UNKNOWN_VALUE);
1413 }
1414 }
1415 return new DartObjectImpl(type, GenericState.UNKNOWN_VALUE);
1416 }
1417
1418 /**
1419 * Return the value of the given expression, or a representation of 'null' if the expression
1420 * cannot be evaluated.
1421 *
1422 * @param expression the expression whose value is to be returned
1423 * @return the value of the given expression
1424 */
1425 DartObjectImpl _valueOf(Expression expression) {
1426 DartObjectImpl expressionValue = expression.accept(this);
1427 if (expressionValue != null) {
1428 return expressionValue;
1429 }
1430 return null2;
1431 }
1432
1433 /**
1434 * Create an error associated with the given node. 1587 * Create an error associated with the given node.
1435 * 1588 *
1436 * @param node the AST node associated with the error 1589 * @param node the AST node associated with the error
1437 * @param code the error code indicating the nature of the error 1590 * @param code the error code indicating the nature of the error
1438 */ 1591 */
1439 void _error(AstNode node, ErrorCode code) { 1592 void _error(AstNode node, ErrorCode code) {
1440 _errorReporter.reportErrorForNode(code == null ? CompileTimeErrorCode.INVALI D_CONSTANT : code, node); 1593 _errorReporter.reportErrorForNode(
1594 code == null ? CompileTimeErrorCode.INVALID_CONSTANT : code,
1595 node);
1441 } 1596 }
1442 1597
1443 /** 1598 /**
1444 * Return the constant value of the static constant represented by the given e lement. 1599 * Return the constant value of the static constant represented by the given e lement.
1445 * 1600 *
1446 * @param node the node to be used if an error needs to be reported 1601 * @param node the node to be used if an error needs to be reported
1447 * @param element the element whose value is to be returned 1602 * @param element the element whose value is to be returned
1448 * @return the constant value of the static constant 1603 * @return the constant value of the static constant
1449 */ 1604 */
1450 DartObjectImpl _getConstantValue(AstNode node, Element element) { 1605 DartObjectImpl _getConstantValue(AstNode node, Element element) {
(...skipping 16 matching lines...) Expand all
1467 } 1622 }
1468 return new DartObjectImpl(functionType, new FunctionState(function)); 1623 return new DartObjectImpl(functionType, new FunctionState(function));
1469 } 1624 }
1470 } else if (element is ClassElement || element is FunctionTypeAliasElement) { 1625 } else if (element is ClassElement || element is FunctionTypeAliasElement) {
1471 return new DartObjectImpl(_typeProvider.typeType, new TypeState(element)); 1626 return new DartObjectImpl(_typeProvider.typeType, new TypeState(element));
1472 } 1627 }
1473 // TODO(brianwilkerson) Figure out which error to report. 1628 // TODO(brianwilkerson) Figure out which error to report.
1474 _error(node, null); 1629 _error(node, null);
1475 return null; 1630 return null;
1476 } 1631 }
1632
1633 DartObjectImpl _validWithUnknownValue(InterfaceType type) {
1634 if (type.element.library.isDartCore) {
1635 String typeName = type.name;
1636 if (typeName == "bool") {
1637 return new DartObjectImpl(type, BoolState.UNKNOWN_VALUE);
1638 } else if (typeName == "double") {
1639 return new DartObjectImpl(type, DoubleState.UNKNOWN_VALUE);
1640 } else if (typeName == "int") {
1641 return new DartObjectImpl(type, IntState.UNKNOWN_VALUE);
1642 } else if (typeName == "String") {
1643 return new DartObjectImpl(type, StringState.UNKNOWN_VALUE);
1644 }
1645 }
1646 return new DartObjectImpl(type, GenericState.UNKNOWN_VALUE);
1647 }
1648
1649 /**
1650 * Return the value of the given expression, or a representation of 'null' if the expression
1651 * cannot be evaluated.
1652 *
1653 * @param expression the expression whose value is to be returned
1654 * @return the value of the given expression
1655 */
1656 DartObjectImpl _valueOf(Expression expression) {
1657 DartObjectImpl expressionValue = expression.accept(this);
1658 if (expressionValue != null) {
1659 return expressionValue;
1660 }
1661 return null2;
1662 }
1477 } 1663 }
1478 1664
1479 /** 1665 /**
1480 * The interface `DartObject` defines the behavior of objects that represent the state of a 1666 * The interface `DartObject` defines the behavior of objects that represent the state of a
1481 * Dart object. 1667 * Dart object.
1482 */ 1668 */
1483 abstract class DartObject { 1669 abstract class DartObject {
1484 /** 1670 /**
1485 * Return the boolean value of this object, or `null` if either the value of t his object is 1671 * Return the boolean value of this object, or `null` if either the value of t his object is
1486 * not known or this object is not of type 'bool'. 1672 * not known or this object is not of type 'bool'.
1487 * 1673 *
1488 * @return the boolean value of this object 1674 * @return the boolean value of this object
1489 */ 1675 */
1490 bool get boolValue; 1676 bool get boolValue;
1491 1677
1492 /** 1678 /**
1493 * Return the floating point value of this object, or `null` if either the val ue of this 1679 * Return the floating point value of this object, or `null` if either the val ue of this
1494 * object is not known or this object is not of type 'double'. 1680 * object is not known or this object is not of type 'double'.
1495 * 1681 *
1496 * @return the floating point value of this object 1682 * @return the floating point value of this object
1497 */ 1683 */
1498 double get doubleValue; 1684 double get doubleValue;
1499 1685
1500 /** 1686 /**
1687 * Return `true` if this object's value can be represented exactly.
1688 *
1689 * @return `true` if this object's value can be represented exactly
1690 */
1691 bool get hasExactValue;
1692
1693 /**
1501 * Return the integer value of this object, or `null` if either the value of t his object is 1694 * Return the integer value of this object, or `null` if either the value of t his object is
1502 * not known or this object is not of type 'int'. 1695 * not known or this object is not of type 'int'.
1503 * 1696 *
1504 * @return the integer value of this object 1697 * @return the integer value of this object
1505 */ 1698 */
1506 int get intValue; 1699 int get intValue;
1507 1700
1508 /** 1701 /**
1702 * Return `true` if this object represents the value 'false'.
1703 *
1704 * @return `true` if this object represents the value 'false'
1705 */
1706 bool get isFalse;
1707
1708 /**
1709 * Return `true` if this object represents the value 'null'.
1710 *
1711 * @return `true` if this object represents the value 'null'
1712 */
1713 bool get isNull;
1714
1715 /**
1716 * Return `true` if this object represents the value 'true'.
1717 *
1718 * @return `true` if this object represents the value 'true'
1719 */
1720 bool get isTrue;
1721
1722 /**
1509 * Return the string value of this object, or `null` if either the value of th is object is 1723 * Return the string value of this object, or `null` if either the value of th is object is
1510 * not known or this object is not of type 'String'. 1724 * not known or this object is not of type 'String'.
1511 * 1725 *
1512 * @return the string value of this object 1726 * @return the string value of this object
1513 */ 1727 */
1514 String get stringValue; 1728 String get stringValue;
1515 1729
1516 /** 1730 /**
1517 * Return the run-time type of this object. 1731 * Return the run-time type of this object.
1518 * 1732 *
1519 * @return the run-time type of this object 1733 * @return the run-time type of this object
1520 */ 1734 */
1521 ParameterizedType get type; 1735 ParameterizedType get type;
1522 1736
1523 /** 1737 /**
1524 * 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 e ither the
1525 * value cannot be represented exactly or if the value is `null`. Clients shou ld use 1739 * value cannot be represented exactly or if the value is `null`. Clients shou ld use
1526 * [hasExactValue] to distinguish between these two cases. 1740 * [hasExactValue] to distinguish between these two cases.
1527 * 1741 *
1528 * @return this object's value 1742 * @return this object's value
1529 */ 1743 */
1530 Object get value; 1744 Object get value;
1531
1532 /**
1533 * Return `true` if this object's value can be represented exactly.
1534 *
1535 * @return `true` if this object's value can be represented exactly
1536 */
1537 bool get hasExactValue;
1538
1539 /**
1540 * Return `true` if this object represents the value 'false'.
1541 *
1542 * @return `true` if this object represents the value 'false'
1543 */
1544 bool get isFalse;
1545
1546 /**
1547 * Return `true` if this object represents the value 'null'.
1548 *
1549 * @return `true` if this object represents the value 'null'
1550 */
1551 bool get isNull;
1552
1553 /**
1554 * Return `true` if this object represents the value 'true'.
1555 *
1556 * @return `true` if this object represents the value 'true'
1557 */
1558 bool get isTrue;
1559 } 1745 }
1560 1746
1561 /** 1747 /**
1562 * Instances of the class `DartObjectComputer` contain methods for manipulating instances of a 1748 * Instances of the class `DartObjectComputer` contain methods for manipulating instances of a
1563 * Dart class and for collecting errors during evaluation. 1749 * Dart class and for collecting errors during evaluation.
1564 */ 1750 */
1565 class DartObjectComputer { 1751 class DartObjectComputer {
1566 /** 1752 /**
1567 * The error reporter that we are using to collect errors. 1753 * The error reporter that we are using to collect errors.
1568 */ 1754 */
1569 final ErrorReporter _errorReporter; 1755 final ErrorReporter _errorReporter;
1570 1756
1571 /** 1757 /**
1572 * The type provider. Used to create objects of the appropriate types, and to identify when an 1758 * The type provider. Used to create objects of the appropriate types, and to identify when an
1573 * object is of a built-in type. 1759 * object is of a built-in type.
1574 */ 1760 */
1575 final TypeProvider _typeProvider; 1761 final TypeProvider _typeProvider;
1576 1762
1577 DartObjectComputer(this._errorReporter, this._typeProvider); 1763 DartObjectComputer(this._errorReporter, this._typeProvider);
1578 1764
1579 DartObjectImpl add(BinaryExpression node, DartObjectImpl leftOperand, DartObje ctImpl rightOperand) { 1765 DartObjectImpl add(BinaryExpression node, DartObjectImpl leftOperand,
1766 DartObjectImpl rightOperand) {
1580 if (leftOperand != null && rightOperand != null) { 1767 if (leftOperand != null && rightOperand != null) {
1581 try { 1768 try {
1582 return leftOperand.add(_typeProvider, rightOperand); 1769 return leftOperand.add(_typeProvider, rightOperand);
1583 } on EvaluationException catch (exception) { 1770 } on EvaluationException catch (exception) {
1584 _errorReporter.reportErrorForNode(exception.errorCode, node); 1771 _errorReporter.reportErrorForNode(exception.errorCode, node);
1585 return null; 1772 return null;
1586 } 1773 }
1587 } 1774 }
1588 return null; 1775 return null;
1589 } 1776 }
1590 1777
1591 /** 1778 /**
1592 * Return the result of applying boolean conversion to this result. 1779 * Return the result of applying boolean conversion to this result.
1593 * 1780 *
1594 * @param node the node against which errors should be reported 1781 * @param node the node against which errors should be reported
1595 * @return the result of applying boolean conversion to the given value 1782 * @return the result of applying boolean conversion to the given value
1596 */ 1783 */
1597 DartObjectImpl applyBooleanConversion(AstNode node, DartObjectImpl evaluationR esult) { 1784 DartObjectImpl applyBooleanConversion(AstNode node,
1785 DartObjectImpl evaluationResult) {
1598 if (evaluationResult != null) { 1786 if (evaluationResult != null) {
1599 try { 1787 try {
1600 return evaluationResult.convertToBool(_typeProvider); 1788 return evaluationResult.convertToBool(_typeProvider);
1601 } on EvaluationException catch (exception) { 1789 } on EvaluationException catch (exception) {
1602 _errorReporter.reportErrorForNode(exception.errorCode, node); 1790 _errorReporter.reportErrorForNode(exception.errorCode, node);
1603 } 1791 }
1604 } 1792 }
1605 return null; 1793 return null;
1606 } 1794 }
1607 1795
1608 DartObjectImpl bitAnd(BinaryExpression node, DartObjectImpl leftOperand, DartO bjectImpl rightOperand) { 1796 DartObjectImpl bitAnd(BinaryExpression node, DartObjectImpl leftOperand,
1797 DartObjectImpl rightOperand) {
1609 if (leftOperand != null && rightOperand != null) { 1798 if (leftOperand != null && rightOperand != null) {
1610 try { 1799 try {
1611 return leftOperand.bitAnd(_typeProvider, rightOperand); 1800 return leftOperand.bitAnd(_typeProvider, rightOperand);
1612 } on EvaluationException catch (exception) { 1801 } on EvaluationException catch (exception) {
1613 _errorReporter.reportErrorForNode(exception.errorCode, node); 1802 _errorReporter.reportErrorForNode(exception.errorCode, node);
1614 } 1803 }
1615 } 1804 }
1616 return null; 1805 return null;
1617 } 1806 }
1618 1807
1619 DartObjectImpl bitNot(Expression node, DartObjectImpl evaluationResult) { 1808 DartObjectImpl bitNot(Expression node, DartObjectImpl evaluationResult) {
1620 if (evaluationResult != null) { 1809 if (evaluationResult != null) {
1621 try { 1810 try {
1622 return evaluationResult.bitNot(_typeProvider); 1811 return evaluationResult.bitNot(_typeProvider);
1623 } on EvaluationException catch (exception) { 1812 } on EvaluationException catch (exception) {
1624 _errorReporter.reportErrorForNode(exception.errorCode, node); 1813 _errorReporter.reportErrorForNode(exception.errorCode, node);
1625 } 1814 }
1626 } 1815 }
1627 return null; 1816 return null;
1628 } 1817 }
1629 1818
1630 DartObjectImpl bitOr(BinaryExpression node, DartObjectImpl leftOperand, DartOb jectImpl rightOperand) { 1819 DartObjectImpl bitOr(BinaryExpression node, DartObjectImpl leftOperand,
1820 DartObjectImpl rightOperand) {
1631 if (leftOperand != null && rightOperand != null) { 1821 if (leftOperand != null && rightOperand != null) {
1632 try { 1822 try {
1633 return leftOperand.bitOr(_typeProvider, rightOperand); 1823 return leftOperand.bitOr(_typeProvider, rightOperand);
1634 } on EvaluationException catch (exception) { 1824 } on EvaluationException catch (exception) {
1635 _errorReporter.reportErrorForNode(exception.errorCode, node); 1825 _errorReporter.reportErrorForNode(exception.errorCode, node);
1636 } 1826 }
1637 } 1827 }
1638 return null; 1828 return null;
1639 } 1829 }
1640 1830
1641 DartObjectImpl bitXor(BinaryExpression node, DartObjectImpl leftOperand, DartO bjectImpl rightOperand) { 1831 DartObjectImpl bitXor(BinaryExpression node, DartObjectImpl leftOperand,
1832 DartObjectImpl rightOperand) {
1642 if (leftOperand != null && rightOperand != null) { 1833 if (leftOperand != null && rightOperand != null) {
1643 try { 1834 try {
1644 return leftOperand.bitXor(_typeProvider, rightOperand); 1835 return leftOperand.bitXor(_typeProvider, rightOperand);
1645 } on EvaluationException catch (exception) { 1836 } on EvaluationException catch (exception) {
1646 _errorReporter.reportErrorForNode(exception.errorCode, node); 1837 _errorReporter.reportErrorForNode(exception.errorCode, node);
1647 } 1838 }
1648 } 1839 }
1649 return null; 1840 return null;
1650 } 1841 }
1651 1842
1652 DartObjectImpl concatenate(Expression node, DartObjectImpl leftOperand, DartOb jectImpl rightOperand) { 1843 DartObjectImpl concatenate(Expression node, DartObjectImpl leftOperand,
1844 DartObjectImpl rightOperand) {
1653 if (leftOperand != null && rightOperand != null) { 1845 if (leftOperand != null && rightOperand != null) {
1654 try { 1846 try {
1655 return leftOperand.concatenate(_typeProvider, rightOperand); 1847 return leftOperand.concatenate(_typeProvider, rightOperand);
1656 } on EvaluationException catch (exception) { 1848 } on EvaluationException catch (exception) {
1657 _errorReporter.reportErrorForNode(exception.errorCode, node); 1849 _errorReporter.reportErrorForNode(exception.errorCode, node);
1658 } 1850 }
1659 } 1851 }
1660 return null; 1852 return null;
1661 } 1853 }
1662 1854
1663 DartObjectImpl divide(BinaryExpression node, DartObjectImpl leftOperand, DartO bjectImpl rightOperand) { 1855 DartObjectImpl divide(BinaryExpression node, DartObjectImpl leftOperand,
1856 DartObjectImpl rightOperand) {
1664 if (leftOperand != null && rightOperand != null) { 1857 if (leftOperand != null && rightOperand != null) {
1665 try { 1858 try {
1666 return leftOperand.divide(_typeProvider, rightOperand); 1859 return leftOperand.divide(_typeProvider, rightOperand);
1667 } on EvaluationException catch (exception) { 1860 } on EvaluationException catch (exception) {
1668 _errorReporter.reportErrorForNode(exception.errorCode, node); 1861 _errorReporter.reportErrorForNode(exception.errorCode, node);
1669 } 1862 }
1670 } 1863 }
1671 return null; 1864 return null;
1672 } 1865 }
1673 1866
1674 DartObjectImpl equalEqual(Expression node, DartObjectImpl leftOperand, DartObj ectImpl rightOperand) { 1867 DartObjectImpl equalEqual(Expression node, DartObjectImpl leftOperand,
1868 DartObjectImpl rightOperand) {
1675 if (leftOperand != null && rightOperand != null) { 1869 if (leftOperand != null && rightOperand != null) {
1676 try { 1870 try {
1677 return leftOperand.equalEqual(_typeProvider, rightOperand); 1871 return leftOperand.equalEqual(_typeProvider, rightOperand);
1678 } on EvaluationException catch (exception) { 1872 } on EvaluationException catch (exception) {
1679 _errorReporter.reportErrorForNode(exception.errorCode, node); 1873 _errorReporter.reportErrorForNode(exception.errorCode, node);
1680 } 1874 }
1681 } 1875 }
1682 return null; 1876 return null;
1683 } 1877 }
1684 1878
1685 DartObjectImpl greaterThan(BinaryExpression node, DartObjectImpl leftOperand, DartObjectImpl rightOperand) { 1879 DartObjectImpl greaterThan(BinaryExpression node, DartObjectImpl leftOperand,
1880 DartObjectImpl rightOperand) {
1686 if (leftOperand != null && rightOperand != null) { 1881 if (leftOperand != null && rightOperand != null) {
1687 try { 1882 try {
1688 return leftOperand.greaterThan(_typeProvider, rightOperand); 1883 return leftOperand.greaterThan(_typeProvider, rightOperand);
1689 } on EvaluationException catch (exception) { 1884 } on EvaluationException catch (exception) {
1690 _errorReporter.reportErrorForNode(exception.errorCode, node); 1885 _errorReporter.reportErrorForNode(exception.errorCode, node);
1691 } 1886 }
1692 } 1887 }
1693 return null; 1888 return null;
1694 } 1889 }
1695 1890
1696 DartObjectImpl greaterThanOrEqual(BinaryExpression node, DartObjectImpl leftOp erand, DartObjectImpl rightOperand) { 1891 DartObjectImpl greaterThanOrEqual(BinaryExpression node,
1892 DartObjectImpl leftOperand, DartObjectImpl rightOperand) {
1697 if (leftOperand != null && rightOperand != null) { 1893 if (leftOperand != null && rightOperand != null) {
1698 try { 1894 try {
1699 return leftOperand.greaterThanOrEqual(_typeProvider, rightOperand); 1895 return leftOperand.greaterThanOrEqual(_typeProvider, rightOperand);
1700 } on EvaluationException catch (exception) { 1896 } on EvaluationException catch (exception) {
1701 _errorReporter.reportErrorForNode(exception.errorCode, node); 1897 _errorReporter.reportErrorForNode(exception.errorCode, node);
1702 } 1898 }
1703 } 1899 }
1704 return null; 1900 return null;
1705 } 1901 }
1706 1902
1707 DartObjectImpl integerDivide(BinaryExpression node, DartObjectImpl leftOperand , DartObjectImpl rightOperand) { 1903 DartObjectImpl integerDivide(BinaryExpression node,
1904 DartObjectImpl leftOperand, DartObjectImpl rightOperand) {
1708 if (leftOperand != null && rightOperand != null) { 1905 if (leftOperand != null && rightOperand != null) {
1709 try { 1906 try {
1710 return leftOperand.integerDivide(_typeProvider, rightOperand); 1907 return leftOperand.integerDivide(_typeProvider, rightOperand);
1711 } on EvaluationException catch (exception) { 1908 } on EvaluationException catch (exception) {
1712 _errorReporter.reportErrorForNode(exception.errorCode, node); 1909 _errorReporter.reportErrorForNode(exception.errorCode, node);
1713 } 1910 }
1714 } 1911 }
1715 return null; 1912 return null;
1716 } 1913 }
1717 1914
1718 DartObjectImpl isIdentical(Expression node, DartObjectImpl leftOperand, 1915 DartObjectImpl isIdentical(Expression node, DartObjectImpl leftOperand,
1719 DartObjectImpl rightOperand) { 1916 DartObjectImpl rightOperand) {
1720 if (leftOperand != null && rightOperand != null) { 1917 if (leftOperand != null && rightOperand != null) {
1721 try { 1918 try {
1722 return leftOperand.isIdentical(_typeProvider, rightOperand); 1919 return leftOperand.isIdentical(_typeProvider, rightOperand);
1723 } on EvaluationException catch (exception) { 1920 } on EvaluationException catch (exception) {
1724 _errorReporter.reportErrorForNode(exception.errorCode, node); 1921 _errorReporter.reportErrorForNode(exception.errorCode, node);
1725 } 1922 }
1726 } 1923 }
1727 return null; 1924 return null;
1728 } 1925 }
1729 1926
1730 DartObjectImpl lessThan(BinaryExpression node, DartObjectImpl leftOperand, Dar tObjectImpl rightOperand) { 1927 DartObjectImpl lessThan(BinaryExpression node, DartObjectImpl leftOperand,
1928 DartObjectImpl rightOperand) {
1731 if (leftOperand != null && rightOperand != null) { 1929 if (leftOperand != null && rightOperand != null) {
1732 try { 1930 try {
1733 return leftOperand.lessThan(_typeProvider, rightOperand); 1931 return leftOperand.lessThan(_typeProvider, rightOperand);
1734 } on EvaluationException catch (exception) { 1932 } on EvaluationException catch (exception) {
1735 _errorReporter.reportErrorForNode(exception.errorCode, node); 1933 _errorReporter.reportErrorForNode(exception.errorCode, node);
1736 } 1934 }
1737 } 1935 }
1738 return null; 1936 return null;
1739 } 1937 }
1740 1938
1741 DartObjectImpl lessThanOrEqual(BinaryExpression node, DartObjectImpl leftOpera nd, DartObjectImpl rightOperand) { 1939 DartObjectImpl lessThanOrEqual(BinaryExpression node,
1940 DartObjectImpl leftOperand, DartObjectImpl rightOperand) {
1742 if (leftOperand != null && rightOperand != null) { 1941 if (leftOperand != null && rightOperand != null) {
1743 try { 1942 try {
1744 return leftOperand.lessThanOrEqual(_typeProvider, rightOperand); 1943 return leftOperand.lessThanOrEqual(_typeProvider, rightOperand);
1745 } on EvaluationException catch (exception) { 1944 } on EvaluationException catch (exception) {
1746 _errorReporter.reportErrorForNode(exception.errorCode, node); 1945 _errorReporter.reportErrorForNode(exception.errorCode, node);
1747 } 1946 }
1748 } 1947 }
1749 return null; 1948 return null;
1750 } 1949 }
1751 1950
1752 DartObjectImpl logicalAnd(BinaryExpression node, DartObjectImpl leftOperand, D artObjectImpl rightOperand) { 1951 DartObjectImpl logicalAnd(BinaryExpression node, DartObjectImpl leftOperand,
1952 DartObjectImpl rightOperand) {
1753 if (leftOperand != null && rightOperand != null) { 1953 if (leftOperand != null && rightOperand != null) {
1754 try { 1954 try {
1755 return leftOperand.logicalAnd(_typeProvider, rightOperand); 1955 return leftOperand.logicalAnd(_typeProvider, rightOperand);
1756 } on EvaluationException catch (exception) { 1956 } on EvaluationException catch (exception) {
1757 _errorReporter.reportErrorForNode(exception.errorCode, node); 1957 _errorReporter.reportErrorForNode(exception.errorCode, node);
1758 } 1958 }
1759 } 1959 }
1760 return null; 1960 return null;
1761 } 1961 }
1762 1962
1763 DartObjectImpl logicalNot(Expression node, DartObjectImpl evaluationResult) { 1963 DartObjectImpl logicalNot(Expression node, DartObjectImpl evaluationResult) {
1764 if (evaluationResult != null) { 1964 if (evaluationResult != null) {
1765 try { 1965 try {
1766 return evaluationResult.logicalNot(_typeProvider); 1966 return evaluationResult.logicalNot(_typeProvider);
1767 } on EvaluationException catch (exception) { 1967 } on EvaluationException catch (exception) {
1768 _errorReporter.reportErrorForNode(exception.errorCode, node); 1968 _errorReporter.reportErrorForNode(exception.errorCode, node);
1769 } 1969 }
1770 } 1970 }
1771 return null; 1971 return null;
1772 } 1972 }
1773 1973
1774 DartObjectImpl logicalOr(BinaryExpression node, DartObjectImpl leftOperand, Da rtObjectImpl rightOperand) { 1974 DartObjectImpl logicalOr(BinaryExpression node, DartObjectImpl leftOperand,
1975 DartObjectImpl rightOperand) {
1775 if (leftOperand != null && rightOperand != null) { 1976 if (leftOperand != null && rightOperand != null) {
1776 try { 1977 try {
1777 return leftOperand.logicalOr(_typeProvider, rightOperand); 1978 return leftOperand.logicalOr(_typeProvider, rightOperand);
1778 } on EvaluationException catch (exception) { 1979 } on EvaluationException catch (exception) {
1779 _errorReporter.reportErrorForNode(exception.errorCode, node); 1980 _errorReporter.reportErrorForNode(exception.errorCode, node);
1780 } 1981 }
1781 } 1982 }
1782 return null; 1983 return null;
1783 } 1984 }
1784 1985
1785 DartObjectImpl minus(BinaryExpression node, DartObjectImpl leftOperand, DartOb jectImpl rightOperand) { 1986 DartObjectImpl minus(BinaryExpression node, DartObjectImpl leftOperand,
1987 DartObjectImpl rightOperand) {
1786 if (leftOperand != null && rightOperand != null) { 1988 if (leftOperand != null && rightOperand != null) {
1787 try { 1989 try {
1788 return leftOperand.minus(_typeProvider, rightOperand); 1990 return leftOperand.minus(_typeProvider, rightOperand);
1789 } on EvaluationException catch (exception) { 1991 } on EvaluationException catch (exception) {
1790 _errorReporter.reportErrorForNode(exception.errorCode, node); 1992 _errorReporter.reportErrorForNode(exception.errorCode, node);
1791 } 1993 }
1792 } 1994 }
1793 return null; 1995 return null;
1794 } 1996 }
1795 1997
1796 DartObjectImpl negated(Expression node, DartObjectImpl evaluationResult) { 1998 DartObjectImpl negated(Expression node, DartObjectImpl evaluationResult) {
1797 if (evaluationResult != null) { 1999 if (evaluationResult != null) {
1798 try { 2000 try {
1799 return evaluationResult.negated(_typeProvider); 2001 return evaluationResult.negated(_typeProvider);
1800 } on EvaluationException catch (exception) { 2002 } on EvaluationException catch (exception) {
1801 _errorReporter.reportErrorForNode(exception.errorCode, node); 2003 _errorReporter.reportErrorForNode(exception.errorCode, node);
1802 } 2004 }
1803 } 2005 }
1804 return null; 2006 return null;
1805 } 2007 }
1806 2008
1807 DartObjectImpl notEqual(BinaryExpression node, DartObjectImpl leftOperand, Dar tObjectImpl rightOperand) { 2009 DartObjectImpl notEqual(BinaryExpression node, DartObjectImpl leftOperand,
2010 DartObjectImpl rightOperand) {
1808 if (leftOperand != null && rightOperand != null) { 2011 if (leftOperand != null && rightOperand != null) {
1809 try { 2012 try {
1810 return leftOperand.notEqual(_typeProvider, rightOperand); 2013 return leftOperand.notEqual(_typeProvider, rightOperand);
1811 } on EvaluationException catch (exception) { 2014 } on EvaluationException catch (exception) {
1812 _errorReporter.reportErrorForNode(exception.errorCode, node); 2015 _errorReporter.reportErrorForNode(exception.errorCode, node);
1813 } 2016 }
1814 } 2017 }
1815 return null; 2018 return null;
1816 } 2019 }
1817 2020
1818 DartObjectImpl performToString(AstNode node, DartObjectImpl evaluationResult) { 2021 DartObjectImpl performToString(AstNode node,
2022 DartObjectImpl evaluationResult) {
1819 if (evaluationResult != null) { 2023 if (evaluationResult != null) {
1820 try { 2024 try {
1821 return evaluationResult.performToString(_typeProvider); 2025 return evaluationResult.performToString(_typeProvider);
1822 } on EvaluationException catch (exception) { 2026 } on EvaluationException catch (exception) {
1823 _errorReporter.reportErrorForNode(exception.errorCode, node); 2027 _errorReporter.reportErrorForNode(exception.errorCode, node);
1824 } 2028 }
1825 } 2029 }
1826 return null; 2030 return null;
1827 } 2031 }
1828 2032
1829 DartObjectImpl remainder(BinaryExpression node, DartObjectImpl leftOperand, Da rtObjectImpl rightOperand) { 2033 DartObjectImpl remainder(BinaryExpression node, DartObjectImpl leftOperand,
2034 DartObjectImpl rightOperand) {
1830 if (leftOperand != null && rightOperand != null) { 2035 if (leftOperand != null && rightOperand != null) {
1831 try { 2036 try {
1832 return leftOperand.remainder(_typeProvider, rightOperand); 2037 return leftOperand.remainder(_typeProvider, rightOperand);
1833 } on EvaluationException catch (exception) { 2038 } on EvaluationException catch (exception) {
1834 _errorReporter.reportErrorForNode(exception.errorCode, node); 2039 _errorReporter.reportErrorForNode(exception.errorCode, node);
1835 } 2040 }
1836 } 2041 }
1837 return null; 2042 return null;
1838 } 2043 }
1839 2044
1840 DartObjectImpl shiftLeft(BinaryExpression node, DartObjectImpl leftOperand, Da rtObjectImpl rightOperand) { 2045 DartObjectImpl shiftLeft(BinaryExpression node, DartObjectImpl leftOperand,
2046 DartObjectImpl rightOperand) {
1841 if (leftOperand != null && rightOperand != null) { 2047 if (leftOperand != null && rightOperand != null) {
1842 try { 2048 try {
1843 return leftOperand.shiftLeft(_typeProvider, rightOperand); 2049 return leftOperand.shiftLeft(_typeProvider, rightOperand);
1844 } on EvaluationException catch (exception) { 2050 } on EvaluationException catch (exception) {
1845 _errorReporter.reportErrorForNode(exception.errorCode, node); 2051 _errorReporter.reportErrorForNode(exception.errorCode, node);
1846 } 2052 }
1847 } 2053 }
1848 return null; 2054 return null;
1849 } 2055 }
1850 2056
1851 DartObjectImpl shiftRight(BinaryExpression node, DartObjectImpl leftOperand, D artObjectImpl rightOperand) { 2057 DartObjectImpl shiftRight(BinaryExpression node, DartObjectImpl leftOperand,
2058 DartObjectImpl rightOperand) {
1852 if (leftOperand != null && rightOperand != null) { 2059 if (leftOperand != null && rightOperand != null) {
1853 try { 2060 try {
1854 return leftOperand.shiftRight(_typeProvider, rightOperand); 2061 return leftOperand.shiftRight(_typeProvider, rightOperand);
1855 } on EvaluationException catch (exception) { 2062 } on EvaluationException catch (exception) {
1856 _errorReporter.reportErrorForNode(exception.errorCode, node); 2063 _errorReporter.reportErrorForNode(exception.errorCode, node);
1857 } 2064 }
1858 } 2065 }
1859 return null; 2066 return null;
1860 } 2067 }
1861 2068
1862 /** 2069 /**
1863 * Return the result of invoking the 'length' getter on this result. 2070 * Return the result of invoking the 'length' getter on this result.
1864 * 2071 *
1865 * @param node the node against which errors should be reported 2072 * @param node the node against which errors should be reported
1866 * @return the result of invoking the 'length' getter on this result 2073 * @return the result of invoking the 'length' getter on this result
1867 */ 2074 */
1868 EvaluationResultImpl stringLength(Expression node, EvaluationResultImpl evalua tionResult) { 2075 EvaluationResultImpl stringLength(Expression node,
2076 EvaluationResultImpl evaluationResult) {
1869 if (evaluationResult.value != null) { 2077 if (evaluationResult.value != null) {
1870 try { 2078 try {
1871 return new EvaluationResultImpl.con1(evaluationResult.value.stringLength (_typeProvider)); 2079 return new EvaluationResultImpl.con1(
2080 evaluationResult.value.stringLength(_typeProvider));
1872 } on EvaluationException catch (exception) { 2081 } on EvaluationException catch (exception) {
1873 _errorReporter.reportErrorForNode(exception.errorCode, node); 2082 _errorReporter.reportErrorForNode(exception.errorCode, node);
1874 } 2083 }
1875 } 2084 }
1876 return new EvaluationResultImpl.con1(null); 2085 return new EvaluationResultImpl.con1(null);
1877 } 2086 }
1878 2087
1879 DartObjectImpl times(BinaryExpression node, DartObjectImpl leftOperand, DartOb jectImpl rightOperand) { 2088 DartObjectImpl times(BinaryExpression node, DartObjectImpl leftOperand,
2089 DartObjectImpl rightOperand) {
1880 if (leftOperand != null && rightOperand != null) { 2090 if (leftOperand != null && rightOperand != null) {
1881 try { 2091 try {
1882 return leftOperand.times(_typeProvider, rightOperand); 2092 return leftOperand.times(_typeProvider, rightOperand);
1883 } on EvaluationException catch (exception) { 2093 } on EvaluationException catch (exception) {
1884 _errorReporter.reportErrorForNode(exception.errorCode, node); 2094 _errorReporter.reportErrorForNode(exception.errorCode, node);
1885 } 2095 }
1886 } 2096 }
1887 return null; 2097 return null;
1888 } 2098 }
1889 } 2099 }
1890 2100
1891 /** 2101 /**
1892 * Instances of the class `DartObjectImpl` represent an instance of a Dart class . 2102 * Instances of the class `DartObjectImpl` represent an instance of a Dart class .
1893 */ 2103 */
1894 class DartObjectImpl implements DartObject { 2104 class DartObjectImpl implements DartObject {
1895 /** 2105 /**
2106 * An empty list of objects.
2107 */
2108 static const List<DartObjectImpl> EMPTY_LIST = const <DartObjectImpl>[];
2109
2110 /**
1896 * The run-time type of this object. 2111 * The run-time type of this object.
1897 */ 2112 */
1898 final ParameterizedType type; 2113 final ParameterizedType type;
1899 2114
1900 /** 2115 /**
1901 * The state of the object. 2116 * The state of the object.
1902 */ 2117 */
1903 final InstanceState _state; 2118 final InstanceState _state;
1904 2119
1905 /** 2120 /**
1906 * An empty list of objects.
1907 */
1908 static const List<DartObjectImpl> EMPTY_LIST = const <DartObjectImpl>[];
1909
1910 /**
1911 * Initialize a newly created object to have the given type and state. 2121 * Initialize a newly created object to have the given type and state.
1912 * 2122 *
1913 * @param type the run-time type of this object 2123 * @param type the run-time type of this object
1914 * @param state the state of the object 2124 * @param state the state of the object
1915 */ 2125 */
1916 DartObjectImpl(this.type, this._state); 2126 DartObjectImpl(this.type, this._state);
1917 2127
2128 @override
2129 bool get boolValue {
2130 if (_state is BoolState) {
2131 return (_state as BoolState).value;
2132 }
2133 return null;
2134 }
2135
2136 @override
2137 double get doubleValue {
2138 if (_state is DoubleState) {
2139 return (_state as DoubleState).value;
2140 }
2141 return null;
2142 }
2143
2144 HashMap<String, DartObjectImpl> get fields => _state.fields;
2145
2146 @override
2147 bool get hasExactValue => _state.hasExactValue;
2148
2149 @override
2150 int get hashCode =>
2151 ObjectUtilities.combineHashCodes(type.hashCode, _state.hashCode);
2152
2153 @override
2154 int get intValue {
2155 if (_state is IntState) {
2156 return (_state as IntState).value;
2157 }
2158 return null;
2159 }
2160
2161 /**
2162 * Return `true` if this object represents an object whose type is 'bool'.
2163 *
2164 * @return `true` if this object represents a boolean value
2165 */
2166 bool get isBool => _state.isBool;
2167
2168 /**
2169 * Return `true` if this object represents an object whose type is either 'boo l', 'num',
2170 * 'String', or 'Null'.
2171 *
2172 * @return `true` if this object represents either a boolean, numeric, string or null value
2173 */
2174 bool get isBoolNumStringOrNull => _state.isBoolNumStringOrNull;
2175
2176 @override
2177 bool get isFalse =>
2178 _state is BoolState && identical((_state as BoolState).value, false);
2179
2180 @override
2181 bool get isNull => _state is NullState;
2182
2183 @override
2184 bool get isTrue =>
2185 _state is BoolState && identical((_state as BoolState).value, true);
2186
2187 /**
2188 * Return true if this object represents an unknown value.
2189 */
2190 bool get isUnknown => _state.isUnknown;
2191
2192 /**
2193 * Return `true` if this object represents an instance of a user-defined class .
2194 *
2195 * @return `true` if this object represents an instance of a user-defined clas s
2196 */
2197 bool get isUserDefinedObject => _state is GenericState;
2198
2199 @override
2200 String get stringValue {
2201 if (_state is StringState) {
2202 return (_state as StringState).value;
2203 }
2204 return null;
2205 }
2206
2207 @override
2208 Object get value => _state.value;
2209
2210 @override
2211 bool operator ==(Object object) {
2212 if (object is! DartObjectImpl) {
2213 return false;
2214 }
2215 DartObjectImpl dartObject = object as DartObjectImpl;
2216 return type == dartObject.type && _state == dartObject._state;
2217 }
2218
1918 /** 2219 /**
1919 * Return the result of invoking the '+' operator on this object with the give n argument. 2220 * Return the result of invoking the '+' operator on this object with the give n argument.
1920 * 2221 *
1921 * @param typeProvider the type provider used to find known types 2222 * @param typeProvider the type provider used to find known types
1922 * @param rightOperand the right-hand operand of the operation 2223 * @param rightOperand the right-hand operand of the operation
1923 * @return the result of invoking the '+' operator on this object with the giv en argument 2224 * @return the result of invoking the '+' operator on this object with the giv en argument
1924 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 2225 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
1925 */ 2226 */
1926 DartObjectImpl add(TypeProvider typeProvider, DartObjectImpl rightOperand) { 2227 DartObjectImpl add(TypeProvider typeProvider, DartObjectImpl rightOperand) {
1927 InstanceState result = _state.add(rightOperand._state); 2228 InstanceState result = _state.add(rightOperand._state);
(...skipping 11 matching lines...) Expand all
1939 } 2240 }
1940 2241
1941 /** 2242 /**
1942 * Return the result of invoking the '&' operator on this object with the give n argument. 2243 * Return the result of invoking the '&' operator on this object with the give n argument.
1943 * 2244 *
1944 * @param typeProvider the type provider used to find known types 2245 * @param typeProvider the type provider used to find known types
1945 * @param rightOperand the right-hand operand of the operation 2246 * @param rightOperand the right-hand operand of the operation
1946 * @return the result of invoking the '&' operator on this object with the giv en argument 2247 * @return the result of invoking the '&' operator on this object with the giv en argument
1947 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 2248 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
1948 */ 2249 */
1949 DartObjectImpl bitAnd(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.intType, _state.bitAnd(rightOperand._state)); 2250 DartObjectImpl bitAnd(TypeProvider typeProvider,
2251 DartObjectImpl rightOperand) =>
2252 new DartObjectImpl(typeProvider.intType, _state.bitAnd(rightOperand._state ));
1950 2253
1951 /** 2254 /**
1952 * Return the result of invoking the '~' operator on this object. 2255 * Return the result of invoking the '~' operator on this object.
1953 * 2256 *
1954 * @param typeProvider the type provider used to find known types 2257 * @param typeProvider the type provider used to find known types
1955 * @return the result of invoking the '~' operator on this object 2258 * @return the result of invoking the '~' operator on this object
1956 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 2259 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
1957 */ 2260 */
1958 DartObjectImpl bitNot(TypeProvider typeProvider) => new DartObjectImpl(typePro vider.intType, _state.bitNot()); 2261 DartObjectImpl bitNot(TypeProvider typeProvider) =>
2262 new DartObjectImpl(typeProvider.intType, _state.bitNot());
1959 2263
1960 /** 2264 /**
1961 * 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 give n argument.
1962 * 2266 *
1963 * @param typeProvider the type provider used to find known types 2267 * @param typeProvider the type provider used to find known types
1964 * @param rightOperand the right-hand operand of the operation 2268 * @param rightOperand the right-hand operand of the operation
1965 * @return the result of invoking the '|' operator on this object with the giv en argument 2269 * @return the result of invoking the '|' operator on this object with the giv en argument
1966 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 2270 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
1967 */ 2271 */
1968 DartObjectImpl bitOr(TypeProvider typeProvider, DartObjectImpl rightOperand) = > new DartObjectImpl(typeProvider.intType, _state.bitOr(rightOperand._state)); 2272 DartObjectImpl bitOr(TypeProvider typeProvider,
2273 DartObjectImpl rightOperand) =>
2274 new DartObjectImpl(typeProvider.intType, _state.bitOr(rightOperand._state) );
1969 2275
1970 /** 2276 /**
1971 * Return the result of invoking the '^' operator on this object with the give n argument. 2277 * Return the result of invoking the '^' operator on this object with the give n argument.
1972 * 2278 *
1973 * @param typeProvider the type provider used to find known types 2279 * @param typeProvider the type provider used to find known types
1974 * @param rightOperand the right-hand operand of the operation 2280 * @param rightOperand the right-hand operand of the operation
1975 * @return the result of invoking the '^' operator on this object with the giv en argument 2281 * @return the result of invoking the '^' operator on this object with the giv en argument
1976 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 2282 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
1977 */ 2283 */
1978 DartObjectImpl bitXor(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.intType, _state.bitXor(rightOperand._state)); 2284 DartObjectImpl bitXor(TypeProvider typeProvider,
2285 DartObjectImpl rightOperand) =>
2286 new DartObjectImpl(typeProvider.intType, _state.bitXor(rightOperand._state ));
1979 2287
1980 /** 2288 /**
1981 * Return the result of invoking the ' ' operator on this object with the give n argument. 2289 * Return the result of invoking the ' ' operator on this object with the give n argument.
1982 * 2290 *
1983 * @param typeProvider the type provider used to find known types 2291 * @param typeProvider the type provider used to find known types
1984 * @param rightOperand the right-hand operand of the operation 2292 * @param rightOperand the right-hand operand of the operation
1985 * @return the result of invoking the ' ' operator on this object with the giv en argument 2293 * @return the result of invoking the ' ' operator on this object with the giv en argument
1986 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 2294 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
1987 */ 2295 */
1988 DartObjectImpl concatenate(TypeProvider typeProvider, DartObjectImpl rightOper and) => new DartObjectImpl(typeProvider.stringType, _state.concatenate(rightOper and._state)); 2296 DartObjectImpl concatenate(TypeProvider typeProvider,
2297 DartObjectImpl rightOperand) =>
2298 new DartObjectImpl(
2299 typeProvider.stringType,
2300 _state.concatenate(rightOperand._state));
1989 2301
1990 /** 2302 /**
1991 * Return the result of applying boolean conversion to this object. 2303 * Return the result of applying boolean conversion to this object.
1992 * 2304 *
1993 * @param typeProvider the type provider used to find known types 2305 * @param typeProvider the type provider used to find known types
1994 * @return the result of applying boolean conversion to this object 2306 * @return the result of applying boolean conversion to this object
1995 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 2307 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
1996 */ 2308 */
1997 DartObjectImpl convertToBool(TypeProvider typeProvider) { 2309 DartObjectImpl convertToBool(TypeProvider typeProvider) {
1998 InterfaceType boolType = typeProvider.boolType; 2310 InterfaceType boolType = typeProvider.boolType;
1999 if (identical(type, boolType)) { 2311 if (identical(type, boolType)) {
2000 return this; 2312 return this;
2001 } 2313 }
2002 return new DartObjectImpl(boolType, _state.convertToBool()); 2314 return new DartObjectImpl(boolType, _state.convertToBool());
2003 } 2315 }
2004 2316
2005 /** 2317 /**
2006 * Return the result of invoking the '/' operator on this object with the give n argument. 2318 * Return the result of invoking the '/' operator on this object with the give n argument.
2007 * 2319 *
2008 * @param typeProvider the type provider used to find known types 2320 * @param typeProvider the type provider used to find known types
2009 * @param rightOperand the right-hand operand of the operation 2321 * @param rightOperand the right-hand operand of the operation
2010 * @return the result of invoking the '/' operator on this object with the giv en argument 2322 * @return the result of invoking the '/' operator on this object with the giv en argument
2011 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 2323 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2012 */ 2324 */
2013 DartObjectImpl divide(TypeProvider typeProvider, DartObjectImpl rightOperand) { 2325 DartObjectImpl divide(TypeProvider typeProvider,
2326 DartObjectImpl rightOperand) {
2014 InstanceState result = _state.divide(rightOperand._state); 2327 InstanceState result = _state.divide(rightOperand._state);
2015 if (result is IntState) { 2328 if (result is IntState) {
2016 return new DartObjectImpl(typeProvider.intType, result); 2329 return new DartObjectImpl(typeProvider.intType, result);
2017 } else if (result is DoubleState) { 2330 } else if (result is DoubleState) {
2018 return new DartObjectImpl(typeProvider.doubleType, result); 2331 return new DartObjectImpl(typeProvider.doubleType, result);
2019 } else if (result is NumState) { 2332 } else if (result is NumState) {
2020 return new DartObjectImpl(typeProvider.numType, result); 2333 return new DartObjectImpl(typeProvider.numType, result);
2021 } 2334 }
2022 // We should never get here. 2335 // We should never get here.
2023 throw new IllegalStateException("divide returned a ${result.runtimeType}"); 2336 throw new IllegalStateException("divide returned a ${result.runtimeType}");
2024 } 2337 }
2025 2338
2026 /** 2339 /**
2027 * Return the result of invoking the '==' operator on this object with the giv en argument. 2340 * Return the result of invoking the '==' operator on this object with the giv en argument.
2028 * 2341 *
2029 * @param typeProvider the type provider used to find known types 2342 * @param typeProvider the type provider used to find known types
2030 * @param rightOperand the right-hand operand of the operation 2343 * @param rightOperand the right-hand operand of the operation
2031 * @return the result of invoking the '==' operator on this object with the gi ven argument 2344 * @return the result of invoking the '==' operator on this object with the gi ven argument
2032 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 2345 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2033 */ 2346 */
2034 DartObjectImpl equalEqual(TypeProvider typeProvider, DartObjectImpl rightOpera nd) { 2347 DartObjectImpl equalEqual(TypeProvider typeProvider,
2348 DartObjectImpl rightOperand) {
2035 if (type != rightOperand.type) { 2349 if (type != rightOperand.type) {
2036 String typeName = type.name; 2350 String typeName = type.name;
2037 if (!(typeName == "bool" || typeName == "double" || typeName == "int" || t ypeName == "num" || typeName == "String" || typeName == "Null" || type.isDynamic )) { 2351 if (!(typeName == "bool" ||
2038 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_ NUM_STRING); 2352 typeName == "double" ||
2353 typeName == "int" ||
2354 typeName == "num" ||
2355 typeName == "String" ||
2356 typeName == "Null" ||
2357 type.isDynamic)) {
2358 throw new EvaluationException(
2359 CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING);
2039 } 2360 }
2040 } 2361 }
2041 return new DartObjectImpl(typeProvider.boolType, _state.equalEqual(rightOper and._state)); 2362 return new DartObjectImpl(
2363 typeProvider.boolType,
2364 _state.equalEqual(rightOperand._state));
2042 } 2365 }
2043 2366
2044 @override
2045 bool operator ==(Object object) {
2046 if (object is! DartObjectImpl) {
2047 return false;
2048 }
2049 DartObjectImpl dartObject = object as DartObjectImpl;
2050 return type == dartObject.type && _state == dartObject._state;
2051 }
2052
2053 @override
2054 bool get boolValue {
2055 if (_state is BoolState) {
2056 return (_state as BoolState).value;
2057 }
2058 return null;
2059 }
2060
2061 @override
2062 double get doubleValue {
2063 if (_state is DoubleState) {
2064 return (_state as DoubleState).value;
2065 }
2066 return null;
2067 }
2068
2069 HashMap<String, DartObjectImpl> get fields => _state.fields;
2070
2071 @override
2072 int get intValue {
2073 if (_state is IntState) {
2074 return (_state as IntState).value;
2075 }
2076 return null;
2077 }
2078
2079 @override
2080 String get stringValue {
2081 if (_state is StringState) {
2082 return (_state as StringState).value;
2083 }
2084 return null;
2085 }
2086
2087 @override
2088 Object get value => _state.value;
2089
2090 /** 2367 /**
2091 * Return the result of invoking the '&gt;' operator on this object with the g iven argument. 2368 * Return the result of invoking the '&gt;' operator on this object with the g iven argument.
2092 * 2369 *
2093 * @param typeProvider the type provider used to find known types 2370 * @param typeProvider the type provider used to find known types
2094 * @param rightOperand the right-hand operand of the operation 2371 * @param rightOperand the right-hand operand of the operation
2095 * @return the result of invoking the '&gt;' operator on this object with the given argument 2372 * @return the result of invoking the '&gt;' operator on this object with the given argument
2096 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 2373 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2097 */ 2374 */
2098 DartObjectImpl greaterThan(TypeProvider typeProvider, DartObjectImpl rightOper and) => new DartObjectImpl(typeProvider.boolType, _state.greaterThan(rightOperan d._state)); 2375 DartObjectImpl greaterThan(TypeProvider typeProvider,
2376 DartObjectImpl rightOperand) =>
2377 new DartObjectImpl(
2378 typeProvider.boolType,
2379 _state.greaterThan(rightOperand._state));
2099 2380
2100 /** 2381 /**
2101 * Return the result of invoking the '&gt;=' operator on this object with the given argument. 2382 * Return the result of invoking the '&gt;=' operator on this object with the given argument.
2102 * 2383 *
2103 * @param typeProvider the type provider used to find known types 2384 * @param typeProvider the type provider used to find known types
2104 * @param rightOperand the right-hand operand of the operation 2385 * @param rightOperand the right-hand operand of the operation
2105 * @return the result of invoking the '&gt;=' operator on this object with the given argument 2386 * @return the result of invoking the '&gt;=' operator on this object with the given argument
2106 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 2387 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2107 */ 2388 */
2108 DartObjectImpl greaterThanOrEqual(TypeProvider typeProvider, DartObjectImpl ri ghtOperand) => new DartObjectImpl(typeProvider.boolType, _state.greaterThanOrEqu al(rightOperand._state)); 2389 DartObjectImpl greaterThanOrEqual(TypeProvider typeProvider,
2109 2390 DartObjectImpl rightOperand) =>
2110 @override 2391 new DartObjectImpl(
2111 bool get hasExactValue => _state.hasExactValue; 2392 typeProvider.boolType,
2112 2393 _state.greaterThanOrEqual(rightOperand._state));
2113 @override
2114 int get hashCode => ObjectUtilities.combineHashCodes(type.hashCode, _state.has hCode);
2115 2394
2116 /** 2395 /**
2117 * Return the result of invoking the '~/' operator on this object with the giv en argument. 2396 * Return the result of invoking the '~/' operator on this object with the giv en argument.
2118 * 2397 *
2119 * @param typeProvider the type provider used to find known types 2398 * @param typeProvider the type provider used to find known types
2120 * @param rightOperand the right-hand operand of the operation 2399 * @param rightOperand the right-hand operand of the operation
2121 * @return the result of invoking the '~/' operator on this object with the gi ven argument 2400 * @return the result of invoking the '~/' operator on this object with the gi ven argument
2122 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 2401 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2123 */ 2402 */
2124 DartObjectImpl integerDivide(TypeProvider typeProvider, DartObjectImpl rightOp erand) => new DartObjectImpl(typeProvider.intType, _state.integerDivide(rightOpe rand._state)); 2403 DartObjectImpl integerDivide(TypeProvider typeProvider,
2404 DartObjectImpl rightOperand) =>
2405 new DartObjectImpl(
2406 typeProvider.intType,
2407 _state.integerDivide(rightOperand._state));
2125 2408
2126 /** 2409 /**
2127 * Return the result of invoking the identical function on this object with 2410 * Return the result of invoking the identical function on this object with
2128 * the given argument. 2411 * the given argument.
2129 * 2412 *
2130 * @param typeProvider the type provider used to find known types 2413 * @param typeProvider the type provider used to find known types
2131 * @param rightOperand the right-hand operand of the operation 2414 * @param rightOperand the right-hand operand of the operation
2132 * @return the result of invoking the identical function on this object with 2415 * @return the result of invoking the identical function on this object with
2133 * the given argument 2416 * the given argument
2134 */ 2417 */
2135 DartObjectImpl isIdentical(TypeProvider typeProvider, 2418 DartObjectImpl isIdentical(TypeProvider typeProvider,
2136 DartObjectImpl rightOperand) { 2419 DartObjectImpl rightOperand) {
2137 return new DartObjectImpl(typeProvider.boolType, 2420 return new DartObjectImpl(
2421 typeProvider.boolType,
2138 _state.isIdentical(rightOperand._state)); 2422 _state.isIdentical(rightOperand._state));
2139 } 2423 }
2140 2424
2141 /** 2425 /**
2142 * Return `true` if this object represents an object whose type is 'bool'.
2143 *
2144 * @return `true` if this object represents a boolean value
2145 */
2146 bool get isBool => _state.isBool;
2147
2148 /**
2149 * Return `true` if this object represents an object whose type is either 'boo l', 'num',
2150 * 'String', or 'Null'.
2151 *
2152 * @return `true` if this object represents either a boolean, numeric, string or null value
2153 */
2154 bool get isBoolNumStringOrNull => _state.isBoolNumStringOrNull;
2155
2156 @override
2157 bool get isFalse => _state is BoolState && identical((_state as BoolState).val ue, false);
2158
2159 @override
2160 bool get isNull => _state is NullState;
2161
2162 @override
2163 bool get isTrue => _state is BoolState && identical((_state as BoolState).valu e, true);
2164
2165 /**
2166 * Return true if this object represents an unknown value.
2167 */
2168 bool get isUnknown => _state.isUnknown;
2169
2170 /**
2171 * Return `true` if this object represents an instance of a user-defined class .
2172 *
2173 * @return `true` if this object represents an instance of a user-defined clas s
2174 */
2175 bool get isUserDefinedObject => _state is GenericState;
2176
2177 /**
2178 * Return the result of invoking the '&lt;' operator on this object with the g iven argument. 2426 * Return the result of invoking the '&lt;' operator on this object with the g iven argument.
2179 * 2427 *
2180 * @param typeProvider the type provider used to find known types 2428 * @param typeProvider the type provider used to find known types
2181 * @param rightOperand the right-hand operand of the operation 2429 * @param rightOperand the right-hand operand of the operation
2182 * @return the result of invoking the '&lt;' operator on this object with the given argument 2430 * @return the result of invoking the '&lt;' operator on this object with the given argument
2183 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 2431 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2184 */ 2432 */
2185 DartObjectImpl lessThan(TypeProvider typeProvider, DartObjectImpl rightOperand ) => new DartObjectImpl(typeProvider.boolType, _state.lessThan(rightOperand._sta te)); 2433 DartObjectImpl lessThan(TypeProvider typeProvider,
2434 DartObjectImpl rightOperand) =>
2435 new DartObjectImpl(typeProvider.boolType, _state.lessThan(rightOperand._st ate));
2186 2436
2187 /** 2437 /**
2188 * Return the result of invoking the '&lt;=' operator on this object with the given argument. 2438 * Return the result of invoking the '&lt;=' operator on this object with the given argument.
2189 * 2439 *
2190 * @param typeProvider the type provider used to find known types 2440 * @param typeProvider the type provider used to find known types
2191 * @param rightOperand the right-hand operand of the operation 2441 * @param rightOperand the right-hand operand of the operation
2192 * @return the result of invoking the '&lt;=' operator on this object with the given argument 2442 * @return the result of invoking the '&lt;=' operator on this object with the given argument
2193 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 2443 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2194 */ 2444 */
2195 DartObjectImpl lessThanOrEqual(TypeProvider typeProvider, DartObjectImpl right Operand) => new DartObjectImpl(typeProvider.boolType, _state.lessThanOrEqual(rig htOperand._state)); 2445 DartObjectImpl lessThanOrEqual(TypeProvider typeProvider,
2446 DartObjectImpl rightOperand) =>
2447 new DartObjectImpl(
2448 typeProvider.boolType,
2449 _state.lessThanOrEqual(rightOperand._state));
2196 2450
2197 /** 2451 /**
2198 * Return the result of invoking the '&&' operator on this object with the giv en argument. 2452 * Return the result of invoking the '&&' operator on this object with the giv en argument.
2199 * 2453 *
2200 * @param typeProvider the type provider used to find known types 2454 * @param typeProvider the type provider used to find known types
2201 * @param rightOperand the right-hand operand of the operation 2455 * @param rightOperand the right-hand operand of the operation
2202 * @return the result of invoking the '&&' operator on this object with the gi ven argument 2456 * @return the result of invoking the '&&' operator on this object with the gi ven argument
2203 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 2457 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2204 */ 2458 */
2205 DartObjectImpl logicalAnd(TypeProvider typeProvider, DartObjectImpl rightOpera nd) => new DartObjectImpl(typeProvider.boolType, _state.logicalAnd(rightOperand. _state)); 2459 DartObjectImpl logicalAnd(TypeProvider typeProvider,
2460 DartObjectImpl rightOperand) =>
2461 new DartObjectImpl(
2462 typeProvider.boolType,
2463 _state.logicalAnd(rightOperand._state));
2206 2464
2207 /** 2465 /**
2208 * Return the result of invoking the '!' operator on this object. 2466 * Return the result of invoking the '!' operator on this object.
2209 * 2467 *
2210 * @param typeProvider the type provider used to find known types 2468 * @param typeProvider the type provider used to find known types
2211 * @return the result of invoking the '!' operator on this object 2469 * @return the result of invoking the '!' operator on this object
2212 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 2470 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2213 */ 2471 */
2214 DartObjectImpl logicalNot(TypeProvider typeProvider) => new DartObjectImpl(typ eProvider.boolType, _state.logicalNot()); 2472 DartObjectImpl logicalNot(TypeProvider typeProvider) =>
2473 new DartObjectImpl(typeProvider.boolType, _state.logicalNot());
2215 2474
2216 /** 2475 /**
2217 * Return the result of invoking the '||' operator on this object with the giv en argument. 2476 * Return the result of invoking the '||' operator on this object with the giv en argument.
2218 * 2477 *
2219 * @param typeProvider the type provider used to find known types 2478 * @param typeProvider the type provider used to find known types
2220 * @param rightOperand the right-hand operand of the operation 2479 * @param rightOperand the right-hand operand of the operation
2221 * @return the result of invoking the '||' operator on this object with the gi ven argument 2480 * @return the result of invoking the '||' operator on this object with the gi ven argument
2222 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 2481 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2223 */ 2482 */
2224 DartObjectImpl logicalOr(TypeProvider typeProvider, DartObjectImpl rightOperan d) => new DartObjectImpl(typeProvider.boolType, _state.logicalOr(rightOperand._s tate)); 2483 DartObjectImpl logicalOr(TypeProvider typeProvider,
2484 DartObjectImpl rightOperand) =>
2485 new DartObjectImpl(
2486 typeProvider.boolType,
2487 _state.logicalOr(rightOperand._state));
2225 2488
2226 /** 2489 /**
2227 * Return the result of invoking the '-' operator on this object with the give n argument. 2490 * Return the result of invoking the '-' operator on this object with the give n argument.
2228 * 2491 *
2229 * @param typeProvider the type provider used to find known types 2492 * @param typeProvider the type provider used to find known types
2230 * @param rightOperand the right-hand operand of the operation 2493 * @param rightOperand the right-hand operand of the operation
2231 * @return the result of invoking the '-' operator on this object with the giv en argument 2494 * @return the result of invoking the '-' operator on this object with the giv en argument
2232 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 2495 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2233 */ 2496 */
2234 DartObjectImpl minus(TypeProvider typeProvider, DartObjectImpl rightOperand) { 2497 DartObjectImpl minus(TypeProvider typeProvider, DartObjectImpl rightOperand) {
(...skipping 30 matching lines...) Expand all
2265 } 2528 }
2266 2529
2267 /** 2530 /**
2268 * Return the result of invoking the '!=' operator on this object with the giv en argument. 2531 * Return the result of invoking the '!=' operator on this object with the giv en argument.
2269 * 2532 *
2270 * @param typeProvider the type provider used to find known types 2533 * @param typeProvider the type provider used to find known types
2271 * @param rightOperand the right-hand operand of the operation 2534 * @param rightOperand the right-hand operand of the operation
2272 * @return the result of invoking the '!=' operator on this object with the gi ven argument 2535 * @return the result of invoking the '!=' operator on this object with the gi ven argument
2273 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 2536 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2274 */ 2537 */
2275 DartObjectImpl notEqual(TypeProvider typeProvider, DartObjectImpl rightOperand ) { 2538 DartObjectImpl notEqual(TypeProvider typeProvider,
2539 DartObjectImpl rightOperand) {
2276 if (type != rightOperand.type) { 2540 if (type != rightOperand.type) {
2277 String typeName = type.name; 2541 String typeName = type.name;
2278 if (typeName != "bool" && typeName != "double" && typeName != "int" && typ eName != "num" && typeName != "String") { 2542 if (typeName != "bool" &&
2543 typeName != "double" &&
2544 typeName != "int" &&
2545 typeName != "num" &&
2546 typeName != "String") {
2279 return new DartObjectImpl(typeProvider.boolType, BoolState.TRUE_STATE); 2547 return new DartObjectImpl(typeProvider.boolType, BoolState.TRUE_STATE);
2280 } 2548 }
2281 } 2549 }
2282 return new DartObjectImpl(typeProvider.boolType, _state.equalEqual(rightOper and._state).logicalNot()); 2550 return new DartObjectImpl(
2551 typeProvider.boolType,
2552 _state.equalEqual(rightOperand._state).logicalNot());
2283 } 2553 }
2284 2554
2285 /** 2555 /**
2286 * Return the result of converting this object to a String. 2556 * Return the result of converting this object to a String.
2287 * 2557 *
2288 * @param typeProvider the type provider used to find known types 2558 * @param typeProvider the type provider used to find known types
2289 * @return the result of converting this object to a String 2559 * @return the result of converting this object to a String
2290 * @throws EvaluationException if the object cannot be converted to a String 2560 * @throws EvaluationException if the object cannot be converted to a String
2291 */ 2561 */
2292 DartObjectImpl performToString(TypeProvider typeProvider) { 2562 DartObjectImpl performToString(TypeProvider typeProvider) {
2293 InterfaceType stringType = typeProvider.stringType; 2563 InterfaceType stringType = typeProvider.stringType;
2294 if (identical(type, stringType)) { 2564 if (identical(type, stringType)) {
2295 return this; 2565 return this;
2296 } 2566 }
2297 return new DartObjectImpl(stringType, _state.convertToString()); 2567 return new DartObjectImpl(stringType, _state.convertToString());
2298 } 2568 }
2299 2569
2300 /** 2570 /**
2301 * Return the result of invoking the '%' operator on this object with the give n argument. 2571 * Return the result of invoking the '%' operator on this object with the give n argument.
2302 * 2572 *
2303 * @param typeProvider the type provider used to find known types 2573 * @param typeProvider the type provider used to find known types
2304 * @param rightOperand the right-hand operand of the operation 2574 * @param rightOperand the right-hand operand of the operation
2305 * @return the result of invoking the '%' operator on this object with the giv en argument 2575 * @return the result of invoking the '%' operator on this object with the giv en argument
2306 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 2576 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2307 */ 2577 */
2308 DartObjectImpl remainder(TypeProvider typeProvider, DartObjectImpl rightOperan d) { 2578 DartObjectImpl remainder(TypeProvider typeProvider,
2579 DartObjectImpl rightOperand) {
2309 InstanceState result = _state.remainder(rightOperand._state); 2580 InstanceState result = _state.remainder(rightOperand._state);
2310 if (result is IntState) { 2581 if (result is IntState) {
2311 return new DartObjectImpl(typeProvider.intType, result); 2582 return new DartObjectImpl(typeProvider.intType, result);
2312 } else if (result is DoubleState) { 2583 } else if (result is DoubleState) {
2313 return new DartObjectImpl(typeProvider.doubleType, result); 2584 return new DartObjectImpl(typeProvider.doubleType, result);
2314 } else if (result is NumState) { 2585 } else if (result is NumState) {
2315 return new DartObjectImpl(typeProvider.numType, result); 2586 return new DartObjectImpl(typeProvider.numType, result);
2316 } 2587 }
2317 // We should never get here. 2588 // We should never get here.
2318 throw new IllegalStateException("remainder returned a ${result.runtimeType}" ); 2589 throw new IllegalStateException(
2590 "remainder returned a ${result.runtimeType}");
2319 } 2591 }
2320 2592
2321 /** 2593 /**
2322 * Return the result of invoking the '&lt;&lt;' operator on this object with t he given argument. 2594 * Return the result of invoking the '&lt;&lt;' operator on this object with t he given argument.
2323 * 2595 *
2324 * @param typeProvider the type provider used to find known types 2596 * @param typeProvider the type provider used to find known types
2325 * @param rightOperand the right-hand operand of the operation 2597 * @param rightOperand the right-hand operand of the operation
2326 * @return the result of invoking the '&lt;&lt;' operator on this object with the given argument 2598 * @return the result of invoking the '&lt;&lt;' operator on this object with the given argument
2327 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 2599 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2328 */ 2600 */
2329 DartObjectImpl shiftLeft(TypeProvider typeProvider, DartObjectImpl rightOperan d) => new DartObjectImpl(typeProvider.intType, _state.shiftLeft(rightOperand._st ate)); 2601 DartObjectImpl shiftLeft(TypeProvider typeProvider,
2602 DartObjectImpl rightOperand) =>
2603 new DartObjectImpl(typeProvider.intType, _state.shiftLeft(rightOperand._st ate));
2330 2604
2331 /** 2605 /**
2332 * Return the result of invoking the '&gt;&gt;' operator on this object with t he given argument. 2606 * Return the result of invoking the '&gt;&gt;' operator on this object with t he given argument.
2333 * 2607 *
2334 * @param typeProvider the type provider used to find known types 2608 * @param typeProvider the type provider used to find known types
2335 * @param rightOperand the right-hand operand of the operation 2609 * @param rightOperand the right-hand operand of the operation
2336 * @return the result of invoking the '&gt;&gt;' operator on this object with the given argument 2610 * @return the result of invoking the '&gt;&gt;' operator on this object with the given argument
2337 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 2611 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2338 */ 2612 */
2339 DartObjectImpl shiftRight(TypeProvider typeProvider, DartObjectImpl rightOpera nd) => new DartObjectImpl(typeProvider.intType, _state.shiftRight(rightOperand._ state)); 2613 DartObjectImpl shiftRight(TypeProvider typeProvider,
2614 DartObjectImpl rightOperand) =>
2615 new DartObjectImpl(
2616 typeProvider.intType,
2617 _state.shiftRight(rightOperand._state));
2340 2618
2341 /** 2619 /**
2342 * Return the result of invoking the 'length' getter on this object. 2620 * Return the result of invoking the 'length' getter on this object.
2343 * 2621 *
2344 * @param typeProvider the type provider used to find known types 2622 * @param typeProvider the type provider used to find known types
2345 * @return the result of invoking the 'length' getter on this object 2623 * @return the result of invoking the 'length' getter on this object
2346 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 2624 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2347 */ 2625 */
2348 DartObjectImpl stringLength(TypeProvider typeProvider) => new DartObjectImpl(t ypeProvider.intType, _state.stringLength()); 2626 DartObjectImpl stringLength(TypeProvider typeProvider) =>
2627 new DartObjectImpl(typeProvider.intType, _state.stringLength());
2349 2628
2350 /** 2629 /**
2351 * Return the result of invoking the '*' operator on this object with the give n argument. 2630 * Return the result of invoking the '*' operator on this object with the give n argument.
2352 * 2631 *
2353 * @param typeProvider the type provider used to find known types 2632 * @param typeProvider the type provider used to find known types
2354 * @param rightOperand the right-hand operand of the operation 2633 * @param rightOperand the right-hand operand of the operation
2355 * @return the result of invoking the '*' operator on this object with the giv en argument 2634 * @return the result of invoking the '*' operator on this object with the giv en argument
2356 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 2635 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
2357 */ 2636 */
2358 DartObjectImpl times(TypeProvider typeProvider, DartObjectImpl rightOperand) { 2637 DartObjectImpl times(TypeProvider typeProvider, DartObjectImpl rightOperand) {
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
2442 * `null` if the variable is not defined. Return the value of the variable wit h the given 2721 * `null` if the variable is not defined. Return the value of the variable wit h the given
2443 * name interpreted as a String value. If the variable is not defined (or [var iableName] is 2722 * name interpreted as a String value. If the variable is not defined (or [var iableName] is
2444 * null), a DartObject representing "unknown" is returned. 2723 * null), a DartObject representing "unknown" is returned.
2445 * 2724 *
2446 * @param typeProvider the type provider used to find the type 'String' 2725 * @param typeProvider the type provider used to find the type 'String'
2447 * @param variableName the name of the variable whose value is to be returned 2726 * @param variableName the name of the variable whose value is to be returned
2448 */ 2727 */
2449 DartObject getString(TypeProvider typeProvider, String variableName) { 2728 DartObject getString(TypeProvider typeProvider, String variableName) {
2450 String value = _declaredVariables[variableName]; 2729 String value = _declaredVariables[variableName];
2451 if (value == null) { 2730 if (value == null) {
2452 return new DartObjectImpl(typeProvider.stringType, 2731 return new DartObjectImpl(
2732 typeProvider.stringType,
2453 StringState.UNKNOWN_VALUE); 2733 StringState.UNKNOWN_VALUE);
2454 } 2734 }
2455 return new DartObjectImpl(typeProvider.stringType, new StringState(value)); 2735 return new DartObjectImpl(typeProvider.stringType, new StringState(value));
2456 } 2736 }
2457 } 2737 }
2458 2738
2459 /** 2739 /**
2460 * Instances of the class `DoubleState` represent the state of an object represe nting a 2740 * Instances of the class `DoubleState` represent the state of an object represe nting a
2461 * double. 2741 * double.
2462 */ 2742 */
2463 class DoubleState extends NumState { 2743 class DoubleState extends NumState {
2464 /** 2744 /**
2745 * A state that can be used to represent a double whose value is not known.
2746 */
2747 static DoubleState UNKNOWN_VALUE = new DoubleState(null);
2748
2749 /**
2465 * The value of this instance. 2750 * The value of this instance.
2466 */ 2751 */
2467 final double value; 2752 final double value;
2468 2753
2469 /** 2754 /**
2470 * A state that can be used to represent a double whose value is not known.
2471 */
2472 static DoubleState UNKNOWN_VALUE = new DoubleState(null);
2473
2474 /**
2475 * Initialize a newly created state to represent a double with the given value . 2755 * Initialize a newly created state to represent a double with the given value .
2476 * 2756 *
2477 * @param value the value of this instance 2757 * @param value the value of this instance
2478 */ 2758 */
2479 DoubleState(this.value); 2759 DoubleState(this.value);
2480 2760
2481 @override 2761 @override
2762 bool get hasExactValue => true;
2763
2764 @override
2765 int get hashCode => value == null ? 0 : value.hashCode;
2766
2767 @override
2768 bool get isBoolNumStringOrNull => true;
2769
2770 @override
2771 bool get isUnknown => value == null;
2772
2773 @override
2774 String get typeName => "double";
2775
2776 @override
2777 bool operator ==(Object object) =>
2778 object is DoubleState && (value == object.value);
2779
2780 @override
2482 NumState add(InstanceState rightOperand) { 2781 NumState add(InstanceState rightOperand) {
2483 assertNumOrNull(rightOperand); 2782 assertNumOrNull(rightOperand);
2484 if (value == null) { 2783 if (value == null) {
2485 return UNKNOWN_VALUE; 2784 return UNKNOWN_VALUE;
2486 } 2785 }
2487 if (rightOperand is IntState) { 2786 if (rightOperand is IntState) {
2488 int rightValue = rightOperand.value; 2787 int rightValue = rightOperand.value;
2489 if (rightValue == null) { 2788 if (rightValue == null) {
2490 return UNKNOWN_VALUE; 2789 return UNKNOWN_VALUE;
2491 } 2790 }
2492 return new DoubleState(value + rightValue.toDouble()); 2791 return new DoubleState(value + rightValue.toDouble());
2493 } else if (rightOperand is DoubleState) { 2792 } else if (rightOperand is DoubleState) {
2494 double rightValue = rightOperand.value; 2793 double rightValue = rightOperand.value;
2495 if (rightValue == null) { 2794 if (rightValue == null) {
2496 return UNKNOWN_VALUE; 2795 return UNKNOWN_VALUE;
2497 } 2796 }
2498 return new DoubleState(value + rightValue); 2797 return new DoubleState(value + rightValue);
2499 } else if (rightOperand is DynamicState || rightOperand is NumState) { 2798 } else if (rightOperand is DynamicState || rightOperand is NumState) {
2500 return UNKNOWN_VALUE; 2799 return UNKNOWN_VALUE;
2501 } 2800 }
2502 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI ON); 2801 throw new EvaluationException(
2802 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
2503 } 2803 }
2504 2804
2505 @override 2805 @override
2506 StringState convertToString() { 2806 StringState convertToString() {
2507 if (value == null) { 2807 if (value == null) {
2508 return StringState.UNKNOWN_VALUE; 2808 return StringState.UNKNOWN_VALUE;
2509 } 2809 }
2510 return new StringState(value.toString()); 2810 return new StringState(value.toString());
2511 } 2811 }
2512 2812
(...skipping 11 matching lines...) Expand all
2524 return new DoubleState(value / rightValue.toDouble()); 2824 return new DoubleState(value / rightValue.toDouble());
2525 } else if (rightOperand is DoubleState) { 2825 } else if (rightOperand is DoubleState) {
2526 double rightValue = rightOperand.value; 2826 double rightValue = rightOperand.value;
2527 if (rightValue == null) { 2827 if (rightValue == null) {
2528 return UNKNOWN_VALUE; 2828 return UNKNOWN_VALUE;
2529 } 2829 }
2530 return new DoubleState(value / rightValue); 2830 return new DoubleState(value / rightValue);
2531 } else if (rightOperand is DynamicState || rightOperand is NumState) { 2831 } else if (rightOperand is DynamicState || rightOperand is NumState) {
2532 return UNKNOWN_VALUE; 2832 return UNKNOWN_VALUE;
2533 } 2833 }
2534 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI ON); 2834 throw new EvaluationException(
2835 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
2535 } 2836 }
2536 2837
2537 @override 2838 @override
2538 BoolState equalEqual(InstanceState rightOperand) { 2839 BoolState equalEqual(InstanceState rightOperand) {
2539 assertBoolNumStringOrNull(rightOperand); 2840 assertBoolNumStringOrNull(rightOperand);
2540 return isIdentical(rightOperand); 2841 return isIdentical(rightOperand);
2541 } 2842 }
2542 2843
2543 @override 2844 @override
2544 BoolState isIdentical(InstanceState rightOperand) {
2545 if (value == null) {
2546 return BoolState.UNKNOWN_VALUE;
2547 }
2548 if (rightOperand is DoubleState) {
2549 double rightValue = rightOperand.value;
2550 if (rightValue == null) {
2551 return BoolState.UNKNOWN_VALUE;
2552 }
2553 return BoolState.from(value == rightValue);
2554 } else if (rightOperand is IntState) {
2555 int rightValue = rightOperand.value;
2556 if (rightValue == null) {
2557 return BoolState.UNKNOWN_VALUE;
2558 }
2559 return BoolState.from(value == rightValue.toDouble());
2560 } else if (rightOperand is DynamicState || rightOperand is NumState) {
2561 return BoolState.UNKNOWN_VALUE;
2562 }
2563 return BoolState.FALSE_STATE;
2564 }
2565
2566 @override
2567 bool operator ==(Object object) => object is DoubleState && (value == object.v alue);
2568
2569 @override
2570 String get typeName => "double";
2571
2572 @override
2573 BoolState greaterThan(InstanceState rightOperand) { 2845 BoolState greaterThan(InstanceState rightOperand) {
2574 assertNumOrNull(rightOperand); 2846 assertNumOrNull(rightOperand);
2575 if (value == null) { 2847 if (value == null) {
2576 return BoolState.UNKNOWN_VALUE; 2848 return BoolState.UNKNOWN_VALUE;
2577 } 2849 }
2578 if (rightOperand is IntState) { 2850 if (rightOperand is IntState) {
2579 int rightValue = rightOperand.value; 2851 int rightValue = rightOperand.value;
2580 if (rightValue == null) { 2852 if (rightValue == null) {
2581 return BoolState.UNKNOWN_VALUE; 2853 return BoolState.UNKNOWN_VALUE;
2582 } 2854 }
2583 return BoolState.from(value > rightValue.toDouble()); 2855 return BoolState.from(value > rightValue.toDouble());
2584 } else if (rightOperand is DoubleState) { 2856 } else if (rightOperand is DoubleState) {
2585 double rightValue = rightOperand.value; 2857 double rightValue = rightOperand.value;
2586 if (rightValue == null) { 2858 if (rightValue == null) {
2587 return BoolState.UNKNOWN_VALUE; 2859 return BoolState.UNKNOWN_VALUE;
2588 } 2860 }
2589 return BoolState.from(value > rightValue); 2861 return BoolState.from(value > rightValue);
2590 } else if (rightOperand is DynamicState || rightOperand is NumState) { 2862 } else if (rightOperand is DynamicState || rightOperand is NumState) {
2591 return BoolState.UNKNOWN_VALUE; 2863 return BoolState.UNKNOWN_VALUE;
2592 } 2864 }
2593 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI ON); 2865 throw new EvaluationException(
2866 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
2594 } 2867 }
2595 2868
2596 @override 2869 @override
2597 BoolState greaterThanOrEqual(InstanceState rightOperand) { 2870 BoolState greaterThanOrEqual(InstanceState rightOperand) {
2598 assertNumOrNull(rightOperand); 2871 assertNumOrNull(rightOperand);
2599 if (value == null) { 2872 if (value == null) {
2600 return BoolState.UNKNOWN_VALUE; 2873 return BoolState.UNKNOWN_VALUE;
2601 } 2874 }
2602 if (rightOperand is IntState) { 2875 if (rightOperand is IntState) {
2603 int rightValue = rightOperand.value; 2876 int rightValue = rightOperand.value;
2604 if (rightValue == null) { 2877 if (rightValue == null) {
2605 return BoolState.UNKNOWN_VALUE; 2878 return BoolState.UNKNOWN_VALUE;
2606 } 2879 }
2607 return BoolState.from(value >= rightValue.toDouble()); 2880 return BoolState.from(value >= rightValue.toDouble());
2608 } else if (rightOperand is DoubleState) { 2881 } else if (rightOperand is DoubleState) {
2609 double rightValue = rightOperand.value; 2882 double rightValue = rightOperand.value;
2610 if (rightValue == null) { 2883 if (rightValue == null) {
2611 return BoolState.UNKNOWN_VALUE; 2884 return BoolState.UNKNOWN_VALUE;
2612 } 2885 }
2613 return BoolState.from(value >= rightValue); 2886 return BoolState.from(value >= rightValue);
2614 } else if (rightOperand is DynamicState || rightOperand is NumState) { 2887 } else if (rightOperand is DynamicState || rightOperand is NumState) {
2615 return BoolState.UNKNOWN_VALUE; 2888 return BoolState.UNKNOWN_VALUE;
2616 } 2889 }
2617 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI ON); 2890 throw new EvaluationException(
2891 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
2618 } 2892 }
2619 2893
2620 @override 2894 @override
2621 bool get hasExactValue => true;
2622
2623 @override
2624 int get hashCode => value == null ? 0 : value.hashCode;
2625
2626 @override
2627 IntState integerDivide(InstanceState rightOperand) { 2895 IntState integerDivide(InstanceState rightOperand) {
2628 assertNumOrNull(rightOperand); 2896 assertNumOrNull(rightOperand);
2629 if (value == null) { 2897 if (value == null) {
2630 return IntState.UNKNOWN_VALUE; 2898 return IntState.UNKNOWN_VALUE;
2631 } 2899 }
2632 if (rightOperand is IntState) { 2900 if (rightOperand is IntState) {
2633 int rightValue = rightOperand.value; 2901 int rightValue = rightOperand.value;
2634 if (rightValue == null) { 2902 if (rightValue == null) {
2635 return IntState.UNKNOWN_VALUE; 2903 return IntState.UNKNOWN_VALUE;
2636 } 2904 }
2637 double result = value / rightValue.toDouble(); 2905 double result = value / rightValue.toDouble();
2638 return new IntState(result.toInt()); 2906 return new IntState(result.toInt());
2639 } else if (rightOperand is DoubleState) { 2907 } else if (rightOperand is DoubleState) {
2640 double rightValue = rightOperand.value; 2908 double rightValue = rightOperand.value;
2641 if (rightValue == null) { 2909 if (rightValue == null) {
2642 return IntState.UNKNOWN_VALUE; 2910 return IntState.UNKNOWN_VALUE;
2643 } 2911 }
2644 double result = value / rightValue; 2912 double result = value / rightValue;
2645 return new IntState(result.toInt()); 2913 return new IntState(result.toInt());
2646 } else if (rightOperand is DynamicState || rightOperand is NumState) { 2914 } else if (rightOperand is DynamicState || rightOperand is NumState) {
2647 return IntState.UNKNOWN_VALUE; 2915 return IntState.UNKNOWN_VALUE;
2648 } 2916 }
2649 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI ON); 2917 throw new EvaluationException(
2918 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
2650 } 2919 }
2651 2920
2652 @override 2921 @override
2653 bool get isBoolNumStringOrNull => true; 2922 BoolState isIdentical(InstanceState rightOperand) {
2654 2923 if (value == null) {
2655 @override 2924 return BoolState.UNKNOWN_VALUE;
2656 bool get isUnknown => value == null; 2925 }
2926 if (rightOperand is DoubleState) {
2927 double rightValue = rightOperand.value;
2928 if (rightValue == null) {
2929 return BoolState.UNKNOWN_VALUE;
2930 }
2931 return BoolState.from(value == rightValue);
2932 } else if (rightOperand is IntState) {
2933 int rightValue = rightOperand.value;
2934 if (rightValue == null) {
2935 return BoolState.UNKNOWN_VALUE;
2936 }
2937 return BoolState.from(value == rightValue.toDouble());
2938 } else if (rightOperand is DynamicState || rightOperand is NumState) {
2939 return BoolState.UNKNOWN_VALUE;
2940 }
2941 return BoolState.FALSE_STATE;
2942 }
2657 2943
2658 @override 2944 @override
2659 BoolState lessThan(InstanceState rightOperand) { 2945 BoolState lessThan(InstanceState rightOperand) {
2660 assertNumOrNull(rightOperand); 2946 assertNumOrNull(rightOperand);
2661 if (value == null) { 2947 if (value == null) {
2662 return BoolState.UNKNOWN_VALUE; 2948 return BoolState.UNKNOWN_VALUE;
2663 } 2949 }
2664 if (rightOperand is IntState) { 2950 if (rightOperand is IntState) {
2665 int rightValue = rightOperand.value; 2951 int rightValue = rightOperand.value;
2666 if (rightValue == null) { 2952 if (rightValue == null) {
2667 return BoolState.UNKNOWN_VALUE; 2953 return BoolState.UNKNOWN_VALUE;
2668 } 2954 }
2669 return BoolState.from(value < rightValue.toDouble()); 2955 return BoolState.from(value < rightValue.toDouble());
2670 } else if (rightOperand is DoubleState) { 2956 } else if (rightOperand is DoubleState) {
2671 double rightValue = rightOperand.value; 2957 double rightValue = rightOperand.value;
2672 if (rightValue == null) { 2958 if (rightValue == null) {
2673 return BoolState.UNKNOWN_VALUE; 2959 return BoolState.UNKNOWN_VALUE;
2674 } 2960 }
2675 return BoolState.from(value < rightValue); 2961 return BoolState.from(value < rightValue);
2676 } else if (rightOperand is DynamicState || rightOperand is NumState) { 2962 } else if (rightOperand is DynamicState || rightOperand is NumState) {
2677 return BoolState.UNKNOWN_VALUE; 2963 return BoolState.UNKNOWN_VALUE;
2678 } 2964 }
2679 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI ON); 2965 throw new EvaluationException(
2966 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
2680 } 2967 }
2681 2968
2682 @override 2969 @override
2683 BoolState lessThanOrEqual(InstanceState rightOperand) { 2970 BoolState lessThanOrEqual(InstanceState rightOperand) {
2684 assertNumOrNull(rightOperand); 2971 assertNumOrNull(rightOperand);
2685 if (value == null) { 2972 if (value == null) {
2686 return BoolState.UNKNOWN_VALUE; 2973 return BoolState.UNKNOWN_VALUE;
2687 } 2974 }
2688 if (rightOperand is IntState) { 2975 if (rightOperand is IntState) {
2689 int rightValue = rightOperand.value; 2976 int rightValue = rightOperand.value;
2690 if (rightValue == null) { 2977 if (rightValue == null) {
2691 return BoolState.UNKNOWN_VALUE; 2978 return BoolState.UNKNOWN_VALUE;
2692 } 2979 }
2693 return BoolState.from(value <= rightValue.toDouble()); 2980 return BoolState.from(value <= rightValue.toDouble());
2694 } else if (rightOperand is DoubleState) { 2981 } else if (rightOperand is DoubleState) {
2695 double rightValue = rightOperand.value; 2982 double rightValue = rightOperand.value;
2696 if (rightValue == null) { 2983 if (rightValue == null) {
2697 return BoolState.UNKNOWN_VALUE; 2984 return BoolState.UNKNOWN_VALUE;
2698 } 2985 }
2699 return BoolState.from(value <= rightValue); 2986 return BoolState.from(value <= rightValue);
2700 } else if (rightOperand is DynamicState || rightOperand is NumState) { 2987 } else if (rightOperand is DynamicState || rightOperand is NumState) {
2701 return BoolState.UNKNOWN_VALUE; 2988 return BoolState.UNKNOWN_VALUE;
2702 } 2989 }
2703 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI ON); 2990 throw new EvaluationException(
2991 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
2704 } 2992 }
2705 2993
2706 @override 2994 @override
2707 NumState minus(InstanceState rightOperand) { 2995 NumState minus(InstanceState rightOperand) {
2708 assertNumOrNull(rightOperand); 2996 assertNumOrNull(rightOperand);
2709 if (value == null) { 2997 if (value == null) {
2710 return UNKNOWN_VALUE; 2998 return UNKNOWN_VALUE;
2711 } 2999 }
2712 if (rightOperand is IntState) { 3000 if (rightOperand is IntState) {
2713 int rightValue = rightOperand.value; 3001 int rightValue = rightOperand.value;
2714 if (rightValue == null) { 3002 if (rightValue == null) {
2715 return UNKNOWN_VALUE; 3003 return UNKNOWN_VALUE;
2716 } 3004 }
2717 return new DoubleState(value - rightValue.toDouble()); 3005 return new DoubleState(value - rightValue.toDouble());
2718 } else if (rightOperand is DoubleState) { 3006 } else if (rightOperand is DoubleState) {
2719 double rightValue = rightOperand.value; 3007 double rightValue = rightOperand.value;
2720 if (rightValue == null) { 3008 if (rightValue == null) {
2721 return UNKNOWN_VALUE; 3009 return UNKNOWN_VALUE;
2722 } 3010 }
2723 return new DoubleState(value - rightValue); 3011 return new DoubleState(value - rightValue);
2724 } else if (rightOperand is DynamicState || rightOperand is NumState) { 3012 } else if (rightOperand is DynamicState || rightOperand is NumState) {
2725 return UNKNOWN_VALUE; 3013 return UNKNOWN_VALUE;
2726 } 3014 }
2727 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI ON); 3015 throw new EvaluationException(
3016 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
2728 } 3017 }
2729 3018
2730 @override 3019 @override
2731 NumState negated() { 3020 NumState negated() {
2732 if (value == null) { 3021 if (value == null) {
2733 return UNKNOWN_VALUE; 3022 return UNKNOWN_VALUE;
2734 } 3023 }
2735 return new DoubleState(-(value)); 3024 return new DoubleState(-(value));
2736 } 3025 }
2737 3026
(...skipping 11 matching lines...) Expand all
2749 return new DoubleState(value % rightValue.toDouble()); 3038 return new DoubleState(value % rightValue.toDouble());
2750 } else if (rightOperand is DoubleState) { 3039 } else if (rightOperand is DoubleState) {
2751 double rightValue = rightOperand.value; 3040 double rightValue = rightOperand.value;
2752 if (rightValue == null) { 3041 if (rightValue == null) {
2753 return UNKNOWN_VALUE; 3042 return UNKNOWN_VALUE;
2754 } 3043 }
2755 return new DoubleState(value % rightValue); 3044 return new DoubleState(value % rightValue);
2756 } else if (rightOperand is DynamicState || rightOperand is NumState) { 3045 } else if (rightOperand is DynamicState || rightOperand is NumState) {
2757 return UNKNOWN_VALUE; 3046 return UNKNOWN_VALUE;
2758 } 3047 }
2759 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI ON); 3048 throw new EvaluationException(
3049 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
2760 } 3050 }
2761 3051
2762 @override 3052 @override
2763 NumState times(InstanceState rightOperand) { 3053 NumState times(InstanceState rightOperand) {
2764 assertNumOrNull(rightOperand); 3054 assertNumOrNull(rightOperand);
2765 if (value == null) { 3055 if (value == null) {
2766 return UNKNOWN_VALUE; 3056 return UNKNOWN_VALUE;
2767 } 3057 }
2768 if (rightOperand is IntState) { 3058 if (rightOperand is IntState) {
2769 int rightValue = rightOperand.value; 3059 int rightValue = rightOperand.value;
2770 if (rightValue == null) { 3060 if (rightValue == null) {
2771 return UNKNOWN_VALUE; 3061 return UNKNOWN_VALUE;
2772 } 3062 }
2773 return new DoubleState(value * rightValue.toDouble()); 3063 return new DoubleState(value * rightValue.toDouble());
2774 } else if (rightOperand is DoubleState) { 3064 } else if (rightOperand is DoubleState) {
2775 double rightValue = rightOperand.value; 3065 double rightValue = rightOperand.value;
2776 if (rightValue == null) { 3066 if (rightValue == null) {
2777 return UNKNOWN_VALUE; 3067 return UNKNOWN_VALUE;
2778 } 3068 }
2779 return new DoubleState(value * rightValue); 3069 return new DoubleState(value * rightValue);
2780 } else if (rightOperand is DynamicState || rightOperand is NumState) { 3070 } else if (rightOperand is DynamicState || rightOperand is NumState) {
2781 return UNKNOWN_VALUE; 3071 return UNKNOWN_VALUE;
2782 } 3072 }
2783 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI ON); 3073 throw new EvaluationException(
3074 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
2784 } 3075 }
2785 3076
2786 @override 3077 @override
2787 String toString() => value == null ? "-unknown-" : value.toString(); 3078 String toString() => value == null ? "-unknown-" : value.toString();
2788 } 3079 }
2789 3080
2790 /** 3081 /**
2791 * Instances of the class `DynamicState` represent the state of an object repres enting a Dart 3082 * Instances of the class `DynamicState` represent the state of an object repres enting a Dart
2792 * object for which there is no type information. 3083 * object for which there is no type information.
2793 */ 3084 */
2794 class DynamicState extends InstanceState { 3085 class DynamicState extends InstanceState {
2795 /** 3086 /**
2796 * The unique instance of this class. 3087 * The unique instance of this class.
2797 */ 3088 */
2798 static DynamicState DYNAMIC_STATE = new DynamicState(); 3089 static DynamicState DYNAMIC_STATE = new DynamicState();
2799 3090
2800 @override 3091 @override
3092 bool get isBool => true;
3093
3094 @override
3095 bool get isBoolNumStringOrNull => true;
3096
3097 @override
3098 String get typeName => "dynamic";
3099
3100 @override
2801 NumState add(InstanceState rightOperand) { 3101 NumState add(InstanceState rightOperand) {
2802 assertNumOrNull(rightOperand); 3102 assertNumOrNull(rightOperand);
2803 return _unknownNum(rightOperand); 3103 return _unknownNum(rightOperand);
2804 } 3104 }
2805 3105
2806 @override 3106 @override
2807 IntState bitAnd(InstanceState rightOperand) { 3107 IntState bitAnd(InstanceState rightOperand) {
2808 assertIntOrNull(rightOperand); 3108 assertIntOrNull(rightOperand);
2809 return IntState.UNKNOWN_VALUE; 3109 return IntState.UNKNOWN_VALUE;
2810 } 3110 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2842 return _unknownNum(rightOperand); 3142 return _unknownNum(rightOperand);
2843 } 3143 }
2844 3144
2845 @override 3145 @override
2846 BoolState equalEqual(InstanceState rightOperand) { 3146 BoolState equalEqual(InstanceState rightOperand) {
2847 assertBoolNumStringOrNull(rightOperand); 3147 assertBoolNumStringOrNull(rightOperand);
2848 return BoolState.UNKNOWN_VALUE; 3148 return BoolState.UNKNOWN_VALUE;
2849 } 3149 }
2850 3150
2851 @override 3151 @override
2852 BoolState isIdentical(InstanceState rightOperand) {
2853 return BoolState.UNKNOWN_VALUE;
2854 }
2855
2856 @override
2857 String get typeName => "dynamic";
2858
2859 @override
2860 BoolState greaterThan(InstanceState rightOperand) { 3152 BoolState greaterThan(InstanceState rightOperand) {
2861 assertNumOrNull(rightOperand); 3153 assertNumOrNull(rightOperand);
2862 return BoolState.UNKNOWN_VALUE; 3154 return BoolState.UNKNOWN_VALUE;
2863 } 3155 }
2864 3156
2865 @override 3157 @override
2866 BoolState greaterThanOrEqual(InstanceState rightOperand) { 3158 BoolState greaterThanOrEqual(InstanceState rightOperand) {
2867 assertNumOrNull(rightOperand); 3159 assertNumOrNull(rightOperand);
2868 return BoolState.UNKNOWN_VALUE; 3160 return BoolState.UNKNOWN_VALUE;
2869 } 3161 }
2870 3162
2871 @override 3163 @override
2872 IntState integerDivide(InstanceState rightOperand) { 3164 IntState integerDivide(InstanceState rightOperand) {
2873 assertNumOrNull(rightOperand); 3165 assertNumOrNull(rightOperand);
2874 return IntState.UNKNOWN_VALUE; 3166 return IntState.UNKNOWN_VALUE;
2875 } 3167 }
2876 3168
2877 @override 3169 @override
2878 bool get isBool => true; 3170 BoolState isIdentical(InstanceState rightOperand) {
2879 3171 return BoolState.UNKNOWN_VALUE;
2880 @override 3172 }
2881 bool get isBoolNumStringOrNull => true;
2882 3173
2883 @override 3174 @override
2884 BoolState lessThan(InstanceState rightOperand) { 3175 BoolState lessThan(InstanceState rightOperand) {
2885 assertNumOrNull(rightOperand); 3176 assertNumOrNull(rightOperand);
2886 return BoolState.UNKNOWN_VALUE; 3177 return BoolState.UNKNOWN_VALUE;
2887 } 3178 }
2888 3179
2889 @override 3180 @override
2890 BoolState lessThanOrEqual(InstanceState rightOperand) { 3181 BoolState lessThanOrEqual(InstanceState rightOperand) {
2891 assertNumOrNull(rightOperand); 3182 assertNumOrNull(rightOperand);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
2974 */ 3265 */
2975 EvaluationException(this.errorCode); 3266 EvaluationException(this.errorCode);
2976 } 3267 }
2977 3268
2978 /** 3269 /**
2979 * Instances of the class `EvaluationResult` represent the result of attempting to evaluate an 3270 * Instances of the class `EvaluationResult` represent the result of attempting to evaluate an
2980 * expression. 3271 * expression.
2981 */ 3272 */
2982 class EvaluationResult { 3273 class EvaluationResult {
2983 /** 3274 /**
2984 * Return an evaluation result representing the result of evaluating an expres sion that is not a
2985 * compile-time constant because of the given errors.
2986 *
2987 * @param errors the errors that should be reported for the expression(s) that were evaluated
2988 * @return the result of evaluating an expression that is not a compile-time c onstant
2989 */
2990 static EvaluationResult forErrors(List<AnalysisError> errors) => new Evaluatio nResult(null, errors);
2991
2992 /**
2993 * Return an evaluation result representing the result of evaluating an expres sion that is a
2994 * compile-time constant that evaluates to the given value.
2995 *
2996 * @param value the value of the expression
2997 * @return the result of evaluating an expression that is a compile-time const ant
2998 */
2999 static EvaluationResult forValue(DartObject value) => new EvaluationResult(val ue, null);
3000
3001 /**
3002 * The value of the expression. 3275 * The value of the expression.
3003 */ 3276 */
3004 final DartObject value; 3277 final DartObject value;
3005 3278
3006 /** 3279 /**
3007 * The errors that should be reported for the expression(s) that were evaluate d. 3280 * The errors that should be reported for the expression(s) that were evaluate d.
3008 */ 3281 */
3009 final List<AnalysisError> _errors; 3282 final List<AnalysisError> _errors;
3010 3283
3011 /** 3284 /**
3012 * Initialize a newly created result object with the given state. Clients shou ld use one of the 3285 * Initialize a newly created result object with the given state. Clients shou ld use one of the
3013 * factory methods: [forErrors] and [forValue]. 3286 * factory methods: [forErrors] and [forValue].
3014 * 3287 *
3015 * @param value the value of the expression 3288 * @param value the value of the expression
3016 * @param errors the errors that should be reported for the expression(s) that were evaluated 3289 * @param errors the errors that should be reported for the expression(s) that were evaluated
3017 */ 3290 */
3018 EvaluationResult(this.value, this._errors); 3291 EvaluationResult(this.value, this._errors);
3019 3292
3020 /** 3293 /**
3021 * Return an array containing the errors that should be reported for the expre ssion(s) that were 3294 * Return an array containing the errors that should be reported for the expre ssion(s) that were
3022 * evaluated. If there are no such errors, the array will be empty. The array can be empty even if 3295 * evaluated. If there are no such errors, the array will be empty. The array can be empty even if
3023 * the expression is not a valid compile time constant if the errors would hav e been reported by 3296 * the expression is not a valid compile time constant if the errors would hav e been reported by
3024 * other parts of the analysis engine. 3297 * other parts of the analysis engine.
3025 */ 3298 */
3026 List<AnalysisError> get errors => _errors == null ? AnalysisError.NO_ERRORS : _errors; 3299 List<AnalysisError> get errors =>
3300 _errors == null ? AnalysisError.NO_ERRORS : _errors;
3027 3301
3028 /** 3302 /**
3029 * Return `true` if the expression is a compile-time constant expression that would not 3303 * Return `true` if the expression is a compile-time constant expression that would not
3030 * throw an exception when evaluated. 3304 * throw an exception when evaluated.
3031 * 3305 *
3032 * @return `true` if the expression is a valid compile-time constant expressio n 3306 * @return `true` if the expression is a valid compile-time constant expressio n
3033 */ 3307 */
3034 bool get isValid => _errors == null; 3308 bool get isValid => _errors == null;
3309
3310 /**
3311 * Return an evaluation result representing the result of evaluating an expres sion that is not a
3312 * compile-time constant because of the given errors.
3313 *
3314 * @param errors the errors that should be reported for the expression(s) that were evaluated
3315 * @return the result of evaluating an expression that is not a compile-time c onstant
3316 */
3317 static EvaluationResult forErrors(List<AnalysisError> errors) =>
3318 new EvaluationResult(null, errors);
3319
3320 /**
3321 * Return an evaluation result representing the result of evaluating an expres sion that is a
3322 * compile-time constant that evaluates to the given value.
3323 *
3324 * @param value the value of the expression
3325 * @return the result of evaluating an expression that is a compile-time const ant
3326 */
3327 static EvaluationResult forValue(DartObject value) =>
3328 new EvaluationResult(value, null);
3035 } 3329 }
3036 3330
3037 /** 3331 /**
3038 * Instances of the class `InternalResult` represent the result of attempting to evaluate a 3332 * Instances of the class `InternalResult` represent the result of attempting to evaluate a
3039 * expression. 3333 * expression.
3040 */ 3334 */
3041 class EvaluationResultImpl { 3335 class EvaluationResultImpl {
3042 /** 3336 /**
3043 * The errors encountered while trying to evaluate the compile time constant. These errors may or 3337 * The errors encountered while trying to evaluate the compile time constant. These errors may or
3044 * may not have prevented the expression from being a valid compile time const ant. 3338 * may not have prevented the expression from being a valid compile time const ant.
3045 */ 3339 */
3046 List<AnalysisError> _errors; 3340 List<AnalysisError> _errors;
3047 3341
3048 /** 3342 /**
3049 * The value of the expression, or null if the value couldn't be computed due to errors. 3343 * The value of the expression, or null if the value couldn't be computed due to errors.
3050 */ 3344 */
3051 final DartObjectImpl value; 3345 final DartObjectImpl value;
3052 3346
3053 EvaluationResultImpl.con1(this.value) { 3347 EvaluationResultImpl.con1(this.value) {
3054 this._errors = new List<AnalysisError>(0); 3348 this._errors = new List<AnalysisError>(0);
3055 } 3349 }
3056 3350
3057 EvaluationResultImpl.con2(this.value, List<AnalysisError> errors) { 3351 EvaluationResultImpl.con2(this.value, List<AnalysisError> errors) {
3058 this._errors = errors; 3352 this._errors = errors;
3059 } 3353 }
3060 3354
3355 List<AnalysisError> get errors => _errors;
3356
3061 bool equalValues(TypeProvider typeProvider, EvaluationResultImpl result) { 3357 bool equalValues(TypeProvider typeProvider, EvaluationResultImpl result) {
3062 if (this.value != null) { 3358 if (this.value != null) {
3063 if (result.value == null) { 3359 if (result.value == null) {
3064 return false; 3360 return false;
3065 } 3361 }
3066 return value == result.value; 3362 return value == result.value;
3067 } else { 3363 } else {
3068 return false; 3364 return false;
3069 } 3365 }
3070 } 3366 }
3071 3367
3072 List<AnalysisError> get errors => _errors;
3073
3074 @override 3368 @override
3075 String toString() { 3369 String toString() {
3076 if (value == null) { 3370 if (value == null) {
3077 return "error"; 3371 return "error";
3078 } 3372 }
3079 return value.toString(); 3373 return value.toString();
3080 } 3374 }
3081 } 3375 }
3082 3376
3083 /** 3377 /**
3084 * Instances of the class `FunctionState` represent the state of an object repre senting a 3378 * Instances of the class `FunctionState` represent the state of an object repre senting a
3085 * function. 3379 * function.
3086 */ 3380 */
3087 class FunctionState extends InstanceState { 3381 class FunctionState extends InstanceState {
3088 /** 3382 /**
3089 * The element representing the function being modeled. 3383 * The element representing the function being modeled.
3090 */ 3384 */
3091 final ExecutableElement _element; 3385 final ExecutableElement _element;
3092 3386
3093 /** 3387 /**
3094 * Initialize a newly created state to represent the given function. 3388 * Initialize a newly created state to represent the given function.
3095 * 3389 *
3096 * @param element the element representing the function being modeled 3390 * @param element the element representing the function being modeled
3097 */ 3391 */
3098 FunctionState(this._element); 3392 FunctionState(this._element);
3099 3393
3100 @override 3394 @override
3395 int get hashCode => _element == null ? 0 : _element.hashCode;
3396
3397 @override
3398 String get typeName => "Function";
3399
3400 @override
3401 bool operator ==(Object object) =>
3402 object is FunctionState && (_element == object._element);
3403
3404 @override
3101 StringState convertToString() { 3405 StringState convertToString() {
3102 if (_element == null) { 3406 if (_element == null) {
3103 return StringState.UNKNOWN_VALUE; 3407 return StringState.UNKNOWN_VALUE;
3104 } 3408 }
3105 return new StringState(_element.name); 3409 return new StringState(_element.name);
3106 } 3410 }
3107 3411
3108 @override 3412 @override
3109 bool operator ==(Object object) => object is FunctionState && (_element == obj ect._element);
3110
3111 @override
3112 BoolState equalEqual(InstanceState rightOperand) { 3413 BoolState equalEqual(InstanceState rightOperand) {
3113 return isIdentical(rightOperand); 3414 return isIdentical(rightOperand);
3114 } 3415 }
3115 3416
3116 @override 3417 @override
3117 BoolState isIdentical(InstanceState rightOperand) { 3418 BoolState isIdentical(InstanceState rightOperand) {
3118 if (_element == null) { 3419 if (_element == null) {
3119 return BoolState.UNKNOWN_VALUE; 3420 return BoolState.UNKNOWN_VALUE;
3120 } 3421 }
3121 if (rightOperand is FunctionState) { 3422 if (rightOperand is FunctionState) {
3122 ExecutableElement rightElement = rightOperand._element; 3423 ExecutableElement rightElement = rightOperand._element;
3123 if (rightElement == null) { 3424 if (rightElement == null) {
3124 return BoolState.UNKNOWN_VALUE; 3425 return BoolState.UNKNOWN_VALUE;
3125 } 3426 }
3126 return BoolState.from(_element == rightElement); 3427 return BoolState.from(_element == rightElement);
3127 } else if (rightOperand is DynamicState) { 3428 } else if (rightOperand is DynamicState) {
3128 return BoolState.UNKNOWN_VALUE; 3429 return BoolState.UNKNOWN_VALUE;
3129 } 3430 }
3130 return BoolState.FALSE_STATE; 3431 return BoolState.FALSE_STATE;
3131 } 3432 }
3132 3433
3133 @override 3434 @override
3134 String get typeName => "Function";
3135
3136 @override
3137 int get hashCode => _element == null ? 0 : _element.hashCode;
3138
3139 @override
3140 String toString() => _element == null ? "-unknown-" : _element.name; 3435 String toString() => _element == null ? "-unknown-" : _element.name;
3141 } 3436 }
3142 3437
3143 /** 3438 /**
3144 * Instances of the class `GenericState` represent the state of an object repres enting a Dart 3439 * Instances of the class `GenericState` represent the state of an object repres enting a Dart
3145 * object for which there is no more specific state. 3440 * object for which there is no more specific state.
3146 */ 3441 */
3147 class GenericState extends InstanceState { 3442 class GenericState extends InstanceState {
3148 /** 3443 /**
3149 * The values of the fields of this instance.
3150 */
3151 final HashMap<String, DartObjectImpl> _fieldMap;
3152
3153 /**
3154 * Pseudo-field that we use to represent fields in the superclass. 3444 * Pseudo-field that we use to represent fields in the superclass.
3155 */ 3445 */
3156 static String SUPERCLASS_FIELD = "(super)"; 3446 static String SUPERCLASS_FIELD = "(super)";
3157 3447
3158 /** 3448 /**
3159 * A state that can be used to represent an object whose state is not known. 3449 * A state that can be used to represent an object whose state is not known.
3160 */ 3450 */
3161 static GenericState UNKNOWN_VALUE = new GenericState(new HashMap<String, DartO bjectImpl>()); 3451 static GenericState UNKNOWN_VALUE =
3452 new GenericState(new HashMap<String, DartObjectImpl>());
3453
3454 /**
3455 * The values of the fields of this instance.
3456 */
3457 final HashMap<String, DartObjectImpl> _fieldMap;
3162 3458
3163 /** 3459 /**
3164 * Initialize a newly created state to represent a newly created object. 3460 * Initialize a newly created state to represent a newly created object.
3165 * 3461 *
3166 * @param fieldMap the values of the fields of this instance 3462 * @param fieldMap the values of the fields of this instance
3167 */ 3463 */
3168 GenericState(this._fieldMap); 3464 GenericState(this._fieldMap);
3169 3465
3170 @override 3466 @override
3171 StringState convertToString() => StringState.UNKNOWN_VALUE; 3467 HashMap<String, DartObjectImpl> get fields => _fieldMap;
3172 3468
3173 @override 3469 @override
3174 BoolState equalEqual(InstanceState rightOperand) { 3470 int get hashCode {
3175 assertBoolNumStringOrNull(rightOperand); 3471 int hashCode = 0;
3176 return isIdentical(rightOperand); 3472 for (DartObjectImpl value in _fieldMap.values) {
3473 hashCode += value.hashCode;
3474 }
3475 return hashCode;
3177 } 3476 }
3178 3477
3179 @override 3478 @override
3180 BoolState isIdentical(InstanceState rightOperand) { 3479 bool get isUnknown => identical(this, UNKNOWN_VALUE);
3181 if (rightOperand is DynamicState) { 3480
3182 return BoolState.UNKNOWN_VALUE; 3481 @override
3183 } 3482 String get typeName => "user defined type";
3184 return BoolState.from(this == rightOperand);
3185 }
3186 3483
3187 @override 3484 @override
3188 bool operator ==(Object object) { 3485 bool operator ==(Object object) {
3189 if (object is! GenericState) { 3486 if (object is! GenericState) {
3190 return false; 3487 return false;
3191 } 3488 }
3192 GenericState state = object as GenericState; 3489 GenericState state = object as GenericState;
3193 HashSet<String> otherFields = new HashSet<String>.from(state._fieldMap.keys. toSet()); 3490 HashSet<String> otherFields =
3491 new HashSet<String>.from(state._fieldMap.keys.toSet());
3194 for (String fieldName in _fieldMap.keys.toSet()) { 3492 for (String fieldName in _fieldMap.keys.toSet()) {
3195 if (_fieldMap[fieldName] != state._fieldMap[fieldName]) { 3493 if (_fieldMap[fieldName] != state._fieldMap[fieldName]) {
3196 return false; 3494 return false;
3197 } 3495 }
3198 otherFields.remove(fieldName); 3496 otherFields.remove(fieldName);
3199 } 3497 }
3200 for (String fieldName in otherFields) { 3498 for (String fieldName in otherFields) {
3201 if (state._fieldMap[fieldName] != _fieldMap[fieldName]) { 3499 if (state._fieldMap[fieldName] != _fieldMap[fieldName]) {
3202 return false; 3500 return false;
3203 } 3501 }
3204 } 3502 }
3205 return true; 3503 return true;
3206 } 3504 }
3207 3505
3208 @override 3506 @override
3209 HashMap<String, DartObjectImpl> get fields => _fieldMap; 3507 StringState convertToString() => StringState.UNKNOWN_VALUE;
3210 3508
3211 @override 3509 @override
3212 String get typeName => "user defined type"; 3510 BoolState equalEqual(InstanceState rightOperand) {
3213 3511 assertBoolNumStringOrNull(rightOperand);
3214 @override 3512 return isIdentical(rightOperand);
3215 int get hashCode {
3216 int hashCode = 0;
3217 for (DartObjectImpl value in _fieldMap.values) {
3218 hashCode += value.hashCode;
3219 }
3220 return hashCode;
3221 } 3513 }
3222 3514
3223 @override 3515 @override
3224 bool get isUnknown => identical(this, UNKNOWN_VALUE); 3516 BoolState isIdentical(InstanceState rightOperand) {
3517 if (rightOperand is DynamicState) {
3518 return BoolState.UNKNOWN_VALUE;
3519 }
3520 return BoolState.from(this == rightOperand);
3521 }
3225 } 3522 }
3226 3523
3227 /** 3524 /**
3228 * The class `InstanceState` defines the behavior of objects representing the st ate of a Dart 3525 * The class `InstanceState` defines the behavior of objects representing the st ate of a Dart
3229 * object. 3526 * object.
3230 */ 3527 */
3231 abstract class InstanceState { 3528 abstract class InstanceState {
3232 /** 3529 /**
3530 * If this represents a generic dart object, return a map from its fieldnames to their values.
3531 * Otherwise return null.
3532 */
3533 HashMap<String, DartObjectImpl> get fields => null;
3534
3535 /**
3536 * Return `true` if this object's value can be represented exactly.
3537 *
3538 * @return `true` if this object's value can be represented exactly
3539 */
3540 bool get hasExactValue => false;
3541
3542 /**
3543 * Return `true` if this object represents an object whose type is 'bool'.
3544 *
3545 * @return `true` if this object represents a boolean value
3546 */
3547 bool get isBool => false;
3548
3549 /**
3550 * Return `true` if this object represents an object whose type is either 'boo l', 'num',
3551 * 'String', or 'Null'.
3552 *
3553 * @return `true` if this object represents either a boolean, numeric, string or null value
3554 */
3555 bool get isBoolNumStringOrNull => false;
3556
3557 /**
3558 * Return true if this object represents an unknown value.
3559 */
3560 bool get isUnknown => false;
3561
3562 /**
3563 * Return the name of the type of this value.
3564 *
3565 * @return the name of the type of this value
3566 */
3567 String get typeName;
3568
3569 /**
3570 * Return this object's value if it can be represented exactly, or `null` if e ither the
3571 * value cannot be represented exactly or if the value is `null`. Clients shou ld use
3572 * [hasExactValue] to distinguish between these two cases.
3573 *
3574 * @return this object's value
3575 */
3576 Object get value => null;
3577
3578 /**
3233 * Return the result of invoking the '+' operator on this object with the give n argument. 3579 * Return the result of invoking the '+' operator on this object with the give n argument.
3234 * 3580 *
3235 * @param rightOperand the right-hand operand of the operation 3581 * @param rightOperand the right-hand operand of the operation
3236 * @return the result of invoking the '+' operator on this object with the giv en argument 3582 * @return the result of invoking the '+' operator on this object with the giv en argument
3237 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 3583 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
3238 */ 3584 */
3239 InstanceState add(InstanceState rightOperand) { 3585 InstanceState add(InstanceState rightOperand) {
3240 // TODO(brianwilkerson) Uncomment the code below when the new constant suppo rt can be added. 3586 // TODO(brianwilkerson) Uncomment the code below when the new constant
3241 // if (this instanceof StringState || rightOperand instanceof StringState ) { 3587 // support can be added.
3242 // return concatenate(rightOperand); 3588 // if (this instanceof StringState || rightOperand instanceof StringState) {
3243 // } 3589 // return concatenate(rightOperand);
3590 // }
3244 assertNumOrNull(this); 3591 assertNumOrNull(this);
3245 assertNumOrNull(rightOperand); 3592 assertNumOrNull(rightOperand);
3246 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); 3593 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
3247 } 3594 }
3248 3595
3249 /** 3596 /**
3597 * Throw an exception if the given state does not represent a boolean value.
3598 *
3599 * @param state the state being tested
3600 * @throws EvaluationException if the given state does not represent a boolean value
3601 */
3602 void assertBool(InstanceState state) {
3603 if (!(state is BoolState || state is DynamicState)) {
3604 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL);
3605 }
3606 }
3607
3608 /**
3609 * Throw an exception if the given state does not represent a boolean, numeric , string or null
3610 * value.
3611 *
3612 * @param state the state being tested
3613 * @throws EvaluationException if the given state does not represent a boolean , numeric, string or
3614 * null value
3615 */
3616 void assertBoolNumStringOrNull(InstanceState state) {
3617 if (!(state is BoolState ||
3618 state is DoubleState ||
3619 state is IntState ||
3620 state is NumState ||
3621 state is StringState ||
3622 state is NullState ||
3623 state is DynamicState)) {
3624 throw new EvaluationException(
3625 CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING);
3626 }
3627 }
3628
3629 /**
3630 * Throw an exception if the given state does not represent an integer or null value.
3631 *
3632 * @param state the state being tested
3633 * @throws EvaluationException if the given state does not represent an intege r or null value
3634 */
3635 void assertIntOrNull(InstanceState state) {
3636 if (!(state is IntState ||
3637 state is NumState ||
3638 state is NullState ||
3639 state is DynamicState)) {
3640 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
3641 }
3642 }
3643
3644 /**
3645 * Throw an exception if the given state does not represent a boolean, numeric , string or null
3646 * value.
3647 *
3648 * @param state the state being tested
3649 * @throws EvaluationException if the given state does not represent a boolean , numeric, string or
3650 * null value
3651 */
3652 void assertNumOrNull(InstanceState state) {
3653 if (!(state is DoubleState ||
3654 state is IntState ||
3655 state is NumState ||
3656 state is NullState ||
3657 state is DynamicState)) {
3658 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
3659 }
3660 }
3661
3662 /**
3663 * Throw an exception if the given state does not represent a String value.
3664 *
3665 * @param state the state being tested
3666 * @throws EvaluationException if the given state does not represent a String value
3667 */
3668 void assertString(InstanceState state) {
3669 if (!(state is StringState || state is DynamicState)) {
3670 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL);
3671 }
3672 }
3673
3674 /**
3250 * Return the result of invoking the '&' operator on this object with the give n argument. 3675 * Return the result of invoking the '&' operator on this object with the give n argument.
3251 * 3676 *
3252 * @param rightOperand the right-hand operand of the operation 3677 * @param rightOperand the right-hand operand of the operation
3253 * @return the result of invoking the '&' operator on this object with the giv en argument 3678 * @return the result of invoking the '&' operator on this object with the giv en argument
3254 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 3679 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
3255 */ 3680 */
3256 IntState bitAnd(InstanceState rightOperand) { 3681 IntState bitAnd(InstanceState rightOperand) {
3257 assertIntOrNull(this); 3682 assertIntOrNull(this);
3258 assertIntOrNull(rightOperand); 3683 assertIntOrNull(rightOperand);
3259 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); 3684 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
3341 /** 3766 /**
3342 * Return the result of invoking the '==' operator on this object with the giv en argument. 3767 * Return the result of invoking the '==' operator on this object with the giv en argument.
3343 * 3768 *
3344 * @param rightOperand the right-hand operand of the operation 3769 * @param rightOperand the right-hand operand of the operation
3345 * @return the result of invoking the '==' operator on this object with the gi ven argument 3770 * @return the result of invoking the '==' operator on this object with the gi ven argument
3346 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 3771 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
3347 */ 3772 */
3348 BoolState equalEqual(InstanceState rightOperand); 3773 BoolState equalEqual(InstanceState rightOperand);
3349 3774
3350 /** 3775 /**
3351 * If this represents a generic dart object, return a map from its fieldnames to their values.
3352 * Otherwise return null.
3353 */
3354 HashMap<String, DartObjectImpl> get fields => null;
3355
3356 /**
3357 * Return the name of the type of this value.
3358 *
3359 * @return the name of the type of this value
3360 */
3361 String get typeName;
3362
3363 /**
3364 * Return this object's value if it can be represented exactly, or `null` if e ither the
3365 * value cannot be represented exactly or if the value is `null`. Clients shou ld use
3366 * [hasExactValue] to distinguish between these two cases.
3367 *
3368 * @return this object's value
3369 */
3370 Object get value => null;
3371
3372 /**
3373 * Return the result of invoking the '&gt;' operator on this object with the g iven argument. 3776 * Return the result of invoking the '&gt;' operator on this object with the g iven argument.
3374 * 3777 *
3375 * @param rightOperand the right-hand operand of the operation 3778 * @param rightOperand the right-hand operand of the operation
3376 * @return the result of invoking the '&gt;' operator on this object with the given argument 3779 * @return the result of invoking the '&gt;' operator on this object with the given argument
3377 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 3780 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
3378 */ 3781 */
3379 BoolState greaterThan(InstanceState rightOperand) { 3782 BoolState greaterThan(InstanceState rightOperand) {
3380 assertNumOrNull(this); 3783 assertNumOrNull(this);
3381 assertNumOrNull(rightOperand); 3784 assertNumOrNull(rightOperand);
3382 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); 3785 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
3383 } 3786 }
3384 3787
3385 /** 3788 /**
3386 * Return the result of invoking the '&gt;=' operator on this object with the given argument. 3789 * Return the result of invoking the '&gt;=' operator on this object with the given argument.
3387 * 3790 *
3388 * @param rightOperand the right-hand operand of the operation 3791 * @param rightOperand the right-hand operand of the operation
3389 * @return the result of invoking the '&gt;=' operator on this object with the given argument 3792 * @return the result of invoking the '&gt;=' operator on this object with the given argument
3390 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 3793 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
3391 */ 3794 */
3392 BoolState greaterThanOrEqual(InstanceState rightOperand) { 3795 BoolState greaterThanOrEqual(InstanceState rightOperand) {
3393 assertNumOrNull(this); 3796 assertNumOrNull(this);
3394 assertNumOrNull(rightOperand); 3797 assertNumOrNull(rightOperand);
3395 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); 3798 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
3396 } 3799 }
3397 3800
3398 /** 3801 /**
3399 * Return `true` if this object's value can be represented exactly.
3400 *
3401 * @return `true` if this object's value can be represented exactly
3402 */
3403 bool get hasExactValue => false;
3404
3405 /**
3406 * Return the result of invoking the '~/' operator on this object with the giv en argument. 3802 * Return the result of invoking the '~/' operator on this object with the giv en argument.
3407 * 3803 *
3408 * @param rightOperand the right-hand operand of the operation 3804 * @param rightOperand the right-hand operand of the operation
3409 * @return the result of invoking the '~/' operator on this object with the gi ven argument 3805 * @return the result of invoking the '~/' operator on this object with the gi ven argument
3410 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 3806 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
3411 */ 3807 */
3412 IntState integerDivide(InstanceState rightOperand) { 3808 IntState integerDivide(InstanceState rightOperand) {
3413 assertNumOrNull(this); 3809 assertNumOrNull(this);
3414 assertNumOrNull(rightOperand); 3810 assertNumOrNull(rightOperand);
3415 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); 3811 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
3416 } 3812 }
3417 3813
3418 /** 3814 /**
3419 * Return the result of invoking the identical function on this object with 3815 * Return the result of invoking the identical function on this object with
3420 * the given argument. 3816 * the given argument.
3421 * 3817 *
3422 * @param rightOperand the right-hand operand of the operation 3818 * @param rightOperand the right-hand operand of the operation
3423 * @return the result of invoking the identical function on this object with 3819 * @return the result of invoking the identical function on this object with
3424 * the given argument 3820 * the given argument
3425 */ 3821 */
3426 BoolState isIdentical(InstanceState rightOperand); 3822 BoolState isIdentical(InstanceState rightOperand);
3427 3823
3428 /** 3824 /**
3429 * Return `true` if this object represents an object whose type is 'bool'.
3430 *
3431 * @return `true` if this object represents a boolean value
3432 */
3433 bool get isBool => false;
3434
3435 /**
3436 * Return `true` if this object represents an object whose type is either 'boo l', 'num',
3437 * 'String', or 'Null'.
3438 *
3439 * @return `true` if this object represents either a boolean, numeric, string or null value
3440 */
3441 bool get isBoolNumStringOrNull => false;
3442
3443 /**
3444 * Return true if this object represents an unknown value.
3445 */
3446 bool get isUnknown => false;
3447
3448 /**
3449 * Return the result of invoking the '&lt;' operator on this object with the g iven argument. 3825 * Return the result of invoking the '&lt;' operator on this object with the g iven argument.
3450 * 3826 *
3451 * @param rightOperand the right-hand operand of the operation 3827 * @param rightOperand the right-hand operand of the operation
3452 * @return the result of invoking the '&lt;' operator on this object with the given argument 3828 * @return the result of invoking the '&lt;' operator on this object with the given argument
3453 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 3829 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
3454 */ 3830 */
3455 BoolState lessThan(InstanceState rightOperand) { 3831 BoolState lessThan(InstanceState rightOperand) {
3456 assertNumOrNull(this); 3832 assertNumOrNull(this);
3457 assertNumOrNull(rightOperand); 3833 assertNumOrNull(rightOperand);
3458 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); 3834 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
3587 * 3963 *
3588 * @param rightOperand the right-hand operand of the operation 3964 * @param rightOperand the right-hand operand of the operation
3589 * @return the result of invoking the '*' operator on this object with the giv en argument 3965 * @return the result of invoking the '*' operator on this object with the giv en argument
3590 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind 3966 * @throws EvaluationException if the operator is not appropriate for an objec t of this kind
3591 */ 3967 */
3592 NumState times(InstanceState rightOperand) { 3968 NumState times(InstanceState rightOperand) {
3593 assertNumOrNull(this); 3969 assertNumOrNull(this);
3594 assertNumOrNull(rightOperand); 3970 assertNumOrNull(rightOperand);
3595 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT); 3971 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
3596 } 3972 }
3597
3598 /**
3599 * Throw an exception if the given state does not represent a boolean value.
3600 *
3601 * @param state the state being tested
3602 * @throws EvaluationException if the given state does not represent a boolean value
3603 */
3604 void assertBool(InstanceState state) {
3605 if (!(state is BoolState || state is DynamicState)) {
3606 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL);
3607 }
3608 }
3609
3610 /**
3611 * Throw an exception if the given state does not represent a boolean, numeric , string or null
3612 * value.
3613 *
3614 * @param state the state being tested
3615 * @throws EvaluationException if the given state does not represent a boolean , numeric, string or
3616 * null value
3617 */
3618 void assertBoolNumStringOrNull(InstanceState state) {
3619 if (!(state is BoolState || state is DoubleState || state is IntState || sta te is NumState || state is StringState || state is NullState || state is Dynamic State)) {
3620 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NU M_STRING);
3621 }
3622 }
3623
3624 /**
3625 * Throw an exception if the given state does not represent an integer or null value.
3626 *
3627 * @param state the state being tested
3628 * @throws EvaluationException if the given state does not represent an intege r or null value
3629 */
3630 void assertIntOrNull(InstanceState state) {
3631 if (!(state is IntState || state is NumState || state is NullState || state is DynamicState)) {
3632 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
3633 }
3634 }
3635
3636 /**
3637 * Throw an exception if the given state does not represent a boolean, numeric , string or null
3638 * value.
3639 *
3640 * @param state the state being tested
3641 * @throws EvaluationException if the given state does not represent a boolean , numeric, string or
3642 * null value
3643 */
3644 void assertNumOrNull(InstanceState state) {
3645 if (!(state is DoubleState || state is IntState || state is NumState || stat e is NullState || state is DynamicState)) {
3646 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
3647 }
3648 }
3649
3650 /**
3651 * Throw an exception if the given state does not represent a String value.
3652 *
3653 * @param state the state being tested
3654 * @throws EvaluationException if the given state does not represent a String value
3655 */
3656 void assertString(InstanceState state) {
3657 if (!(state is StringState || state is DynamicState)) {
3658 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL);
3659 }
3660 }
3661 } 3973 }
3662 3974
3663 /** 3975 /**
3664 * Instances of the class `IntState` represent the state of an object representi ng an int. 3976 * Instances of the class `IntState` represent the state of an object representi ng an int.
3665 */ 3977 */
3666 class IntState extends NumState { 3978 class IntState extends NumState {
3667 /** 3979 /**
3980 * A state that can be used to represent an int whose value is not known.
3981 */
3982 static IntState UNKNOWN_VALUE = new IntState(null);
3983
3984 /**
3668 * The value of this instance. 3985 * The value of this instance.
3669 */ 3986 */
3670 final int value; 3987 final int value;
3671 3988
3672 /** 3989 /**
3673 * A state that can be used to represent an int whose value is not known.
3674 */
3675 static IntState UNKNOWN_VALUE = new IntState(null);
3676
3677 /**
3678 * Initialize a newly created state to represent an int with the given value. 3990 * Initialize a newly created state to represent an int with the given value.
3679 * 3991 *
3680 * @param value the value of this instance 3992 * @param value the value of this instance
3681 */ 3993 */
3682 IntState(this.value); 3994 IntState(this.value);
3683 3995
3684 @override 3996 @override
3997 bool get hasExactValue => true;
3998
3999 @override
4000 int get hashCode => value == null ? 0 : value.hashCode;
4001
4002 @override
4003 bool get isBoolNumStringOrNull => true;
4004
4005 @override
4006 bool get isUnknown => value == null;
4007
4008 @override
4009 String get typeName => "int";
4010
4011 @override
4012 bool operator ==(Object object) =>
4013 object is IntState && (value == object.value);
4014
4015 @override
3685 NumState add(InstanceState rightOperand) { 4016 NumState add(InstanceState rightOperand) {
3686 assertNumOrNull(rightOperand); 4017 assertNumOrNull(rightOperand);
3687 if (value == null) { 4018 if (value == null) {
3688 if (rightOperand is DoubleState) { 4019 if (rightOperand is DoubleState) {
3689 return DoubleState.UNKNOWN_VALUE; 4020 return DoubleState.UNKNOWN_VALUE;
3690 } 4021 }
3691 return UNKNOWN_VALUE; 4022 return UNKNOWN_VALUE;
3692 } 4023 }
3693 if (rightOperand is IntState) { 4024 if (rightOperand is IntState) {
3694 int rightValue = rightOperand.value; 4025 int rightValue = rightOperand.value;
3695 if (rightValue == null) { 4026 if (rightValue == null) {
3696 return UNKNOWN_VALUE; 4027 return UNKNOWN_VALUE;
3697 } 4028 }
3698 return new IntState(value + rightValue); 4029 return new IntState(value + rightValue);
3699 } else if (rightOperand is DoubleState) { 4030 } else if (rightOperand is DoubleState) {
3700 double rightValue = rightOperand.value; 4031 double rightValue = rightOperand.value;
3701 if (rightValue == null) { 4032 if (rightValue == null) {
3702 return DoubleState.UNKNOWN_VALUE; 4033 return DoubleState.UNKNOWN_VALUE;
3703 } 4034 }
3704 return new DoubleState(value.toDouble() + rightValue); 4035 return new DoubleState(value.toDouble() + rightValue);
3705 } else if (rightOperand is DynamicState || rightOperand is NumState) { 4036 } else if (rightOperand is DynamicState || rightOperand is NumState) {
3706 return UNKNOWN_VALUE; 4037 return UNKNOWN_VALUE;
3707 } 4038 }
3708 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI ON); 4039 throw new EvaluationException(
4040 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
3709 } 4041 }
3710 4042
3711 @override 4043 @override
3712 IntState bitAnd(InstanceState rightOperand) { 4044 IntState bitAnd(InstanceState rightOperand) {
3713 assertIntOrNull(rightOperand); 4045 assertIntOrNull(rightOperand);
3714 if (value == null) { 4046 if (value == null) {
3715 return UNKNOWN_VALUE; 4047 return UNKNOWN_VALUE;
3716 } 4048 }
3717 if (rightOperand is IntState) { 4049 if (rightOperand is IntState) {
3718 int rightValue = rightOperand.value; 4050 int rightValue = rightOperand.value;
3719 if (rightValue == null) { 4051 if (rightValue == null) {
3720 return UNKNOWN_VALUE; 4052 return UNKNOWN_VALUE;
3721 } 4053 }
3722 return new IntState(value & rightValue); 4054 return new IntState(value & rightValue);
3723 } else if (rightOperand is DynamicState || rightOperand is NumState) { 4055 } else if (rightOperand is DynamicState || rightOperand is NumState) {
3724 return UNKNOWN_VALUE; 4056 return UNKNOWN_VALUE;
3725 } 4057 }
3726 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI ON); 4058 throw new EvaluationException(
4059 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
3727 } 4060 }
3728 4061
3729 @override 4062 @override
3730 IntState bitNot() { 4063 IntState bitNot() {
3731 if (value == null) { 4064 if (value == null) {
3732 return UNKNOWN_VALUE; 4065 return UNKNOWN_VALUE;
3733 } 4066 }
3734 return new IntState(~value); 4067 return new IntState(~value);
3735 } 4068 }
3736 4069
3737 @override 4070 @override
3738 IntState bitOr(InstanceState rightOperand) { 4071 IntState bitOr(InstanceState rightOperand) {
3739 assertIntOrNull(rightOperand); 4072 assertIntOrNull(rightOperand);
3740 if (value == null) { 4073 if (value == null) {
3741 return UNKNOWN_VALUE; 4074 return UNKNOWN_VALUE;
3742 } 4075 }
3743 if (rightOperand is IntState) { 4076 if (rightOperand is IntState) {
3744 int rightValue = rightOperand.value; 4077 int rightValue = rightOperand.value;
3745 if (rightValue == null) { 4078 if (rightValue == null) {
3746 return UNKNOWN_VALUE; 4079 return UNKNOWN_VALUE;
3747 } 4080 }
3748 return new IntState(value | rightValue); 4081 return new IntState(value | rightValue);
3749 } else if (rightOperand is DynamicState || rightOperand is NumState) { 4082 } else if (rightOperand is DynamicState || rightOperand is NumState) {
3750 return UNKNOWN_VALUE; 4083 return UNKNOWN_VALUE;
3751 } 4084 }
3752 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI ON); 4085 throw new EvaluationException(
4086 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
3753 } 4087 }
3754 4088
3755 @override 4089 @override
3756 IntState bitXor(InstanceState rightOperand) { 4090 IntState bitXor(InstanceState rightOperand) {
3757 assertIntOrNull(rightOperand); 4091 assertIntOrNull(rightOperand);
3758 if (value == null) { 4092 if (value == null) {
3759 return UNKNOWN_VALUE; 4093 return UNKNOWN_VALUE;
3760 } 4094 }
3761 if (rightOperand is IntState) { 4095 if (rightOperand is IntState) {
3762 int rightValue = rightOperand.value; 4096 int rightValue = rightOperand.value;
3763 if (rightValue == null) { 4097 if (rightValue == null) {
3764 return UNKNOWN_VALUE; 4098 return UNKNOWN_VALUE;
3765 } 4099 }
3766 return new IntState(value ^ rightValue); 4100 return new IntState(value ^ rightValue);
3767 } else if (rightOperand is DynamicState || rightOperand is NumState) { 4101 } else if (rightOperand is DynamicState || rightOperand is NumState) {
3768 return UNKNOWN_VALUE; 4102 return UNKNOWN_VALUE;
3769 } 4103 }
3770 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI ON); 4104 throw new EvaluationException(
4105 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
3771 } 4106 }
3772 4107
3773 @override 4108 @override
3774 StringState convertToString() { 4109 StringState convertToString() {
3775 if (value == null) { 4110 if (value == null) {
3776 return StringState.UNKNOWN_VALUE; 4111 return StringState.UNKNOWN_VALUE;
3777 } 4112 }
3778 return new StringState(value.toString()); 4113 return new StringState(value.toString());
3779 } 4114 }
3780 4115
(...skipping 16 matching lines...) Expand all
3797 return new IntState(value ~/ rightValue); 4132 return new IntState(value ~/ rightValue);
3798 } else if (rightOperand is DoubleState) { 4133 } else if (rightOperand is DoubleState) {
3799 double rightValue = rightOperand.value; 4134 double rightValue = rightOperand.value;
3800 if (rightValue == null) { 4135 if (rightValue == null) {
3801 return DoubleState.UNKNOWN_VALUE; 4136 return DoubleState.UNKNOWN_VALUE;
3802 } 4137 }
3803 return new DoubleState(value.toDouble() / rightValue); 4138 return new DoubleState(value.toDouble() / rightValue);
3804 } else if (rightOperand is DynamicState || rightOperand is NumState) { 4139 } else if (rightOperand is DynamicState || rightOperand is NumState) {
3805 return UNKNOWN_VALUE; 4140 return UNKNOWN_VALUE;
3806 } 4141 }
3807 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI ON); 4142 throw new EvaluationException(
4143 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
3808 } 4144 }
3809 4145
3810 @override 4146 @override
3811 BoolState equalEqual(InstanceState rightOperand) { 4147 BoolState equalEqual(InstanceState rightOperand) {
3812 assertBoolNumStringOrNull(rightOperand); 4148 assertBoolNumStringOrNull(rightOperand);
3813 return isIdentical(rightOperand); 4149 return isIdentical(rightOperand);
3814 } 4150 }
3815 4151
3816 @override 4152 @override
3817 BoolState isIdentical(InstanceState rightOperand) {
3818 if (value == null) {
3819 return BoolState.UNKNOWN_VALUE;
3820 }
3821 if (rightOperand is IntState) {
3822 int rightValue = rightOperand.value;
3823 if (rightValue == null) {
3824 return BoolState.UNKNOWN_VALUE;
3825 }
3826 return BoolState.from(value == rightValue);
3827 } else if (rightOperand is DoubleState) {
3828 double rightValue = rightOperand.value;
3829 if (rightValue == null) {
3830 return BoolState.UNKNOWN_VALUE;
3831 }
3832 return BoolState.from(rightValue == value.toDouble());
3833 } else if (rightOperand is DynamicState || rightOperand is NumState) {
3834 return BoolState.UNKNOWN_VALUE;
3835 }
3836 return BoolState.FALSE_STATE;
3837 }
3838
3839 @override
3840 bool operator ==(Object object) => object is IntState && (value == object.valu e);
3841
3842 @override
3843 String get typeName => "int";
3844
3845 @override
3846 BoolState greaterThan(InstanceState rightOperand) { 4153 BoolState greaterThan(InstanceState rightOperand) {
3847 assertNumOrNull(rightOperand); 4154 assertNumOrNull(rightOperand);
3848 if (value == null) { 4155 if (value == null) {
3849 return BoolState.UNKNOWN_VALUE; 4156 return BoolState.UNKNOWN_VALUE;
3850 } 4157 }
3851 if (rightOperand is IntState) { 4158 if (rightOperand is IntState) {
3852 int rightValue = rightOperand.value; 4159 int rightValue = rightOperand.value;
3853 if (rightValue == null) { 4160 if (rightValue == null) {
3854 return BoolState.UNKNOWN_VALUE; 4161 return BoolState.UNKNOWN_VALUE;
3855 } 4162 }
3856 return BoolState.from(value.compareTo(rightValue) > 0); 4163 return BoolState.from(value.compareTo(rightValue) > 0);
3857 } else if (rightOperand is DoubleState) { 4164 } else if (rightOperand is DoubleState) {
3858 double rightValue = rightOperand.value; 4165 double rightValue = rightOperand.value;
3859 if (rightValue == null) { 4166 if (rightValue == null) {
3860 return BoolState.UNKNOWN_VALUE; 4167 return BoolState.UNKNOWN_VALUE;
3861 } 4168 }
3862 return BoolState.from(value.toDouble() > rightValue); 4169 return BoolState.from(value.toDouble() > rightValue);
3863 } else if (rightOperand is DynamicState || rightOperand is NumState) { 4170 } else if (rightOperand is DynamicState || rightOperand is NumState) {
3864 return BoolState.UNKNOWN_VALUE; 4171 return BoolState.UNKNOWN_VALUE;
3865 } 4172 }
3866 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI ON); 4173 throw new EvaluationException(
4174 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
3867 } 4175 }
3868 4176
3869 @override 4177 @override
3870 BoolState greaterThanOrEqual(InstanceState rightOperand) { 4178 BoolState greaterThanOrEqual(InstanceState rightOperand) {
3871 assertNumOrNull(rightOperand); 4179 assertNumOrNull(rightOperand);
3872 if (value == null) { 4180 if (value == null) {
3873 return BoolState.UNKNOWN_VALUE; 4181 return BoolState.UNKNOWN_VALUE;
3874 } 4182 }
3875 if (rightOperand is IntState) { 4183 if (rightOperand is IntState) {
3876 int rightValue = rightOperand.value; 4184 int rightValue = rightOperand.value;
3877 if (rightValue == null) { 4185 if (rightValue == null) {
3878 return BoolState.UNKNOWN_VALUE; 4186 return BoolState.UNKNOWN_VALUE;
3879 } 4187 }
3880 return BoolState.from(value.compareTo(rightValue) >= 0); 4188 return BoolState.from(value.compareTo(rightValue) >= 0);
3881 } else if (rightOperand is DoubleState) { 4189 } else if (rightOperand is DoubleState) {
3882 double rightValue = rightOperand.value; 4190 double rightValue = rightOperand.value;
3883 if (rightValue == null) { 4191 if (rightValue == null) {
3884 return BoolState.UNKNOWN_VALUE; 4192 return BoolState.UNKNOWN_VALUE;
3885 } 4193 }
3886 return BoolState.from(value.toDouble() >= rightValue); 4194 return BoolState.from(value.toDouble() >= rightValue);
3887 } else if (rightOperand is DynamicState || rightOperand is NumState) { 4195 } else if (rightOperand is DynamicState || rightOperand is NumState) {
3888 return BoolState.UNKNOWN_VALUE; 4196 return BoolState.UNKNOWN_VALUE;
3889 } 4197 }
3890 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI ON); 4198 throw new EvaluationException(
4199 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
3891 } 4200 }
3892 4201
3893 @override 4202 @override
3894 bool get hasExactValue => true;
3895
3896 @override
3897 int get hashCode => value == null ? 0 : value.hashCode;
3898
3899 @override
3900 IntState integerDivide(InstanceState rightOperand) { 4203 IntState integerDivide(InstanceState rightOperand) {
3901 assertNumOrNull(rightOperand); 4204 assertNumOrNull(rightOperand);
3902 if (value == null) { 4205 if (value == null) {
3903 return UNKNOWN_VALUE; 4206 return UNKNOWN_VALUE;
3904 } 4207 }
3905 if (rightOperand is IntState) { 4208 if (rightOperand is IntState) {
3906 int rightValue = rightOperand.value; 4209 int rightValue = rightOperand.value;
3907 if (rightValue == null) { 4210 if (rightValue == null) {
3908 return UNKNOWN_VALUE; 4211 return UNKNOWN_VALUE;
3909 } else if (rightValue == 0) { 4212 } else if (rightValue == 0) {
3910 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_IDB ZE); 4213 throw new EvaluationException(
4214 CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE);
3911 } 4215 }
3912 return new IntState(value ~/ rightValue); 4216 return new IntState(value ~/ rightValue);
3913 } else if (rightOperand is DoubleState) { 4217 } else if (rightOperand is DoubleState) {
3914 double rightValue = rightOperand.value; 4218 double rightValue = rightOperand.value;
3915 if (rightValue == null) { 4219 if (rightValue == null) {
3916 return UNKNOWN_VALUE; 4220 return UNKNOWN_VALUE;
3917 } 4221 }
3918 double result = value.toDouble() / rightValue; 4222 double result = value.toDouble() / rightValue;
3919 return new IntState(result.toInt()); 4223 return new IntState(result.toInt());
3920 } else if (rightOperand is DynamicState || rightOperand is NumState) { 4224 } else if (rightOperand is DynamicState || rightOperand is NumState) {
3921 return UNKNOWN_VALUE; 4225 return UNKNOWN_VALUE;
3922 } 4226 }
3923 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI ON); 4227 throw new EvaluationException(
4228 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
3924 } 4229 }
3925 4230
3926 @override 4231 @override
3927 bool get isBoolNumStringOrNull => true; 4232 BoolState isIdentical(InstanceState rightOperand) {
3928 4233 if (value == null) {
3929 @override 4234 return BoolState.UNKNOWN_VALUE;
3930 bool get isUnknown => value == null; 4235 }
4236 if (rightOperand is IntState) {
4237 int rightValue = rightOperand.value;
4238 if (rightValue == null) {
4239 return BoolState.UNKNOWN_VALUE;
4240 }
4241 return BoolState.from(value == rightValue);
4242 } else if (rightOperand is DoubleState) {
4243 double rightValue = rightOperand.value;
4244 if (rightValue == null) {
4245 return BoolState.UNKNOWN_VALUE;
4246 }
4247 return BoolState.from(rightValue == value.toDouble());
4248 } else if (rightOperand is DynamicState || rightOperand is NumState) {
4249 return BoolState.UNKNOWN_VALUE;
4250 }
4251 return BoolState.FALSE_STATE;
4252 }
3931 4253
3932 @override 4254 @override
3933 BoolState lessThan(InstanceState rightOperand) { 4255 BoolState lessThan(InstanceState rightOperand) {
3934 assertNumOrNull(rightOperand); 4256 assertNumOrNull(rightOperand);
3935 if (value == null) { 4257 if (value == null) {
3936 return BoolState.UNKNOWN_VALUE; 4258 return BoolState.UNKNOWN_VALUE;
3937 } 4259 }
3938 if (rightOperand is IntState) { 4260 if (rightOperand is IntState) {
3939 int rightValue = rightOperand.value; 4261 int rightValue = rightOperand.value;
3940 if (rightValue == null) { 4262 if (rightValue == null) {
3941 return BoolState.UNKNOWN_VALUE; 4263 return BoolState.UNKNOWN_VALUE;
3942 } 4264 }
3943 return BoolState.from(value.compareTo(rightValue) < 0); 4265 return BoolState.from(value.compareTo(rightValue) < 0);
3944 } else if (rightOperand is DoubleState) { 4266 } else if (rightOperand is DoubleState) {
3945 double rightValue = rightOperand.value; 4267 double rightValue = rightOperand.value;
3946 if (rightValue == null) { 4268 if (rightValue == null) {
3947 return BoolState.UNKNOWN_VALUE; 4269 return BoolState.UNKNOWN_VALUE;
3948 } 4270 }
3949 return BoolState.from(value.toDouble() < rightValue); 4271 return BoolState.from(value.toDouble() < rightValue);
3950 } else if (rightOperand is DynamicState || rightOperand is NumState) { 4272 } else if (rightOperand is DynamicState || rightOperand is NumState) {
3951 return BoolState.UNKNOWN_VALUE; 4273 return BoolState.UNKNOWN_VALUE;
3952 } 4274 }
3953 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI ON); 4275 throw new EvaluationException(
4276 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
3954 } 4277 }
3955 4278
3956 @override 4279 @override
3957 BoolState lessThanOrEqual(InstanceState rightOperand) { 4280 BoolState lessThanOrEqual(InstanceState rightOperand) {
3958 assertNumOrNull(rightOperand); 4281 assertNumOrNull(rightOperand);
3959 if (value == null) { 4282 if (value == null) {
3960 return BoolState.UNKNOWN_VALUE; 4283 return BoolState.UNKNOWN_VALUE;
3961 } 4284 }
3962 if (rightOperand is IntState) { 4285 if (rightOperand is IntState) {
3963 int rightValue = rightOperand.value; 4286 int rightValue = rightOperand.value;
3964 if (rightValue == null) { 4287 if (rightValue == null) {
3965 return BoolState.UNKNOWN_VALUE; 4288 return BoolState.UNKNOWN_VALUE;
3966 } 4289 }
3967 return BoolState.from(value.compareTo(rightValue) <= 0); 4290 return BoolState.from(value.compareTo(rightValue) <= 0);
3968 } else if (rightOperand is DoubleState) { 4291 } else if (rightOperand is DoubleState) {
3969 double rightValue = rightOperand.value; 4292 double rightValue = rightOperand.value;
3970 if (rightValue == null) { 4293 if (rightValue == null) {
3971 return BoolState.UNKNOWN_VALUE; 4294 return BoolState.UNKNOWN_VALUE;
3972 } 4295 }
3973 return BoolState.from(value.toDouble() <= rightValue); 4296 return BoolState.from(value.toDouble() <= rightValue);
3974 } else if (rightOperand is DynamicState || rightOperand is NumState) { 4297 } else if (rightOperand is DynamicState || rightOperand is NumState) {
3975 return BoolState.UNKNOWN_VALUE; 4298 return BoolState.UNKNOWN_VALUE;
3976 } 4299 }
3977 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI ON); 4300 throw new EvaluationException(
4301 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
3978 } 4302 }
3979 4303
3980 @override 4304 @override
3981 NumState minus(InstanceState rightOperand) { 4305 NumState minus(InstanceState rightOperand) {
3982 assertNumOrNull(rightOperand); 4306 assertNumOrNull(rightOperand);
3983 if (value == null) { 4307 if (value == null) {
3984 if (rightOperand is DoubleState) { 4308 if (rightOperand is DoubleState) {
3985 return DoubleState.UNKNOWN_VALUE; 4309 return DoubleState.UNKNOWN_VALUE;
3986 } 4310 }
3987 return UNKNOWN_VALUE; 4311 return UNKNOWN_VALUE;
3988 } 4312 }
3989 if (rightOperand is IntState) { 4313 if (rightOperand is IntState) {
3990 int rightValue = rightOperand.value; 4314 int rightValue = rightOperand.value;
3991 if (rightValue == null) { 4315 if (rightValue == null) {
3992 return UNKNOWN_VALUE; 4316 return UNKNOWN_VALUE;
3993 } 4317 }
3994 return new IntState(value - rightValue); 4318 return new IntState(value - rightValue);
3995 } else if (rightOperand is DoubleState) { 4319 } else if (rightOperand is DoubleState) {
3996 double rightValue = rightOperand.value; 4320 double rightValue = rightOperand.value;
3997 if (rightValue == null) { 4321 if (rightValue == null) {
3998 return DoubleState.UNKNOWN_VALUE; 4322 return DoubleState.UNKNOWN_VALUE;
3999 } 4323 }
4000 return new DoubleState(value.toDouble() - rightValue); 4324 return new DoubleState(value.toDouble() - rightValue);
4001 } else if (rightOperand is DynamicState || rightOperand is NumState) { 4325 } else if (rightOperand is DynamicState || rightOperand is NumState) {
4002 return UNKNOWN_VALUE; 4326 return UNKNOWN_VALUE;
4003 } 4327 }
4004 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI ON); 4328 throw new EvaluationException(
4329 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
4005 } 4330 }
4006 4331
4007 @override 4332 @override
4008 NumState negated() { 4333 NumState negated() {
4009 if (value == null) { 4334 if (value == null) {
4010 return UNKNOWN_VALUE; 4335 return UNKNOWN_VALUE;
4011 } 4336 }
4012 return new IntState(-value); 4337 return new IntState(-value);
4013 } 4338 }
4014 4339
(...skipping 16 matching lines...) Expand all
4031 return new IntState(value.remainder(rightValue)); 4356 return new IntState(value.remainder(rightValue));
4032 } else if (rightOperand is DoubleState) { 4357 } else if (rightOperand is DoubleState) {
4033 double rightValue = rightOperand.value; 4358 double rightValue = rightOperand.value;
4034 if (rightValue == null) { 4359 if (rightValue == null) {
4035 return DoubleState.UNKNOWN_VALUE; 4360 return DoubleState.UNKNOWN_VALUE;
4036 } 4361 }
4037 return new DoubleState(value.toDouble() % rightValue); 4362 return new DoubleState(value.toDouble() % rightValue);
4038 } else if (rightOperand is DynamicState || rightOperand is NumState) { 4363 } else if (rightOperand is DynamicState || rightOperand is NumState) {
4039 return UNKNOWN_VALUE; 4364 return UNKNOWN_VALUE;
4040 } 4365 }
4041 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI ON); 4366 throw new EvaluationException(
4367 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
4042 } 4368 }
4043 4369
4044 @override 4370 @override
4045 IntState shiftLeft(InstanceState rightOperand) { 4371 IntState shiftLeft(InstanceState rightOperand) {
4046 assertIntOrNull(rightOperand); 4372 assertIntOrNull(rightOperand);
4047 if (value == null) { 4373 if (value == null) {
4048 return UNKNOWN_VALUE; 4374 return UNKNOWN_VALUE;
4049 } 4375 }
4050 if (rightOperand is IntState) { 4376 if (rightOperand is IntState) {
4051 int rightValue = rightOperand.value; 4377 int rightValue = rightOperand.value;
4052 if (rightValue == null) { 4378 if (rightValue == null) {
4053 return UNKNOWN_VALUE; 4379 return UNKNOWN_VALUE;
4054 } else if (rightValue.bitLength > 31) { 4380 } else if (rightValue.bitLength > 31) {
4055 return UNKNOWN_VALUE; 4381 return UNKNOWN_VALUE;
4056 } 4382 }
4057 return new IntState(value << rightValue); 4383 return new IntState(value << rightValue);
4058 } else if (rightOperand is DynamicState || rightOperand is NumState) { 4384 } else if (rightOperand is DynamicState || rightOperand is NumState) {
4059 return UNKNOWN_VALUE; 4385 return UNKNOWN_VALUE;
4060 } 4386 }
4061 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI ON); 4387 throw new EvaluationException(
4388 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
4062 } 4389 }
4063 4390
4064 @override 4391 @override
4065 IntState shiftRight(InstanceState rightOperand) { 4392 IntState shiftRight(InstanceState rightOperand) {
4066 assertIntOrNull(rightOperand); 4393 assertIntOrNull(rightOperand);
4067 if (value == null) { 4394 if (value == null) {
4068 return UNKNOWN_VALUE; 4395 return UNKNOWN_VALUE;
4069 } 4396 }
4070 if (rightOperand is IntState) { 4397 if (rightOperand is IntState) {
4071 int rightValue = rightOperand.value; 4398 int rightValue = rightOperand.value;
4072 if (rightValue == null) { 4399 if (rightValue == null) {
4073 return UNKNOWN_VALUE; 4400 return UNKNOWN_VALUE;
4074 } else if (rightValue.bitLength > 31) { 4401 } else if (rightValue.bitLength > 31) {
4075 return UNKNOWN_VALUE; 4402 return UNKNOWN_VALUE;
4076 } 4403 }
4077 return new IntState(value >> rightValue); 4404 return new IntState(value >> rightValue);
4078 } else if (rightOperand is DynamicState || rightOperand is NumState) { 4405 } else if (rightOperand is DynamicState || rightOperand is NumState) {
4079 return UNKNOWN_VALUE; 4406 return UNKNOWN_VALUE;
4080 } 4407 }
4081 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI ON); 4408 throw new EvaluationException(
4409 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
4082 } 4410 }
4083 4411
4084 @override 4412 @override
4085 NumState times(InstanceState rightOperand) { 4413 NumState times(InstanceState rightOperand) {
4086 assertNumOrNull(rightOperand); 4414 assertNumOrNull(rightOperand);
4087 if (value == null) { 4415 if (value == null) {
4088 if (rightOperand is DoubleState) { 4416 if (rightOperand is DoubleState) {
4089 return DoubleState.UNKNOWN_VALUE; 4417 return DoubleState.UNKNOWN_VALUE;
4090 } 4418 }
4091 return UNKNOWN_VALUE; 4419 return UNKNOWN_VALUE;
4092 } 4420 }
4093 if (rightOperand is IntState) { 4421 if (rightOperand is IntState) {
4094 int rightValue = rightOperand.value; 4422 int rightValue = rightOperand.value;
4095 if (rightValue == null) { 4423 if (rightValue == null) {
4096 return UNKNOWN_VALUE; 4424 return UNKNOWN_VALUE;
4097 } 4425 }
4098 return new IntState(value * rightValue); 4426 return new IntState(value * rightValue);
4099 } else if (rightOperand is DoubleState) { 4427 } else if (rightOperand is DoubleState) {
4100 double rightValue = rightOperand.value; 4428 double rightValue = rightOperand.value;
4101 if (rightValue == null) { 4429 if (rightValue == null) {
4102 return DoubleState.UNKNOWN_VALUE; 4430 return DoubleState.UNKNOWN_VALUE;
4103 } 4431 }
4104 return new DoubleState(value.toDouble() * rightValue); 4432 return new DoubleState(value.toDouble() * rightValue);
4105 } else if (rightOperand is DynamicState || rightOperand is NumState) { 4433 } else if (rightOperand is DynamicState || rightOperand is NumState) {
4106 return UNKNOWN_VALUE; 4434 return UNKNOWN_VALUE;
4107 } 4435 }
4108 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI ON); 4436 throw new EvaluationException(
4437 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
4109 } 4438 }
4110 4439
4111 @override 4440 @override
4112 String toString() => value == null ? "-unknown-" : value.toString(); 4441 String toString() => value == null ? "-unknown-" : value.toString();
4113 } 4442 }
4114 4443
4115 /** 4444 /**
4116 * The unique instance of the class `ListState` represents the state of an objec t representing 4445 * The unique instance of the class `ListState` represents the state of an objec t representing
4117 * a list. 4446 * a list.
4118 */ 4447 */
4119 class ListState extends InstanceState { 4448 class ListState extends InstanceState {
4120 /** 4449 /**
4121 * The elements of the list. 4450 * The elements of the list.
4122 */ 4451 */
4123 final List<DartObjectImpl> _elements; 4452 final List<DartObjectImpl> _elements;
4124 4453
4125 /** 4454 /**
4126 * Initialize a newly created state to represent a list with the given element s. 4455 * Initialize a newly created state to represent a list with the given element s.
4127 * 4456 *
4128 * @param elements the elements of the list 4457 * @param elements the elements of the list
4129 */ 4458 */
4130 ListState(this._elements); 4459 ListState(this._elements);
4131 4460
4132 @override 4461 @override
4133 StringState convertToString() => StringState.UNKNOWN_VALUE; 4462 bool get hasExactValue {
4134
4135 @override
4136 BoolState equalEqual(InstanceState rightOperand) {
4137 assertBoolNumStringOrNull(rightOperand);
4138 return isIdentical(rightOperand);
4139 }
4140
4141 @override
4142 BoolState isIdentical(InstanceState rightOperand) {
4143 if (rightOperand is DynamicState) {
4144 return BoolState.UNKNOWN_VALUE;
4145 }
4146 return BoolState.from(this == rightOperand);
4147 }
4148
4149 @override
4150 bool operator ==(Object object) {
4151 if (object is! ListState) {
4152 return false;
4153 }
4154 List<DartObjectImpl> otherElements = (object as ListState)._elements;
4155 int count = _elements.length; 4463 int count = _elements.length;
4156 if (otherElements.length != count) {
4157 return false;
4158 } else if (count == 0) {
4159 return true;
4160 }
4161 for (int i = 0; i < count; i++) { 4464 for (int i = 0; i < count; i++) {
4162 if (_elements[i] != otherElements[i]) { 4465 if (!_elements[i].hasExactValue) {
4163 return false; 4466 return false;
4164 } 4467 }
4165 } 4468 }
4166 return true; 4469 return true;
4167 } 4470 }
4168 4471
4169 @override 4472 @override
4473 int get hashCode {
4474 int value = 0;
4475 int count = _elements.length;
4476 for (int i = 0; i < count; i++) {
4477 value = (value << 3) ^ _elements[i].hashCode;
4478 }
4479 return value;
4480 }
4481
4482 @override
4170 String get typeName => "List"; 4483 String get typeName => "List";
4171 4484
4172 @override 4485 @override
4173 List<Object> get value { 4486 List<Object> get value {
4174 int count = _elements.length; 4487 int count = _elements.length;
4175 List<Object> result = new List<Object>(count); 4488 List<Object> result = new List<Object>(count);
4176 for (int i = 0; i < count; i++) { 4489 for (int i = 0; i < count; i++) {
4177 DartObjectImpl element = _elements[i]; 4490 DartObjectImpl element = _elements[i];
4178 if (!element.hasExactValue) { 4491 if (!element.hasExactValue) {
4179 return null; 4492 return null;
4180 } 4493 }
4181 result[i] = element.value; 4494 result[i] = element.value;
4182 } 4495 }
4183 return result; 4496 return result;
4184 } 4497 }
4185 4498
4186 @override 4499 @override
4187 bool get hasExactValue { 4500 bool operator ==(Object object) {
4501 if (object is! ListState) {
4502 return false;
4503 }
4504 List<DartObjectImpl> otherElements = (object as ListState)._elements;
4188 int count = _elements.length; 4505 int count = _elements.length;
4506 if (otherElements.length != count) {
4507 return false;
4508 } else if (count == 0) {
4509 return true;
4510 }
4189 for (int i = 0; i < count; i++) { 4511 for (int i = 0; i < count; i++) {
4190 if (!_elements[i].hasExactValue) { 4512 if (_elements[i] != otherElements[i]) {
4191 return false; 4513 return false;
4192 } 4514 }
4193 } 4515 }
4194 return true; 4516 return true;
4195 } 4517 }
4196 4518
4197 @override 4519 @override
4198 int get hashCode { 4520 StringState convertToString() => StringState.UNKNOWN_VALUE;
4199 int value = 0; 4521
4200 int count = _elements.length; 4522 @override
4201 for (int i = 0; i < count; i++) { 4523 BoolState equalEqual(InstanceState rightOperand) {
4202 value = (value << 3) ^ _elements[i].hashCode; 4524 assertBoolNumStringOrNull(rightOperand);
4525 return isIdentical(rightOperand);
4526 }
4527
4528 @override
4529 BoolState isIdentical(InstanceState rightOperand) {
4530 if (rightOperand is DynamicState) {
4531 return BoolState.UNKNOWN_VALUE;
4203 } 4532 }
4204 return value; 4533 return BoolState.from(this == rightOperand);
4205 } 4534 }
4206 } 4535 }
4207 4536
4208 /** 4537 /**
4209 * The unique instance of the class `ListState` represents the state of an objec t representing 4538 * The unique instance of the class `ListState` represents the state of an objec t representing
4210 * a map. 4539 * a map.
4211 */ 4540 */
4212 class MapState extends InstanceState { 4541 class MapState extends InstanceState {
4213 /** 4542 /**
4214 * The entries in the map. 4543 * The entries in the map.
4215 */ 4544 */
4216 final HashMap<DartObjectImpl, DartObjectImpl> _entries; 4545 final HashMap<DartObjectImpl, DartObjectImpl> _entries;
4217 4546
4218 /** 4547 /**
4219 * Initialize a newly created state to represent a map with the given entries. 4548 * Initialize a newly created state to represent a map with the given entries.
4220 * 4549 *
4221 * @param entries the entries in the map 4550 * @param entries the entries in the map
4222 */ 4551 */
4223 MapState(this._entries); 4552 MapState(this._entries);
4224 4553
4225 @override 4554 @override
4226 StringState convertToString() => StringState.UNKNOWN_VALUE; 4555 bool get hasExactValue {
4227 4556 for (DartObjectImpl key in _entries.keys) {
4228 @override 4557 if (!key.hasExactValue || !_entries[key].hasExactValue) {
4229 BoolState equalEqual(InstanceState rightOperand) { 4558 return false;
4230 assertBoolNumStringOrNull(rightOperand); 4559 }
4231 return isIdentical(rightOperand); 4560 }
4561 return true;
4232 } 4562 }
4233 4563
4234 @override 4564 @override
4235 BoolState isIdentical(InstanceState rightOperand) { 4565 int get hashCode {
4236 if (rightOperand is DynamicState) { 4566 int value = 0;
4237 return BoolState.UNKNOWN_VALUE; 4567 for (DartObjectImpl key in _entries.keys.toSet()) {
4568 value = (value << 3) ^ key.hashCode;
4238 } 4569 }
4239 return BoolState.from(this == rightOperand); 4570 return value;
4240 } 4571 }
4241 4572
4242 @override 4573 @override
4574 String get typeName => "Map";
4575
4576 @override
4577 Map<Object, Object> get value {
4578 HashMap<Object, Object> result = new HashMap<Object, Object>();
4579 for (DartObjectImpl key in _entries.keys) {
4580 DartObjectImpl value = _entries[key];
4581 if (!key.hasExactValue || !value.hasExactValue) {
4582 return null;
4583 }
4584 result[key.value] = value.value;
4585 }
4586 return result;
4587 }
4588
4589 @override
4243 bool operator ==(Object object) { 4590 bool operator ==(Object object) {
4244 if (object is! MapState) { 4591 if (object is! MapState) {
4245 return false; 4592 return false;
4246 } 4593 }
4247 HashMap<DartObjectImpl, DartObjectImpl> otherElements = (object as MapState) ._entries; 4594 HashMap<DartObjectImpl, DartObjectImpl> otherElements =
4595 (object as MapState)._entries;
4248 int count = _entries.length; 4596 int count = _entries.length;
4249 if (otherElements.length != count) { 4597 if (otherElements.length != count) {
4250 return false; 4598 return false;
4251 } else if (count == 0) { 4599 } else if (count == 0) {
4252 return true; 4600 return true;
4253 } 4601 }
4254 for (DartObjectImpl key in _entries.keys) { 4602 for (DartObjectImpl key in _entries.keys) {
4255 DartObjectImpl value = _entries[key]; 4603 DartObjectImpl value = _entries[key];
4256 DartObjectImpl otherValue = otherElements[key]; 4604 DartObjectImpl otherValue = otherElements[key];
4257 if (value != otherValue) { 4605 if (value != otherValue) {
4258 return false; 4606 return false;
4259 } 4607 }
4260 } 4608 }
4261 return true; 4609 return true;
4262 } 4610 }
4263 4611
4264 @override 4612 @override
4265 String get typeName => "Map"; 4613 StringState convertToString() => StringState.UNKNOWN_VALUE;
4266 4614
4267 @override 4615 @override
4268 Map<Object, Object> get value { 4616 BoolState equalEqual(InstanceState rightOperand) {
4269 HashMap<Object, Object> result = new HashMap<Object, Object>(); 4617 assertBoolNumStringOrNull(rightOperand);
4270 for (DartObjectImpl key in _entries.keys) { 4618 return isIdentical(rightOperand);
4271 DartObjectImpl value = _entries[key];
4272 if (!key.hasExactValue || !value.hasExactValue) {
4273 return null;
4274 }
4275 result[key.value] = value.value;
4276 }
4277 return result;
4278 } 4619 }
4279 4620
4280 @override 4621 @override
4281 bool get hasExactValue { 4622 BoolState isIdentical(InstanceState rightOperand) {
4282 for (DartObjectImpl key in _entries.keys) { 4623 if (rightOperand is DynamicState) {
4283 if (!key.hasExactValue || !_entries[key].hasExactValue) { 4624 return BoolState.UNKNOWN_VALUE;
4284 return false;
4285 }
4286 } 4625 }
4287 return true; 4626 return BoolState.from(this == rightOperand);
4288 }
4289
4290 @override
4291 int get hashCode {
4292 int value = 0;
4293 for (DartObjectImpl key in _entries.keys.toSet()) {
4294 value = (value << 3) ^ key.hashCode;
4295 }
4296 return value;
4297 } 4627 }
4298 } 4628 }
4299 4629
4300 /** 4630 /**
4301 * The unique instance of the class `NullState` represents the state of the valu e 'null'. 4631 * The unique instance of the class `NullState` represents the state of the valu e 'null'.
4302 */ 4632 */
4303 class NullState extends InstanceState { 4633 class NullState extends InstanceState {
4304 /** 4634 /**
4305 * An instance representing the boolean value 'true'. 4635 * An instance representing the boolean value 'true'.
4306 */ 4636 */
4307 static NullState NULL_STATE = new NullState(); 4637 static NullState NULL_STATE = new NullState();
4308 4638
4309 @override 4639 @override
4640 bool get hasExactValue => true;
4641
4642 @override
4643 int get hashCode => 0;
4644
4645 @override
4646 bool get isBoolNumStringOrNull => true;
4647
4648 @override
4649 String get typeName => "Null";
4650
4651 @override
4652 bool operator ==(Object object) => object is NullState;
4653
4654 @override
4310 BoolState convertToBool() { 4655 BoolState convertToBool() {
4311 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI ON); 4656 throw new EvaluationException(
4657 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
4312 } 4658 }
4313 4659
4314 @override 4660 @override
4315 StringState convertToString() => new StringState("null"); 4661 StringState convertToString() => new StringState("null");
4316 4662
4317 @override 4663 @override
4318 BoolState equalEqual(InstanceState rightOperand) { 4664 BoolState equalEqual(InstanceState rightOperand) {
4319 assertBoolNumStringOrNull(rightOperand); 4665 assertBoolNumStringOrNull(rightOperand);
4320 return isIdentical(rightOperand); 4666 return isIdentical(rightOperand);
4321 } 4667 }
4322 4668
4323 @override 4669 @override
4324 BoolState isIdentical(InstanceState rightOperand) { 4670 BoolState isIdentical(InstanceState rightOperand) {
4325 if (rightOperand is DynamicState) { 4671 if (rightOperand is DynamicState) {
4326 return BoolState.UNKNOWN_VALUE; 4672 return BoolState.UNKNOWN_VALUE;
4327 } 4673 }
4328 return BoolState.from(rightOperand is NullState); 4674 return BoolState.from(rightOperand is NullState);
4329 } 4675 }
4330 4676
4331 @override 4677 @override
4332 bool operator ==(Object object) => object is NullState;
4333
4334 @override
4335 String get typeName => "Null";
4336
4337 @override
4338 bool get hasExactValue => true;
4339
4340 @override
4341 int get hashCode => 0;
4342
4343 @override
4344 bool get isBoolNumStringOrNull => true;
4345
4346 @override
4347 BoolState logicalNot() { 4678 BoolState logicalNot() {
4348 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTI ON); 4679 throw new EvaluationException(
4680 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
4349 } 4681 }
4350 4682
4351 @override 4683 @override
4352 String toString() => "null"; 4684 String toString() => "null";
4353 } 4685 }
4354 4686
4355 /** 4687 /**
4356 * Instances of the class `NumState` represent the state of an object representi ng a number of 4688 * Instances of the class `NumState` represent the state of an object representi ng a number of
4357 * an unknown type (a 'num'). 4689 * an unknown type (a 'num').
4358 */ 4690 */
4359 class NumState extends InstanceState { 4691 class NumState extends InstanceState {
4360 /** 4692 /**
4361 * A state that can be used to represent a number whose value is not known. 4693 * A state that can be used to represent a number whose value is not known.
4362 */ 4694 */
4363 static NumState UNKNOWN_VALUE = new NumState(); 4695 static NumState UNKNOWN_VALUE = new NumState();
4364 4696
4365 @override 4697 @override
4698 int get hashCode => 7;
4699
4700 @override
4701 bool get isBoolNumStringOrNull => true;
4702
4703 @override
4704 bool get isUnknown => identical(this, UNKNOWN_VALUE);
4705
4706 @override
4707 String get typeName => "num";
4708
4709 @override
4710 bool operator ==(Object object) => object is NumState;
4711
4712 @override
4366 NumState add(InstanceState rightOperand) { 4713 NumState add(InstanceState rightOperand) {
4367 assertNumOrNull(rightOperand); 4714 assertNumOrNull(rightOperand);
4368 return UNKNOWN_VALUE; 4715 return UNKNOWN_VALUE;
4369 } 4716 }
4370 4717
4371 @override 4718 @override
4372 StringState convertToString() => StringState.UNKNOWN_VALUE; 4719 StringState convertToString() => StringState.UNKNOWN_VALUE;
4373 4720
4374 @override 4721 @override
4375 NumState divide(InstanceState rightOperand) { 4722 NumState divide(InstanceState rightOperand) {
4376 assertNumOrNull(rightOperand); 4723 assertNumOrNull(rightOperand);
4377 return UNKNOWN_VALUE; 4724 return UNKNOWN_VALUE;
4378 } 4725 }
4379 4726
4380 @override 4727 @override
4381 BoolState equalEqual(InstanceState rightOperand) { 4728 BoolState equalEqual(InstanceState rightOperand) {
4382 assertBoolNumStringOrNull(rightOperand); 4729 assertBoolNumStringOrNull(rightOperand);
4383 return BoolState.UNKNOWN_VALUE; 4730 return BoolState.UNKNOWN_VALUE;
4384 } 4731 }
4385 4732
4386 @override 4733 @override
4387 BoolState isIdentical(InstanceState rightOperand) {
4388 return BoolState.UNKNOWN_VALUE;
4389 }
4390
4391 @override
4392 bool operator ==(Object object) => object is NumState;
4393
4394 @override
4395 String get typeName => "num";
4396
4397 @override
4398 BoolState greaterThan(InstanceState rightOperand) { 4734 BoolState greaterThan(InstanceState rightOperand) {
4399 assertNumOrNull(rightOperand); 4735 assertNumOrNull(rightOperand);
4400 return BoolState.UNKNOWN_VALUE; 4736 return BoolState.UNKNOWN_VALUE;
4401 } 4737 }
4402 4738
4403 @override 4739 @override
4404 BoolState greaterThanOrEqual(InstanceState rightOperand) { 4740 BoolState greaterThanOrEqual(InstanceState rightOperand) {
4405 assertNumOrNull(rightOperand); 4741 assertNumOrNull(rightOperand);
4406 return BoolState.UNKNOWN_VALUE; 4742 return BoolState.UNKNOWN_VALUE;
4407 } 4743 }
4408 4744
4409 @override 4745 @override
4410 int get hashCode => 7;
4411
4412 @override
4413 IntState integerDivide(InstanceState rightOperand) { 4746 IntState integerDivide(InstanceState rightOperand) {
4414 assertNumOrNull(rightOperand); 4747 assertNumOrNull(rightOperand);
4415 if (rightOperand is IntState) { 4748 if (rightOperand is IntState) {
4416 int rightValue = rightOperand.value; 4749 int rightValue = rightOperand.value;
4417 if (rightValue == null) { 4750 if (rightValue == null) {
4418 return IntState.UNKNOWN_VALUE; 4751 return IntState.UNKNOWN_VALUE;
4419 } else if (rightValue == 0) { 4752 } else if (rightValue == 0) {
4420 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_IDB ZE); 4753 throw new EvaluationException(
4754 CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE);
4421 } 4755 }
4422 } else if (rightOperand is DynamicState) { 4756 } else if (rightOperand is DynamicState) {
4423 return IntState.UNKNOWN_VALUE; 4757 return IntState.UNKNOWN_VALUE;
4424 } 4758 }
4425 return IntState.UNKNOWN_VALUE; 4759 return IntState.UNKNOWN_VALUE;
4426 } 4760 }
4427 4761
4428 @override 4762 @override
4429 bool get isBoolNumStringOrNull => true; 4763 BoolState isIdentical(InstanceState rightOperand) {
4430 4764 return BoolState.UNKNOWN_VALUE;
4431 @override 4765 }
4432 bool get isUnknown => identical(this, UNKNOWN_VALUE);
4433 4766
4434 @override 4767 @override
4435 BoolState lessThan(InstanceState rightOperand) { 4768 BoolState lessThan(InstanceState rightOperand) {
4436 assertNumOrNull(rightOperand); 4769 assertNumOrNull(rightOperand);
4437 return BoolState.UNKNOWN_VALUE; 4770 return BoolState.UNKNOWN_VALUE;
4438 } 4771 }
4439 4772
4440 @override 4773 @override
4441 BoolState lessThanOrEqual(InstanceState rightOperand) { 4774 BoolState lessThanOrEqual(InstanceState rightOperand) {
4442 assertNumOrNull(rightOperand); 4775 assertNumOrNull(rightOperand);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
4485 final DirectedGraph<AstNode> _referenceGraph; 4818 final DirectedGraph<AstNode> _referenceGraph;
4486 4819
4487 /** 4820 /**
4488 * A table mapping constant variables to the declarations of those variables. 4821 * A table mapping constant variables to the declarations of those variables.
4489 */ 4822 */
4490 final HashMap<VariableElement, VariableDeclaration> _variableDeclarationMap; 4823 final HashMap<VariableElement, VariableDeclaration> _variableDeclarationMap;
4491 4824
4492 /** 4825 /**
4493 * A table mapping constant constructors to the declarations of those construc tors. 4826 * A table mapping constant constructors to the declarations of those construc tors.
4494 */ 4827 */
4495 final HashMap<ConstructorElement, ConstructorDeclaration> _constructorDeclarat ionMap; 4828 final HashMap<ConstructorElement, ConstructorDeclaration>
4829 _constructorDeclarationMap;
4496 4830
4497 /** 4831 /**
4498 * Initialize a newly created reference finder to find references from the giv en variable to other 4832 * Initialize a newly created reference finder to find references from the giv en variable to other
4499 * variables and to add those references to the given graph. 4833 * variables and to add those references to the given graph.
4500 * 4834 *
4501 * @param source the element representing the variable whose initializer will be visited 4835 * @param source the element representing the variable whose initializer will be visited
4502 * @param referenceGraph a graph recording which variables (heads) reference w hich other variables 4836 * @param referenceGraph a graph recording which variables (heads) reference w hich other variables
4503 * (tails) in their initializers 4837 * (tails) in their initializers
4504 * @param variableDeclarationMap A table mapping constant variables to the dec larations of those 4838 * @param variableDeclarationMap A table mapping constant variables to the dec larations of those
4505 * variables. 4839 * variables.
4506 * @param constructorDeclarationMap A table mapping constant constructors to t he declarations of 4840 * @param constructorDeclarationMap A table mapping constant constructors to t he declarations of
4507 * those constructors. 4841 * those constructors.
4508 */ 4842 */
4509 ReferenceFinder(this._source, this._referenceGraph, this._variableDeclarationM ap, this._constructorDeclarationMap); 4843 ReferenceFinder(this._source, this._referenceGraph,
4844 this._variableDeclarationMap, this._constructorDeclarationMap);
4510 4845
4511 @override 4846 @override
4512 Object visitInstanceCreationExpression(InstanceCreationExpression node) { 4847 Object visitInstanceCreationExpression(InstanceCreationExpression node) {
4513 if (node.isConst) { 4848 if (node.isConst) {
4514 _referenceGraph.addEdge(_source, node); 4849 _referenceGraph.addEdge(_source, node);
4515 } 4850 }
4516 return null; 4851 return null;
4517 } 4852 }
4518 4853
4519 @override 4854 @override
4855 Object
4856 visitRedirectingConstructorInvocation(RedirectingConstructorInvocation nod e) {
4857 super.visitRedirectingConstructorInvocation(node);
4858 ConstructorElement target = node.staticElement;
4859 if (target != null && target.isConst) {
4860 ConstructorDeclaration targetDeclaration =
4861 _constructorDeclarationMap[target];
4862 if (targetDeclaration != null) {
4863 _referenceGraph.addEdge(_source, targetDeclaration);
4864 }
4865 }
4866 return null;
4867 }
4868
4869 @override
4520 Object visitSimpleIdentifier(SimpleIdentifier node) { 4870 Object visitSimpleIdentifier(SimpleIdentifier node) {
4521 Element element = node.staticElement; 4871 Element element = node.staticElement;
4522 if (element is PropertyAccessorElement) { 4872 if (element is PropertyAccessorElement) {
4523 element = (element as PropertyAccessorElement).variable; 4873 element = (element as PropertyAccessorElement).variable;
4524 } 4874 }
4525 if (element is VariableElement) { 4875 if (element is VariableElement) {
4526 VariableElement variable = element as VariableElement; 4876 VariableElement variable = element as VariableElement;
4527 if (variable.isConst) { 4877 if (variable.isConst) {
4528 VariableDeclaration variableDeclaration = _variableDeclarationMap[variab le]; 4878 VariableDeclaration variableDeclaration =
4529 // The declaration will be null when the variable is not defined in the compilation units 4879 _variableDeclarationMap[variable];
4530 // that were used to produce the variableDeclarationMap. In such cases, the variable should 4880 // The declaration will be null when the variable is not defined in the
4531 // already have a value associated with it, but we don't bother to check because there's 4881 // compilation units that were used to produce the
4532 // nothing we can do about it at this point. 4882 // variableDeclarationMap. In such cases, the variable should already
4883 // have a value associated with it, but we don't bother to check because
4884 // there's nothing we can do about it at this point.
4533 if (variableDeclaration != null) { 4885 if (variableDeclaration != null) {
4534 _referenceGraph.addEdge(_source, variableDeclaration); 4886 _referenceGraph.addEdge(_source, variableDeclaration);
4535 } 4887 }
4536 } 4888 }
4537 } 4889 }
4538 return null; 4890 return null;
4539 } 4891 }
4540 4892
4541 @override 4893 @override
4542 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { 4894 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
4543 super.visitSuperConstructorInvocation(node); 4895 super.visitSuperConstructorInvocation(node);
4544 ConstructorElement constructor = node.staticElement; 4896 ConstructorElement constructor = node.staticElement;
4545 if (constructor != null && constructor.isConst) { 4897 if (constructor != null && constructor.isConst) {
4546 ConstructorDeclaration constructorDeclaration = _constructorDeclarationMap [constructor]; 4898 ConstructorDeclaration constructorDeclaration =
4547 // The declaration will be null when the constructor is not defined in the compilation 4899 _constructorDeclarationMap[constructor];
4548 // units that were used to produce the constructorDeclarationMap. In such cases, the 4900 // The declaration will be null when the constructor is not defined in the
4549 // constructor should already have its initializer AST's stored in it, but we don't bother 4901 // compilation units that were used to produce the
4902 // constructorDeclarationMap. In such cases, the constructor should
4903 // already have its initializer AST's stored in it, but we don't bother
4550 // to check because there's nothing we can do about it at this point. 4904 // to check because there's nothing we can do about it at this point.
4551 if (constructorDeclaration != null) { 4905 if (constructorDeclaration != null) {
4552 _referenceGraph.addEdge(_source, constructorDeclaration); 4906 _referenceGraph.addEdge(_source, constructorDeclaration);
4553 } 4907 }
4554 } 4908 }
4555 return null; 4909 return null;
4556 } 4910 }
4557
4558 @override
4559 Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
4560 super.visitRedirectingConstructorInvocation(node);
4561 ConstructorElement target = node.staticElement;
4562 if (target != null && target.isConst) {
4563 ConstructorDeclaration targetDeclaration = _constructorDeclarationMap[targ et];
4564 if (targetDeclaration != null) {
4565 _referenceGraph.addEdge(_source, targetDeclaration);
4566 }
4567 }
4568 return null;
4569 }
4570 } 4911 }
4571 4912
4572 /** 4913 /**
4573 * Instances of the class `StringState` represent the state of an object represe nting a 4914 * Instances of the class `StringState` represent the state of an object represe nting a
4574 * string. 4915 * string.
4575 */ 4916 */
4576 class StringState extends InstanceState { 4917 class StringState extends InstanceState {
4577 /** 4918 /**
4919 * A state that can be used to represent a double whose value is not known.
4920 */
4921 static StringState UNKNOWN_VALUE = new StringState(null);
4922
4923 /**
4578 * The value of this instance. 4924 * The value of this instance.
4579 */ 4925 */
4580 final String value; 4926 final String value;
4581 4927
4582 /** 4928 /**
4583 * A state that can be used to represent a double whose value is not known.
4584 */
4585 static StringState UNKNOWN_VALUE = new StringState(null);
4586
4587 /**
4588 * Initialize a newly created state to represent the given value. 4929 * Initialize a newly created state to represent the given value.
4589 * 4930 *
4590 * @param value the value of this instance 4931 * @param value the value of this instance
4591 */ 4932 */
4592 StringState(this.value); 4933 StringState(this.value);
4593 4934
4594 @override 4935 @override
4936 bool get hasExactValue => true;
4937
4938 @override
4939 int get hashCode => value == null ? 0 : value.hashCode;
4940
4941 @override
4942 bool get isBoolNumStringOrNull => true;
4943
4944 @override
4945 bool get isUnknown => value == null;
4946
4947 @override
4948 String get typeName => "String";
4949
4950 @override
4951 bool operator ==(Object object) =>
4952 object is StringState && (value == object.value);
4953
4954 @override
4595 StringState concatenate(InstanceState rightOperand) { 4955 StringState concatenate(InstanceState rightOperand) {
4596 if (value == null) { 4956 if (value == null) {
4597 return UNKNOWN_VALUE; 4957 return UNKNOWN_VALUE;
4598 } 4958 }
4599 if (rightOperand is StringState) { 4959 if (rightOperand is StringState) {
4600 String rightValue = rightOperand.value; 4960 String rightValue = rightOperand.value;
4601 if (rightValue == null) { 4961 if (rightValue == null) {
4602 return UNKNOWN_VALUE; 4962 return UNKNOWN_VALUE;
4603 } 4963 }
4604 return new StringState("$value$rightValue"); 4964 return new StringState("$value$rightValue");
(...skipping 23 matching lines...) Expand all
4628 return BoolState.UNKNOWN_VALUE; 4988 return BoolState.UNKNOWN_VALUE;
4629 } 4989 }
4630 return BoolState.from(value == rightValue); 4990 return BoolState.from(value == rightValue);
4631 } else if (rightOperand is DynamicState) { 4991 } else if (rightOperand is DynamicState) {
4632 return BoolState.UNKNOWN_VALUE; 4992 return BoolState.UNKNOWN_VALUE;
4633 } 4993 }
4634 return BoolState.FALSE_STATE; 4994 return BoolState.FALSE_STATE;
4635 } 4995 }
4636 4996
4637 @override 4997 @override
4638 bool operator ==(Object object) => object is StringState && (value == object.v alue);
4639
4640 @override
4641 String get typeName => "String";
4642
4643 @override
4644 bool get hasExactValue => true;
4645
4646 @override
4647 int get hashCode => value == null ? 0 : value.hashCode;
4648
4649 @override
4650 bool get isBoolNumStringOrNull => true;
4651
4652 @override
4653 bool get isUnknown => value == null;
4654
4655 @override
4656 IntState stringLength() { 4998 IntState stringLength() {
4657 if (value == null) { 4999 if (value == null) {
4658 return IntState.UNKNOWN_VALUE; 5000 return IntState.UNKNOWN_VALUE;
4659 } 5001 }
4660 return new IntState(value.length); 5002 return new IntState(value.length);
4661 } 5003 }
4662 5004
4663 @override 5005 @override
4664 String toString() => value == null ? "-unknown-" : "'$value'"; 5006 String toString() => value == null ? "-unknown-" : "'$value'";
4665 } 5007 }
4666 5008
4667 /** 5009 /**
4668 * Instances of the class `StringState` represent the state of an object represe nting a 5010 * Instances of the class `StringState` represent the state of an object represe nting a
4669 * symbol. 5011 * symbol.
4670 */ 5012 */
4671 class SymbolState extends InstanceState { 5013 class SymbolState extends InstanceState {
4672 /** 5014 /**
4673 * The value of this instance. 5015 * The value of this instance.
4674 */ 5016 */
4675 final String value; 5017 final String value;
4676 5018
4677 /** 5019 /**
4678 * Initialize a newly created state to represent the given value. 5020 * Initialize a newly created state to represent the given value.
4679 * 5021 *
4680 * @param value the value of this instance 5022 * @param value the value of this instance
4681 */ 5023 */
4682 SymbolState(this.value); 5024 SymbolState(this.value);
4683 5025
4684 @override 5026 @override
5027 bool get hasExactValue => true;
5028
5029 @override
5030 int get hashCode => value == null ? 0 : value.hashCode;
5031
5032 @override
5033 String get typeName => "Symbol";
5034
5035 @override
5036 bool operator ==(Object object) =>
5037 object is SymbolState && (value == object.value);
5038
5039 @override
4685 StringState convertToString() { 5040 StringState convertToString() {
4686 if (value == null) { 5041 if (value == null) {
4687 return StringState.UNKNOWN_VALUE; 5042 return StringState.UNKNOWN_VALUE;
4688 } 5043 }
4689 return new StringState(value); 5044 return new StringState(value);
4690 } 5045 }
4691 5046
4692 @override 5047 @override
4693 BoolState equalEqual(InstanceState rightOperand) { 5048 BoolState equalEqual(InstanceState rightOperand) {
4694 assertBoolNumStringOrNull(rightOperand); 5049 assertBoolNumStringOrNull(rightOperand);
(...skipping 11 matching lines...) Expand all
4706 return BoolState.UNKNOWN_VALUE; 5061 return BoolState.UNKNOWN_VALUE;
4707 } 5062 }
4708 return BoolState.from(value == rightValue); 5063 return BoolState.from(value == rightValue);
4709 } else if (rightOperand is DynamicState) { 5064 } else if (rightOperand is DynamicState) {
4710 return BoolState.UNKNOWN_VALUE; 5065 return BoolState.UNKNOWN_VALUE;
4711 } 5066 }
4712 return BoolState.FALSE_STATE; 5067 return BoolState.FALSE_STATE;
4713 } 5068 }
4714 5069
4715 @override 5070 @override
4716 bool operator ==(Object object) => object is SymbolState && (value == object.v alue);
4717
4718 @override
4719 String get typeName => "Symbol";
4720
4721 @override
4722 bool get hasExactValue => true;
4723
4724 @override
4725 int get hashCode => value == null ? 0 : value.hashCode;
4726
4727 @override
4728 String toString() => value == null ? "-unknown-" : "#$value"; 5071 String toString() => value == null ? "-unknown-" : "#$value";
4729 } 5072 }
4730 5073
4731 /** 5074 /**
4732 * Instances of the class `TypeState` represent the state of an object represent ing a type. 5075 * Instances of the class `TypeState` represent the state of an object represent ing a type.
4733 */ 5076 */
4734 class TypeState extends InstanceState { 5077 class TypeState extends InstanceState {
4735 /** 5078 /**
4736 * The element representing the type being modeled. 5079 * The element representing the type being modeled.
4737 */ 5080 */
4738 final Element _element; 5081 final Element _element;
4739 5082
4740 /** 5083 /**
4741 * Initialize a newly created state to represent the given value. 5084 * Initialize a newly created state to represent the given value.
4742 * 5085 *
4743 * @param element the element representing the type being modeled 5086 * @param element the element representing the type being modeled
4744 */ 5087 */
4745 TypeState(this._element); 5088 TypeState(this._element);
4746 5089
4747 @override 5090 @override
5091 int get hashCode => _element == null ? 0 : _element.hashCode;
5092
5093 @override
5094 String get typeName => "Type";
5095
5096 @override
5097 bool operator ==(Object object) =>
5098 object is TypeState && (_element == object._element);
5099
5100 @override
4748 StringState convertToString() { 5101 StringState convertToString() {
4749 if (_element == null) { 5102 if (_element == null) {
4750 return StringState.UNKNOWN_VALUE; 5103 return StringState.UNKNOWN_VALUE;
4751 } 5104 }
4752 return new StringState(_element.name); 5105 return new StringState(_element.name);
4753 } 5106 }
4754 5107
4755 @override 5108 @override
4756 bool operator ==(Object object) => object is TypeState && (_element == object. _element);
4757
4758 @override
4759 BoolState equalEqual(InstanceState rightOperand) { 5109 BoolState equalEqual(InstanceState rightOperand) {
4760 assertBoolNumStringOrNull(rightOperand); 5110 assertBoolNumStringOrNull(rightOperand);
4761 return isIdentical(rightOperand); 5111 return isIdentical(rightOperand);
4762 } 5112 }
4763 5113
4764 @override 5114 @override
4765 BoolState isIdentical(InstanceState rightOperand) { 5115 BoolState isIdentical(InstanceState rightOperand) {
4766 if (_element == null) { 5116 if (_element == null) {
4767 return BoolState.UNKNOWN_VALUE; 5117 return BoolState.UNKNOWN_VALUE;
4768 } 5118 }
4769 if (rightOperand is TypeState) { 5119 if (rightOperand is TypeState) {
4770 Element rightElement = rightOperand._element; 5120 Element rightElement = rightOperand._element;
4771 if (rightElement == null) { 5121 if (rightElement == null) {
4772 return BoolState.UNKNOWN_VALUE; 5122 return BoolState.UNKNOWN_VALUE;
4773 } 5123 }
4774 return BoolState.from(_element == rightElement); 5124 return BoolState.from(_element == rightElement);
4775 } else if (rightOperand is DynamicState) { 5125 } else if (rightOperand is DynamicState) {
4776 return BoolState.UNKNOWN_VALUE; 5126 return BoolState.UNKNOWN_VALUE;
4777 } 5127 }
4778 return BoolState.FALSE_STATE; 5128 return BoolState.FALSE_STATE;
4779 } 5129 }
4780 5130
4781 @override 5131 @override
4782 String get typeName => "Type";
4783
4784 @override
4785 int get hashCode => _element == null ? 0 : _element.hashCode;
4786
4787 @override
4788 String toString() => _element == null ? "-unknown-" : _element.name; 5132 String toString() => _element == null ? "-unknown-" : _element.name;
4789 } 5133 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/generated/ast.dart ('k') | pkg/analyzer/lib/src/generated/element.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698