| 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 Resolution; | 7 import 'common/resolution.dart' show Resolution; |
| 8 import 'common/tasks.dart' show CompilerTask, Measurer; | 8 import 'common/tasks.dart' show CompilerTask, Measurer; |
| 9 import 'common.dart'; | 9 import 'common.dart'; |
| 10 import 'compiler.dart' show Compiler; | 10 import 'compiler.dart' show Compiler; |
| 11 import 'constant_system_dart.dart'; | 11 import 'constant_system_dart.dart'; |
| 12 import 'constants/constant_system.dart'; | 12 import 'constants/constant_system.dart'; |
| 13 import 'constants/evaluation.dart'; | 13 import 'constants/evaluation.dart'; |
| 14 import 'constants/expressions.dart'; | 14 import 'constants/expressions.dart'; |
| 15 import 'constants/values.dart'; | 15 import 'constants/values.dart'; |
| 16 import 'core_types.dart' show CoreTypes; | 16 import 'core_types.dart' show CommonElements; |
| 17 import 'dart_types.dart'; | 17 import 'dart_types.dart'; |
| 18 import 'elements/elements.dart'; | 18 import 'elements/elements.dart'; |
| 19 import 'elements/modelx.dart' show ConstantVariableMixin; | 19 import 'elements/modelx.dart' show ConstantVariableMixin; |
| 20 import 'resolution/operators.dart'; | 20 import 'resolution/operators.dart'; |
| 21 import 'resolution/tree_elements.dart' show TreeElements; | 21 import 'resolution/tree_elements.dart' show TreeElements; |
| 22 import 'tree/tree.dart'; | 22 import 'tree/tree.dart'; |
| 23 import 'universe/call_structure.dart' show CallStructure; | 23 import 'universe/call_structure.dart' show CallStructure; |
| 24 import 'util/util.dart' show Link; | 24 import 'util/util.dart' show Link; |
| 25 | 25 |
| 26 /// A [ConstantEnvironment] provides access for constants compiled for variable | 26 /// A [ConstantEnvironment] provides access for constants compiled for variable |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 152 /** The set of variable elements that are in the process of being computed. */ | 152 /** The set of variable elements that are in the process of being computed. */ |
| 153 final Set<VariableElement> pendingVariables = new Set<VariableElement>(); | 153 final Set<VariableElement> pendingVariables = new Set<VariableElement>(); |
| 154 | 154 |
| 155 final Map<ConstantExpression, ConstantValue> constantValueMap = | 155 final Map<ConstantExpression, ConstantValue> constantValueMap = |
| 156 <ConstantExpression, ConstantValue>{}; | 156 <ConstantExpression, ConstantValue>{}; |
| 157 | 157 |
| 158 ConstantCompilerBase(this.compiler, this.constantSystem); | 158 ConstantCompilerBase(this.compiler, this.constantSystem); |
| 159 | 159 |
| 160 DiagnosticReporter get reporter => compiler.reporter; | 160 DiagnosticReporter get reporter => compiler.reporter; |
| 161 | 161 |
| 162 CoreTypes get coreTypes => compiler.coreTypes; | 162 CommonElements get commonElements => compiler.commonElements; |
| 163 | 163 |
| 164 @override | 164 @override |
| 165 @deprecated | 165 @deprecated |
| 166 ConstantValue getConstantValueForVariable(VariableElement element) { | 166 ConstantValue getConstantValueForVariable(VariableElement element) { |
| 167 ConstantExpression constant = initialVariableValues[element.declaration]; | 167 ConstantExpression constant = initialVariableValues[element.declaration]; |
| 168 // TODO(johnniwinther): Support eager evaluation of the constant. | 168 // TODO(johnniwinther): Support eager evaluation of the constant. |
| 169 return constant != null ? getConstantValue(constant) : null; | 169 return constant != null ? getConstantValue(constant) : null; |
| 170 } | 170 } |
| 171 | 171 |
| 172 ConstantExpression compileConstant(VariableElement element) { | 172 ConstantExpression compileConstant(VariableElement element) { |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 } else { | 265 } else { |
| 266 assert(elementType is MethodTypeVariableType); | 266 assert(elementType is MethodTypeVariableType); |
| 267 reporter.reportErrorMessage( | 267 reporter.reportErrorMessage( |
| 268 node, MessageKind.TYPE_VARIABLE_FROM_METHOD_NOT_REIFIED); | 268 node, MessageKind.TYPE_VARIABLE_FROM_METHOD_NOT_REIFIED); |
| 269 } | 269 } |
| 270 } else { | 270 } else { |
| 271 // We need to throw an exception at runtime. | 271 // We need to throw an exception at runtime. |
| 272 expression = null; | 272 expression = null; |
| 273 } | 273 } |
| 274 } else { | 274 } else { |
| 275 DartType constantType = value.getType(coreTypes); | 275 DartType constantType = value.getType(commonElements); |
| 276 if (!constantSystem.isSubtype( | 276 if (!constantSystem.isSubtype( |
| 277 compiler.types, constantType, elementType)) { | 277 compiler.types, constantType, elementType)) { |
| 278 if (isConst) { | 278 if (isConst) { |
| 279 reporter.reportErrorMessage(node, MessageKind.NOT_ASSIGNABLE, | 279 reporter.reportErrorMessage(node, MessageKind.NOT_ASSIGNABLE, |
| 280 {'fromType': constantType, 'toType': elementType}); | 280 {'fromType': constantType, 'toType': elementType}); |
| 281 } else { | 281 } else { |
| 282 // If the field cannot be lazily initialized, we will throw | 282 // If the field cannot be lazily initialized, we will throw |
| 283 // the exception at runtime. | 283 // the exception at runtime. |
| 284 expression = null; | 284 expression = null; |
| 285 } | 285 } |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 final Compiler compiler; | 400 final Compiler compiler; |
| 401 | 401 |
| 402 Element get context => elements.analyzedElement; | 402 Element get context => elements.analyzedElement; |
| 403 | 403 |
| 404 CompileTimeConstantEvaluator(this.handler, this.elements, this.compiler, | 404 CompileTimeConstantEvaluator(this.handler, this.elements, this.compiler, |
| 405 {bool isConst: false}) | 405 {bool isConst: false}) |
| 406 : this.isEvaluatingConstant = isConst; | 406 : this.isEvaluatingConstant = isConst; |
| 407 | 407 |
| 408 ConstantSystem get constantSystem => handler.constantSystem; | 408 ConstantSystem get constantSystem => handler.constantSystem; |
| 409 Resolution get resolution => compiler.resolution; | 409 Resolution get resolution => compiler.resolution; |
| 410 CoreTypes get coreTypes => compiler.coreTypes; | 410 CommonElements get commonElements => compiler.commonElements; |
| 411 DiagnosticReporter get reporter => compiler.reporter; | 411 DiagnosticReporter get reporter => compiler.reporter; |
| 412 | 412 |
| 413 AstConstant evaluate(Node node) { | 413 AstConstant evaluate(Node node) { |
| 414 // TODO(johnniwinther): should there be a visitErrorNode? | 414 // TODO(johnniwinther): should there be a visitErrorNode? |
| 415 if (node is ErrorNode) return new ErroneousAstConstant(context, node); | 415 if (node is ErrorNode) return new ErroneousAstConstant(context, node); |
| 416 AstConstant result = node.accept(this); | 416 AstConstant result = node.accept(this); |
| 417 assert(invariant(node, !isEvaluatingConstant || result != null, | 417 assert(invariant(node, !isEvaluatingConstant || result != null, |
| 418 message: "No AstConstant computed for the node.")); | 418 message: "No AstConstant computed for the node.")); |
| 419 return result; | 419 return result; |
| 420 } | 420 } |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 587 new DartString.concat(accumulator, partStringValue.primitiveValue); | 587 new DartString.concat(accumulator, partStringValue.primitiveValue); |
| 588 } | 588 } |
| 589 return new AstConstant( | 589 return new AstConstant( |
| 590 context, | 590 context, |
| 591 node, | 591 node, |
| 592 new ConcatenateConstantExpression(subexpressions), | 592 new ConcatenateConstantExpression(subexpressions), |
| 593 constantSystem.createString(accumulator)); | 593 constantSystem.createString(accumulator)); |
| 594 } | 594 } |
| 595 | 595 |
| 596 AstConstant visitLiteralSymbol(LiteralSymbol node) { | 596 AstConstant visitLiteralSymbol(LiteralSymbol node) { |
| 597 InterfaceType type = coreTypes.symbolType; | 597 InterfaceType type = commonElements.symbolType; |
| 598 String text = node.slowNameString; | 598 String text = node.slowNameString; |
| 599 List<AstConstant> arguments = <AstConstant>[ | 599 List<AstConstant> arguments = <AstConstant>[ |
| 600 new AstConstant(context, node, new StringConstantExpression(text), | 600 new AstConstant(context, node, new StringConstantExpression(text), |
| 601 constantSystem.createString(new LiteralDartString(text))) | 601 constantSystem.createString(new LiteralDartString(text))) |
| 602 ]; | 602 ]; |
| 603 ConstructorElement constructor = compiler.commonElements.symbolConstructor; | 603 ConstructorElement constructor = compiler.commonElements.symbolConstructor; |
| 604 AstConstant constant = createConstructorInvocation( | 604 AstConstant constant = createConstructorInvocation( |
| 605 node, type, constructor, CallStructure.ONE_ARG, | 605 node, type, constructor, CallStructure.ONE_ARG, |
| 606 normalizedArguments: arguments); | 606 normalizedArguments: arguments); |
| 607 return new AstConstant( | 607 return new AstConstant( |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 803 folded); | 803 folded); |
| 804 } | 804 } |
| 805 return signalNotCompileTimeConstant(send); | 805 return signalNotCompileTimeConstant(send); |
| 806 } | 806 } |
| 807 | 807 |
| 808 AstConstant visitConditional(Conditional node) { | 808 AstConstant visitConditional(Conditional node) { |
| 809 AstConstant condition = evaluate(node.condition); | 809 AstConstant condition = evaluate(node.condition); |
| 810 if (condition == null || condition.isError) { | 810 if (condition == null || condition.isError) { |
| 811 return condition; | 811 return condition; |
| 812 } else if (!condition.value.isBool) { | 812 } else if (!condition.value.isBool) { |
| 813 DartType conditionType = condition.value.getType(coreTypes); | 813 DartType conditionType = condition.value.getType(commonElements); |
| 814 if (isEvaluatingConstant) { | 814 if (isEvaluatingConstant) { |
| 815 reporter.reportErrorMessage(node.condition, MessageKind.NOT_ASSIGNABLE, | 815 reporter.reportErrorMessage(node.condition, MessageKind.NOT_ASSIGNABLE, |
| 816 {'fromType': conditionType, 'toType': coreTypes.boolType}); | 816 {'fromType': conditionType, 'toType': commonElements.boolType}); |
| 817 return new ErroneousAstConstant(context, node); | 817 return new ErroneousAstConstant(context, node); |
| 818 } | 818 } |
| 819 return null; | 819 return null; |
| 820 } | 820 } |
| 821 AstConstant thenExpression = evaluate(node.thenExpression); | 821 AstConstant thenExpression = evaluate(node.thenExpression); |
| 822 AstConstant elseExpression = evaluate(node.elseExpression); | 822 AstConstant elseExpression = evaluate(node.elseExpression); |
| 823 if (thenExpression == null || thenExpression.isError) { | 823 if (thenExpression == null || thenExpression.isError) { |
| 824 return thenExpression; | 824 return thenExpression; |
| 825 } | 825 } |
| 826 if (elseExpression == null || elseExpression.isError) { | 826 if (elseExpression == null || elseExpression.isError) { |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1001 List<AstConstant> concreteArguments) { | 1001 List<AstConstant> concreteArguments) { |
| 1002 var firstArgument = normalizedArguments[0].value; | 1002 var firstArgument = normalizedArguments[0].value; |
| 1003 ConstantValue defaultValue = normalizedArguments[1].value; | 1003 ConstantValue defaultValue = normalizedArguments[1].value; |
| 1004 | 1004 |
| 1005 if (firstArgument.isNull) { | 1005 if (firstArgument.isNull) { |
| 1006 return reportNotCompileTimeConstant( | 1006 return reportNotCompileTimeConstant( |
| 1007 normalizedArguments[0].node, MessageKind.NULL_NOT_ALLOWED); | 1007 normalizedArguments[0].node, MessageKind.NULL_NOT_ALLOWED); |
| 1008 } | 1008 } |
| 1009 | 1009 |
| 1010 if (!firstArgument.isString) { | 1010 if (!firstArgument.isString) { |
| 1011 DartType type = defaultValue.getType(coreTypes); | 1011 DartType type = defaultValue.getType(commonElements); |
| 1012 return reportNotCompileTimeConstant( | 1012 return reportNotCompileTimeConstant( |
| 1013 normalizedArguments[0].node, | 1013 normalizedArguments[0].node, |
| 1014 MessageKind.NOT_ASSIGNABLE, | 1014 MessageKind.NOT_ASSIGNABLE, |
| 1015 {'fromType': type, 'toType': coreTypes.stringType}); | 1015 {'fromType': type, 'toType': commonElements.stringType}); |
| 1016 } | 1016 } |
| 1017 | 1017 |
| 1018 if (constructor.isIntFromEnvironmentConstructor && | 1018 if (constructor.isIntFromEnvironmentConstructor && |
| 1019 !(defaultValue.isNull || defaultValue.isInt)) { | 1019 !(defaultValue.isNull || defaultValue.isInt)) { |
| 1020 DartType type = defaultValue.getType(coreTypes); | 1020 DartType type = defaultValue.getType(commonElements); |
| 1021 return reportNotCompileTimeConstant( | 1021 return reportNotCompileTimeConstant( |
| 1022 normalizedArguments[1].node, | 1022 normalizedArguments[1].node, |
| 1023 MessageKind.NOT_ASSIGNABLE, | 1023 MessageKind.NOT_ASSIGNABLE, |
| 1024 {'fromType': type, 'toType': coreTypes.intType}); | 1024 {'fromType': type, 'toType': commonElements.intType}); |
| 1025 } | 1025 } |
| 1026 | 1026 |
| 1027 if (constructor.isBoolFromEnvironmentConstructor && | 1027 if (constructor.isBoolFromEnvironmentConstructor && |
| 1028 !(defaultValue.isNull || defaultValue.isBool)) { | 1028 !(defaultValue.isNull || defaultValue.isBool)) { |
| 1029 DartType type = defaultValue.getType(coreTypes); | 1029 DartType type = defaultValue.getType(commonElements); |
| 1030 return reportNotCompileTimeConstant( | 1030 return reportNotCompileTimeConstant( |
| 1031 normalizedArguments[1].node, | 1031 normalizedArguments[1].node, |
| 1032 MessageKind.NOT_ASSIGNABLE, | 1032 MessageKind.NOT_ASSIGNABLE, |
| 1033 {'fromType': type, 'toType': coreTypes.boolType}); | 1033 {'fromType': type, 'toType': commonElements.boolType}); |
| 1034 } | 1034 } |
| 1035 | 1035 |
| 1036 if (constructor.isStringFromEnvironmentConstructor && | 1036 if (constructor.isStringFromEnvironmentConstructor && |
| 1037 !(defaultValue.isNull || defaultValue.isString)) { | 1037 !(defaultValue.isNull || defaultValue.isString)) { |
| 1038 DartType type = defaultValue.getType(coreTypes); | 1038 DartType type = defaultValue.getType(commonElements); |
| 1039 return reportNotCompileTimeConstant( | 1039 return reportNotCompileTimeConstant( |
| 1040 normalizedArguments[1].node, | 1040 normalizedArguments[1].node, |
| 1041 MessageKind.NOT_ASSIGNABLE, | 1041 MessageKind.NOT_ASSIGNABLE, |
| 1042 {'fromType': type, 'toType': coreTypes.stringType}); | 1042 {'fromType': type, 'toType': commonElements.stringType}); |
| 1043 } | 1043 } |
| 1044 | 1044 |
| 1045 String name = firstArgument.primitiveValue.slowToString(); | 1045 String name = firstArgument.primitiveValue.slowToString(); |
| 1046 String value = compiler.fromEnvironment(name); | 1046 String value = compiler.fromEnvironment(name); |
| 1047 | 1047 |
| 1048 AstConstant createEvaluatedConstant(ConstantValue value) { | 1048 AstConstant createEvaluatedConstant(ConstantValue value) { |
| 1049 ConstantExpression expression; | 1049 ConstantExpression expression; |
| 1050 ConstantExpression name = concreteArguments[0].expression; | 1050 ConstantExpression name = concreteArguments[0].expression; |
| 1051 ConstantExpression defaultValue; | 1051 ConstantExpression defaultValue; |
| 1052 if (concreteArguments.length > 1) { | 1052 if (concreteArguments.length > 1) { |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1202 reporter.internalError(send, "Local variable without value."); | 1202 reporter.internalError(send, "Local variable without value."); |
| 1203 } | 1203 } |
| 1204 return constant; | 1204 return constant; |
| 1205 } | 1205 } |
| 1206 return super.visitSend(send); | 1206 return super.visitSend(send); |
| 1207 } | 1207 } |
| 1208 | 1208 |
| 1209 void potentiallyCheckType(TypedElement element, AstConstant constant) { | 1209 void potentiallyCheckType(TypedElement element, AstConstant constant) { |
| 1210 if (compiler.options.enableTypeAssertions) { | 1210 if (compiler.options.enableTypeAssertions) { |
| 1211 DartType elementType = element.type.substByContext(constructedType); | 1211 DartType elementType = element.type.substByContext(constructedType); |
| 1212 DartType constantType = constant.value.getType(coreTypes); | 1212 DartType constantType = constant.value.getType(commonElements); |
| 1213 if (!constantSystem.isSubtype( | 1213 if (!constantSystem.isSubtype( |
| 1214 compiler.types, constantType, elementType)) { | 1214 compiler.types, constantType, elementType)) { |
| 1215 reporter.withCurrentElement(constant.element, () { | 1215 reporter.withCurrentElement(constant.element, () { |
| 1216 reporter.reportErrorMessage(constant.node, MessageKind.NOT_ASSIGNABLE, | 1216 reporter.reportErrorMessage(constant.node, MessageKind.NOT_ASSIGNABLE, |
| 1217 {'fromType': constantType, 'toType': elementType}); | 1217 {'fromType': constantType, 'toType': elementType}); |
| 1218 }); | 1218 }); |
| 1219 } | 1219 } |
| 1220 } | 1220 } |
| 1221 } | 1221 } |
| 1222 | 1222 |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1443 class _CompilerEnvironment implements Environment { | 1443 class _CompilerEnvironment implements Environment { |
| 1444 final Compiler compiler; | 1444 final Compiler compiler; |
| 1445 | 1445 |
| 1446 _CompilerEnvironment(this.compiler); | 1446 _CompilerEnvironment(this.compiler); |
| 1447 | 1447 |
| 1448 @override | 1448 @override |
| 1449 String readFromEnvironment(String name) { | 1449 String readFromEnvironment(String name) { |
| 1450 return compiler.fromEnvironment(name); | 1450 return compiler.fromEnvironment(name); |
| 1451 } | 1451 } |
| 1452 } | 1452 } |
| OLD | NEW |