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 | |
6 // significant change. Please see the README file for more information. | |
7 | |
8 library engine.constant; | 5 library engine.constant; |
9 | 6 |
10 import 'dart:collection'; | 7 import 'dart:collection'; |
11 | 8 |
12 import 'package:analyzer/src/generated/engine.dart'; | 9 import 'package:analyzer/src/generated/engine.dart'; |
13 import 'package:analyzer/src/generated/utilities_general.dart'; | 10 import 'package:analyzer/src/generated/utilities_general.dart'; |
14 import 'package:analyzer/src/task/dart.dart'; | 11 import 'package:analyzer/src/task/dart.dart'; |
15 | 12 |
16 import 'ast.dart'; | 13 import 'ast.dart'; |
17 import 'element.dart'; | 14 import 'element.dart'; |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 "(?!${ConstantValueComputer._RESERVED_WORD_RE}\\b(?!\\\$))[a-zA-Z\$][\\w\$
]*"; | 207 "(?!${ConstantValueComputer._RESERVED_WORD_RE}\\b(?!\\\$))[a-zA-Z\$][\\w\$
]*"; |
211 | 208 |
212 /** | 209 /** |
213 * RegExp that validates a non-empty non-private symbol. | 210 * RegExp that validates a non-empty non-private symbol. |
214 * From sdk/lib/internal/symbol.dart. | 211 * From sdk/lib/internal/symbol.dart. |
215 */ | 212 */ |
216 static RegExp _PUBLIC_SYMBOL_PATTERN = new RegExp( | 213 static RegExp _PUBLIC_SYMBOL_PATTERN = new RegExp( |
217 "^(?:${ConstantValueComputer._OPERATOR_RE}\$|$_PUBLIC_IDENTIFIER_RE(?:=?\$
|[.](?!\$)))+?\$"); | 214 "^(?:${ConstantValueComputer._OPERATOR_RE}\$|$_PUBLIC_IDENTIFIER_RE(?:=?\$
|[.](?!\$)))+?\$"); |
218 | 215 |
219 /** | 216 /** |
| 217 * The type provider used to access the known types. |
| 218 */ |
| 219 final TypeProvider typeProvider; |
| 220 |
| 221 /** |
220 * The type system. This is used to gues the types of constants when their | 222 * The type system. This is used to gues the types of constants when their |
221 * exact value is unknown. | 223 * exact value is unknown. |
222 */ | 224 */ |
223 final TypeSystem typeSystem; | 225 final TypeSystem typeSystem; |
224 | 226 |
225 /** | 227 /** |
226 * The set of variables declared on the command line using '-D'. | 228 * The set of variables declared on the command line using '-D'. |
227 */ | 229 */ |
228 final DeclaredVariables _declaredVariables; | 230 final DeclaredVariables _declaredVariables; |
229 | 231 |
230 /** | 232 /** |
231 * Validator used to verify correct dependency analysis when running unit | 233 * Validator used to verify correct dependency analysis when running unit |
232 * tests. | 234 * tests. |
233 */ | 235 */ |
234 final ConstantEvaluationValidator validator; | 236 final ConstantEvaluationValidator validator; |
235 | 237 |
236 /** | 238 /** |
237 * Initialize a newly created [ConstantEvaluationEngine]. The [typeProvider] | 239 * Initialize a newly created [ConstantEvaluationEngine]. The [typeProvider] |
238 * is used to access known types. [_declaredVariables] is the set of | 240 * is used to access known types. [_declaredVariables] is the set of |
239 * variables declared on the command line using '-D'. The [validator], if | 241 * variables declared on the command line using '-D'. The [validator], if |
240 * given, is used to verify correct dependency analysis when running unit | 242 * given, is used to verify correct dependency analysis when running unit |
241 * tests. | 243 * tests. |
242 */ | 244 */ |
243 ConstantEvaluationEngine(TypeProvider typeProvider, this._declaredVariables, | 245 ConstantEvaluationEngine(this.typeProvider, this._declaredVariables, |
244 {ConstantEvaluationValidator validator}) | 246 {ConstantEvaluationValidator validator, TypeSystem typeSystem}) |
245 : validator = validator != null | 247 : validator = validator != null |
246 ? validator | 248 ? validator |
247 : new ConstantEvaluationValidator_ForProduction(), | 249 : new ConstantEvaluationValidator_ForProduction(), |
248 typeSystem = new TypeSystemImpl(typeProvider); | 250 typeSystem = typeSystem != null ? typeSystem : new TypeSystemImpl(); |
249 | |
250 /** | |
251 * The type provider used to access the known types. | |
252 */ | |
253 TypeProvider get typeProvider => typeSystem.typeProvider; | |
254 | 251 |
255 /** | 252 /** |
256 * Check that the arguments to a call to fromEnvironment() are correct. The | 253 * Check that the arguments to a call to fromEnvironment() are correct. The |
257 * [arguments] are the AST nodes of the arguments. The [argumentValues] are | 254 * [arguments] are the AST nodes of the arguments. The [argumentValues] are |
258 * the values of the unnamed arguments. The [namedArgumentValues] are the | 255 * the values of the unnamed arguments. The [namedArgumentValues] are the |
259 * values of the named arguments. The [expectedDefaultValueType] is the | 256 * values of the named arguments. The [expectedDefaultValueType] is the |
260 * allowed type of the "defaultValue" parameter (if present). Note: | 257 * allowed type of the "defaultValue" parameter (if present). Note: |
261 * "defaultValue" is always allowed to be null. Return `true` if the arguments | 258 * "defaultValue" is always allowed to be null. Return `true` if the arguments |
262 * are correct, `false` if there is an error. | 259 * are correct, `false` if there is an error. |
263 */ | 260 */ |
264 bool checkFromEnvironmentArguments(NodeList<Expression> arguments, | 261 bool checkFromEnvironmentArguments( |
| 262 NodeList<Expression> arguments, |
265 List<DartObjectImpl> argumentValues, | 263 List<DartObjectImpl> argumentValues, |
266 HashMap<String, DartObjectImpl> namedArgumentValues, | 264 HashMap<String, DartObjectImpl> namedArgumentValues, |
267 InterfaceType expectedDefaultValueType) { | 265 InterfaceType expectedDefaultValueType) { |
268 int argumentCount = arguments.length; | 266 int argumentCount = arguments.length; |
269 if (argumentCount < 1 || argumentCount > 2) { | 267 if (argumentCount < 1 || argumentCount > 2) { |
270 return false; | 268 return false; |
271 } | 269 } |
272 if (arguments[0] is NamedExpression) { | 270 if (arguments[0] is NamedExpression) { |
273 return false; | 271 return false; |
274 } | 272 } |
(...skipping 18 matching lines...) Expand all Loading... |
293 return true; | 291 return true; |
294 } | 292 } |
295 | 293 |
296 /** | 294 /** |
297 * Check that the arguments to a call to Symbol() are correct. The [arguments] | 295 * Check that the arguments to a call to Symbol() are correct. The [arguments] |
298 * are the AST nodes of the arguments. The [argumentValues] are the values of | 296 * are the AST nodes of the arguments. The [argumentValues] are the values of |
299 * the unnamed arguments. The [namedArgumentValues] are the values of the | 297 * the unnamed arguments. The [namedArgumentValues] are the values of the |
300 * named arguments. Return `true` if the arguments are correct, `false` if | 298 * named arguments. Return `true` if the arguments are correct, `false` if |
301 * there is an error. | 299 * there is an error. |
302 */ | 300 */ |
303 bool checkSymbolArguments(NodeList<Expression> arguments, | 301 bool checkSymbolArguments( |
| 302 NodeList<Expression> arguments, |
304 List<DartObjectImpl> argumentValues, | 303 List<DartObjectImpl> argumentValues, |
305 HashMap<String, DartObjectImpl> namedArgumentValues) { | 304 HashMap<String, DartObjectImpl> namedArgumentValues) { |
306 if (arguments.length != 1) { | 305 if (arguments.length != 1) { |
307 return false; | 306 return false; |
308 } | 307 } |
309 if (arguments[0] is NamedExpression) { | 308 if (arguments[0] is NamedExpression) { |
310 return false; | 309 return false; |
311 } | 310 } |
312 if (!identical(argumentValues[0].type, typeProvider.stringType)) { | 311 if (!identical(argumentValues[0].type, typeProvider.stringType)) { |
313 return false; | 312 return false; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 DartObjectImpl dartObject = constantInitializer | 344 DartObjectImpl dartObject = constantInitializer |
346 .accept(new ConstantVisitor(this, errorReporter)); | 345 .accept(new ConstantVisitor(this, errorReporter)); |
347 // Only check the type for truly const declarations (don't check final | 346 // Only check the type for truly const declarations (don't check final |
348 // fields with initializers, since their types may be generic. The type | 347 // fields with initializers, since their types may be generic. The type |
349 // of the final field will be checked later, when the constructor is | 348 // of the final field will be checked later, when the constructor is |
350 // invoked). | 349 // invoked). |
351 if (dartObject != null && constant.isConst) { | 350 if (dartObject != null && constant.isConst) { |
352 if (!runtimeTypeMatch(dartObject, constant.type)) { | 351 if (!runtimeTypeMatch(dartObject, constant.type)) { |
353 errorReporter.reportErrorForElement( | 352 errorReporter.reportErrorForElement( |
354 CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH, | 353 CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH, |
355 constant, [dartObject.type, constant.type]); | 354 constant, |
| 355 [dartObject.type, constant.type]); |
356 } | 356 } |
357 } | 357 } |
358 (constant as VariableElementImpl).evaluationResult = | 358 (constant as VariableElementImpl).evaluationResult = |
359 new EvaluationResultImpl(dartObject, errorListener.errors); | 359 new EvaluationResultImpl(dartObject, errorListener.errors); |
360 } | 360 } |
361 } else if (constant is ConstructorElement) { | 361 } else if (constant is ConstructorElement) { |
362 if (constant.isConst) { | 362 if (constant.isConst) { |
363 // No evaluation needs to be done; constructor declarations are only in | 363 // No evaluation needs to be done; constructor declarations are only in |
364 // the dependency graph to ensure that any constants referred to in | 364 // the dependency graph to ensure that any constants referred to in |
365 // initializer lists and parameter defaults are evaluated before | 365 // initializer lists and parameter defaults are evaluated before |
(...skipping 27 matching lines...) Expand all Loading... |
393 } else if (element is ConstructorElementImpl && | 393 } else if (element is ConstructorElementImpl && |
394 element.isConst && | 394 element.isConst && |
395 constNode.arguments != null) { | 395 constNode.arguments != null) { |
396 RecordingErrorListener errorListener = new RecordingErrorListener(); | 396 RecordingErrorListener errorListener = new RecordingErrorListener(); |
397 CompilationUnit sourceCompilationUnit = | 397 CompilationUnit sourceCompilationUnit = |
398 constNode.getAncestor((node) => node is CompilationUnit); | 398 constNode.getAncestor((node) => node is CompilationUnit); |
399 ErrorReporter errorReporter = new ErrorReporter( | 399 ErrorReporter errorReporter = new ErrorReporter( |
400 errorListener, sourceCompilationUnit.element.source); | 400 errorListener, sourceCompilationUnit.element.source); |
401 ConstantVisitor constantVisitor = | 401 ConstantVisitor constantVisitor = |
402 new ConstantVisitor(this, errorReporter); | 402 new ConstantVisitor(this, errorReporter); |
403 DartObjectImpl result = evaluateConstructorCall(constNode, | 403 DartObjectImpl result = evaluateConstructorCall( |
404 constNode.arguments.arguments, element, constantVisitor, | 404 constNode, |
| 405 constNode.arguments.arguments, |
| 406 element, |
| 407 constantVisitor, |
405 errorReporter); | 408 errorReporter); |
406 elementAnnotation.evaluationResult = | 409 elementAnnotation.evaluationResult = |
407 new EvaluationResultImpl(result, errorListener.errors); | 410 new EvaluationResultImpl(result, errorListener.errors); |
408 } else { | 411 } else { |
409 // This may happen for invalid code (e.g. failing to pass arguments | 412 // This may happen for invalid code (e.g. failing to pass arguments |
410 // to an annotation which references a const constructor). The error | 413 // to an annotation which references a const constructor). The error |
411 // is detected elsewhere, so just silently ignore it here. | 414 // is detected elsewhere, so just silently ignore it here. |
412 elementAnnotation.evaluationResult = new EvaluationResultImpl(null); | 415 elementAnnotation.evaluationResult = new EvaluationResultImpl(null); |
413 } | 416 } |
414 } | 417 } |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
539 | 542 |
540 /** | 543 /** |
541 * Evaluate a call to fromEnvironment() on the bool, int, or String class. The | 544 * Evaluate a call to fromEnvironment() on the bool, int, or String class. The |
542 * [environmentValue] is the value fetched from the environment. The | 545 * [environmentValue] is the value fetched from the environment. The |
543 * [builtInDefaultValue] is the value that should be used as the default if no | 546 * [builtInDefaultValue] is the value that should be used as the default if no |
544 * "defaultValue" argument appears in [namedArgumentValues]. The | 547 * "defaultValue" argument appears in [namedArgumentValues]. The |
545 * [namedArgumentValues] are the values of the named parameters passed to | 548 * [namedArgumentValues] are the values of the named parameters passed to |
546 * fromEnvironment(). Return a [DartObjectImpl] object corresponding to the | 549 * fromEnvironment(). Return a [DartObjectImpl] object corresponding to the |
547 * evaluated result. | 550 * evaluated result. |
548 */ | 551 */ |
549 DartObjectImpl computeValueFromEnvironment(DartObject environmentValue, | 552 DartObjectImpl computeValueFromEnvironment( |
| 553 DartObject environmentValue, |
550 DartObjectImpl builtInDefaultValue, | 554 DartObjectImpl builtInDefaultValue, |
551 HashMap<String, DartObjectImpl> namedArgumentValues) { | 555 HashMap<String, DartObjectImpl> namedArgumentValues) { |
552 DartObjectImpl value = environmentValue as DartObjectImpl; | 556 DartObjectImpl value = environmentValue as DartObjectImpl; |
553 if (value.isUnknown || value.isNull) { | 557 if (value.isUnknown || value.isNull) { |
554 // The name either doesn't exist in the environment or we couldn't parse | 558 // The name either doesn't exist in the environment or we couldn't parse |
555 // the corresponding value. | 559 // the corresponding value. |
556 // If the code supplied an explicit default, use it. | 560 // If the code supplied an explicit default, use it. |
557 if (namedArgumentValues.containsKey(_DEFAULT_VALUE_PARAM)) { | 561 if (namedArgumentValues.containsKey(_DEFAULT_VALUE_PARAM)) { |
558 value = namedArgumentValues[_DEFAULT_VALUE_PARAM]; | 562 value = namedArgumentValues[_DEFAULT_VALUE_PARAM]; |
559 } else if (value.isNull) { | 563 } else if (value.isNull) { |
560 // The code didn't supply an explicit default. | 564 // The code didn't supply an explicit default. |
561 // The name exists in the environment but we couldn't parse the | 565 // The name exists in the environment but we couldn't parse the |
562 // corresponding value. | 566 // corresponding value. |
563 // So use the built-in default value, because this is what the VM does. | 567 // So use the built-in default value, because this is what the VM does. |
564 value = builtInDefaultValue; | 568 value = builtInDefaultValue; |
565 } else { | 569 } else { |
566 // The code didn't supply an explicit default. | 570 // The code didn't supply an explicit default. |
567 // The name doesn't exist in the environment. | 571 // The name doesn't exist in the environment. |
568 // The VM would use the built-in default value, but we don't want to do | 572 // The VM would use the built-in default value, but we don't want to do |
569 // that for analysis because it's likely to lead to cascading errors. | 573 // that for analysis because it's likely to lead to cascading errors. |
570 // So just leave [value] in the unknown state. | 574 // So just leave [value] in the unknown state. |
571 } | 575 } |
572 } | 576 } |
573 return value; | 577 return value; |
574 } | 578 } |
575 | 579 |
576 DartObjectImpl evaluateConstructorCall(AstNode node, | 580 DartObjectImpl evaluateConstructorCall( |
577 NodeList<Expression> arguments, ConstructorElement constructor, | 581 AstNode node, |
578 ConstantVisitor constantVisitor, ErrorReporter errorReporter) { | 582 NodeList<Expression> arguments, |
| 583 ConstructorElement constructor, |
| 584 ConstantVisitor constantVisitor, |
| 585 ErrorReporter errorReporter) { |
579 if (!_getConstructorBase(constructor).isCycleFree) { | 586 if (!_getConstructorBase(constructor).isCycleFree) { |
580 // It's not safe to evaluate this constructor, so bail out. | 587 // It's not safe to evaluate this constructor, so bail out. |
581 // TODO(paulberry): ensure that a reasonable error message is produced | 588 // TODO(paulberry): ensure that a reasonable error message is produced |
582 // in this case, as well as other cases involving constant expression | 589 // in this case, as well as other cases involving constant expression |
583 // circularities (e.g. "compile-time constant expression depends on | 590 // circularities (e.g. "compile-time constant expression depends on |
584 // itself") | 591 // itself") |
585 return new DartObjectImpl.validWithUnknownValue(constructor.returnType); | 592 return new DartObjectImpl.validWithUnknownValue(constructor.returnType); |
586 } | 593 } |
587 int argumentCount = arguments.length; | 594 int argumentCount = arguments.length; |
588 List<DartObjectImpl> argumentValues = | 595 List<DartObjectImpl> argumentValues = |
(...skipping 28 matching lines...) Expand all Loading... |
617 errorReporter.reportErrorForNode( | 624 errorReporter.reportErrorForNode( |
618 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, node); | 625 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, node); |
619 return null; | 626 return null; |
620 } | 627 } |
621 String variableName = | 628 String variableName = |
622 argumentCount < 1 ? null : argumentValues[0].stringValue; | 629 argumentCount < 1 ? null : argumentValues[0].stringValue; |
623 if (identical(definingClass, typeProvider.boolType)) { | 630 if (identical(definingClass, typeProvider.boolType)) { |
624 DartObject valueFromEnvironment; | 631 DartObject valueFromEnvironment; |
625 valueFromEnvironment = | 632 valueFromEnvironment = |
626 _declaredVariables.getBool(typeProvider, variableName); | 633 _declaredVariables.getBool(typeProvider, variableName); |
627 return computeValueFromEnvironment(valueFromEnvironment, | 634 return computeValueFromEnvironment( |
| 635 valueFromEnvironment, |
628 new DartObjectImpl(typeProvider.boolType, BoolState.FALSE_STATE), | 636 new DartObjectImpl(typeProvider.boolType, BoolState.FALSE_STATE), |
629 namedArgumentValues); | 637 namedArgumentValues); |
630 } else if (identical(definingClass, typeProvider.intType)) { | 638 } else if (identical(definingClass, typeProvider.intType)) { |
631 DartObject valueFromEnvironment; | 639 DartObject valueFromEnvironment; |
632 valueFromEnvironment = | 640 valueFromEnvironment = |
633 _declaredVariables.getInt(typeProvider, variableName); | 641 _declaredVariables.getInt(typeProvider, variableName); |
634 return computeValueFromEnvironment(valueFromEnvironment, | 642 return computeValueFromEnvironment( |
| 643 valueFromEnvironment, |
635 new DartObjectImpl(typeProvider.nullType, NullState.NULL_STATE), | 644 new DartObjectImpl(typeProvider.nullType, NullState.NULL_STATE), |
636 namedArgumentValues); | 645 namedArgumentValues); |
637 } else if (identical(definingClass, typeProvider.stringType)) { | 646 } else if (identical(definingClass, typeProvider.stringType)) { |
638 DartObject valueFromEnvironment; | 647 DartObject valueFromEnvironment; |
639 valueFromEnvironment = | 648 valueFromEnvironment = |
640 _declaredVariables.getString(typeProvider, variableName); | 649 _declaredVariables.getString(typeProvider, variableName); |
641 return computeValueFromEnvironment(valueFromEnvironment, | 650 return computeValueFromEnvironment( |
| 651 valueFromEnvironment, |
642 new DartObjectImpl(typeProvider.nullType, NullState.NULL_STATE), | 652 new DartObjectImpl(typeProvider.nullType, NullState.NULL_STATE), |
643 namedArgumentValues); | 653 namedArgumentValues); |
644 } | 654 } |
645 } else if (constructor.name == "" && | 655 } else if (constructor.name == "" && |
646 identical(definingClass, typeProvider.symbolType) && | 656 identical(definingClass, typeProvider.symbolType) && |
647 argumentCount == 1) { | 657 argumentCount == 1) { |
648 if (!checkSymbolArguments( | 658 if (!checkSymbolArguments( |
649 arguments, argumentValues, namedArgumentValues)) { | 659 arguments, argumentValues, namedArgumentValues)) { |
650 errorReporter.reportErrorForNode( | 660 errorReporter.reportErrorForNode( |
651 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, node); | 661 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, node); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
683 !field.isStatic && | 693 !field.isStatic && |
684 field is ConstFieldElementImpl) { | 694 field is ConstFieldElementImpl) { |
685 validator.beforeGetFieldEvaluationResult(field); | 695 validator.beforeGetFieldEvaluationResult(field); |
686 EvaluationResultImpl evaluationResult = field.evaluationResult; | 696 EvaluationResultImpl evaluationResult = field.evaluationResult; |
687 DartType fieldType = | 697 DartType fieldType = |
688 FieldMember.from(field, constructor.returnType).type; | 698 FieldMember.from(field, constructor.returnType).type; |
689 DartObjectImpl fieldValue = evaluationResult.value; | 699 DartObjectImpl fieldValue = evaluationResult.value; |
690 if (fieldValue != null && !runtimeTypeMatch(fieldValue, fieldType)) { | 700 if (fieldValue != null && !runtimeTypeMatch(fieldValue, fieldType)) { |
691 errorReporter.reportErrorForNode( | 701 errorReporter.reportErrorForNode( |
692 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMA
TCH, | 702 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMA
TCH, |
693 node, [fieldValue.type, field.name, fieldType]); | 703 node, |
| 704 [fieldValue.type, field.name, fieldType]); |
694 } | 705 } |
695 fieldMap[field.name] = evaluationResult.value; | 706 fieldMap[field.name] = evaluationResult.value; |
696 } | 707 } |
697 } | 708 } |
698 // Now evaluate the constructor declaration. | 709 // Now evaluate the constructor declaration. |
699 HashMap<String, DartObjectImpl> parameterMap = | 710 HashMap<String, DartObjectImpl> parameterMap = |
700 new HashMap<String, DartObjectImpl>(); | 711 new HashMap<String, DartObjectImpl>(); |
701 List<ParameterElement> parameters = constructor.parameters; | 712 List<ParameterElement> parameters = constructor.parameters; |
702 int parameterCount = parameters.length; | 713 int parameterCount = parameters.length; |
703 for (int i = 0; i < parameterCount; i++) { | 714 for (int i = 0; i < parameterCount; i++) { |
(...skipping 26 matching lines...) Expand all Loading... |
730 // No default was provided, so the default value is null. | 741 // No default was provided, so the default value is null. |
731 argumentValue = typeProvider.nullObject; | 742 argumentValue = typeProvider.nullObject; |
732 } else if (evaluationResult.value != null) { | 743 } else if (evaluationResult.value != null) { |
733 argumentValue = evaluationResult.value; | 744 argumentValue = evaluationResult.value; |
734 } | 745 } |
735 } | 746 } |
736 if (argumentValue != null) { | 747 if (argumentValue != null) { |
737 if (!runtimeTypeMatch(argumentValue, parameter.type)) { | 748 if (!runtimeTypeMatch(argumentValue, parameter.type)) { |
738 errorReporter.reportErrorForNode( | 749 errorReporter.reportErrorForNode( |
739 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMA
TCH, | 750 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMA
TCH, |
740 errorTarget, [argumentValue.type, parameter.type]); | 751 errorTarget, |
| 752 [argumentValue.type, parameter.type]); |
741 } | 753 } |
742 if (baseParameter.isInitializingFormal) { | 754 if (baseParameter.isInitializingFormal) { |
743 FieldElement field = (parameter as FieldFormalParameterElement).field; | 755 FieldElement field = (parameter as FieldFormalParameterElement).field; |
744 if (field != null) { | 756 if (field != null) { |
745 DartType fieldType = field.type; | 757 DartType fieldType = field.type; |
746 if (fieldType != parameter.type) { | 758 if (fieldType != parameter.type) { |
747 // We've already checked that the argument can be assigned to the | 759 // We've already checked that the argument can be assigned to the |
748 // parameter; we also need to check that it can be assigned to | 760 // parameter; we also need to check that it can be assigned to |
749 // the field. | 761 // the field. |
750 if (!runtimeTypeMatch(argumentValue, fieldType)) { | 762 if (!runtimeTypeMatch(argumentValue, fieldType)) { |
751 errorReporter.reportErrorForNode( | 763 errorReporter.reportErrorForNode( |
752 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE
_MISMATCH, | 764 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE
_MISMATCH, |
753 errorTarget, [argumentValue.type, fieldType]); | 765 errorTarget, |
| 766 [argumentValue.type, fieldType]); |
754 } | 767 } |
755 } | 768 } |
756 String fieldName = field.name; | 769 String fieldName = field.name; |
757 if (fieldMap.containsKey(fieldName)) { | 770 if (fieldMap.containsKey(fieldName)) { |
758 errorReporter.reportErrorForNode( | 771 errorReporter.reportErrorForNode( |
759 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, node); | 772 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, node); |
760 } | 773 } |
761 fieldMap[fieldName] = argumentValue; | 774 fieldMap[fieldName] = argumentValue; |
762 } | 775 } |
763 } else { | 776 } else { |
764 String name = baseParameter.name; | 777 String name = baseParameter.name; |
765 parameterMap[name] = argumentValue; | 778 parameterMap[name] = argumentValue; |
766 } | 779 } |
767 } | 780 } |
768 } | 781 } |
769 ConstantVisitor initializerVisitor = new ConstantVisitor( | 782 ConstantVisitor initializerVisitor = new ConstantVisitor( |
770 this, errorReporter, lexicalEnvironment: parameterMap); | 783 this, errorReporter, |
| 784 lexicalEnvironment: parameterMap); |
771 String superName = null; | 785 String superName = null; |
772 NodeList<Expression> superArguments = null; | 786 NodeList<Expression> superArguments = null; |
773 for (ConstructorInitializer initializer in initializers) { | 787 for (ConstructorInitializer initializer in initializers) { |
774 if (initializer is ConstructorFieldInitializer) { | 788 if (initializer is ConstructorFieldInitializer) { |
775 ConstructorFieldInitializer constructorFieldInitializer = initializer; | 789 ConstructorFieldInitializer constructorFieldInitializer = initializer; |
776 Expression initializerExpression = | 790 Expression initializerExpression = |
777 constructorFieldInitializer.expression; | 791 constructorFieldInitializer.expression; |
778 DartObjectImpl evaluationResult = | 792 DartObjectImpl evaluationResult = |
779 initializerExpression.accept(initializerVisitor); | 793 initializerExpression.accept(initializerVisitor); |
780 if (evaluationResult != null) { | 794 if (evaluationResult != null) { |
781 String fieldName = constructorFieldInitializer.fieldName.name; | 795 String fieldName = constructorFieldInitializer.fieldName.name; |
782 if (fieldMap.containsKey(fieldName)) { | 796 if (fieldMap.containsKey(fieldName)) { |
783 errorReporter.reportErrorForNode( | 797 errorReporter.reportErrorForNode( |
784 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, node); | 798 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, node); |
785 } | 799 } |
786 fieldMap[fieldName] = evaluationResult; | 800 fieldMap[fieldName] = evaluationResult; |
787 PropertyAccessorElement getter = definingClass.getGetter(fieldName); | 801 PropertyAccessorElement getter = definingClass.getGetter(fieldName); |
788 if (getter != null) { | 802 if (getter != null) { |
789 PropertyInducingElement field = getter.variable; | 803 PropertyInducingElement field = getter.variable; |
790 if (!runtimeTypeMatch(evaluationResult, field.type)) { | 804 if (!runtimeTypeMatch(evaluationResult, field.type)) { |
791 errorReporter.reportErrorForNode( | 805 errorReporter.reportErrorForNode( |
792 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_M
ISMATCH, | 806 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_M
ISMATCH, |
793 node, [evaluationResult.type, fieldName, field.type]); | 807 node, |
| 808 [evaluationResult.type, fieldName, field.type]); |
794 } | 809 } |
795 } | 810 } |
796 } | 811 } |
797 } else if (initializer is SuperConstructorInvocation) { | 812 } else if (initializer is SuperConstructorInvocation) { |
798 SuperConstructorInvocation superConstructorInvocation = initializer; | 813 SuperConstructorInvocation superConstructorInvocation = initializer; |
799 SimpleIdentifier name = superConstructorInvocation.constructorName; | 814 SimpleIdentifier name = superConstructorInvocation.constructorName; |
800 if (name != null) { | 815 if (name != null) { |
801 superName = name.name; | 816 superName = name.name; |
802 } | 817 } |
803 superArguments = superConstructorInvocation.argumentList.arguments; | 818 superArguments = superConstructorInvocation.argumentList.arguments; |
804 } else if (initializer is RedirectingConstructorInvocation) { | 819 } else if (initializer is RedirectingConstructorInvocation) { |
805 // This is a redirecting constructor, so just evaluate the constructor | 820 // This is a redirecting constructor, so just evaluate the constructor |
806 // it redirects to. | 821 // it redirects to. |
807 ConstructorElement constructor = initializer.staticElement; | 822 ConstructorElement constructor = initializer.staticElement; |
808 if (constructor != null && constructor.isConst) { | 823 if (constructor != null && constructor.isConst) { |
809 return evaluateConstructorCall(node, | 824 return evaluateConstructorCall( |
810 initializer.argumentList.arguments, constructor, | 825 node, |
811 initializerVisitor, errorReporter); | 826 initializer.argumentList.arguments, |
| 827 constructor, |
| 828 initializerVisitor, |
| 829 errorReporter); |
812 } | 830 } |
813 } | 831 } |
814 } | 832 } |
815 // Evaluate explicit or implicit call to super(). | 833 // Evaluate explicit or implicit call to super(). |
816 InterfaceType superclass = definingClass.superclass; | 834 InterfaceType superclass = definingClass.superclass; |
817 if (superclass != null && !superclass.isObject) { | 835 if (superclass != null && !superclass.isObject) { |
818 ConstructorElement superConstructor = | 836 ConstructorElement superConstructor = |
819 superclass.lookUpConstructor(superName, constructor.library); | 837 superclass.lookUpConstructor(superName, constructor.library); |
820 if (superConstructor != null) { | 838 if (superConstructor != null) { |
821 if (superArguments == null) { | 839 if (superArguments == null) { |
822 superArguments = new NodeList<Expression>(null); | 840 superArguments = new NodeList<Expression>(null); |
823 } | 841 } |
824 evaluateSuperConstructorCall(node, fieldMap, superConstructor, | 842 evaluateSuperConstructorCall(node, fieldMap, superConstructor, |
825 superArguments, initializerVisitor, errorReporter); | 843 superArguments, initializerVisitor, errorReporter); |
826 } | 844 } |
827 } | 845 } |
828 return new DartObjectImpl(definingClass, new GenericState(fieldMap)); | 846 return new DartObjectImpl(definingClass, new GenericState(fieldMap)); |
829 } | 847 } |
830 | 848 |
831 void evaluateSuperConstructorCall(AstNode node, | 849 void evaluateSuperConstructorCall( |
| 850 AstNode node, |
832 HashMap<String, DartObjectImpl> fieldMap, | 851 HashMap<String, DartObjectImpl> fieldMap, |
833 ConstructorElement superConstructor, NodeList<Expression> superArguments, | 852 ConstructorElement superConstructor, |
834 ConstantVisitor initializerVisitor, ErrorReporter errorReporter) { | 853 NodeList<Expression> superArguments, |
| 854 ConstantVisitor initializerVisitor, |
| 855 ErrorReporter errorReporter) { |
835 if (superConstructor != null && superConstructor.isConst) { | 856 if (superConstructor != null && superConstructor.isConst) { |
836 DartObjectImpl evaluationResult = evaluateConstructorCall(node, | 857 DartObjectImpl evaluationResult = evaluateConstructorCall(node, |
837 superArguments, superConstructor, initializerVisitor, errorReporter); | 858 superArguments, superConstructor, initializerVisitor, errorReporter); |
838 if (evaluationResult != null) { | 859 if (evaluationResult != null) { |
839 fieldMap[GenericState.SUPERCLASS_FIELD] = evaluationResult; | 860 fieldMap[GenericState.SUPERCLASS_FIELD] = evaluationResult; |
840 } | 861 } |
841 } | 862 } |
842 } | 863 } |
843 | 864 |
844 /** | 865 /** |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
990 bool operator ==(other) { | 1011 bool operator ==(other) { |
991 if (other is ConstantEvaluationTarget_Annotation) { | 1012 if (other is ConstantEvaluationTarget_Annotation) { |
992 return this.context == other.context && | 1013 return this.context == other.context && |
993 this.source == other.source && | 1014 this.source == other.source && |
994 this.librarySource == other.librarySource && | 1015 this.librarySource == other.librarySource && |
995 this.annotation == other.annotation; | 1016 this.annotation == other.annotation; |
996 } else { | 1017 } else { |
997 return false; | 1018 return false; |
998 } | 1019 } |
999 } | 1020 } |
| 1021 |
| 1022 @override |
| 1023 String toString() => 'Constant: $annotation'; |
1000 } | 1024 } |
1001 | 1025 |
1002 /** | 1026 /** |
1003 * Interface used by unit tests to verify correct dependency analysis during | 1027 * Interface used by unit tests to verify correct dependency analysis during |
1004 * constant evaluation. | 1028 * constant evaluation. |
1005 */ | 1029 */ |
1006 abstract class ConstantEvaluationValidator { | 1030 abstract class ConstantEvaluationValidator { |
1007 /** | 1031 /** |
1008 * This method is called just before computing the constant value associated | 1032 * This method is called just before computing the constant value associated |
1009 * with [constant]. Unit tests will override this method to introduce | 1033 * with [constant]. Unit tests will override this method to introduce |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1054 @override | 1078 @override |
1055 void beforeGetEvaluationResult(ConstantEvaluationTarget constant) {} | 1079 void beforeGetEvaluationResult(ConstantEvaluationTarget constant) {} |
1056 | 1080 |
1057 @override | 1081 @override |
1058 void beforeGetFieldEvaluationResult(FieldElementImpl field) {} | 1082 void beforeGetFieldEvaluationResult(FieldElementImpl field) {} |
1059 | 1083 |
1060 @override | 1084 @override |
1061 void beforeGetParameterDefault(ParameterElement parameter) {} | 1085 void beforeGetParameterDefault(ParameterElement parameter) {} |
1062 } | 1086 } |
1063 | 1087 |
1064 /** | 1088 /// Instances of the class [ConstantEvaluator] evaluate constant expressions to |
1065 * Instances of the class `ConstantEvaluator` evaluate constant expressions to | 1089 /// produce their compile-time value. |
1066 * produce their compile-time value. According to the Dart Language | 1090 /// |
1067 * Specification: | 1091 /// According to the Dart Language Specification: |
1068 * <blockquote> | 1092 /// |
1069 * A constant expression is one of the following: | 1093 /// > A constant expression is one of the following: |
1070 * * A literal number. | 1094 /// > |
1071 * * A literal boolean. | 1095 /// > * A literal number. |
1072 * * A literal string where any interpolated expression is a compile-time | 1096 /// > * A literal boolean. |
1073 * constant that evaluates to a numeric, string or boolean value or to | 1097 /// > * A literal string where any interpolated expression is a compile-time |
1074 * <b>null</b>. | 1098 /// > constant that evaluates to a numeric, string or boolean value or to |
1075 * * A literal symbol. | 1099 /// > **null**. |
1076 * * <b>null</b>. | 1100 /// > * A literal symbol. |
1077 * * A qualified reference to a static constant variable. | 1101 /// > * **null**. |
1078 * * An identifier expression that denotes a constant variable, class or type | 1102 /// > * A qualified reference to a static constant variable. |
1079 * alias. | 1103 /// > * An identifier expression that denotes a constant variable, class or type |
1080 * * A constant constructor invocation. | 1104 /// > alias. |
1081 * * A constant list literal. | 1105 /// > * A constant constructor invocation. |
1082 * * A constant map literal. | 1106 /// > * A constant list literal. |
1083 * * A simple or qualified identifier denoting a top-level function or a static | 1107 /// > * A constant map literal. |
1084 * method. | 1108 /// > * A simple or qualified identifier denoting a top-level function or a |
1085 * * A parenthesized expression <i>(e)</i> where <i>e</i> is a constant | 1109 /// > static method. |
1086 * expression. | 1110 /// > * A parenthesized expression _(e)_ where _e_ is a constant expression. |
1087 * * An expression of the form <i>identical(e<sub>1</sub>, e<sub>2</sub>)</i> | 1111 /// > * <span> |
1088 * where <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant | 1112 /// > An expression of the form <i>identical(e<sub>1</sub>, e<sub>2</sub>)</i> |
1089 * expressions and <i>identical()</i> is statically bound to the predefined | 1113 /// > where <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant |
1090 * dart function <i>identical()</i> discussed above. | 1114 /// > expressions and <i>identical()</i> is statically bound to the predefined |
1091 * * An expression of one of the forms <i>e<sub>1</sub> == e<sub>2</sub></i> or | 1115 /// > dart function <i>identical()</i> discussed above. |
1092 * <i>e<sub>1</sub> != e<sub>2</sub></i> where <i>e<sub>1</sub></i> and | 1116 /// > </span> |
1093 * <i>e<sub>2</sub></i> are constant expressions that evaluate to a numeric, | 1117 /// > * <span> |
1094 * string or boolean value. | 1118 /// > An expression of one of the forms <i>e<sub>1</sub> == e<sub>2</sub></i> |
1095 * * An expression of one of the forms <i>!e</i>, <i>e<sub>1</sub> && | 1119 /// > or <i>e<sub>1</sub> != e<sub>2</sub></i> where <i>e<sub>1</sub></i> and |
1096 * e<sub>2</sub></i> or <i>e<sub>1</sub> || e<sub>2</sub></i>, where <i>e</i>, | 1120 /// > <i>e<sub>2</sub></i> are constant expressions that evaluate to a |
1097 * <i>e1</sub></i> and <i>e2</sub></i> are constant expressions that evaluate | 1121 /// > numeric, string or boolean value. |
1098 * to a boolean value. | 1122 /// > </span> |
1099 * * An expression of one of the forms <i>~e</i>, <i>e<sub>1</sub> ^ | 1123 /// > * <span> |
1100 * e<sub>2</sub></i>, <i>e<sub>1</sub> & e<sub>2</sub></i>, | 1124 /// > An expression of one of the forms <i>!e</i>, <i>e<sub>1</sub> && |
1101 * <i>e<sub>1</sub> | e<sub>2</sub></i>, <i>e<sub>1</sub> >> | 1125 /// > e<sub>2</sub></i> or <i>e<sub>1</sub> || e<sub>2</sub></i>, where |
1102 * e<sub>2</sub></i> or <i>e<sub>1</sub> << e<sub>2</sub></i>, where | 1126 /// > <i>e</i>, <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant |
1103 * <i>e</i>, <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant | 1127 /// > expressions that evaluate to a boolean value. |
1104 * expressions that evaluate to an integer value or to <b>null</b>. | 1128 /// > </span> |
1105 * * An expression of one of the forms <i>-e</i>, <i>e<sub>1</sub> + | 1129 /// > * <span> |
1106 * e<sub>2</sub></i>, <i>e<sub>1</sub> -e<sub>2</sub></i>, <i>e<sub>1</sub> * | 1130 /// > An expression of one of the forms <i>~e</i>, <i>e<sub>1</sub> ^ |
1107 * e<sub>2</sub></i>, <i>e<sub>1</sub> / e<sub>2</sub></i>, <i>e<sub>1</sub> | 1131 /// > e<sub>2</sub></i>, <i>e<sub>1</sub> & e<sub>2</sub></i>, |
1108 * ~/ e<sub>2</sub></i>, <i>e<sub>1</sub> > e<sub>2</sub></i>, | 1132 /// > <i>e<sub>1</sub> | e<sub>2</sub></i>, <i>e<sub>1</sub> >> |
1109 * <i>e<sub>1</sub> < e<sub>2</sub></i>, <i>e<sub>1</sub> >= | 1133 /// > e<sub>2</sub></i> or <i>e<sub>1</sub> << e<sub>2</sub></i>, where |
1110 * e<sub>2</sub></i>, <i>e<sub>1</sub> <= e<sub>2</sub></i> or | 1134 /// > <i>e</i>, <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant |
1111 * <i>e<sub>1</sub> % e<sub>2</sub></i>, where <i>e</i>, <i>e<sub>1</sub></i> | 1135 /// > expressions that evaluate to an integer value or to <b>null</b>. |
1112 * and <i>e<sub>2</sub></i> are constant expressions that evaluate to a | 1136 /// > </span> |
1113 * numeric value or to <b>null</b>. | 1137 /// > * <span> |
1114 * * An expression of the form <i>e<sub>1</sub> ? e<sub>2</sub> : | 1138 /// > An expression of one of the forms <i>-e</i>, <i>e<sub>1</sub> + |
1115 * e<sub>3</sub></i> where <i>e<sub>1</sub></i>, <i>e<sub>2</sub></i> and | 1139 /// > e<sub>2</sub></i>, <i>e<sub>1</sub> -e<sub>2</sub></i>, |
1116 * <i>e<sub>3</sub></i> are constant expressions, and <i>e<sub>1</sub></i> | 1140 /// > <i>e<sub>1</sub> * e<sub>2</sub></i>, <i>e<sub>1</sub> / |
1117 * evaluates to a boolean value. | 1141 /// > e<sub>2</sub></i>, <i>e<sub>1</sub> ~/ e<sub>2</sub></i>, |
1118 * </blockquote> | 1142 /// > <i>e<sub>1</sub> > e<sub>2</sub></i>, <i>e<sub>1</sub> < |
1119 */ | 1143 /// > e<sub>2</sub></i>, <i>e<sub>1</sub> >= e<sub>2</sub></i>, |
| 1144 /// > <i>e<sub>1</sub> <= e<sub>2</sub></i> or <i>e<sub>1</sub> % |
| 1145 /// > e<sub>2</sub></i>, where <i>e</i>, <i>e<sub>1</sub></i> and |
| 1146 /// > <i>e<sub>2</sub></i> are constant expressions that evaluate to a numeric |
| 1147 /// > value or to <b>null</b>. |
| 1148 /// > </span> |
| 1149 /// > * <span> |
| 1150 /// > An expression of the form <i>e<sub>1</sub> ? e<sub>2</sub> : |
| 1151 /// > e<sub>3</sub></i> where <i>e<sub>1</sub></i>, <i>e<sub>2</sub></i> and |
| 1152 /// > <i>e<sub>3</sub></i> are constant expressions, and <i>e<sub>1</sub></i> |
| 1153 /// > evaluates to a boolean value. |
| 1154 /// > </span> |
| 1155 /// |
| 1156 /// The values returned by instances of this class are therefore `null` and |
| 1157 /// instances of the classes `Boolean`, `BigInteger`, `Double`, `String`, and |
| 1158 /// `DartObject`. |
| 1159 /// |
| 1160 /// In addition, this class defines several values that can be returned to |
| 1161 /// indicate various conditions encountered during evaluation. These are |
| 1162 /// documented with the static fields that define those values. |
1120 class ConstantEvaluator { | 1163 class ConstantEvaluator { |
1121 /** | 1164 /** |
1122 * The source containing the expression(s) that will be evaluated. | 1165 * The source containing the expression(s) that will be evaluated. |
1123 */ | 1166 */ |
1124 final Source _source; | 1167 final Source _source; |
1125 | 1168 |
1126 /** | 1169 /** |
1127 * The type provider used to access the known types. | 1170 * The type provider used to access the known types. |
1128 */ | 1171 */ |
1129 final TypeProvider _typeProvider; | 1172 final TypeProvider _typeProvider; |
1130 | 1173 |
1131 /** | 1174 /** |
| 1175 * The type system primitives. |
| 1176 */ |
| 1177 final TypeSystem _typeSystem; |
| 1178 |
| 1179 /** |
1132 * Initialize a newly created evaluator to evaluate expressions in the given | 1180 * Initialize a newly created evaluator to evaluate expressions in the given |
1133 * [source]. The [typeProvider] is the type provider used to access known | 1181 * [source]. The [typeProvider] is the type provider used to access known |
1134 * types. | 1182 * types. |
1135 */ | 1183 */ |
1136 ConstantEvaluator(this._source, this._typeProvider); | 1184 ConstantEvaluator(this._source, this._typeProvider, {TypeSystem typeSystem}) |
| 1185 : _typeSystem = typeSystem != null ? typeSystem : new TypeSystemImpl(); |
1137 | 1186 |
1138 EvaluationResult evaluate(Expression expression) { | 1187 EvaluationResult evaluate(Expression expression) { |
1139 RecordingErrorListener errorListener = new RecordingErrorListener(); | 1188 RecordingErrorListener errorListener = new RecordingErrorListener(); |
1140 ErrorReporter errorReporter = new ErrorReporter(errorListener, _source); | 1189 ErrorReporter errorReporter = new ErrorReporter(errorListener, _source); |
1141 DartObjectImpl result = expression.accept(new ConstantVisitor( | 1190 DartObjectImpl result = expression.accept(new ConstantVisitor( |
1142 new ConstantEvaluationEngine(_typeProvider, new DeclaredVariables()), | 1191 new ConstantEvaluationEngine(_typeProvider, new DeclaredVariables(), |
| 1192 typeSystem: _typeSystem), |
1143 errorReporter)); | 1193 errorReporter)); |
1144 if (result != null) { | 1194 if (result != null) { |
1145 return EvaluationResult.forValue(result); | 1195 return EvaluationResult.forValue(result); |
1146 } | 1196 } |
1147 return EvaluationResult.forErrors(errorListener.errors); | 1197 return EvaluationResult.forErrors(errorListener.errors); |
1148 } | 1198 } |
1149 } | 1199 } |
1150 | 1200 |
1151 /** | 1201 /** |
1152 * A visitor used to traverse the AST structures of all of the compilation units | 1202 * A visitor used to traverse the AST structures of all of the compilation units |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1276 | 1326 |
1277 final AnalysisContext _context; | 1327 final AnalysisContext _context; |
1278 | 1328 |
1279 /** | 1329 /** |
1280 * Initialize a newly created constant value computer. The [typeProvider] is | 1330 * Initialize a newly created constant value computer. The [typeProvider] is |
1281 * the type provider used to access known types. The [declaredVariables] is | 1331 * the type provider used to access known types. The [declaredVariables] is |
1282 * the set of variables declared on the command line using '-D'. | 1332 * the set of variables declared on the command line using '-D'. |
1283 */ | 1333 */ |
1284 ConstantValueComputer(this._context, TypeProvider typeProvider, | 1334 ConstantValueComputer(this._context, TypeProvider typeProvider, |
1285 DeclaredVariables declaredVariables, | 1335 DeclaredVariables declaredVariables, |
1286 [ConstantEvaluationValidator validator]) | 1336 [ConstantEvaluationValidator validator, TypeSystem typeSystem]) |
1287 : evaluationEngine = new ConstantEvaluationEngine( | 1337 : evaluationEngine = new ConstantEvaluationEngine( |
1288 typeProvider, declaredVariables, validator: validator); | 1338 typeProvider, declaredVariables, |
| 1339 validator: validator, typeSystem: typeSystem); |
1289 | 1340 |
1290 /** | 1341 /** |
1291 * Add the constants in the given compilation [unit] to the list of constants | 1342 * Add the constants in the given compilation [unit] to the list of constants |
1292 * whose value needs to be computed. | 1343 * whose value needs to be computed. |
1293 */ | 1344 */ |
1294 void add(CompilationUnit unit, Source source, Source librarySource) { | 1345 void add(CompilationUnit unit, Source source, Source librarySource) { |
1295 ConstantFinder constantFinder = | 1346 ConstantFinder constantFinder = |
1296 new ConstantFinder(_context, source, librarySource); | 1347 new ConstantFinder(_context, source, librarySource); |
1297 unit.accept(constantFinder); | 1348 unit.accept(constantFinder); |
1298 _constantsToCompute.addAll(constantFinder.constantsToCompute); | 1349 _constantsToCompute.addAll(constantFinder.constantsToCompute); |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1548 return conditionResult; | 1599 return conditionResult; |
1549 } | 1600 } |
1550 if (conditionResult.isTrue) { | 1601 if (conditionResult.isTrue) { |
1551 return thenResult; | 1602 return thenResult; |
1552 } else if (conditionResult.isFalse) { | 1603 } else if (conditionResult.isFalse) { |
1553 return elseResult; | 1604 return elseResult; |
1554 } | 1605 } |
1555 ParameterizedType thenType = thenResult.type; | 1606 ParameterizedType thenType = thenResult.type; |
1556 ParameterizedType elseType = elseResult.type; | 1607 ParameterizedType elseType = elseResult.type; |
1557 return new DartObjectImpl.validWithUnknownValue( | 1608 return new DartObjectImpl.validWithUnknownValue( |
1558 _typeSystem.getLeastUpperBound(thenType, elseType) as InterfaceType); | 1609 _typeSystem.getLeastUpperBound(_typeProvider, thenType, elseType) |
| 1610 as InterfaceType); |
1559 } | 1611 } |
1560 | 1612 |
1561 @override | 1613 @override |
1562 DartObjectImpl visitDoubleLiteral(DoubleLiteral node) => | 1614 DartObjectImpl visitDoubleLiteral(DoubleLiteral node) => |
1563 new DartObjectImpl(_typeProvider.doubleType, new DoubleState(node.value)); | 1615 new DartObjectImpl(_typeProvider.doubleType, new DoubleState(node.value)); |
1564 | 1616 |
1565 @override | 1617 @override |
1566 DartObjectImpl visitInstanceCreationExpression( | 1618 DartObjectImpl visitInstanceCreationExpression( |
1567 InstanceCreationExpression node) { | 1619 InstanceCreationExpression node) { |
1568 if (!node.isConst) { | 1620 if (!node.isConst) { |
(...skipping 1017 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2586 typeProvider.boolType, _state.greaterThan(rightOperand._state)); | 2638 typeProvider.boolType, _state.greaterThan(rightOperand._state)); |
2587 | 2639 |
2588 /** | 2640 /** |
2589 * Return the result of invoking the '>=' operator on this object with the | 2641 * Return the result of invoking the '>=' operator on this object with the |
2590 * [rightOperand]. The [typeProvider] is the type provider used to find known | 2642 * [rightOperand]. The [typeProvider] is the type provider used to find known |
2591 * types. | 2643 * types. |
2592 * | 2644 * |
2593 * Throws an [EvaluationException] if the operator is not appropriate for an | 2645 * Throws an [EvaluationException] if the operator is not appropriate for an |
2594 * object of this kind. | 2646 * object of this kind. |
2595 */ | 2647 */ |
2596 DartObjectImpl greaterThanOrEqual(TypeProvider typeProvider, | 2648 DartObjectImpl greaterThanOrEqual( |
2597 DartObjectImpl rightOperand) => new DartObjectImpl( | 2649 TypeProvider typeProvider, DartObjectImpl rightOperand) => |
2598 typeProvider.boolType, _state.greaterThanOrEqual(rightOperand._state)); | 2650 new DartObjectImpl(typeProvider.boolType, |
| 2651 _state.greaterThanOrEqual(rightOperand._state)); |
2599 | 2652 |
2600 /** | 2653 /** |
2601 * Return the result of invoking the '~/' operator on this object with the | 2654 * Return the result of invoking the '~/' operator on this object with the |
2602 * [rightOperand]. The [typeProvider] is the type provider used to find known | 2655 * [rightOperand]. The [typeProvider] is the type provider used to find known |
2603 * types. | 2656 * types. |
2604 * | 2657 * |
2605 * Throws an [EvaluationException] if the operator is not appropriate for an | 2658 * Throws an [EvaluationException] if the operator is not appropriate for an |
2606 * object of this kind. | 2659 * object of this kind. |
2607 */ | 2660 */ |
2608 DartObjectImpl integerDivide( | 2661 DartObjectImpl integerDivide( |
(...skipping 910 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3519 EvaluationResultImpl(this.value, [List<AnalysisError> errors]) { | 3572 EvaluationResultImpl(this.value, [List<AnalysisError> errors]) { |
3520 this._errors = errors == null ? <AnalysisError>[] : errors; | 3573 this._errors = errors == null ? <AnalysisError>[] : errors; |
3521 } | 3574 } |
3522 | 3575 |
3523 @deprecated // Use new EvaluationResultImpl(value) | 3576 @deprecated // Use new EvaluationResultImpl(value) |
3524 EvaluationResultImpl.con1(this.value) { | 3577 EvaluationResultImpl.con1(this.value) { |
3525 this._errors = new List<AnalysisError>(0); | 3578 this._errors = new List<AnalysisError>(0); |
3526 } | 3579 } |
3527 | 3580 |
3528 @deprecated // Use new EvaluationResultImpl(value, errors) | 3581 @deprecated // Use new EvaluationResultImpl(value, errors) |
3529 EvaluationResultImpl.con2(this.value, List<AnalysisError> errors) { | 3582 EvaluationResultImpl.con2(this.value, List<AnalysisError> this._errors); |
3530 this._errors = errors; | |
3531 } | |
3532 | 3583 |
3533 List<AnalysisError> get errors => _errors; | 3584 List<AnalysisError> get errors => _errors; |
3534 | 3585 |
3535 bool equalValues(TypeProvider typeProvider, EvaluationResultImpl result) { | 3586 bool equalValues(TypeProvider typeProvider, EvaluationResultImpl result) { |
3536 if (this.value != null) { | 3587 if (this.value != null) { |
3537 if (result.value == null) { | 3588 if (result.value == null) { |
3538 return false; | 3589 return false; |
3539 } | 3590 } |
3540 return value == result.value; | 3591 return value == result.value; |
3541 } else { | 3592 } else { |
(...skipping 1730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5272 return BoolState.from(_element == rightElement); | 5323 return BoolState.from(_element == rightElement); |
5273 } else if (rightOperand is DynamicState) { | 5324 } else if (rightOperand is DynamicState) { |
5274 return BoolState.UNKNOWN_VALUE; | 5325 return BoolState.UNKNOWN_VALUE; |
5275 } | 5326 } |
5276 return BoolState.FALSE_STATE; | 5327 return BoolState.FALSE_STATE; |
5277 } | 5328 } |
5278 | 5329 |
5279 @override | 5330 @override |
5280 String toString() => _element == null ? "-unknown-" : _element.name; | 5331 String toString() => _element == null ? "-unknown-" : _element.name; |
5281 } | 5332 } |
OLD | NEW |