| 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; |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 // No initial value. | 245 // No initial value. |
| 246 expression = new NullConstantExpression(); | 246 expression = new NullConstantExpression(); |
| 247 constantValueMap[expression] = constantSystem.createNull(); | 247 constantValueMap[expression] = constantSystem.createNull(); |
| 248 } else { | 248 } else { |
| 249 expression = compileNodeWithDefinitions(initializer, definitions, | 249 expression = compileNodeWithDefinitions(initializer, definitions, |
| 250 isConst: isConst); | 250 isConst: isConst); |
| 251 if (compiler.options.enableTypeAssertions && | 251 if (compiler.options.enableTypeAssertions && |
| 252 checkType && | 252 checkType && |
| 253 expression != null && | 253 expression != null && |
| 254 element.isField) { | 254 element.isField) { |
| 255 DartType elementType = element.type; | 255 ResolutionDartType elementType = element.type; |
| 256 ConstantValue value = getConstantValue(expression); | 256 ConstantValue value = getConstantValue(expression); |
| 257 if (elementType.isMalformed && !value.isNull) { | 257 if (elementType.isMalformed && !value.isNull) { |
| 258 if (isConst) { | 258 if (isConst) { |
| 259 // TODO(johnniwinther): Check that it is possible to reach this | 259 // TODO(johnniwinther): Check that it is possible to reach this |
| 260 // point in a situation where `elementType is! MalformedType`. | 260 // point in a situation where `elementType is! MalformedType`. |
| 261 if (elementType is MalformedType) { | 261 if (elementType is MalformedType) { |
| 262 ErroneousElement element = elementType.element; | 262 ErroneousElement element = elementType.element; |
| 263 reporter.reportErrorMessage( | 263 reporter.reportErrorMessage( |
| 264 node, element.messageKind, element.messageArguments); | 264 node, element.messageKind, element.messageArguments); |
| 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(commonElements); | 275 ResolutionDartType 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 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 463 for (Link<Node> link = node.elements.nodes; | 463 for (Link<Node> link = node.elements.nodes; |
| 464 !link.isEmpty; | 464 !link.isEmpty; |
| 465 link = link.tail) { | 465 link = link.tail) { |
| 466 AstConstant argument = evaluateConstant(link.head); | 466 AstConstant argument = evaluateConstant(link.head); |
| 467 if (argument == null || argument.isError) { | 467 if (argument == null || argument.isError) { |
| 468 return argument; | 468 return argument; |
| 469 } | 469 } |
| 470 argumentExpressions.add(argument.expression); | 470 argumentExpressions.add(argument.expression); |
| 471 argumentValues.add(argument.value); | 471 argumentValues.add(argument.value); |
| 472 } | 472 } |
| 473 DartType type = elements.getType(node); | 473 ResolutionDartType type = elements.getType(node); |
| 474 return new AstConstant( | 474 return new AstConstant( |
| 475 context, | 475 context, |
| 476 node, | 476 node, |
| 477 new ListConstantExpression(type, argumentExpressions), | 477 new ListConstantExpression(type, argumentExpressions), |
| 478 constantSystem.createList(type, argumentValues)); | 478 constantSystem.createList(type, argumentValues)); |
| 479 } | 479 } |
| 480 | 480 |
| 481 AstConstant visitLiteralMap(LiteralMap node) { | 481 AstConstant visitLiteralMap(LiteralMap node) { |
| 482 if (!node.isConst) { | 482 if (!node.isConst) { |
| 483 return signalNotCompileTimeConstant(node); | 483 return signalNotCompileTimeConstant(node); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 501 if (!map.containsKey(key.value)) { | 501 if (!map.containsKey(key.value)) { |
| 502 keyValues.add(key.value); | 502 keyValues.add(key.value); |
| 503 } else { | 503 } else { |
| 504 reporter.reportWarningMessage( | 504 reporter.reportWarningMessage( |
| 505 entry.key, MessageKind.EQUAL_MAP_ENTRY_KEY); | 505 entry.key, MessageKind.EQUAL_MAP_ENTRY_KEY); |
| 506 } | 506 } |
| 507 keyExpressions.add(key.expression); | 507 keyExpressions.add(key.expression); |
| 508 valueExpressions.add(value.expression); | 508 valueExpressions.add(value.expression); |
| 509 map[key.value] = value.value; | 509 map[key.value] = value.value; |
| 510 } | 510 } |
| 511 InterfaceType type = elements.getType(node); | 511 ResolutionInterfaceType type = elements.getType(node); |
| 512 return new AstConstant( | 512 return new AstConstant( |
| 513 context, | 513 context, |
| 514 node, | 514 node, |
| 515 new MapConstantExpression(type, keyExpressions, valueExpressions), | 515 new MapConstantExpression(type, keyExpressions, valueExpressions), |
| 516 constantSystem.createMap( | 516 constantSystem.createMap( |
| 517 compiler, type, keyValues, map.values.toList())); | 517 compiler, type, keyValues, map.values.toList())); |
| 518 } | 518 } |
| 519 | 519 |
| 520 AstConstant visitLiteralNull(LiteralNull node) { | 520 AstConstant visitLiteralNull(LiteralNull node) { |
| 521 return new AstConstant(context, node, new NullConstantExpression(), | 521 return new AstConstant(context, node, new NullConstantExpression(), |
| (...skipping 65 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 = commonElements.symbolType; | 597 ResolutionInterfaceType 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( |
| 608 context, node, new SymbolConstantExpression(text), constant.value); | 608 context, node, new SymbolConstantExpression(text), constant.value); |
| 609 } | 609 } |
| 610 | 610 |
| 611 ConstantValue makeTypeConstant(DartType elementType) { | 611 ConstantValue makeTypeConstant(ResolutionDartType elementType) { |
| 612 return constantSystem.createType(compiler, elementType); | 612 return constantSystem.createType(compiler, elementType); |
| 613 } | 613 } |
| 614 | 614 |
| 615 /// Returns true if the prefix of the send resolves to a deferred import | 615 /// Returns true if the prefix of the send resolves to a deferred import |
| 616 /// prefix. | 616 /// prefix. |
| 617 bool isDeferredUse(Send send) { | 617 bool isDeferredUse(Send send) { |
| 618 if (send == null) return false; | 618 if (send == null) return false; |
| 619 return compiler.deferredLoadTask.deferredPrefixElement(send, elements) != | 619 return compiler.deferredLoadTask.deferredPrefixElement(send, elements) != |
| 620 null; | 620 null; |
| 621 } | 621 } |
| 622 | 622 |
| 623 AstConstant visitIdentifier(Identifier node) { | 623 AstConstant visitIdentifier(Identifier node) { |
| 624 Element element = elements[node]; | 624 Element element = elements[node]; |
| 625 if (Elements.isClass(element) || Elements.isTypedef(element)) { | 625 if (Elements.isClass(element) || Elements.isTypedef(element)) { |
| 626 TypeDeclarationElement typeDeclarationElement = element; | 626 TypeDeclarationElement typeDeclarationElement = element; |
| 627 DartType type = typeDeclarationElement.rawType; | 627 ResolutionDartType type = typeDeclarationElement.rawType; |
| 628 return new AstConstant(element, node, new TypeConstantExpression(type), | 628 return new AstConstant(element, node, new TypeConstantExpression(type), |
| 629 makeTypeConstant(type)); | 629 makeTypeConstant(type)); |
| 630 } | 630 } |
| 631 return signalNotCompileTimeConstant(node); | 631 return signalNotCompileTimeConstant(node); |
| 632 } | 632 } |
| 633 | 633 |
| 634 // TODO(floitsch): provide better error-messages. | 634 // TODO(floitsch): provide better error-messages. |
| 635 AstConstant visitSend(Send send) { | 635 AstConstant visitSend(Send send) { |
| 636 Element element = elements[send]; | 636 Element element = elements[send]; |
| 637 if (send.isPropertyAccess) { | 637 if (send.isPropertyAccess) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 653 } | 653 } |
| 654 if (elementExpression != null) { | 654 if (elementExpression != null) { |
| 655 result = new AstConstant( | 655 result = new AstConstant( |
| 656 context, | 656 context, |
| 657 send, | 657 send, |
| 658 new VariableConstantExpression(element), | 658 new VariableConstantExpression(element), |
| 659 handler.getConstantValue(elementExpression)); | 659 handler.getConstantValue(elementExpression)); |
| 660 } | 660 } |
| 661 } else if (Elements.isClass(element) || Elements.isTypedef(element)) { | 661 } else if (Elements.isClass(element) || Elements.isTypedef(element)) { |
| 662 assert(elements.isTypeLiteral(send)); | 662 assert(elements.isTypeLiteral(send)); |
| 663 DartType elementType = elements.getTypeLiteralType(send); | 663 ResolutionDartType elementType = elements.getTypeLiteralType(send); |
| 664 result = new AstConstant( | 664 result = new AstConstant( |
| 665 context, | 665 context, |
| 666 send, | 666 send, |
| 667 new TypeConstantExpression(elementType), | 667 new TypeConstantExpression(elementType), |
| 668 makeTypeConstant(elementType)); | 668 makeTypeConstant(elementType)); |
| 669 } else if (send.receiver != null) { | 669 } else if (send.receiver != null) { |
| 670 if (send.selector.asIdentifier().source == "length") { | 670 if (send.selector.asIdentifier().source == "length") { |
| 671 AstConstant left = evaluate(send.receiver); | 671 AstConstant left = evaluate(send.receiver); |
| 672 if (left != null && left.value.isString) { | 672 if (left != null && left.value.isString) { |
| 673 StringConstantValue stringConstantValue = left.value; | 673 StringConstantValue stringConstantValue = left.value; |
| (...skipping 129 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(commonElements); | 813 ResolutionDartType conditionType = |
| 814 condition.value.getType(commonElements); |
| 814 if (isEvaluatingConstant) { | 815 if (isEvaluatingConstant) { |
| 815 reporter.reportErrorMessage(node.condition, MessageKind.NOT_ASSIGNABLE, | 816 reporter.reportErrorMessage(node.condition, MessageKind.NOT_ASSIGNABLE, |
| 816 {'fromType': conditionType, 'toType': commonElements.boolType}); | 817 {'fromType': conditionType, 'toType': commonElements.boolType}); |
| 817 return new ErroneousAstConstant(context, node); | 818 return new ErroneousAstConstant(context, node); |
| 818 } | 819 } |
| 819 return null; | 820 return null; |
| 820 } | 821 } |
| 821 AstConstant thenExpression = evaluate(node.thenExpression); | 822 AstConstant thenExpression = evaluate(node.thenExpression); |
| 822 AstConstant elseExpression = evaluate(node.elseExpression); | 823 AstConstant elseExpression = evaluate(node.elseExpression); |
| 823 if (thenExpression == null || thenExpression.isError) { | 824 if (thenExpression == null || thenExpression.isError) { |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 890 return signalNotCompileTimeConstant(node); | 891 return signalNotCompileTimeConstant(node); |
| 891 } | 892 } |
| 892 | 893 |
| 893 // Deferred types can not be used in const instance creation expressions. | 894 // Deferred types can not be used in const instance creation expressions. |
| 894 // Check if the constructor comes from a deferred library. | 895 // Check if the constructor comes from a deferred library. |
| 895 if (isDeferredUse(node.send.selector.asSend())) { | 896 if (isDeferredUse(node.send.selector.asSend())) { |
| 896 return signalNotCompileTimeConstant(node, | 897 return signalNotCompileTimeConstant(node, |
| 897 message: MessageKind.DEFERRED_COMPILE_TIME_CONSTANT_CONSTRUCTION); | 898 message: MessageKind.DEFERRED_COMPILE_TIME_CONSTANT_CONSTRUCTION); |
| 898 } | 899 } |
| 899 | 900 |
| 900 InterfaceType type = elements.getType(node); | 901 ResolutionInterfaceType type = elements.getType(node); |
| 901 CallStructure callStructure = elements.getSelector(send).callStructure; | 902 CallStructure callStructure = elements.getSelector(send).callStructure; |
| 902 | 903 |
| 903 return createConstructorInvocation(node, type, constructor, callStructure, | 904 return createConstructorInvocation(node, type, constructor, callStructure, |
| 904 arguments: node.send.arguments); | 905 arguments: node.send.arguments); |
| 905 } | 906 } |
| 906 | 907 |
| 907 AstConstant createConstructorInvocation(Node node, InterfaceType type, | 908 AstConstant createConstructorInvocation( |
| 908 ConstructorElement constructor, CallStructure callStructure, | 909 Node node, |
| 909 {Link<Node> arguments, List<AstConstant> normalizedArguments}) { | 910 ResolutionInterfaceType type, |
| 911 ConstructorElement constructor, |
| 912 CallStructure callStructure, |
| 913 {Link<Node> arguments, |
| 914 List<AstConstant> normalizedArguments}) { |
| 910 // TODO(ahe): This is nasty: we must eagerly analyze the | 915 // TODO(ahe): This is nasty: we must eagerly analyze the |
| 911 // constructor to ensure the redirectionTarget has been computed | 916 // constructor to ensure the redirectionTarget has been computed |
| 912 // correctly. Find a way to avoid this. | 917 // correctly. Find a way to avoid this. |
| 913 resolution.ensureResolved(constructor.declaration); | 918 resolution.ensureResolved(constructor.declaration); |
| 914 | 919 |
| 915 // The redirection chain of this element may not have been resolved through | 920 // The redirection chain of this element may not have been resolved through |
| 916 // a post-process action, so we have to make sure it is done here. | 921 // a post-process action, so we have to make sure it is done here. |
| 917 compiler.resolver.resolveRedirectionChain(constructor, node); | 922 compiler.resolver.resolveRedirectionChain(constructor, node); |
| 918 | 923 |
| 919 bool isInvalid = false; | 924 bool isInvalid = false; |
| 920 InterfaceType constructedType = type; | 925 ResolutionInterfaceType constructedType = type; |
| 921 ConstructorElement implementation; | 926 ConstructorElement implementation; |
| 922 if (constructor.isRedirectingFactory) { | 927 if (constructor.isRedirectingFactory) { |
| 923 if (constructor.isEffectiveTargetMalformed) { | 928 if (constructor.isEffectiveTargetMalformed) { |
| 924 isInvalid = true; | 929 isInvalid = true; |
| 925 } else { | 930 } else { |
| 926 constructedType = constructor.computeEffectiveTargetType(type); | 931 constructedType = constructor.computeEffectiveTargetType(type); |
| 927 ConstructorElement target = constructor.effectiveTarget; | 932 ConstructorElement target = constructor.effectiveTarget; |
| 928 // The constructor must be an implementation to ensure that field | 933 // The constructor must be an implementation to ensure that field |
| 929 // initializers are handled correctly. | 934 // initializers are handled correctly. |
| 930 implementation = target.implementation; | 935 implementation = target.implementation; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 987 constructedType, | 992 constructedType, |
| 988 implementation, | 993 implementation, |
| 989 callStructure, | 994 callStructure, |
| 990 concreteArguments, | 995 concreteArguments, |
| 991 normalizedArguments); | 996 normalizedArguments); |
| 992 } | 997 } |
| 993 } | 998 } |
| 994 | 999 |
| 995 AstConstant createFromEnvironmentConstant( | 1000 AstConstant createFromEnvironmentConstant( |
| 996 Node node, | 1001 Node node, |
| 997 InterfaceType type, | 1002 ResolutionInterfaceType type, |
| 998 ConstructorElement constructor, | 1003 ConstructorElement constructor, |
| 999 CallStructure callStructure, | 1004 CallStructure callStructure, |
| 1000 List<AstConstant> normalizedArguments, | 1005 List<AstConstant> normalizedArguments, |
| 1001 List<AstConstant> concreteArguments) { | 1006 List<AstConstant> concreteArguments) { |
| 1002 var firstArgument = normalizedArguments[0].value; | 1007 var firstArgument = normalizedArguments[0].value; |
| 1003 ConstantValue defaultValue = normalizedArguments[1].value; | 1008 ConstantValue defaultValue = normalizedArguments[1].value; |
| 1004 | 1009 |
| 1005 if (firstArgument.isNull) { | 1010 if (firstArgument.isNull) { |
| 1006 return reportNotCompileTimeConstant( | 1011 return reportNotCompileTimeConstant( |
| 1007 normalizedArguments[0].node, MessageKind.NULL_NOT_ALLOWED); | 1012 normalizedArguments[0].node, MessageKind.NULL_NOT_ALLOWED); |
| 1008 } | 1013 } |
| 1009 | 1014 |
| 1010 if (!firstArgument.isString) { | 1015 if (!firstArgument.isString) { |
| 1011 DartType type = defaultValue.getType(commonElements); | 1016 ResolutionDartType type = defaultValue.getType(commonElements); |
| 1012 return reportNotCompileTimeConstant( | 1017 return reportNotCompileTimeConstant( |
| 1013 normalizedArguments[0].node, | 1018 normalizedArguments[0].node, |
| 1014 MessageKind.NOT_ASSIGNABLE, | 1019 MessageKind.NOT_ASSIGNABLE, |
| 1015 {'fromType': type, 'toType': commonElements.stringType}); | 1020 {'fromType': type, 'toType': commonElements.stringType}); |
| 1016 } | 1021 } |
| 1017 | 1022 |
| 1018 if (constructor.isIntFromEnvironmentConstructor && | 1023 if (constructor.isIntFromEnvironmentConstructor && |
| 1019 !(defaultValue.isNull || defaultValue.isInt)) { | 1024 !(defaultValue.isNull || defaultValue.isInt)) { |
| 1020 DartType type = defaultValue.getType(commonElements); | 1025 ResolutionDartType type = defaultValue.getType(commonElements); |
| 1021 return reportNotCompileTimeConstant( | 1026 return reportNotCompileTimeConstant( |
| 1022 normalizedArguments[1].node, | 1027 normalizedArguments[1].node, |
| 1023 MessageKind.NOT_ASSIGNABLE, | 1028 MessageKind.NOT_ASSIGNABLE, |
| 1024 {'fromType': type, 'toType': commonElements.intType}); | 1029 {'fromType': type, 'toType': commonElements.intType}); |
| 1025 } | 1030 } |
| 1026 | 1031 |
| 1027 if (constructor.isBoolFromEnvironmentConstructor && | 1032 if (constructor.isBoolFromEnvironmentConstructor && |
| 1028 !(defaultValue.isNull || defaultValue.isBool)) { | 1033 !(defaultValue.isNull || defaultValue.isBool)) { |
| 1029 DartType type = defaultValue.getType(commonElements); | 1034 ResolutionDartType type = defaultValue.getType(commonElements); |
| 1030 return reportNotCompileTimeConstant( | 1035 return reportNotCompileTimeConstant( |
| 1031 normalizedArguments[1].node, | 1036 normalizedArguments[1].node, |
| 1032 MessageKind.NOT_ASSIGNABLE, | 1037 MessageKind.NOT_ASSIGNABLE, |
| 1033 {'fromType': type, 'toType': commonElements.boolType}); | 1038 {'fromType': type, 'toType': commonElements.boolType}); |
| 1034 } | 1039 } |
| 1035 | 1040 |
| 1036 if (constructor.isStringFromEnvironmentConstructor && | 1041 if (constructor.isStringFromEnvironmentConstructor && |
| 1037 !(defaultValue.isNull || defaultValue.isString)) { | 1042 !(defaultValue.isNull || defaultValue.isString)) { |
| 1038 DartType type = defaultValue.getType(commonElements); | 1043 ResolutionDartType type = defaultValue.getType(commonElements); |
| 1039 return reportNotCompileTimeConstant( | 1044 return reportNotCompileTimeConstant( |
| 1040 normalizedArguments[1].node, | 1045 normalizedArguments[1].node, |
| 1041 MessageKind.NOT_ASSIGNABLE, | 1046 MessageKind.NOT_ASSIGNABLE, |
| 1042 {'fromType': type, 'toType': commonElements.stringType}); | 1047 {'fromType': type, 'toType': commonElements.stringType}); |
| 1043 } | 1048 } |
| 1044 | 1049 |
| 1045 String name = firstArgument.primitiveValue.slowToString(); | 1050 String name = firstArgument.primitiveValue.slowToString(); |
| 1046 String value = compiler.fromEnvironment(name); | 1051 String value = compiler.fromEnvironment(name); |
| 1047 | 1052 |
| 1048 AstConstant createEvaluatedConstant(ConstantValue value) { | 1053 AstConstant createEvaluatedConstant(ConstantValue value) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1085 return createEvaluatedConstant( | 1090 return createEvaluatedConstant( |
| 1086 constantSystem.createString(new DartString.literal(value))); | 1091 constantSystem.createString(new DartString.literal(value))); |
| 1087 } | 1092 } |
| 1088 } | 1093 } |
| 1089 | 1094 |
| 1090 static AstConstant makeConstructedConstant( | 1095 static AstConstant makeConstructedConstant( |
| 1091 Compiler compiler, | 1096 Compiler compiler, |
| 1092 ConstantCompilerBase handler, | 1097 ConstantCompilerBase handler, |
| 1093 Element context, | 1098 Element context, |
| 1094 Node node, | 1099 Node node, |
| 1095 InterfaceType type, | 1100 ResolutionInterfaceType type, |
| 1096 ConstructorElement constructor, | 1101 ConstructorElement constructor, |
| 1097 InterfaceType constructedType, | 1102 ResolutionInterfaceType constructedType, |
| 1098 ConstructorElement target, | 1103 ConstructorElement target, |
| 1099 CallStructure callStructure, | 1104 CallStructure callStructure, |
| 1100 List<AstConstant> concreteArguments, | 1105 List<AstConstant> concreteArguments, |
| 1101 List<AstConstant> normalizedArguments) { | 1106 List<AstConstant> normalizedArguments) { |
| 1102 if (target.isRedirectingFactory) { | 1107 if (target.isRedirectingFactory) { |
| 1103 // This happens in case of cyclic redirection. | 1108 // This happens in case of cyclic redirection. |
| 1104 assert(invariant(node, compiler.compilationFailed, | 1109 assert(invariant(node, compiler.compilationFailed, |
| 1105 message: "makeConstructedConstant can only be called with the " | 1110 message: "makeConstructedConstant can only be called with the " |
| 1106 "effective target: $constructor")); | 1111 "effective target: $constructor")); |
| 1107 return new ErroneousAstConstant(context, node); | 1112 return new ErroneousAstConstant(context, node); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1156 // Else we don't need to do anything. The final handler is only | 1161 // Else we don't need to do anything. The final handler is only |
| 1157 // optimistically trying to compile constants. So it is normal that we | 1162 // optimistically trying to compile constants. So it is normal that we |
| 1158 // sometimes see non-compile time constants. | 1163 // sometimes see non-compile time constants. |
| 1159 // Simply return [:null:] which is used to propagate a failing | 1164 // Simply return [:null:] which is used to propagate a failing |
| 1160 // compile-time compilation. | 1165 // compile-time compilation. |
| 1161 return null; | 1166 return null; |
| 1162 } | 1167 } |
| 1163 } | 1168 } |
| 1164 | 1169 |
| 1165 class ConstructorEvaluator extends CompileTimeConstantEvaluator { | 1170 class ConstructorEvaluator extends CompileTimeConstantEvaluator { |
| 1166 final InterfaceType constructedType; | 1171 final ResolutionInterfaceType constructedType; |
| 1167 final ConstructorElement constructor; | 1172 final ConstructorElement constructor; |
| 1168 final Map<Element, AstConstant> definitions; | 1173 final Map<Element, AstConstant> definitions; |
| 1169 final Map<Element, AstConstant> fieldValues; | 1174 final Map<Element, AstConstant> fieldValues; |
| 1170 final ResolvedAst resolvedAst; | 1175 final ResolvedAst resolvedAst; |
| 1171 | 1176 |
| 1172 /** | 1177 /** |
| 1173 * Documentation wanted -- johnniwinther | 1178 * Documentation wanted -- johnniwinther |
| 1174 * | 1179 * |
| 1175 * Invariant: [constructor] must be an implementation element. | 1180 * Invariant: [constructor] must be an implementation element. |
| 1176 */ | 1181 */ |
| 1177 ConstructorEvaluator( | 1182 ConstructorEvaluator( |
| 1178 InterfaceType this.constructedType, | 1183 ResolutionInterfaceType this.constructedType, |
| 1179 ConstructorElement constructor, | 1184 ConstructorElement constructor, |
| 1180 ConstantCompiler handler, | 1185 ConstantCompiler handler, |
| 1181 Compiler compiler) | 1186 Compiler compiler) |
| 1182 : this.constructor = constructor, | 1187 : this.constructor = constructor, |
| 1183 this.definitions = new Map<Element, AstConstant>(), | 1188 this.definitions = new Map<Element, AstConstant>(), |
| 1184 this.fieldValues = new Map<Element, AstConstant>(), | 1189 this.fieldValues = new Map<Element, AstConstant>(), |
| 1185 this.resolvedAst = | 1190 this.resolvedAst = |
| 1186 compiler.resolution.computeResolvedAst(constructor.declaration), | 1191 compiler.resolution.computeResolvedAst(constructor.declaration), |
| 1187 super(handler, null, compiler, isConst: true) { | 1192 super(handler, null, compiler, isConst: true) { |
| 1188 assert(invariant(constructor, constructor.isImplementation)); | 1193 assert(invariant(constructor, constructor.isImplementation)); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1201 if (constant == null) { | 1206 if (constant == null) { |
| 1202 reporter.internalError(send, "Local variable without value."); | 1207 reporter.internalError(send, "Local variable without value."); |
| 1203 } | 1208 } |
| 1204 return constant; | 1209 return constant; |
| 1205 } | 1210 } |
| 1206 return super.visitSend(send); | 1211 return super.visitSend(send); |
| 1207 } | 1212 } |
| 1208 | 1213 |
| 1209 void potentiallyCheckType(TypedElement element, AstConstant constant) { | 1214 void potentiallyCheckType(TypedElement element, AstConstant constant) { |
| 1210 if (compiler.options.enableTypeAssertions) { | 1215 if (compiler.options.enableTypeAssertions) { |
| 1211 DartType elementType = element.type.substByContext(constructedType); | 1216 ResolutionDartType elementType = |
| 1212 DartType constantType = constant.value.getType(commonElements); | 1217 element.type.substByContext(constructedType); |
| 1218 ResolutionDartType constantType = constant.value.getType(commonElements); |
| 1213 if (!constantSystem.isSubtype( | 1219 if (!constantSystem.isSubtype( |
| 1214 compiler.types, constantType, elementType)) { | 1220 compiler.types, constantType, elementType)) { |
| 1215 reporter.withCurrentElement(constant.element, () { | 1221 reporter.withCurrentElement(constant.element, () { |
| 1216 reporter.reportErrorMessage(constant.node, MessageKind.NOT_ASSIGNABLE, | 1222 reporter.reportErrorMessage(constant.node, MessageKind.NOT_ASSIGNABLE, |
| 1217 {'fromType': constantType, 'toType': elementType}); | 1223 {'fromType': constantType, 'toType': elementType}); |
| 1218 }); | 1224 }); |
| 1219 } | 1225 } |
| 1220 } | 1226 } |
| 1221 } | 1227 } |
| 1222 | 1228 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1243 updateFieldValue(node, initializingFormal.fieldElement, argument); | 1249 updateFieldValue(node, initializingFormal.fieldElement, argument); |
| 1244 } else { | 1250 } else { |
| 1245 potentiallyCheckType(parameter, argument); | 1251 potentiallyCheckType(parameter, argument); |
| 1246 } | 1252 } |
| 1247 definitions[parameter] = argument; | 1253 definitions[parameter] = argument; |
| 1248 }); | 1254 }); |
| 1249 } | 1255 } |
| 1250 | 1256 |
| 1251 void evaluateSuperOrRedirectSend(List<AstConstant> compiledArguments, | 1257 void evaluateSuperOrRedirectSend(List<AstConstant> compiledArguments, |
| 1252 CallStructure callStructure, ConstructorElement targetConstructor) { | 1258 CallStructure callStructure, ConstructorElement targetConstructor) { |
| 1253 InterfaceType type = | 1259 ResolutionInterfaceType type = |
| 1254 constructedType.asInstanceOf(targetConstructor.enclosingClass); | 1260 constructedType.asInstanceOf(targetConstructor.enclosingClass); |
| 1255 if (compiler.serialization.isDeserialized(targetConstructor)) { | 1261 if (compiler.serialization.isDeserialized(targetConstructor)) { |
| 1256 List<ConstantExpression> arguments = | 1262 List<ConstantExpression> arguments = |
| 1257 compiledArguments.map((c) => c.expression).toList(); | 1263 compiledArguments.map((c) => c.expression).toList(); |
| 1258 ConstructedConstantExpression expression = | 1264 ConstructedConstantExpression expression = |
| 1259 new ConstructedConstantExpression( | 1265 new ConstructedConstantExpression( |
| 1260 type, targetConstructor, callStructure, arguments); | 1266 type, targetConstructor, callStructure, arguments); |
| 1261 | 1267 |
| 1262 Map<FieldElement, ConstantExpression> fields = | 1268 Map<FieldElement, ConstantExpression> fields = |
| 1263 expression.computeInstanceFields(); | 1269 expression.computeInstanceFields(); |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1443 class _CompilerEnvironment implements Environment { | 1449 class _CompilerEnvironment implements Environment { |
| 1444 final Compiler compiler; | 1450 final Compiler compiler; |
| 1445 | 1451 |
| 1446 _CompilerEnvironment(this.compiler); | 1452 _CompilerEnvironment(this.compiler); |
| 1447 | 1453 |
| 1448 @override | 1454 @override |
| 1449 String readFromEnvironment(String name) { | 1455 String readFromEnvironment(String name) { |
| 1450 return compiler.fromEnvironment(name); | 1456 return compiler.fromEnvironment(name); |
| 1451 } | 1457 } |
| 1452 } | 1458 } |
| OLD | NEW |