Index: pkg/analyzer/lib/src/generated/resolver.dart |
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart |
index 239522b70d60a296032bbb8643df73d4246c8e3c..3f6b4a814a9ba567687170cf8bd8eb0e197bf9b8 100644 |
--- a/pkg/analyzer/lib/src/generated/resolver.dart |
+++ b/pkg/analyzer/lib/src/generated/resolver.dart |
@@ -18648,6 +18648,9 @@ class ResolverVisitor extends ScopedVisitor { |
_overrideManager.applyOverrides(elseOverrides); |
} |
} |
+ // TODO(collinsn): union the [thenOverrides] and [elseOverrides] if both branches |
+ // are not abrupt. If both branches are abrupt, then we can mark the |
+ // remaining code as dead. |
return null; |
} |
@@ -19151,7 +19154,16 @@ class ResolverVisitor extends ScopedVisitor { |
// TODO(brianwilkerson) This needs to be significantly improved. Ideally we would eventually |
// turn this into a method on Statement that returns a termination indication (normal, abrupt |
// with no exception, abrupt with an exception). |
- if (statement is ReturnStatement || statement is BreakStatement || statement is ContinueStatement) { |
+ // |
+ // collinsn: it is unsound to assume that [break] and [continue] are "abrupt". |
+ // See: https://code.google.com/p/dart/issues/detail?id=19929#c4 (tests are |
+ // included in TypePropagationTest.java). |
+ // In general, the difficulty is loopy control flow. |
+ // |
+ // In the presence of exceptions things become much more complicated, but while |
+ // we only use this to propagate at [if]-statement join points, checking for [return] |
+ // is probably sound. |
+ if (statement is ReturnStatement) { |
return true; |
} else if (statement is ExpressionStatement) { |
return _isAbruptTerminationExpression(statement.expression); |