Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/compile_time_constants.dart

Issue 146733003: Handle type checking of generic compile time constants. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix for language/const_constructor3_test Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/language/const_constructor2_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 part of dart2js; 5 part of dart2js;
6 6
7 /// A [ConstantEnvironment] provides access for constants compiled for variable 7 /// A [ConstantEnvironment] provides access for constants compiled for variable
8 /// initializers. 8 /// initializers.
9 abstract class ConstantEnvironment { 9 abstract class ConstantEnvironment {
10 /// Returns the constant for the initializer of [element]. 10 /// Returns the constant for the initializer of [element].
(...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after
767 compiler.resolver.resolveRedirectionChain(constructor, node); 767 compiler.resolver.resolveRedirectionChain(constructor, node);
768 InterfaceType constructedType = constructor.computeTargetType(type); 768 InterfaceType constructedType = constructor.computeTargetType(type);
769 constructor = constructor.redirectionTarget; 769 constructor = constructor.redirectionTarget;
770 ClassElement classElement = constructor.getEnclosingClass(); 770 ClassElement classElement = constructor.getEnclosingClass();
771 // The constructor must be an implementation to ensure that field 771 // The constructor must be an implementation to ensure that field
772 // initializers are handled correctly. 772 // initializers are handled correctly.
773 constructor = constructor.implementation; 773 constructor = constructor.implementation;
774 assert(invariant(node, constructor.isImplementation)); 774 assert(invariant(node, constructor.isImplementation));
775 775
776 List<Constant> arguments = getArguments(constructor); 776 List<Constant> arguments = getArguments(constructor);
777 ConstructorEvaluator evaluator = 777 ConstructorEvaluator evaluator = new ConstructorEvaluator(
778 new ConstructorEvaluator(constructor, handler, compiler); 778 constructedType, constructor, handler, compiler);
779 evaluator.evaluateConstructorFieldValues(arguments); 779 evaluator.evaluateConstructorFieldValues(arguments);
780 List<Constant> jsNewArguments = evaluator.buildJsNewArguments(classElement); 780 List<Constant> jsNewArguments = evaluator.buildJsNewArguments(classElement);
781 781
782 return new ConstructedConstant(constructedType, jsNewArguments); 782 return new ConstructedConstant(constructedType, jsNewArguments);
783 } 783 }
784 784
785 Constant visitParenthesizedExpression(ParenthesizedExpression node) { 785 Constant visitParenthesizedExpression(ParenthesizedExpression node) {
786 return node.expression.accept(this); 786 return node.expression.accept(this);
787 } 787 }
788 788
(...skipping 11 matching lines...) Expand all
800 // Else we don't need to do anything. The final handler is only 800 // Else we don't need to do anything. The final handler is only
801 // optimistically trying to compile constants. So it is normal that we 801 // optimistically trying to compile constants. So it is normal that we
802 // sometimes see non-compile time constants. 802 // sometimes see non-compile time constants.
803 // Simply return [:null:] which is used to propagate a failing 803 // Simply return [:null:] which is used to propagate a failing
804 // compile-time compilation. 804 // compile-time compilation.
805 return null; 805 return null;
806 } 806 }
807 } 807 }
808 808
809 class ConstructorEvaluator extends CompileTimeConstantEvaluator { 809 class ConstructorEvaluator extends CompileTimeConstantEvaluator {
810 final InterfaceType constructedType;
810 final FunctionElement constructor; 811 final FunctionElement constructor;
811 final Map<Element, Constant> definitions; 812 final Map<Element, Constant> definitions;
812 final Map<Element, Constant> fieldValues; 813 final Map<Element, Constant> fieldValues;
813 814
814 /** 815 /**
815 * Documentation wanted -- johnniwinther 816 * Documentation wanted -- johnniwinther
816 * 817 *
817 * Invariant: [constructor] must be an implementation element. 818 * Invariant: [constructor] must be an implementation element.
818 */ 819 */
819 ConstructorEvaluator(FunctionElement constructor, 820 ConstructorEvaluator(InterfaceType this.constructedType,
821 FunctionElement constructor,
820 ConstantCompiler handler, 822 ConstantCompiler handler,
821 Compiler compiler) 823 Compiler compiler)
822 : this.constructor = constructor, 824 : this.constructor = constructor,
823 this.definitions = new Map<Element, Constant>(), 825 this.definitions = new Map<Element, Constant>(),
824 this.fieldValues = new Map<Element, Constant>(), 826 this.fieldValues = new Map<Element, Constant>(),
825 super(handler, 827 super(handler,
826 compiler.resolver.resolveMethodElement(constructor.declaration), 828 compiler.resolver.resolveMethodElement(constructor.declaration),
827 compiler, 829 compiler,
828 isConst: true) { 830 isConst: true) {
829 assert(invariant(constructor, constructor.isImplementation)); 831 assert(invariant(constructor, constructor.isImplementation));
830 } 832 }
831 833
832 Constant visitSend(Send send) { 834 Constant visitSend(Send send) {
833 Element element = elements[send]; 835 Element element = elements[send];
834 if (Elements.isLocal(element)) { 836 if (Elements.isLocal(element)) {
835 Constant constant = definitions[element]; 837 Constant constant = definitions[element];
836 if (constant == null) { 838 if (constant == null) {
837 compiler.internalError(send, "Local variable without value."); 839 compiler.internalError(send, "Local variable without value.");
838 } 840 }
839 return constant; 841 return constant;
840 } 842 }
841 return super.visitSend(send); 843 return super.visitSend(send);
842 } 844 }
843 845
844 void potentiallyCheckType(Node node, 846 void potentiallyCheckType(Node node,
845 TypedElement element, 847 TypedElement element,
846 Constant constant) { 848 Constant constant) {
847 if (compiler.enableTypeAssertions) { 849 if (compiler.enableTypeAssertions) {
848 DartType elementType = element.type; 850 DartType elementType = element.type.substByContext(constructedType);
849 DartType constantType = constant.computeType(compiler); 851 DartType constantType = constant.computeType(compiler);
850 // TODO(ngeoffray): Handle type parameters.
851 if (elementType.element.isTypeVariable()) return;
852 if (!constantSystem.isSubtype(compiler, constantType, elementType)) { 852 if (!constantSystem.isSubtype(compiler, constantType, elementType)) {
853 // TODO(johnniwinther): Provide better [node] values that point to the
854 // origin of the constant and not (just) the assignment.
855 compiler.reportFatalError( 853 compiler.reportFatalError(
856 node, MessageKind.NOT_ASSIGNABLE, 854 node, MessageKind.NOT_ASSIGNABLE,
857 {'fromType': elementType, 'toType': constantType}); 855 {'fromType': constantType, 'toType': elementType});
858 } 856 }
859 } 857 }
860 } 858 }
861 859
862 void updateFieldValue(Node node, TypedElement element, Constant constant) { 860 void updateFieldValue(Node node, TypedElement element, Constant constant) {
863 potentiallyCheckType(node, element, constant); 861 potentiallyCheckType(node, element, constant);
864 fieldValues[element] = constant; 862 fieldValues[element] = constant;
865 } 863 }
866 864
867 /** 865 /**
868 * Given the arguments (a list of constants) assigns them to the parameters, 866 * Given the arguments (a list of constants) assigns them to the parameters,
869 * updating the definitions map. If the constructor has field-initializer 867 * updating the definitions map. If the constructor has field-initializer
870 * parameters (like [:this.x:]), also updates the [fieldValues] map. 868 * parameters (like [:this.x:]), also updates the [fieldValues] map.
871 */ 869 */
872 void assignArgumentsToParameters(List<Constant> arguments) { 870 void assignArgumentsToParameters(List<Constant> arguments) {
873 // Assign arguments to parameters. 871 // Assign arguments to parameters.
874 FunctionSignature parameters = constructor.functionSignature; 872 FunctionSignature signature = constructor.functionSignature;
875 int index = 0; 873 int index = 0;
876 parameters.orderedForEachParameter((Element parameter) { 874 signature.orderedForEachParameter((Element parameter) {
877 Constant argument = arguments[index++]; 875 Constant argument = arguments[index++];
878 Node node = parameter.parseNode(compiler); 876 Node node = parameter.parseNode(compiler);
879 potentiallyCheckType(node, parameter, argument); 877 potentiallyCheckType(node, parameter, argument);
880 definitions[parameter] = argument; 878 definitions[parameter] = argument;
881 if (parameter.kind == ElementKind.FIELD_PARAMETER) { 879 if (parameter.kind == ElementKind.FIELD_PARAMETER) {
882 FieldParameterElement fieldParameterElement = parameter; 880 FieldParameterElement fieldParameterElement = parameter;
883 updateFieldValue(node, fieldParameterElement.fieldElement, argument); 881 updateFieldValue(node, fieldParameterElement.fieldElement, argument);
884 } 882 }
885 }); 883 });
886 } 884 }
887 885
888 void evaluateSuperOrRedirectSend(List<Constant> compiledArguments, 886 void evaluateSuperOrRedirectSend(List<Constant> compiledArguments,
889 FunctionElement targetConstructor) { 887 FunctionElement targetConstructor) {
890 ConstructorEvaluator evaluator = new ConstructorEvaluator( 888 ConstructorEvaluator evaluator = new ConstructorEvaluator(
889 constructedType.asInstanceOf(targetConstructor.getEnclosingClass()),
891 targetConstructor, handler, compiler); 890 targetConstructor, handler, compiler);
892 evaluator.evaluateConstructorFieldValues(compiledArguments); 891 evaluator.evaluateConstructorFieldValues(compiledArguments);
893 // Copy over the fieldValues from the super/redirect-constructor. 892 // Copy over the fieldValues from the super/redirect-constructor.
894 // No need to go through [updateFieldValue] because the 893 // No need to go through [updateFieldValue] because the
895 // assignments have already been checked in checked mode. 894 // assignments have already been checked in checked mode.
896 evaluator.fieldValues.forEach((key, value) => fieldValues[key] = value); 895 evaluator.fieldValues.forEach((key, value) => fieldValues[key] = value);
897 } 896 }
898 897
899 /** 898 /**
900 * Runs through the initializers of the given [constructor] and updates 899 * Runs through the initializers of the given [constructor] and updates
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
990 if (fieldValue == null) { 989 if (fieldValue == null) {
991 // Use the default value. 990 // Use the default value.
992 fieldValue = handler.compileConstant(field); 991 fieldValue = handler.compileConstant(field);
993 } 992 }
994 jsNewArguments.add(fieldValue); 993 jsNewArguments.add(fieldValue);
995 }, 994 },
996 includeSuperAndInjectedMembers: true); 995 includeSuperAndInjectedMembers: true);
997 return jsNewArguments; 996 return jsNewArguments;
998 } 997 }
999 } 998 }
OLDNEW
« no previous file with comments | « no previous file | tests/language/const_constructor2_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698