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 c820a6c5eb6268c8c8e9d4bcca282b21f1fe4081..24948efa7901cd2791c0dba17c9699df025f3af3 100644 |
--- a/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart |
+++ b/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart |
@@ -9,6 +9,7 @@ import '../constants/expressions.dart'; |
import '../dart2jslib.dart' hide Selector, TypedSelector; |
import '../dart_types.dart'; |
import '../elements/elements.dart'; |
+import '../resolution/operators.dart'; |
import '../tree/tree.dart'; |
import '../universe/universe.dart'; |
import '../util/util.dart'; |
@@ -983,87 +984,114 @@ abstract class InferrerVisitor |
} |
} |
- T visitOperatorSend(Send node) { |
- Operator op = node.selector; |
- if ("[]" == op.source) { |
- return visitDynamicSend(node); |
- } else if ("&&" == op.source) { |
- conditionIsSimple = false; |
- bool oldAccumulateIsChecks = accumulateIsChecks; |
- List<Send> oldIsChecks = isChecks; |
- if (!accumulateIsChecks) { |
- accumulateIsChecks = true; |
- isChecks = <Send>[]; |
- } |
- visit(node.receiver); |
- LocalsHandler<T> saved = locals; |
- locals = new LocalsHandler<T>.from(locals, node); |
- updateIsChecks(isChecks, usePositive: true); |
- LocalsHandler<T> narrowed; |
- if (oldAccumulateIsChecks) { |
- narrowed = new LocalsHandler<T>.topLevelCopyOf(locals); |
- } else { |
- accumulateIsChecks = false; |
- isChecks = oldIsChecks; |
- } |
- visit(node.arguments.head); |
- if (oldAccumulateIsChecks) { |
+ @override |
+ T visitIndex(Send node, Node receiver, Node index, _) { |
+ return visitDynamicSend(node); |
+ } |
- bool invalidatedInRightHandSide (Send test) { |
- Element receiver = elements[test.receiver]; |
- if (receiver is LocalElement) { |
- return narrowed.locals[receiver] != locals.locals[receiver]; |
- } |
- return false; |
- } |
+ @override |
+ T visitLogicalAnd(Send node, Node left, Node right, _) { |
+ conditionIsSimple = false; |
+ bool oldAccumulateIsChecks = accumulateIsChecks; |
+ List<Send> oldIsChecks = isChecks; |
+ if (!accumulateIsChecks) { |
+ accumulateIsChecks = true; |
+ isChecks = <Send>[]; |
+ } |
+ visit(left); |
+ LocalsHandler<T> saved = locals; |
+ locals = new LocalsHandler<T>.from(locals, node); |
+ updateIsChecks(isChecks, usePositive: true); |
+ LocalsHandler<T> narrowed; |
+ if (oldAccumulateIsChecks) { |
+ narrowed = new LocalsHandler<T>.topLevelCopyOf(locals); |
+ } else { |
+ accumulateIsChecks = false; |
+ isChecks = oldIsChecks; |
+ } |
+ visit(right); |
+ if (oldAccumulateIsChecks) { |
- isChecks.removeWhere(invalidatedInRightHandSide); |
+ bool invalidatedInRightHandSide (Send test) { |
+ Element receiver = elements[test.receiver]; |
+ if (receiver is LocalElement) { |
+ return narrowed.locals[receiver] != locals.locals[receiver]; |
+ } |
+ return false; |
} |
- saved.mergeDiamondFlow(locals, null); |
- locals = saved; |
- return types.boolType; |
- } else if ("||" == op.source) { |
- conditionIsSimple = false; |
- List<Send> tests = <Send>[]; |
- bool isSimple = handleCondition(node.receiver, tests); |
- LocalsHandler<T> saved = locals; |
- locals = new LocalsHandler<T>.from(locals, node); |
- if (isSimple) updateIsChecks(tests, usePositive: false); |
- bool oldAccumulateIsChecks = accumulateIsChecks; |
- accumulateIsChecks = false; |
- visit(node.arguments.head); |
- accumulateIsChecks = oldAccumulateIsChecks; |
- saved.mergeDiamondFlow(locals, null); |
- locals = saved; |
- return types.boolType; |
- } else if ("!" == op.source) { |
- bool oldAccumulateIsChecks = accumulateIsChecks; |
- accumulateIsChecks = false; |
- node.visitChildren(this); |
- accumulateIsChecks = oldAccumulateIsChecks; |
- return types.boolType; |
- } else if ("is" == op.source) { |
- potentiallyAddIsCheck(node); |
- node.visitChildren(this); |
- return types.boolType; |
- } else if ("as" == op.source) { |
- T receiverType = visit(node.receiver); |
- DartType type = elements.getType(node.arguments.head); |
- return types.narrowType(receiverType, type); |
- } else if (node.argumentsNode is Prefix) { |
- // Unary operator. |
- return visitDynamicSend(node); |
- } else if ('===' == op.source |
- || '!==' == op.source) { |
- node.visitChildren(this); |
- return types.boolType; |
- } else if ('!=' == op.source) { |
- visitDynamicSend(node); |
- return types.boolType; |
- } else { |
- // Binary operator. |
- return visitDynamicSend(node); |
+ |
+ isChecks.removeWhere(invalidatedInRightHandSide); |
} |
+ saved.mergeDiamondFlow(locals, null); |
+ locals = saved; |
+ return types.boolType; |
+ } |
+ |
+ @override |
+ T visitLogicalOr(Send node, Node left, Node right, _) { |
+ conditionIsSimple = false; |
+ List<Send> tests = <Send>[]; |
+ bool isSimple = handleCondition(left, tests); |
+ LocalsHandler<T> saved = locals; |
+ locals = new LocalsHandler<T>.from(locals, node); |
+ if (isSimple) updateIsChecks(tests, usePositive: false); |
+ bool oldAccumulateIsChecks = accumulateIsChecks; |
+ accumulateIsChecks = false; |
+ visit(right); |
+ accumulateIsChecks = oldAccumulateIsChecks; |
+ saved.mergeDiamondFlow(locals, null); |
+ locals = saved; |
+ return types.boolType; |
+ } |
+ |
+ @override |
+ T visitNot(Send node, Node expression, _) { |
+ bool oldAccumulateIsChecks = accumulateIsChecks; |
+ accumulateIsChecks = false; |
+ visit(expression); |
+ accumulateIsChecks = oldAccumulateIsChecks; |
+ return types.boolType; |
+ } |
+ |
+ @override |
+ T visitIs(Send node, Node expression, DartType type, _) { |
+ potentiallyAddIsCheck(node); |
+ visit(expression); |
+ return types.boolType; |
+ } |
+ |
+ @override |
+ T visitIsNot(Send node, Node expression, DartType type, _) { |
+ potentiallyAddIsCheck(node); |
+ visit(expression); |
+ return types.boolType; |
+ } |
+ |
+ @override |
+ T visitAs(Send node, Node expression, DartType type, _) { |
+ T receiverType = visit(expression); |
+ return types.narrowType(receiverType, type); |
+ } |
+ |
+ @override |
+ T visitUnary(Send node, UnaryOperator operator, Node expression, _) { |
+ return visitDynamicSend(node); |
+ } |
+ |
+ @override |
+ T visitNotEquals(Send node, Node left, Node right, _) { |
+ visitDynamicSend(node); |
+ return types.boolType; |
+ } |
+ |
+ @override |
+ T visitEquals(Send node, Node left, Node right, _) { |
+ return visitDynamicSend(node); |
+ } |
+ |
+ @override |
+ T visitBinary(Send node, Node left, BinaryOperator operator, Node right, _) { |
+ return visitDynamicSend(node); |
} |
// Because some nodes just visit their children, we may end up |
@@ -1305,7 +1333,7 @@ abstract class InferrerVisitor |
return null; |
} |
- void internalError(Spannable node, String reason) { |
+ internalError(Spannable node, String reason) { |
compiler.internalError(node, reason); |
} |