Chromium Code Reviews| Index: pkg/compiler/lib/src/inferrer/inferrer_visitor.dart |
| diff --git a/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart b/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart |
| index fa961f2390b2c1879b8fd53e5cd7be2488b84228..3314fcdc308d712e688d8c76ee43aebfc308ae1f 100644 |
| --- a/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart |
| +++ b/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart |
| @@ -115,8 +115,12 @@ abstract class TypeSystem<T> { |
| /** |
| * Returns a new receiver type for this [selector] applied to |
| * [receiverType]. |
| + * |
| + * The option [isConditional] is true when [selector] was seen in a |
| + * conditional send (e.g. `a?.selector`), in which case the returned type may |
| + * be null. |
| */ |
| - T refineReceiver(Selector selector, T receiverType); |
| + T refineReceiver(Selector selector, T receiverType, bool isConditional); |
| /** |
| * Returns the internal inferrer representation for [mask]. |
| @@ -441,6 +445,13 @@ class LocalsHandler<T> { |
| } |
| updateLocal() { |
| T currentType = locals[local]; |
| + |
| + SendSet send = node != null ? node.asSendSet() : null; |
|
sra1
2015/05/22 21:17:28
node?.asSendSet()
:-)
Siggi Cherem (dart-lang)
2015/05/22 22:36:08
once the vm has it, we should totally use it :)
|
| + if (send != null && send.isIfNullAssignment && currentType != null) { |
| + // If-null assignments may return either the new or the original value. |
| + type = types.addPhiInput( |
| + local, types.allocatePhi(locals.block, local, currentType), type); |
| + } |
| locals[local] = type; |
| if (currentType != type) { |
| inferrer.recordLocalUpdate(local, type); |
| @@ -988,6 +999,16 @@ abstract class InferrerVisitor |
| } |
| @override |
| + T visitIfNotNullDynamicPropertyInvoke( |
| + Send node, |
| + Node receiver, |
| + NodeList arguments, |
| + Selector selector, |
| + _) { |
| + return handleDynamicInvoke(node); |
| + } |
| + |
| + @override |
| T visitThisPropertyInvoke( |
| Send node, |
| NodeList arguments, |
| @@ -997,6 +1018,13 @@ abstract class InferrerVisitor |
| } |
| @override |
| + T visitIfNull(Send node, Node left, Node right, _) { |
| + T firstType = visit(left); |
| + T secondType = visit(right); |
| + return types.allocateDiamondPhi(firstType, secondType); |
| + } |
| + |
| + @override |
| T visitLogicalAnd(Send node, Node left, Node right, _) { |
| conditionIsSimple = false; |
| bool oldAccumulateIsChecks = accumulateIsChecks; |