Chromium Code Reviews| 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 33dc56e933bfaa1926d071f466bb3efd263c306d..eb2fb9dc384a67d79f698c150a56134aaf46873d 100644 |
| --- a/pkg/analyzer/lib/src/generated/resolver.dart |
| +++ b/pkg/analyzer/lib/src/generated/resolver.dart |
| @@ -3499,6 +3499,12 @@ class ExitDetector extends GeneralizingAstVisitor<bool> { |
| bool _enclosingBlockContainsBreak = false; |
| /** |
| + * Set to `true` when a `continue` is encountered, and reset to `false` when a |
| + * `do`, `while`, `for` or `switch` block is entered. |
| + */ |
| + bool _enclosingBlockContainsContinue = false; |
| + |
| + /** |
| * Add node when a labelled `break` is encountered. |
| */ |
| Set<AstNode> _enclosingBlockBreaksLabel = new Set<AstNode>(); |
| @@ -3606,14 +3612,24 @@ class ExitDetector extends GeneralizingAstVisitor<bool> { |
| } |
| @override |
| - bool visitContinueStatement(ContinueStatement node) => false; |
| + bool visitContinueStatement(ContinueStatement node) { |
| + _enclosingBlockContainsContinue = true; |
|
Brian Wilkerson
2016/06/28 20:47:33
This is ignoring the presence or absence of a labe
|
| + return false; |
| + } |
| @override |
| bool visitDoStatement(DoStatement node) { |
| bool outerBreakValue = _enclosingBlockContainsBreak; |
| + bool outerContinueValue = _enclosingBlockContainsContinue; |
| _enclosingBlockContainsBreak = false; |
| + _enclosingBlockContainsContinue = false; |
| try { |
| - if (_nodeExits(node.body) && !_enclosingBlockContainsBreak) { |
| + bool bodyExits = _nodeExits(node.body); |
| + bool containsBreakOrContinue = |
| + _enclosingBlockContainsBreak || _enclosingBlockContainsContinue; |
| + // Even if we determine that the body "exits", there might be break or |
| + // continue statements that actually mean it _doesn't_ always exit. |
| + if (bodyExits && !containsBreakOrContinue) { |
| return true; |
| } |
| Expression conditionExpression = node.condition; |
| @@ -3630,6 +3646,7 @@ class ExitDetector extends GeneralizingAstVisitor<bool> { |
| return false; |
| } finally { |
| _enclosingBlockContainsBreak = outerBreakValue; |
| + _enclosingBlockContainsContinue = outerContinueValue; |
| } |
| } |
| @@ -3643,18 +3660,23 @@ class ExitDetector extends GeneralizingAstVisitor<bool> { |
| @override |
| bool visitForEachStatement(ForEachStatement node) { |
| bool outerBreakValue = _enclosingBlockContainsBreak; |
| + bool outerContinueValue = _enclosingBlockContainsContinue; |
| _enclosingBlockContainsBreak = false; |
| + _enclosingBlockContainsContinue = false; |
| try { |
| return _nodeExits(node.iterable); |
| } finally { |
| _enclosingBlockContainsBreak = outerBreakValue; |
| + _enclosingBlockContainsContinue = outerContinueValue; |
| } |
| } |
| @override |
| bool visitForStatement(ForStatement node) { |
| bool outerBreakValue = _enclosingBlockContainsBreak; |
| + bool outerContinueValue = _enclosingBlockContainsContinue; |
| _enclosingBlockContainsBreak = false; |
| + _enclosingBlockContainsContinue = false; |
| try { |
| if (node.variables != null && |
| _visitVariableDeclarations(node.variables.variables)) { |
| @@ -3684,6 +3706,7 @@ class ExitDetector extends GeneralizingAstVisitor<bool> { |
| return false; |
| } finally { |
| _enclosingBlockContainsBreak = outerBreakValue; |
| + _enclosingBlockContainsContinue = outerContinueValue; |
| } |
| } |
| @@ -3909,7 +3932,9 @@ class ExitDetector extends GeneralizingAstVisitor<bool> { |
| @override |
| bool visitWhileStatement(WhileStatement node) { |
| bool outerBreakValue = _enclosingBlockContainsBreak; |
| + bool outerContinueValue = _enclosingBlockContainsContinue; |
| _enclosingBlockContainsBreak = false; |
| + _enclosingBlockContainsContinue = false; |
| try { |
| Expression conditionExpression = node.condition; |
| if (conditionExpression.accept(this)) { |
| @@ -3936,6 +3961,7 @@ class ExitDetector extends GeneralizingAstVisitor<bool> { |
| return false; |
| } finally { |
| _enclosingBlockContainsBreak = outerBreakValue; |
| + _enclosingBlockContainsContinue = outerContinueValue; |
| } |
| } |