OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 simple_types_inferrer; | 5 library simple_types_inferrer; |
6 | 6 |
7 import '../closure.dart' show ClosureRepresentationInfo; | 7 import '../closure.dart' show ClosureRepresentationInfo; |
8 import '../common.dart'; | 8 import '../common.dart'; |
9 import '../common/names.dart' show Identifiers, Selectors; | 9 import '../common/names.dart' show Identifiers, Selectors; |
10 import '../compiler.dart' show Compiler; | 10 import '../compiler.dart' show Compiler; |
(...skipping 911 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
922 }); | 922 }); |
923 closureData.forEachBoxedVariable((variable, field) { | 923 closureData.forEachBoxedVariable((variable, field) { |
924 locals.setCapturedAndBoxed(variable, field); | 924 locals.setCapturedAndBoxed(variable, field); |
925 }); | 925 }); |
926 if (analyzedElement.isField) { | 926 if (analyzedElement.isField) { |
927 return visit(initializer); | 927 return visit(initializer); |
928 } | 928 } |
929 | 929 |
930 FunctionElement function = analyzedElement; | 930 FunctionElement function = analyzedElement; |
931 FunctionSignature signature = function.functionSignature; | 931 FunctionSignature signature = function.functionSignature; |
932 signature.forEachOptionalParameter((ParameterElement element) { | 932 signature.forEachOptionalParameter((FormalElement _element) { |
| 933 ParameterElement element = _element; |
933 ast.Expression defaultValue = element.initializer; | 934 ast.Expression defaultValue = element.initializer; |
934 // TODO(25566): The default value of a parameter of a redirecting factory | 935 // TODO(25566): The default value of a parameter of a redirecting factory |
935 // constructor comes from the corresponding parameter of the target. | 936 // constructor comes from the corresponding parameter of the target. |
936 | 937 |
937 // If this is a default value from a different context (because | 938 // If this is a default value from a different context (because |
938 // the current function is synthetic, e.g., a constructor from | 939 // the current function is synthetic, e.g., a constructor from |
939 // a mixin application), we have to start a new inferrer visitor | 940 // a mixin application), we have to start a new inferrer visitor |
940 // with the correct context. | 941 // with the correct context. |
941 // TODO(johnniwinther): Remove once function signatures are fixed. | 942 // TODO(johnniwinther): Remove once function signatures are fixed. |
942 ElementGraphBuilder visitor = this; | 943 ElementGraphBuilder visitor = this; |
943 if (inferrer.hasAlreadyComputedTypeOfParameterDefault(element)) return; | 944 if (inferrer.hasAlreadyComputedTypeOfParameterDefault(element)) return; |
944 if (element.functionDeclaration != analyzedElement) { | 945 if (element.functionDeclaration != analyzedElement) { |
945 visitor = new ElementGraphBuilder(element.functionDeclaration, | 946 visitor = new ElementGraphBuilder(element.functionDeclaration, |
946 element.functionDeclaration.resolvedAst, compiler, inferrer); | 947 element.functionDeclaration.resolvedAst, compiler, inferrer); |
947 } | 948 } |
948 TypeInformation type = | 949 TypeInformation type = |
949 (defaultValue == null) ? types.nullType : visitor.visit(defaultValue); | 950 (defaultValue == null) ? types.nullType : visitor.visit(defaultValue); |
950 inferrer.setDefaultTypeOfParameter(element, type); | 951 inferrer.setDefaultTypeOfParameter(element, type); |
951 }); | 952 }); |
952 | 953 |
953 if (inferrer.isNativeMember(analyzedElement)) { | 954 if (inferrer.isNativeMember(analyzedElement)) { |
954 // Native methods do not have a body, and we currently just say | 955 // Native methods do not have a body, and we currently just say |
955 // they return dynamic. | 956 // they return dynamic. |
956 return types.dynamicType; | 957 return types.dynamicType; |
957 } | 958 } |
958 | 959 |
959 if (analyzedElement.isGenerativeConstructor) { | 960 if (analyzedElement.isGenerativeConstructor) { |
960 isThisExposed = false; | 961 isThisExposed = false; |
961 signature.forEachParameter((ParameterElement element) { | 962 signature.forEachParameter((FormalElement _element) { |
| 963 ParameterElement element = _element; |
962 TypeInformation parameterType = inferrer.typeOfElement(element); | 964 TypeInformation parameterType = inferrer.typeOfElement(element); |
963 if (element.isInitializingFormal) { | 965 if (element.isInitializingFormal) { |
964 InitializingFormalElement initializingFormal = element; | 966 InitializingFormalElement initializingFormal = element; |
965 if (initializingFormal.fieldElement.isFinal) { | 967 if (initializingFormal.fieldElement.isFinal) { |
966 inferrer.recordTypeOfFinalField(node, analyzedElement, | 968 inferrer.recordTypeOfFinalField(node, analyzedElement, |
967 initializingFormal.fieldElement, parameterType); | 969 initializingFormal.fieldElement, parameterType); |
968 } else { | 970 } else { |
969 locals.updateField(initializingFormal.fieldElement, parameterType); | 971 locals.updateField(initializingFormal.fieldElement, parameterType); |
970 inferrer.recordTypeOfNonFinalField(initializingFormal.node, | 972 inferrer.recordTypeOfNonFinalField(initializingFormal.node, |
971 initializingFormal.fieldElement, parameterType); | 973 initializingFormal.fieldElement, parameterType); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1027 returnType = types.nonNullSubclass(cls); | 1029 returnType = types.nonNullSubclass(cls); |
1028 } else { | 1030 } else { |
1029 // TODO(johnniwinther): Avoid analyzing [analyzedElement] in this | 1031 // TODO(johnniwinther): Avoid analyzing [analyzedElement] in this |
1030 // case; it's never called. | 1032 // case; it's never called. |
1031 returnType = types.nonNullEmpty(); | 1033 returnType = types.nonNullEmpty(); |
1032 } | 1034 } |
1033 } else { | 1035 } else { |
1034 returnType = types.nonNullExact(cls); | 1036 returnType = types.nonNullExact(cls); |
1035 } | 1037 } |
1036 } else { | 1038 } else { |
1037 signature.forEachParameter((LocalParameterElement element) { | 1039 signature.forEachParameter((FormalElement _element) { |
| 1040 ParameterElement element = _element; |
1038 locals.update(element, inferrer.typeOfElement(element), node); | 1041 locals.update(element, inferrer.typeOfElement(element), node); |
1039 }); | 1042 }); |
1040 visit(node.body); | 1043 visit(node.body); |
1041 switch (function.asyncMarker) { | 1044 switch (function.asyncMarker) { |
1042 case AsyncMarker.SYNC: | 1045 case AsyncMarker.SYNC: |
1043 if (returnType == null) { | 1046 if (returnType == null) { |
1044 // No return in the body. | 1047 // No return in the body. |
1045 returnType = locals.seenReturnOrThrow | 1048 returnType = locals.seenReturnOrThrow |
1046 ? types.nonNullEmpty() // Body always throws. | 1049 ? types.nonNullEmpty() // Body always throws. |
1047 : types.nullType; | 1050 : types.nullType; |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1187 bool isThisOrSuper(ast.Node node) => node.isThis() || node.isSuper(); | 1190 bool isThisOrSuper(ast.Node node) => node.isThis() || node.isSuper(); |
1188 | 1191 |
1189 bool isInClassOrSubclass(Element element) { | 1192 bool isInClassOrSubclass(Element element) { |
1190 ClassElement cls = outermostElement.enclosingClass; | 1193 ClassElement cls = outermostElement.enclosingClass; |
1191 ClassElement enclosing = element.enclosingClass; | 1194 ClassElement enclosing = element.enclosingClass; |
1192 return closedWorld.isSubclassOf(enclosing, cls); | 1195 return closedWorld.isSubclassOf(enclosing, cls); |
1193 } | 1196 } |
1194 | 1197 |
1195 void checkIfExposesThis(Selector selector, TypeMask mask) { | 1198 void checkIfExposesThis(Selector selector, TypeMask mask) { |
1196 if (isThisExposed) return; | 1199 if (isThisExposed) return; |
1197 inferrer.forEachElementMatching(selector, mask, (element) { | 1200 inferrer.forEachElementMatching(selector, mask, (dynamic element) { |
1198 if (element.isField) { | 1201 if (element.isField) { |
1199 ResolvedAst elementResolvedAst = element.resolvedAst; | 1202 ResolvedAst elementResolvedAst = element.resolvedAst; |
1200 if (!selector.isSetter && | 1203 if (!selector.isSetter && |
1201 isInClassOrSubclass(element) && | 1204 isInClassOrSubclass(element) && |
1202 !element.isFinal && | 1205 !element.isFinal && |
1203 locals.fieldScope.readField(element) == null && | 1206 locals.fieldScope.readField(element) == null && |
1204 elementResolvedAst.body == null) { | 1207 elementResolvedAst.body == null) { |
1205 // If the field is being used before this constructor | 1208 // If the field is being used before this constructor |
1206 // actually had a chance to initialize it, say it can be | 1209 // actually had a chance to initialize it, say it can be |
1207 // null. | 1210 // null. |
(...skipping 1623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2831 Spannable node, ConstructorElement element) { | 2834 Spannable node, ConstructorElement element) { |
2832 element = element.implementation; | 2835 element = element.implementation; |
2833 FunctionElement function = analyzedElement; | 2836 FunctionElement function = analyzedElement; |
2834 FunctionSignature signature = function.functionSignature; | 2837 FunctionSignature signature = function.functionSignature; |
2835 FunctionSignature calleeSignature = element.functionSignature; | 2838 FunctionSignature calleeSignature = element.functionSignature; |
2836 if (!calleeSignature.isCompatibleWith(signature)) { | 2839 if (!calleeSignature.isCompatibleWith(signature)) { |
2837 return types.nonNullEmpty(); | 2840 return types.nonNullEmpty(); |
2838 } | 2841 } |
2839 | 2842 |
2840 List<TypeInformation> unnamed = <TypeInformation>[]; | 2843 List<TypeInformation> unnamed = <TypeInformation>[]; |
2841 signature.forEachRequiredParameter((ParameterElement element) { | 2844 signature.forEachRequiredParameter((FormalElement _element) { |
| 2845 ParameterElement element = _element; |
2842 assert(locals.use(element) != null); | 2846 assert(locals.use(element) != null); |
2843 unnamed.add(locals.use(element)); | 2847 unnamed.add(locals.use(element)); |
2844 }); | 2848 }); |
2845 | 2849 |
2846 Map<String, TypeInformation> named; | 2850 Map<String, TypeInformation> named; |
2847 if (signature.optionalParametersAreNamed) { | 2851 if (signature.optionalParametersAreNamed) { |
2848 named = new Map<String, TypeInformation>(); | 2852 named = new Map<String, TypeInformation>(); |
2849 signature.forEachOptionalParameter((ParameterElement element) { | 2853 signature.forEachOptionalParameter((FormalElement _element) { |
| 2854 ParameterElement element = _element; |
2850 named[element.name] = locals.use(element); | 2855 named[element.name] = locals.use(element); |
2851 }); | 2856 }); |
2852 } else { | 2857 } else { |
2853 signature.forEachOptionalParameter((ParameterElement element) { | 2858 signature.forEachOptionalParameter((FormalElement _element) { |
| 2859 ParameterElement element = _element; |
2854 unnamed.add(locals.use(element)); | 2860 unnamed.add(locals.use(element)); |
2855 }); | 2861 }); |
2856 } | 2862 } |
2857 | 2863 |
2858 ArgumentsTypes arguments = new ArgumentsTypes(unnamed, named); | 2864 ArgumentsTypes arguments = new ArgumentsTypes(unnamed, named); |
2859 return inferrer.registerCalledElement(node, null, null, outermostElement, | 2865 return inferrer.registerCalledElement(node, null, null, outermostElement, |
2860 element, arguments, sideEffects, inLoop); | 2866 element, arguments, sideEffects, inLoop); |
2861 } | 2867 } |
2862 | 2868 |
2863 TypeInformation visitRedirectingFactoryBody(ast.RedirectingFactoryBody node) { | 2869 TypeInformation visitRedirectingFactoryBody(ast.RedirectingFactoryBody node) { |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2951 Selector moveNextSelector = Selectors.moveNext; | 2957 Selector moveNextSelector = Selectors.moveNext; |
2952 TypeMask moveNextMask = inTreeData.typeOfIteratorMoveNext(node); | 2958 TypeMask moveNextMask = inTreeData.typeOfIteratorMoveNext(node); |
2953 | 2959 |
2954 TypeInformation iteratorType = handleDynamicSend(node, iteratorSelector, | 2960 TypeInformation iteratorType = handleDynamicSend(node, iteratorSelector, |
2955 iteratorMask, expressionType, new ArgumentsTypes.empty()); | 2961 iteratorMask, expressionType, new ArgumentsTypes.empty()); |
2956 | 2962 |
2957 return handleForInLoop(node, iteratorType, currentSelector, currentMask, | 2963 return handleForInLoop(node, iteratorType, currentSelector, currentMask, |
2958 moveNextSelector, moveNextMask); | 2964 moveNextSelector, moveNextMask); |
2959 } | 2965 } |
2960 } | 2966 } |
OLD | NEW |