253 } finally { |
253 } finally { |
254 log.popDiagnosticHandler(diagHandler); |
254 log.popDiagnosticHandler(diagHandler); |
255 } |
255 } |
256 } |
256 } |
257 |
257 |
|
258 public boolean aliveAfter(Env<AttrContext> env, JCTree that, TreeMaker make) { |
|
259 //we need to disable diagnostics temporarily; the problem is that if |
|
260 //"that" contains e.g. an unreachable statement, an error |
|
261 //message will be reported and will cause compilation to skip the flow analyis |
|
262 //step - if we suppress diagnostics, we won't stop at Attr for flow-analysis |
|
263 //related errors, which will allow for more errors to be detected |
|
264 Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log); |
|
265 try { |
|
266 SnippetAliveAnalyzer analyzer = new SnippetAliveAnalyzer(); |
|
267 |
|
268 analyzer.analyzeTree(env, that, make); |
|
269 return analyzer.isAlive(); |
|
270 } finally { |
|
271 log.popDiagnosticHandler(diagHandler); |
|
272 } |
|
273 } |
|
274 |
|
275 public boolean breaksOutOf(Env<AttrContext> env, JCTree loop, JCTree body, TreeMaker make) { |
|
276 //we need to disable diagnostics temporarily; the problem is that if |
|
277 //"that" contains e.g. an unreachable statement, an error |
|
278 //message will be reported and will cause compilation to skip the flow analyis |
|
279 //step - if we suppress diagnostics, we won't stop at Attr for flow-analysis |
|
280 //related errors, which will allow for more errors to be detected |
|
281 Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log); |
|
282 try { |
|
283 boolean[] breaksOut = new boolean[1]; |
|
284 SnippetBreakAnalyzer analyzer = new SnippetBreakAnalyzer(loop); |
|
285 |
|
286 analyzer.analyzeTree(env, body, make); |
|
287 return analyzer.breaksOut(); |
|
288 } finally { |
|
289 log.popDiagnosticHandler(diagHandler); |
|
290 } |
|
291 } |
|
292 |
258 /** |
293 /** |
259 * Definite assignment scan mode |
294 * Definite assignment scan mode |
260 */ |
295 */ |
261 enum FlowKind { |
296 enum FlowKind { |
262 /** |
297 /** |
1461 } |
1496 } |
1462 |
1497 |
1463 @Override |
1498 @Override |
1464 public void visitClassDef(JCClassDecl tree) { |
1499 public void visitClassDef(JCClassDecl tree) { |
1465 //skip |
1500 //skip |
|
1501 } |
|
1502 } |
|
1503 |
|
1504 /** |
|
1505 * Determine if alive after the given tree. |
|
1506 */ |
|
1507 class SnippetAliveAnalyzer extends AliveAnalyzer { |
|
1508 @Override |
|
1509 public void visitClassDef(JCClassDecl tree) { |
|
1510 //skip |
|
1511 } |
|
1512 public boolean isAlive() { |
|
1513 return super.alive != Liveness.DEAD; |
|
1514 } |
|
1515 } |
|
1516 |
|
1517 class SnippetBreakAnalyzer extends AliveAnalyzer { |
|
1518 private final JCTree loop; |
|
1519 private boolean breaksOut; |
|
1520 |
|
1521 public SnippetBreakAnalyzer(JCTree loop) { |
|
1522 this.loop = loop; |
|
1523 } |
|
1524 |
|
1525 @Override |
|
1526 public void visitBreak(JCBreak tree) { |
|
1527 breaksOut |= (super.alive == Liveness.ALIVE && tree.target == loop); |
|
1528 super.visitBreak(tree); |
|
1529 } |
|
1530 |
|
1531 public boolean breaksOut() { |
|
1532 return breaksOut; |
1466 } |
1533 } |
1467 } |
1534 } |
1468 |
1535 |
1469 /** |
1536 /** |
1470 * Specialized pass that performs DA/DU on a lambda |
1537 * Specialized pass that performs DA/DU on a lambda |