Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart |
| =================================================================== |
| --- sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart (revision 29362) |
| +++ sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart (working copy) |
| @@ -479,8 +479,25 @@ |
| Iterable<Element> oldTargets = targets; |
| Selector typedSelector = computeTypedSelector(inferrer); |
| inferrer.updateSelectorInTree(caller, call, typedSelector); |
| - targets = inferrer.compiler.world.allFunctions.filter(typedSelector); |
| + Compiler compiler = inferrer.compiler; |
| + TypeMask mask = typedSelector.mask == null |
| + ? inferrer.compiler.typesTask.dynamicType |
| + : typedSelector.mask; |
| + |
| + bool canReachAll = compiler.enabledInvokeOn |
|
kasperl
2013/10/29 08:35:27
Move this code to the selector? Maybe it could be
ngeoffray
2013/10/29 09:19:28
Done.
|
| + && mask.needsNoSuchMethodHandling(typedSelector, compiler); |
| + |
| + // If this call could potentially reach all methods that satisfy |
| + // the untyped selector (through noSuchMethod's `InvocationMirror` |
|
kasperl
2013/10/29 08:35:27
InvocationMirror -> Invocation.
kasperl
2013/10/29 08:35:27
InvocationMirror -> Invocation.
ngeoffray
2013/10/29 09:19:28
Done.
ngeoffray
2013/10/29 09:19:28
Done.
|
| + // and a call to `delegate`), we iterate over all these methods to |
| + // update their parameter types. |
| + Selector selectorToUse = canReachAll ? selector.asUntyped : typedSelector; |
| + targets = compiler.world.allFunctions.filter(selectorToUse); |
| + Iterable<Element> typedTargets = canReachAll |
| + ? compiler.world.allFunctions.filter(typedSelector) |
| + : targets; |
| + |
| // Walk over the found targets, and compute the joined union type mask |
| // for all these targets. |
| TypeMask newType = inferrer.types.joinTypeMasks(targets.map((element) { |
| @@ -493,6 +510,14 @@ |
| this, element, arguments, typedSelector, remove: false); |
| } |
| + // If [canReachAll] is true, then we are iterating over all |
| + // targets that satisfy the untyped selector. We skip the return |
| + // type of the targets that can only be reached through |
| + // `InvocationMirror.delegate`. |
|
kasperl
2013/10/29 08:35:27
InvocationMirror -> Invocation.
kasperl
2013/10/29 08:35:27
So the return type for those is covered because th
ngeoffray
2013/10/29 09:19:28
Done.
ngeoffray
2013/10/29 09:19:28
Done.
|
| + if (canReachAll && !typedTargets.contains(element)) { |
| + return const TypeMask.nonNullEmpty(); |
| + } |
| + |
| if (returnsElementType(typedSelector)) { |
| ContainerTypeMask mask = receiver.type; |
| return mask.elementType; |
| @@ -516,6 +541,7 @@ |
| this, element, arguments, typedSelector, remove: true); |
| } |
| }); |
| + |
| return newType; |
| } |