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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 ElementGraphBuilder.internal( | 80 ElementGraphBuilder.internal( |
81 AstElement analyzedElement, | 81 AstElement analyzedElement, |
82 this.resolvedAst, | 82 this.resolvedAst, |
83 this.outermostElement, | 83 this.outermostElement, |
84 InferrerEngine inferrer, | 84 InferrerEngine inferrer, |
85 this.compiler, | 85 this.compiler, |
86 this.locals) | 86 this.locals) |
87 : this.analyzedElement = analyzedElement, | 87 : this.analyzedElement = analyzedElement, |
88 this.inferrer = inferrer, | 88 this.inferrer = inferrer, |
89 this.types = inferrer.types, | 89 this.types = inferrer.types, |
90 this.inTreeData = inferrer.dataOf(analyzedElement) { | 90 this.inTreeData = analyzedElement.isLocal |
| 91 ? inferrer.dataOfLocalFunction(analyzedElement) |
| 92 : inferrer.dataOfMember(analyzedElement) { |
91 assert(outermostElement != null); | 93 assert(outermostElement != null); |
92 if (locals != null) return; | 94 if (locals != null) return; |
93 ast.Node node; | 95 ast.Node node; |
94 if (resolvedAst.kind == ResolvedAstKind.PARSED) { | 96 if (resolvedAst.kind == ResolvedAstKind.PARSED) { |
95 node = resolvedAst.node; | 97 node = resolvedAst.node; |
96 } | 98 } |
97 FieldInitializationScope fieldScope = | 99 FieldInitializationScope fieldScope = |
98 analyzedElement.isGenerativeConstructor | 100 analyzedElement.isGenerativeConstructor |
99 ? new FieldInitializationScope(types) | 101 ? new FieldInitializationScope(types) |
100 : null; | 102 : null; |
(...skipping 1007 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1108 inferrer.recordTypeOfField(field, thisType); | 1110 inferrer.recordTypeOfField(field, thisType); |
1109 } | 1111 } |
1110 // The type is null for type parameters. | 1112 // The type is null for type parameters. |
1111 if (locals.locals[variable] == null) return; | 1113 if (locals.locals[variable] == null) return; |
1112 inferrer.recordTypeOfField(field, locals.locals[variable]); | 1114 inferrer.recordTypeOfField(field, locals.locals[variable]); |
1113 } | 1115 } |
1114 capturedVariables.add(variable); | 1116 capturedVariables.add(variable); |
1115 }); | 1117 }); |
1116 | 1118 |
1117 return inferrer.concreteTypes.putIfAbsent(node, () { | 1119 return inferrer.concreteTypes.putIfAbsent(node, () { |
1118 return types.allocateClosure(node, element); | 1120 return types.allocateClosureForLocalFunction(node, element); |
1119 }); | 1121 }); |
1120 } | 1122 } |
1121 | 1123 |
1122 TypeInformation visitFunctionDeclaration(ast.FunctionDeclaration node) { | 1124 TypeInformation visitFunctionDeclaration(ast.FunctionDeclaration node) { |
1123 LocalFunctionElement element = | 1125 LocalFunctionElement element = |
1124 elements.getFunctionDefinition(node.function); | 1126 elements.getFunctionDefinition(node.function); |
1125 TypeInformation type = | 1127 TypeInformation type = |
1126 inferrer.concreteTypes.putIfAbsent(node.function, () { | 1128 inferrer.concreteTypes.putIfAbsent(node.function, () { |
1127 return types.allocateClosure(node.function, element); | 1129 return types.allocateClosureForLocalFunction(node.function, element); |
1128 }); | 1130 }); |
1129 locals.update(element, type, node); | 1131 locals.update(element, type, node); |
1130 visit(node.function); | 1132 visit(node.function); |
1131 return type; | 1133 return type; |
1132 } | 1134 } |
1133 | 1135 |
1134 TypeInformation visitStringInterpolation(ast.StringInterpolation node) { | 1136 TypeInformation visitStringInterpolation(ast.StringInterpolation node) { |
1135 // Interpolation could have any effects since it could call any toString() | 1137 // Interpolation could have any effects since it could call any toString() |
1136 // method. | 1138 // method. |
1137 // TODO(sra): This could be modelled by a call to toString() but with a | 1139 // TODO(sra): This could be modelled by a call to toString() but with a |
(...skipping 1590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2728 element, arguments, sideEffects, inLoop); | 2730 element, arguments, sideEffects, inLoop); |
2729 } | 2731 } |
2730 | 2732 |
2731 TypeInformation handleDynamicSend(ast.Node node, Selector selector, | 2733 TypeInformation handleDynamicSend(ast.Node node, Selector selector, |
2732 TypeMask mask, TypeInformation receiverType, ArgumentsTypes arguments) { | 2734 TypeMask mask, TypeInformation receiverType, ArgumentsTypes arguments) { |
2733 assert(receiverType != null); | 2735 assert(receiverType != null); |
2734 if (types.selectorNeedsUpdate(receiverType, mask)) { | 2736 if (types.selectorNeedsUpdate(receiverType, mask)) { |
2735 mask = receiverType == types.dynamicType | 2737 mask = receiverType == types.dynamicType |
2736 ? null | 2738 ? null |
2737 : types.newTypedSelector(receiverType, mask); | 2739 : types.newTypedSelector(receiverType, mask); |
2738 inferrer.updateSelectorInTree(analyzedElement, node, selector, mask); | 2740 if (analyzedElement.isLocal) { |
| 2741 inferrer.updateSelectorInLocalFunction( |
| 2742 analyzedElement, node, selector, mask); |
| 2743 } else { |
| 2744 inferrer.updateSelectorInMember(analyzedElement, node, selector, mask); |
| 2745 } |
2739 } | 2746 } |
2740 | 2747 |
2741 // If the receiver of the call is a local, we may know more about | 2748 // If the receiver of the call is a local, we may know more about |
2742 // its type by refining it with the potential targets of the | 2749 // its type by refining it with the potential targets of the |
2743 // calls. | 2750 // calls. |
2744 ast.Send send = node.asSend(); | 2751 ast.Send send = node.asSend(); |
2745 if (send != null) { | 2752 if (send != null) { |
2746 ast.Node receiver = send.receiver; | 2753 ast.Node receiver = send.receiver; |
2747 if (receiver != null) { | 2754 if (receiver != null) { |
2748 Element element = elements[receiver]; | 2755 Element element = elements[receiver]; |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2938 Selector moveNextSelector = Selectors.moveNext; | 2945 Selector moveNextSelector = Selectors.moveNext; |
2939 TypeMask moveNextMask = inTreeData.typeOfIteratorMoveNext(node); | 2946 TypeMask moveNextMask = inTreeData.typeOfIteratorMoveNext(node); |
2940 | 2947 |
2941 TypeInformation iteratorType = handleDynamicSend(node, iteratorSelector, | 2948 TypeInformation iteratorType = handleDynamicSend(node, iteratorSelector, |
2942 iteratorMask, expressionType, new ArgumentsTypes.empty()); | 2949 iteratorMask, expressionType, new ArgumentsTypes.empty()); |
2943 | 2950 |
2944 return handleForInLoop(node, iteratorType, currentSelector, currentMask, | 2951 return handleForInLoop(node, iteratorType, currentSelector, currentMask, |
2945 moveNextSelector, moveNextMask); | 2952 moveNextSelector, moveNextMask); |
2946 } | 2953 } |
2947 } | 2954 } |
OLD | NEW |