OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 '>' operator on this object with the g
iven argument. | 2368 * Return the result of invoking the '>' 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 '>' operator on this object with the
given argument | 2372 * @return the result of invoking the '>' 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 '>=' operator on this object with the
given argument. | 2382 * Return the result of invoking the '>=' 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 '>=' operator on this object with the
given argument | 2386 * @return the result of invoking the '>=' 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 '<' operator on this object with the g
iven argument. | 2426 * Return the result of invoking the '<' 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 '<' operator on this object with the
given argument | 2430 * @return the result of invoking the '<' 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 '<=' operator on this object with the
given argument. | 2438 * Return the result of invoking the '<=' 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 '<=' operator on this object with the
given argument | 2442 * @return the result of invoking the '<=' 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 Loading... |
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 '<<' operator on this object with t
he given argument. | 2594 * Return the result of invoking the '<<' 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 '<<' operator on this object with
the given argument | 2598 * @return the result of invoking the '<<' 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 '>>' operator on this object with t
he given argument. | 2606 * Return the result of invoking the '>>' 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 '>>' operator on this object with
the given argument | 2610 * @return the result of invoking the '>>' 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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 '>' operator on this object with the g
iven argument. | 3776 * Return the result of invoking the '>' 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 '>' operator on this object with the
given argument | 3779 * @return the result of invoking the '>' 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 '>=' operator on this object with the
given argument. | 3789 * Return the result of invoking the '>=' 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 '>=' operator on this object with the
given argument | 3792 * @return the result of invoking the '>=' 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 '<' operator on this object with the g
iven argument. | 3825 * Return the result of invoking the '<' 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 '<' operator on this object with the
given argument | 3828 * @return the result of invoking the '<' 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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |