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 ClosureClassMap; | 7 import '../closure.dart' show ClosureClassMap; |
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 976 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
987 } | 987 } |
988 } | 988 } |
989 visitingInitializers = false; | 989 visitingInitializers = false; |
990 // For a generative constructor like: `Foo();`, we synthesize | 990 // For a generative constructor like: `Foo();`, we synthesize |
991 // a call to the default super constructor (the one that takes | 991 // a call to the default super constructor (the one that takes |
992 // no argument). Resolution ensures that such a constructor | 992 // no argument). Resolution ensures that such a constructor |
993 // exists. | 993 // exists. |
994 if (!isConstructorRedirect && | 994 if (!isConstructorRedirect && |
995 !seenSuperConstructorCall && | 995 !seenSuperConstructorCall && |
996 !cls.isObject) { | 996 !cls.isObject) { |
997 FunctionElement target = cls.superclass.lookupDefaultConstructor(); | 997 ConstructorElement target = cls.superclass.lookupDefaultConstructor(); |
998 ArgumentsTypes arguments = new ArgumentsTypes([], {}); | 998 ArgumentsTypes arguments = new ArgumentsTypes([], {}); |
999 analyzeSuperConstructorCall(target, arguments); | 999 analyzeSuperConstructorCall(target, arguments); |
1000 inferrer.registerCalledElement(node, null, null, outermostElement, | 1000 inferrer.registerCalledElement(node, null, null, outermostElement, |
1001 target.implementation, arguments, sideEffects, inLoop); | 1001 target.implementation, arguments, sideEffects, inLoop); |
1002 } | 1002 } |
1003 visit(node.body); | 1003 visit(node.body); |
1004 inferrer.recordExposesThis(analyzedElement, isThisExposed); | 1004 inferrer.recordExposesThis(analyzedElement, isThisExposed); |
1005 } | 1005 } |
1006 if (!isConstructorRedirect) { | 1006 if (!isConstructorRedirect) { |
1007 // Iterate over all instance fields, and give a null type to | 1007 // Iterate over all instance fields, and give a null type to |
(...skipping 970 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1978 ArgumentsTypes arguments = new ArgumentsTypes([rhsType], null); | 1978 ArgumentsTypes arguments = new ArgumentsTypes([rhsType], null); |
1979 if (Elements.isMalformed(element)) { | 1979 if (Elements.isMalformed(element)) { |
1980 // Code will always throw. | 1980 // Code will always throw. |
1981 } else if (Elements.isStaticOrTopLevelField(element)) { | 1981 } else if (Elements.isStaticOrTopLevelField(element)) { |
1982 handleStaticSend(node, setterSelector, setterMask, element, arguments); | 1982 handleStaticSend(node, setterSelector, setterMask, element, arguments); |
1983 } else if (Elements.isUnresolved(element) || element.isSetter) { | 1983 } else if (Elements.isUnresolved(element) || element.isSetter) { |
1984 if (analyzedElement.isGenerativeConstructor && | 1984 if (analyzedElement.isGenerativeConstructor && |
1985 (node.asSendSet() != null) && | 1985 (node.asSendSet() != null) && |
1986 (node.asSendSet().receiver != null) && | 1986 (node.asSendSet().receiver != null) && |
1987 node.asSendSet().receiver.isThis()) { | 1987 node.asSendSet().receiver.isThis()) { |
1988 Iterable<Element> targets = closedWorld.allFunctions.filter( | 1988 Iterable<MemberEntity> targets = closedWorld.allFunctions.filter( |
1989 setterSelector, types.newTypedSelector(thisType, setterMask)); | 1989 setterSelector, types.newTypedSelector(thisType, setterMask)); |
1990 // We just recognized a field initialization of the form: | 1990 // We just recognized a field initialization of the form: |
1991 // `this.foo = 42`. If there is only one target, we can update | 1991 // `this.foo = 42`. If there is only one target, we can update |
1992 // its type. | 1992 // its type. |
1993 if (targets.length == 1) { | 1993 if (targets.length == 1) { |
1994 Element single = targets.first; | 1994 MemberElement single = targets.first; |
1995 if (single.isField) { | 1995 if (single.isField) { |
1996 locals.updateField(single, rhsType); | 1996 locals.updateField(single, rhsType); |
1997 } | 1997 } |
1998 } | 1998 } |
1999 } | 1999 } |
2000 handleDynamicSend( | 2000 handleDynamicSend( |
2001 node, setterSelector, setterMask, receiverType, arguments); | 2001 node, setterSelector, setterMask, receiverType, arguments); |
2002 } else if (element.isField) { | 2002 } else if (element.isField) { |
2003 if (element.isFinal) { | 2003 if (element.isFinal) { |
2004 inferrer.recordTypeOfFinalField( | 2004 inferrer.recordTypeOfFinalField( |
(...skipping 804 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2809 } | 2809 } |
2810 } | 2810 } |
2811 return handleDynamicSend(node, selector, mask, receiverType, arguments); | 2811 return handleDynamicSend(node, selector, mask, receiverType, arguments); |
2812 } | 2812 } |
2813 | 2813 |
2814 void recordReturnType(TypeInformation type) { | 2814 void recordReturnType(TypeInformation type) { |
2815 returnType = inferrer.addReturnTypeFor(analyzedElement, returnType, type); | 2815 returnType = inferrer.addReturnTypeFor(analyzedElement, returnType, type); |
2816 } | 2816 } |
2817 | 2817 |
2818 TypeInformation synthesizeForwardingCall( | 2818 TypeInformation synthesizeForwardingCall( |
2819 Spannable node, FunctionElement element) { | 2819 Spannable node, ConstructorElement element) { |
2820 element = element.implementation; | 2820 element = element.implementation; |
2821 FunctionElement function = analyzedElement; | 2821 FunctionElement function = analyzedElement; |
2822 FunctionSignature signature = function.functionSignature; | 2822 FunctionSignature signature = function.functionSignature; |
2823 FunctionSignature calleeSignature = element.functionSignature; | 2823 FunctionSignature calleeSignature = element.functionSignature; |
2824 if (!calleeSignature.isCompatibleWith(signature)) { | 2824 if (!calleeSignature.isCompatibleWith(signature)) { |
2825 return types.nonNullEmpty(); | 2825 return types.nonNullEmpty(); |
2826 } | 2826 } |
2827 | 2827 |
2828 List<TypeInformation> unnamed = <TypeInformation>[]; | 2828 List<TypeInformation> unnamed = <TypeInformation>[]; |
2829 signature.forEachRequiredParameter((ParameterElement element) { | 2829 signature.forEachRequiredParameter((ParameterElement element) { |
(...skipping 12 matching lines...) Expand all Loading... |
2842 unnamed.add(locals.use(element)); | 2842 unnamed.add(locals.use(element)); |
2843 }); | 2843 }); |
2844 } | 2844 } |
2845 | 2845 |
2846 ArgumentsTypes arguments = new ArgumentsTypes(unnamed, named); | 2846 ArgumentsTypes arguments = new ArgumentsTypes(unnamed, named); |
2847 return inferrer.registerCalledElement(node, null, null, outermostElement, | 2847 return inferrer.registerCalledElement(node, null, null, outermostElement, |
2848 element, arguments, sideEffects, inLoop); | 2848 element, arguments, sideEffects, inLoop); |
2849 } | 2849 } |
2850 | 2850 |
2851 TypeInformation visitRedirectingFactoryBody(ast.RedirectingFactoryBody node) { | 2851 TypeInformation visitRedirectingFactoryBody(ast.RedirectingFactoryBody node) { |
2852 Element element = elements.getRedirectingTargetConstructor(node); | 2852 ConstructorElement element = elements.getRedirectingTargetConstructor(node); |
2853 if (Elements.isMalformed(element)) { | 2853 if (Elements.isMalformed(element)) { |
2854 recordReturnType(types.dynamicType); | 2854 recordReturnType(types.dynamicType); |
2855 } else { | 2855 } else { |
2856 // We don'TypeInformation create a selector for redirecting factories, and | 2856 // We don'TypeInformation create a selector for redirecting factories, and |
2857 // the send is just a property access. Therefore we must | 2857 // the send is just a property access. Therefore we must |
2858 // manually create the [ArgumentsTypes] of the call, and | 2858 // manually create the [ArgumentsTypes] of the call, and |
2859 // manually register [analyzedElement] as a caller of [element]. | 2859 // manually register [analyzedElement] as a caller of [element]. |
2860 TypeInformation mask = | 2860 TypeInformation mask = |
2861 synthesizeForwardingCall(node.constructorReference, element); | 2861 synthesizeForwardingCall(node.constructorReference, element); |
2862 recordReturnType(mask); | 2862 recordReturnType(mask); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2939 Selector moveNextSelector = Selectors.moveNext; | 2939 Selector moveNextSelector = Selectors.moveNext; |
2940 TypeMask moveNextMask = inTreeData.typeOfIteratorMoveNext(node); | 2940 TypeMask moveNextMask = inTreeData.typeOfIteratorMoveNext(node); |
2941 | 2941 |
2942 TypeInformation iteratorType = handleDynamicSend(node, iteratorSelector, | 2942 TypeInformation iteratorType = handleDynamicSend(node, iteratorSelector, |
2943 iteratorMask, expressionType, new ArgumentsTypes.empty()); | 2943 iteratorMask, expressionType, new ArgumentsTypes.empty()); |
2944 | 2944 |
2945 return handleForInLoop(node, iteratorType, currentSelector, currentMask, | 2945 return handleForInLoop(node, iteratorType, currentSelector, currentMask, |
2946 moveNextSelector, moveNextMask); | 2946 moveNextSelector, moveNextMask); |
2947 } | 2947 } |
2948 } | 2948 } |
OLD | NEW |