| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 library dart2js.compile_time_constant_evaluator; | 5 library dart2js.compile_time_constant_evaluator; |
| 6 | 6 |
| 7 import 'common/resolution.dart' show | 7 import 'common/resolution.dart' show |
| 8 Resolution; | 8 Resolution; |
| 9 import 'common/tasks.dart' show | 9 import 'common/tasks.dart' show |
| 10 CompilerTask; | 10 CompilerTask; |
| 11 import 'compiler.dart' show | 11 import 'compiler.dart' show |
| 12 Compiler; | 12 Compiler; |
| 13 import 'constant_system_dart.dart'; | 13 import 'constant_system_dart.dart'; |
| 14 import 'constants/constant_system.dart'; | 14 import 'constants/constant_system.dart'; |
| 15 import 'constants/evaluation.dart'; | 15 import 'constants/evaluation.dart'; |
| 16 import 'constants/expressions.dart'; | 16 import 'constants/expressions.dart'; |
| 17 import 'constants/values.dart'; | 17 import 'constants/values.dart'; |
| 18 import 'dart_types.dart'; | 18 import 'dart_types.dart'; |
| 19 import 'diagnostics/diagnostic_listener.dart' show |
| 20 DiagnosticReporter; |
| 19 import 'diagnostics/invariant.dart' show | 21 import 'diagnostics/invariant.dart' show |
| 20 invariant; | 22 invariant; |
| 21 import 'diagnostics/messages.dart' show | 23 import 'diagnostics/messages.dart' show |
| 22 MessageKind; | 24 MessageKind; |
| 23 import 'enqueue.dart' show | 25 import 'enqueue.dart' show |
| 24 WorldImpact; | 26 WorldImpact; |
| 25 import 'elements/elements.dart'; | 27 import 'elements/elements.dart'; |
| 26 import 'elements/modelx.dart' show | 28 import 'elements/modelx.dart' show |
| 27 FunctionElementX; | 29 FunctionElementX; |
| 28 import 'resolution/tree_elements.dart' show | 30 import 'resolution/tree_elements.dart' show |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 156 new Map<VariableElement, ConstantExpression>(); | 158 new Map<VariableElement, ConstantExpression>(); |
| 157 | 159 |
| 158 /** The set of variable elements that are in the process of being computed. */ | 160 /** The set of variable elements that are in the process of being computed. */ |
| 159 final Set<VariableElement> pendingVariables = new Set<VariableElement>(); | 161 final Set<VariableElement> pendingVariables = new Set<VariableElement>(); |
| 160 | 162 |
| 161 final Map<ConstantExpression, ConstantValue> constantValueMap = | 163 final Map<ConstantExpression, ConstantValue> constantValueMap = |
| 162 <ConstantExpression, ConstantValue>{}; | 164 <ConstantExpression, ConstantValue>{}; |
| 163 | 165 |
| 164 ConstantCompilerBase(this.compiler, this.constantSystem); | 166 ConstantCompilerBase(this.compiler, this.constantSystem); |
| 165 | 167 |
| 168 DiagnosticReporter get reporter => compiler.reporter; |
| 169 |
| 166 @override | 170 @override |
| 167 ConstantValue getConstantValueForVariable(VariableElement element) { | 171 ConstantValue getConstantValueForVariable(VariableElement element) { |
| 168 return getConstantValue(initialVariableValues[element.declaration]); | 172 return getConstantValue(initialVariableValues[element.declaration]); |
| 169 } | 173 } |
| 170 | 174 |
| 171 @override | 175 @override |
| 172 ConstantExpression getConstantForVariable(VariableElement element) { | 176 ConstantExpression getConstantForVariable(VariableElement element) { |
| 173 return initialVariableValues[element.declaration]; | 177 return initialVariableValues[element.declaration]; |
| 174 } | 178 } |
| 175 | 179 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 193 /// Compile [element] into a constant expression. If [isConst] is true, | 197 /// Compile [element] into a constant expression. If [isConst] is true, |
| 194 /// then [element] is a constant variable. If [checkType] is true, then | 198 /// then [element] is a constant variable. If [checkType] is true, then |
| 195 /// report an error if [element] does not typecheck. | 199 /// report an error if [element] does not typecheck. |
| 196 ConstantExpression internalCompileVariable( | 200 ConstantExpression internalCompileVariable( |
| 197 VariableElement element, bool isConst, bool checkType) { | 201 VariableElement element, bool isConst, bool checkType) { |
| 198 if (initialVariableValues.containsKey(element.declaration)) { | 202 if (initialVariableValues.containsKey(element.declaration)) { |
| 199 ConstantExpression result = initialVariableValues[element.declaration]; | 203 ConstantExpression result = initialVariableValues[element.declaration]; |
| 200 return result; | 204 return result; |
| 201 } | 205 } |
| 202 AstElement currentElement = element.analyzableElement; | 206 AstElement currentElement = element.analyzableElement; |
| 203 return compiler.withCurrentElement(currentElement, () { | 207 return reporter.withCurrentElement(currentElement, () { |
| 204 // TODO(johnniwinther): Avoid this eager analysis. | 208 // TODO(johnniwinther): Avoid this eager analysis. |
| 205 _analyzeElementEagerly(compiler, currentElement); | 209 _analyzeElementEagerly(compiler, currentElement); |
| 206 | 210 |
| 207 ConstantExpression constant = compileVariableWithDefinitions( | 211 ConstantExpression constant = compileVariableWithDefinitions( |
| 208 element, currentElement.resolvedAst.elements, | 212 element, currentElement.resolvedAst.elements, |
| 209 isConst: isConst, checkType: checkType); | 213 isConst: isConst, checkType: checkType); |
| 210 return constant; | 214 return constant; |
| 211 }); | 215 }); |
| 212 } | 216 } |
| 213 | 217 |
| 214 /** | 218 /** |
| 215 * Returns the a compile-time constant if the variable could be compiled | 219 * Returns the a compile-time constant if the variable could be compiled |
| 216 * eagerly. If the variable needs to be initialized lazily returns `null`. | 220 * eagerly. If the variable needs to be initialized lazily returns `null`. |
| 217 * If the variable is `const` but cannot be compiled eagerly reports an | 221 * If the variable is `const` but cannot be compiled eagerly reports an |
| 218 * error. | 222 * error. |
| 219 */ | 223 */ |
| 220 ConstantExpression compileVariableWithDefinitions( | 224 ConstantExpression compileVariableWithDefinitions( |
| 221 VariableElement element, TreeElements definitions, | 225 VariableElement element, TreeElements definitions, |
| 222 {bool isConst: false, bool checkType: true}) { | 226 {bool isConst: false, bool checkType: true}) { |
| 223 Node node = element.node; | 227 Node node = element.node; |
| 224 if (pendingVariables.contains(element)) { | 228 if (pendingVariables.contains(element)) { |
| 225 if (isConst) { | 229 if (isConst) { |
| 226 compiler.reportErrorMessage( | 230 reporter.reportErrorMessage( |
| 227 node, MessageKind.CYCLIC_COMPILE_TIME_CONSTANTS); | 231 node, MessageKind.CYCLIC_COMPILE_TIME_CONSTANTS); |
| 228 ConstantExpression expression = new ErroneousConstantExpression(); | 232 ConstantExpression expression = new ErroneousConstantExpression(); |
| 229 constantValueMap[expression] = constantSystem.createNull(); | 233 constantValueMap[expression] = constantSystem.createNull(); |
| 230 return expression; | 234 return expression; |
| 231 } | 235 } |
| 232 return null; | 236 return null; |
| 233 } | 237 } |
| 234 pendingVariables.add(element); | 238 pendingVariables.add(element); |
| 235 | 239 |
| 236 Expression initializer = element.initializer; | 240 Expression initializer = element.initializer; |
| 237 ConstantExpression expression; | 241 ConstantExpression expression; |
| 238 if (initializer == null) { | 242 if (initializer == null) { |
| 239 // No initial value. | 243 // No initial value. |
| 240 expression = new NullConstantExpression(); | 244 expression = new NullConstantExpression(); |
| 241 constantValueMap[expression] = constantSystem.createNull(); | 245 constantValueMap[expression] = constantSystem.createNull(); |
| 242 } else { | 246 } else { |
| 243 expression = compileNodeWithDefinitions(initializer, definitions, | 247 expression = compileNodeWithDefinitions(initializer, definitions, |
| 244 isConst: isConst); | 248 isConst: isConst); |
| 245 if (compiler.enableTypeAssertions && | 249 if (compiler.enableTypeAssertions && |
| 246 checkType && | 250 checkType && |
| 247 expression != null && | 251 expression != null && |
| 248 element.isField) { | 252 element.isField) { |
| 249 DartType elementType = element.type; | 253 DartType elementType = element.type; |
| 250 ConstantValue value = getConstantValue(expression); | 254 ConstantValue value = getConstantValue(expression); |
| 251 if (elementType.isMalformed && !value.isNull) { | 255 if (elementType.isMalformed && !value.isNull) { |
| 252 if (isConst) { | 256 if (isConst) { |
| 253 ErroneousElement element = elementType.element; | 257 ErroneousElement element = elementType.element; |
| 254 compiler.reportErrorMessage( | 258 reporter.reportErrorMessage( |
| 255 node, element.messageKind, element.messageArguments); | 259 node, element.messageKind, element.messageArguments); |
| 256 } else { | 260 } else { |
| 257 // We need to throw an exception at runtime. | 261 // We need to throw an exception at runtime. |
| 258 expression = null; | 262 expression = null; |
| 259 } | 263 } |
| 260 } else { | 264 } else { |
| 261 DartType constantType = value.getType(compiler.coreTypes); | 265 DartType constantType = value.getType(compiler.coreTypes); |
| 262 if (!constantSystem.isSubtype( | 266 if (!constantSystem.isSubtype( |
| 263 compiler.types, constantType, elementType)) { | 267 compiler.types, constantType, elementType)) { |
| 264 if (isConst) { | 268 if (isConst) { |
| 265 compiler.reportErrorMessage( | 269 reporter.reportErrorMessage( |
| 266 node, | 270 node, |
| 267 MessageKind.NOT_ASSIGNABLE, | 271 MessageKind.NOT_ASSIGNABLE, |
| 268 {'fromType': constantType, | 272 {'fromType': constantType, |
| 269 'toType': elementType}); | 273 'toType': elementType}); |
| 270 } else { | 274 } else { |
| 271 // If the field cannot be lazily initialized, we will throw | 275 // If the field cannot be lazily initialized, we will throw |
| 272 // the exception at runtime. | 276 // the exception at runtime. |
| 273 expression = null; | 277 expression = null; |
| 274 } | 278 } |
| 275 } | 279 } |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 | 367 |
| 364 Element get context => elements.analyzedElement; | 368 Element get context => elements.analyzedElement; |
| 365 | 369 |
| 366 CompileTimeConstantEvaluator(this.handler, this.elements, this.compiler, | 370 CompileTimeConstantEvaluator(this.handler, this.elements, this.compiler, |
| 367 {bool isConst: false}) | 371 {bool isConst: false}) |
| 368 : this.isEvaluatingConstant = isConst; | 372 : this.isEvaluatingConstant = isConst; |
| 369 | 373 |
| 370 ConstantSystem get constantSystem => handler.constantSystem; | 374 ConstantSystem get constantSystem => handler.constantSystem; |
| 371 Resolution get resolution => compiler.resolution; | 375 Resolution get resolution => compiler.resolution; |
| 372 | 376 |
| 377 DiagnosticReporter get reporter => compiler.reporter; |
| 378 |
| 373 AstConstant evaluate(Node node) { | 379 AstConstant evaluate(Node node) { |
| 374 // TODO(johnniwinther): should there be a visitErrorNode? | 380 // TODO(johnniwinther): should there be a visitErrorNode? |
| 375 if (node is ErrorNode) return new ErroneousAstConstant(context, node); | 381 if (node is ErrorNode) return new ErroneousAstConstant(context, node); |
| 376 return node.accept(this); | 382 return node.accept(this); |
| 377 } | 383 } |
| 378 | 384 |
| 379 AstConstant evaluateConstant(Node node) { | 385 AstConstant evaluateConstant(Node node) { |
| 380 bool oldIsEvaluatingConstant = isEvaluatingConstant; | 386 bool oldIsEvaluatingConstant = isEvaluatingConstant; |
| 381 isEvaluatingConstant = true; | 387 isEvaluatingConstant = true; |
| 382 AstConstant result = node.accept(this); | 388 AstConstant result = node.accept(this); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 if (key == null) { | 450 if (key == null) { |
| 445 return null; | 451 return null; |
| 446 } | 452 } |
| 447 AstConstant value = evaluateConstant(entry.value); | 453 AstConstant value = evaluateConstant(entry.value); |
| 448 if (value == null) { | 454 if (value == null) { |
| 449 return null; | 455 return null; |
| 450 } | 456 } |
| 451 if (!map.containsKey(key.value)) { | 457 if (!map.containsKey(key.value)) { |
| 452 keyValues.add(key.value); | 458 keyValues.add(key.value); |
| 453 } else { | 459 } else { |
| 454 compiler.reportWarningMessage( | 460 reporter.reportWarningMessage( |
| 455 entry.key, MessageKind.EQUAL_MAP_ENTRY_KEY); | 461 entry.key, MessageKind.EQUAL_MAP_ENTRY_KEY); |
| 456 } | 462 } |
| 457 keyExpressions.add(key.expression); | 463 keyExpressions.add(key.expression); |
| 458 valueExpressions.add(value.expression); | 464 valueExpressions.add(value.expression); |
| 459 map[key.value] = value.value; | 465 map[key.value] = value.value; |
| 460 } | 466 } |
| 461 InterfaceType type = elements.getType(node); | 467 InterfaceType type = elements.getType(node); |
| 462 return new AstConstant(context, node, | 468 return new AstConstant(context, node, |
| 463 new MapConstantExpression(type, keyExpressions, valueExpressions), | 469 new MapConstantExpression(type, keyExpressions, valueExpressions), |
| 464 constantSystem.createMap( | 470 constantSystem.createMap( |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 619 result = new AstConstant(context, send, | 625 result = new AstConstant(context, send, |
| 620 new VariableConstantExpression(element), | 626 new VariableConstantExpression(element), |
| 621 handler.getConstantValue(variableExpression)); | 627 handler.getConstantValue(variableExpression)); |
| 622 } | 628 } |
| 623 } | 629 } |
| 624 if (result == null) { | 630 if (result == null) { |
| 625 return signalNotCompileTimeConstant(send); | 631 return signalNotCompileTimeConstant(send); |
| 626 } | 632 } |
| 627 if (isDeferredUse(send)) { | 633 if (isDeferredUse(send)) { |
| 628 if (isEvaluatingConstant) { | 634 if (isEvaluatingConstant) { |
| 629 compiler.reportErrorMessage( | 635 reporter.reportErrorMessage( |
| 630 send, MessageKind.DEFERRED_COMPILE_TIME_CONSTANT); | 636 send, MessageKind.DEFERRED_COMPILE_TIME_CONSTANT); |
| 631 } | 637 } |
| 632 PrefixElement prefix = | 638 PrefixElement prefix = |
| 633 compiler.deferredLoadTask.deferredPrefixElement(send, elements); | 639 compiler.deferredLoadTask.deferredPrefixElement(send, elements); |
| 634 result = new AstConstant(context, send, | 640 result = new AstConstant(context, send, |
| 635 new DeferredConstantExpression(result.expression, prefix), | 641 new DeferredConstantExpression(result.expression, prefix), |
| 636 new DeferredConstantValue(result.value, prefix)); | 642 new DeferredConstantValue(result.value, prefix)); |
| 637 compiler.deferredLoadTask.registerConstantDeferredUse( | 643 compiler.deferredLoadTask.registerConstantDeferredUse( |
| 638 result.value, prefix); | 644 result.value, prefix); |
| 639 } | 645 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 656 } else if (send.isPrefix) { | 662 } else if (send.isPrefix) { |
| 657 assert(send.isOperator); | 663 assert(send.isOperator); |
| 658 AstConstant receiverConstant = evaluate(send.receiver); | 664 AstConstant receiverConstant = evaluate(send.receiver); |
| 659 if (receiverConstant == null) { | 665 if (receiverConstant == null) { |
| 660 return null; | 666 return null; |
| 661 } | 667 } |
| 662 Operator node = send.selector; | 668 Operator node = send.selector; |
| 663 UnaryOperator operator = UnaryOperator.parse(node.source); | 669 UnaryOperator operator = UnaryOperator.parse(node.source); |
| 664 UnaryOperation operation = constantSystem.lookupUnary(operator); | 670 UnaryOperation operation = constantSystem.lookupUnary(operator); |
| 665 if (operation == null) { | 671 if (operation == null) { |
| 666 compiler.internalError(send.selector, "Unexpected operator."); | 672 reporter.internalError(send.selector, "Unexpected operator."); |
| 667 } | 673 } |
| 668 ConstantValue folded = operation.fold(receiverConstant.value); | 674 ConstantValue folded = operation.fold(receiverConstant.value); |
| 669 if (folded == null) { | 675 if (folded == null) { |
| 670 return signalNotCompileTimeConstant(send); | 676 return signalNotCompileTimeConstant(send); |
| 671 } | 677 } |
| 672 return new AstConstant(context, send, | 678 return new AstConstant(context, send, |
| 673 new UnaryConstantExpression(operator, receiverConstant.expression), | 679 new UnaryConstantExpression(operator, receiverConstant.expression), |
| 674 folded); | 680 folded); |
| 675 } else if (send.isOperator && !send.isPostfix) { | 681 } else if (send.isOperator && !send.isPostfix) { |
| 676 assert(send.argumentCount() == 1); | 682 assert(send.argumentCount() == 1); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 719 return signalNotCompileTimeConstant(send); | 725 return signalNotCompileTimeConstant(send); |
| 720 } | 726 } |
| 721 | 727 |
| 722 AstConstant visitConditional(Conditional node) { | 728 AstConstant visitConditional(Conditional node) { |
| 723 AstConstant condition = evaluate(node.condition); | 729 AstConstant condition = evaluate(node.condition); |
| 724 if (condition == null) { | 730 if (condition == null) { |
| 725 return null; | 731 return null; |
| 726 } else if (!condition.value.isBool) { | 732 } else if (!condition.value.isBool) { |
| 727 DartType conditionType = condition.value.getType(compiler.coreTypes); | 733 DartType conditionType = condition.value.getType(compiler.coreTypes); |
| 728 if (isEvaluatingConstant) { | 734 if (isEvaluatingConstant) { |
| 729 compiler.reportErrorMessage( | 735 reporter.reportErrorMessage( |
| 730 node.condition, | 736 node.condition, |
| 731 MessageKind.NOT_ASSIGNABLE, | 737 MessageKind.NOT_ASSIGNABLE, |
| 732 {'fromType': conditionType, | 738 {'fromType': conditionType, |
| 733 'toType': compiler.boolClass.rawType}); | 739 'toType': compiler.boolClass.rawType}); |
| 734 return new ErroneousAstConstant(context, node); | 740 return new ErroneousAstConstant(context, node); |
| 735 } | 741 } |
| 736 return null; | 742 return null; |
| 737 } | 743 } |
| 738 AstConstant thenExpression = evaluate(node.thenExpression); | 744 AstConstant thenExpression = evaluate(node.thenExpression); |
| 739 AstConstant elseExpression = evaluate(node.elseExpression); | 745 AstConstant elseExpression = evaluate(node.elseExpression); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 768 ConstantExpression constant = handler.compileConstant(element); | 774 ConstantExpression constant = handler.compileConstant(element); |
| 769 return new AstConstant.fromDefaultValue( | 775 return new AstConstant.fromDefaultValue( |
| 770 element, constant, handler.getConstantValue(constant)); | 776 element, constant, handler.getConstantValue(constant)); |
| 771 } | 777 } |
| 772 target.computeType(resolution); | 778 target.computeType(resolution); |
| 773 | 779 |
| 774 FunctionSignature signature = target.functionSignature; | 780 FunctionSignature signature = target.functionSignature; |
| 775 if (!callStructure.signatureApplies(signature)) { | 781 if (!callStructure.signatureApplies(signature)) { |
| 776 String name = Elements.constructorNameForDiagnostics( | 782 String name = Elements.constructorNameForDiagnostics( |
| 777 target.enclosingClass.name, target.name); | 783 target.enclosingClass.name, target.name); |
| 778 compiler.reportErrorMessage( | 784 reporter.reportErrorMessage( |
| 779 node, MessageKind.INVALID_CONSTRUCTOR_ARGUMENTS, | 785 node, MessageKind.INVALID_CONSTRUCTOR_ARGUMENTS, |
| 780 {'constructorName': name}); | 786 {'constructorName': name}); |
| 781 | 787 |
| 782 return new List<AstConstant>.filled( | 788 return new List<AstConstant>.filled( |
| 783 target.functionSignature.parameterCount, | 789 target.functionSignature.parameterCount, |
| 784 new ErroneousAstConstant(context, node)); | 790 new ErroneousAstConstant(context, node)); |
| 785 } | 791 } |
| 786 return callStructure.makeArgumentsList( | 792 return callStructure.makeArgumentsList( |
| 787 arguments, target, compileArgument, compileDefaultValue); | 793 arguments, target, compileArgument, compileDefaultValue); |
| 788 } | 794 } |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 872 } | 878 } |
| 873 | 879 |
| 874 AstConstant createFromEnvironmentConstant(Node node, InterfaceType type, | 880 AstConstant createFromEnvironmentConstant(Node node, InterfaceType type, |
| 875 ConstructorElement constructor, CallStructure callStructure, | 881 ConstructorElement constructor, CallStructure callStructure, |
| 876 List<AstConstant> normalizedArguments, | 882 List<AstConstant> normalizedArguments, |
| 877 List<AstConstant> concreteArguments) { | 883 List<AstConstant> concreteArguments) { |
| 878 var firstArgument = normalizedArguments[0].value; | 884 var firstArgument = normalizedArguments[0].value; |
| 879 ConstantValue defaultValue = normalizedArguments[1].value; | 885 ConstantValue defaultValue = normalizedArguments[1].value; |
| 880 | 886 |
| 881 if (firstArgument.isNull) { | 887 if (firstArgument.isNull) { |
| 882 compiler.reportErrorMessage( | 888 reporter.reportErrorMessage( |
| 883 normalizedArguments[0].node, MessageKind.NULL_NOT_ALLOWED); | 889 normalizedArguments[0].node, MessageKind.NULL_NOT_ALLOWED); |
| 884 return null; | 890 return null; |
| 885 } | 891 } |
| 886 | 892 |
| 887 if (!firstArgument.isString) { | 893 if (!firstArgument.isString) { |
| 888 DartType type = defaultValue.getType(compiler.coreTypes); | 894 DartType type = defaultValue.getType(compiler.coreTypes); |
| 889 compiler.reportErrorMessage( | 895 reporter.reportErrorMessage( |
| 890 normalizedArguments[0].node, | 896 normalizedArguments[0].node, |
| 891 MessageKind.NOT_ASSIGNABLE, | 897 MessageKind.NOT_ASSIGNABLE, |
| 892 {'fromType': type, | 898 {'fromType': type, |
| 893 'toType': compiler.stringClass.rawType}); | 899 'toType': compiler.stringClass.rawType}); |
| 894 return null; | 900 return null; |
| 895 } | 901 } |
| 896 | 902 |
| 897 if (constructor == compiler.intEnvironment && | 903 if (constructor == compiler.intEnvironment && |
| 898 !(defaultValue.isNull || defaultValue.isInt)) { | 904 !(defaultValue.isNull || defaultValue.isInt)) { |
| 899 DartType type = defaultValue.getType(compiler.coreTypes); | 905 DartType type = defaultValue.getType(compiler.coreTypes); |
| 900 compiler.reportErrorMessage( | 906 reporter.reportErrorMessage( |
| 901 normalizedArguments[1].node, | 907 normalizedArguments[1].node, |
| 902 MessageKind.NOT_ASSIGNABLE, | 908 MessageKind.NOT_ASSIGNABLE, |
| 903 {'fromType': type, | 909 {'fromType': type, |
| 904 'toType': compiler.intClass.rawType}); | 910 'toType': compiler.intClass.rawType}); |
| 905 return null; | 911 return null; |
| 906 } | 912 } |
| 907 | 913 |
| 908 if (constructor == compiler.boolEnvironment && | 914 if (constructor == compiler.boolEnvironment && |
| 909 !(defaultValue.isNull || defaultValue.isBool)) { | 915 !(defaultValue.isNull || defaultValue.isBool)) { |
| 910 DartType type = defaultValue.getType(compiler.coreTypes); | 916 DartType type = defaultValue.getType(compiler.coreTypes); |
| 911 compiler.reportErrorMessage( | 917 reporter.reportErrorMessage( |
| 912 normalizedArguments[1].node, | 918 normalizedArguments[1].node, |
| 913 MessageKind.NOT_ASSIGNABLE, | 919 MessageKind.NOT_ASSIGNABLE, |
| 914 {'fromType': type, | 920 {'fromType': type, |
| 915 'toType': compiler.boolClass.rawType}); | 921 'toType': compiler.boolClass.rawType}); |
| 916 return null; | 922 return null; |
| 917 } | 923 } |
| 918 | 924 |
| 919 if (constructor == compiler.stringEnvironment && | 925 if (constructor == compiler.stringEnvironment && |
| 920 !(defaultValue.isNull || defaultValue.isString)) { | 926 !(defaultValue.isNull || defaultValue.isString)) { |
| 921 DartType type = defaultValue.getType(compiler.coreTypes); | 927 DartType type = defaultValue.getType(compiler.coreTypes); |
| 922 compiler.reportErrorMessage( | 928 reporter.reportErrorMessage( |
| 923 normalizedArguments[1].node, | 929 normalizedArguments[1].node, |
| 924 MessageKind.NOT_ASSIGNABLE, | 930 MessageKind.NOT_ASSIGNABLE, |
| 925 {'fromType': type, | 931 {'fromType': type, |
| 926 'toType': compiler.stringClass.rawType}); | 932 'toType': compiler.stringClass.rawType}); |
| 927 return null; | 933 return null; |
| 928 } | 934 } |
| 929 | 935 |
| 930 String name = firstArgument.primitiveValue.slowToString(); | 936 String name = firstArgument.primitiveValue.slowToString(); |
| 931 String value = compiler.fromEnvironment(name); | 937 String value = compiler.fromEnvironment(name); |
| 932 | 938 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1006 new ConstructedConstantValue(constructedType, fieldValues)); | 1012 new ConstructedConstantValue(constructedType, fieldValues)); |
| 1007 } | 1013 } |
| 1008 | 1014 |
| 1009 AstConstant visitParenthesizedExpression(ParenthesizedExpression node) { | 1015 AstConstant visitParenthesizedExpression(ParenthesizedExpression node) { |
| 1010 return node.expression.accept(this); | 1016 return node.expression.accept(this); |
| 1011 } | 1017 } |
| 1012 | 1018 |
| 1013 AstConstant signalNotCompileTimeConstant(Node node, | 1019 AstConstant signalNotCompileTimeConstant(Node node, |
| 1014 {MessageKind message: MessageKind.NOT_A_COMPILE_TIME_CONSTANT}) { | 1020 {MessageKind message: MessageKind.NOT_A_COMPILE_TIME_CONSTANT}) { |
| 1015 if (isEvaluatingConstant) { | 1021 if (isEvaluatingConstant) { |
| 1016 compiler.reportErrorMessage(node, message); | 1022 reporter.reportErrorMessage(node, message); |
| 1017 | 1023 |
| 1018 return new AstConstant(context, node, new ErroneousConstantExpression(), | 1024 return new AstConstant(context, node, new ErroneousConstantExpression(), |
| 1019 new NullConstantValue()); | 1025 new NullConstantValue()); |
| 1020 } | 1026 } |
| 1021 // Else we don't need to do anything. The final handler is only | 1027 // Else we don't need to do anything. The final handler is only |
| 1022 // optimistically trying to compile constants. So it is normal that we | 1028 // optimistically trying to compile constants. So it is normal that we |
| 1023 // sometimes see non-compile time constants. | 1029 // sometimes see non-compile time constants. |
| 1024 // Simply return [:null:] which is used to propagate a failing | 1030 // Simply return [:null:] which is used to propagate a failing |
| 1025 // compile-time compilation. | 1031 // compile-time compilation. |
| 1026 return null; | 1032 return null; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1046 super(handler, _analyzeElementEagerly(compiler, constructor), compiler, | 1052 super(handler, _analyzeElementEagerly(compiler, constructor), compiler, |
| 1047 isConst: true) { | 1053 isConst: true) { |
| 1048 assert(invariant(constructor, constructor.isImplementation)); | 1054 assert(invariant(constructor, constructor.isImplementation)); |
| 1049 } | 1055 } |
| 1050 | 1056 |
| 1051 AstConstant visitSend(Send send) { | 1057 AstConstant visitSend(Send send) { |
| 1052 Element element = elements[send]; | 1058 Element element = elements[send]; |
| 1053 if (Elements.isLocal(element)) { | 1059 if (Elements.isLocal(element)) { |
| 1054 AstConstant constant = definitions[element]; | 1060 AstConstant constant = definitions[element]; |
| 1055 if (constant == null) { | 1061 if (constant == null) { |
| 1056 compiler.internalError(send, "Local variable without value."); | 1062 reporter.internalError(send, "Local variable without value."); |
| 1057 } | 1063 } |
| 1058 return constant; | 1064 return constant; |
| 1059 } | 1065 } |
| 1060 return super.visitSend(send); | 1066 return super.visitSend(send); |
| 1061 } | 1067 } |
| 1062 | 1068 |
| 1063 void potentiallyCheckType(TypedElement element, AstConstant constant) { | 1069 void potentiallyCheckType(TypedElement element, AstConstant constant) { |
| 1064 if (compiler.enableTypeAssertions) { | 1070 if (compiler.enableTypeAssertions) { |
| 1065 DartType elementType = element.type.substByContext(constructedType); | 1071 DartType elementType = element.type.substByContext(constructedType); |
| 1066 DartType constantType = constant.value.getType(compiler.coreTypes); | 1072 DartType constantType = constant.value.getType(compiler.coreTypes); |
| 1067 if (!constantSystem.isSubtype( | 1073 if (!constantSystem.isSubtype( |
| 1068 compiler.types, constantType, elementType)) { | 1074 compiler.types, constantType, elementType)) { |
| 1069 compiler.withCurrentElement(constant.element, () { | 1075 reporter.withCurrentElement(constant.element, () { |
| 1070 compiler.reportErrorMessage( | 1076 reporter.reportErrorMessage( |
| 1071 constant.node, | 1077 constant.node, |
| 1072 MessageKind.NOT_ASSIGNABLE, | 1078 MessageKind.NOT_ASSIGNABLE, |
| 1073 {'fromType': constantType, | 1079 {'fromType': constantType, |
| 1074 'toType': elementType}); | 1080 'toType': elementType}); |
| 1075 }); | 1081 }); |
| 1076 } | 1082 } |
| 1077 } | 1083 } |
| 1078 } | 1084 } |
| 1079 | 1085 |
| 1080 void updateFieldValue(Node node, TypedElement element, AstConstant constant) { | 1086 void updateFieldValue(Node node, TypedElement element, AstConstant constant) { |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1186 } | 1192 } |
| 1187 } | 1193 } |
| 1188 | 1194 |
| 1189 /** | 1195 /** |
| 1190 * Simulates the execution of the [constructor] with the given | 1196 * Simulates the execution of the [constructor] with the given |
| 1191 * [arguments] to obtain the field values that need to be passed to the | 1197 * [arguments] to obtain the field values that need to be passed to the |
| 1192 * native JavaScript constructor. | 1198 * native JavaScript constructor. |
| 1193 */ | 1199 */ |
| 1194 void evaluateConstructorFieldValues(List<AstConstant> arguments) { | 1200 void evaluateConstructorFieldValues(List<AstConstant> arguments) { |
| 1195 if (constructor.isErroneous) return; | 1201 if (constructor.isErroneous) return; |
| 1196 compiler.withCurrentElement(constructor, () { | 1202 reporter.withCurrentElement(constructor, () { |
| 1197 assignArgumentsToParameters(arguments); | 1203 assignArgumentsToParameters(arguments); |
| 1198 evaluateConstructorInitializers(); | 1204 evaluateConstructorInitializers(); |
| 1199 }); | 1205 }); |
| 1200 } | 1206 } |
| 1201 | 1207 |
| 1202 /// Builds a normalized list of the constant values for each field in the | 1208 /// Builds a normalized list of the constant values for each field in the |
| 1203 /// inheritance chain of [classElement]. | 1209 /// inheritance chain of [classElement]. |
| 1204 Map<FieldElement, AstConstant> buildFieldConstants( | 1210 Map<FieldElement, AstConstant> buildFieldConstants( |
| 1205 ClassElement classElement) { | 1211 ClassElement classElement) { |
| 1206 Map<FieldElement, AstConstant> fieldConstants = <FieldElement, AstConstant>{ | 1212 Map<FieldElement, AstConstant> fieldConstants = <FieldElement, AstConstant>{ |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1269 class _CompilerEnvironment implements Environment { | 1275 class _CompilerEnvironment implements Environment { |
| 1270 final Compiler compiler; | 1276 final Compiler compiler; |
| 1271 | 1277 |
| 1272 _CompilerEnvironment(this.compiler); | 1278 _CompilerEnvironment(this.compiler); |
| 1273 | 1279 |
| 1274 @override | 1280 @override |
| 1275 String readFromEnvironment(String name) { | 1281 String readFromEnvironment(String name) { |
| 1276 return compiler.fromEnvironment(name); | 1282 return compiler.fromEnvironment(name); |
| 1277 } | 1283 } |
| 1278 } | 1284 } |
| OLD | NEW |