| 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 |