179 * If you write code that depends on this, you do so at your own risk. |
179 * If you write code that depends on this, you do so at your own risk. |
180 * This code and its internal interfaces are subject to change or |
180 * This code and its internal interfaces are subject to change or |
181 * deletion without notice.</b> |
181 * deletion without notice.</b> |
182 */ |
182 */ |
183 public class Flow { |
183 public class Flow { |
184 protected static final Context.Key<Flow> flowKey = |
184 protected static final Context.Key<Flow> flowKey = new Context.Key<>(); |
185 new Context.Key<Flow>(); |
|
186 |
185 |
187 private final Names names; |
186 private final Names names; |
188 private final Log log; |
187 private final Log log; |
189 private final Symtab syms; |
188 private final Symtab syms; |
190 private final Types types; |
189 private final Types types; |
371 return resolved; |
370 return resolved; |
372 } |
371 } |
373 |
372 |
374 /** Resolve all continues of this statement. */ |
373 /** Resolve all continues of this statement. */ |
375 boolean resolveContinues(JCTree tree) { |
374 boolean resolveContinues(JCTree tree) { |
376 return resolveJump(tree, new ListBuffer<P>(), JumpKind.CONTINUE); |
375 return resolveJump(tree, new ListBuffer<>(), JumpKind.CONTINUE); |
377 } |
376 } |
378 |
377 |
379 /** Resolve all breaks of this statement. */ |
378 /** Resolve all breaks of this statement. */ |
380 boolean resolveBreaks(JCTree tree, ListBuffer<P> oldPendingExits) { |
379 boolean resolveBreaks(JCTree tree, ListBuffer<P> oldPendingExits) { |
381 return resolveJump(tree, oldPendingExits, JumpKind.BREAK); |
380 return resolveJump(tree, oldPendingExits, JumpKind.BREAK); |
447 if (tree.sym == null) return; |
446 if (tree.sym == null) return; |
448 boolean alivePrev = alive; |
447 boolean alivePrev = alive; |
449 ListBuffer<PendingExit> pendingExitsPrev = pendingExits; |
448 ListBuffer<PendingExit> pendingExitsPrev = pendingExits; |
450 Lint lintPrev = lint; |
449 Lint lintPrev = lint; |
451 |
450 |
452 pendingExits = new ListBuffer<PendingExit>(); |
451 pendingExits = new ListBuffer<>(); |
453 lint = lint.augment(tree.sym); |
452 lint = lint.augment(tree.sym); |
454 |
453 |
455 try { |
454 try { |
456 // process all the static initializers |
455 // process all the static initializers |
457 for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) { |
456 for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) { |
496 |
495 |
497 if (alive && !tree.sym.type.getReturnType().hasTag(VOID)) |
496 if (alive && !tree.sym.type.getReturnType().hasTag(VOID)) |
498 log.error(TreeInfo.diagEndPos(tree.body), "missing.ret.stmt"); |
497 log.error(TreeInfo.diagEndPos(tree.body), "missing.ret.stmt"); |
499 |
498 |
500 List<PendingExit> exits = pendingExits.toList(); |
499 List<PendingExit> exits = pendingExits.toList(); |
501 pendingExits = new ListBuffer<PendingExit>(); |
500 pendingExits = new ListBuffer<>(); |
502 while (exits.nonEmpty()) { |
501 while (exits.nonEmpty()) { |
503 PendingExit exit = exits.head; |
502 PendingExit exit = exits.head; |
504 exits = exits.tail; |
503 exits = exits.tail; |
505 Assert.check(exit.tree.hasTag(RETURN)); |
504 Assert.check(exit.tree.hasTag(RETURN)); |
506 } |
505 } |
525 scanStats(tree.stats); |
524 scanStats(tree.stats); |
526 } |
525 } |
527 |
526 |
528 public void visitDoLoop(JCDoWhileLoop tree) { |
527 public void visitDoLoop(JCDoWhileLoop tree) { |
529 ListBuffer<PendingExit> prevPendingExits = pendingExits; |
528 ListBuffer<PendingExit> prevPendingExits = pendingExits; |
530 pendingExits = new ListBuffer<PendingExit>(); |
529 pendingExits = new ListBuffer<>(); |
531 scanStat(tree.body); |
530 scanStat(tree.body); |
532 alive |= resolveContinues(tree); |
531 alive |= resolveContinues(tree); |
533 scan(tree.cond); |
532 scan(tree.cond); |
534 alive = alive && !tree.cond.type.isTrue(); |
533 alive = alive && !tree.cond.type.isTrue(); |
535 alive |= resolveBreaks(tree, prevPendingExits); |
534 alive |= resolveBreaks(tree, prevPendingExits); |
536 } |
535 } |
537 |
536 |
538 public void visitWhileLoop(JCWhileLoop tree) { |
537 public void visitWhileLoop(JCWhileLoop tree) { |
539 ListBuffer<PendingExit> prevPendingExits = pendingExits; |
538 ListBuffer<PendingExit> prevPendingExits = pendingExits; |
540 pendingExits = new ListBuffer<PendingExit>(); |
539 pendingExits = new ListBuffer<>(); |
541 scan(tree.cond); |
540 scan(tree.cond); |
542 alive = !tree.cond.type.isFalse(); |
541 alive = !tree.cond.type.isFalse(); |
543 scanStat(tree.body); |
542 scanStat(tree.body); |
544 alive |= resolveContinues(tree); |
543 alive |= resolveContinues(tree); |
545 alive = resolveBreaks(tree, prevPendingExits) || |
544 alive = resolveBreaks(tree, prevPendingExits) || |
547 } |
546 } |
548 |
547 |
549 public void visitForLoop(JCForLoop tree) { |
548 public void visitForLoop(JCForLoop tree) { |
550 ListBuffer<PendingExit> prevPendingExits = pendingExits; |
549 ListBuffer<PendingExit> prevPendingExits = pendingExits; |
551 scanStats(tree.init); |
550 scanStats(tree.init); |
552 pendingExits = new ListBuffer<PendingExit>(); |
551 pendingExits = new ListBuffer<>(); |
553 if (tree.cond != null) { |
552 if (tree.cond != null) { |
554 scan(tree.cond); |
553 scan(tree.cond); |
555 alive = !tree.cond.type.isFalse(); |
554 alive = !tree.cond.type.isFalse(); |
556 } else { |
555 } else { |
557 alive = true; |
556 alive = true; |
565 |
564 |
566 public void visitForeachLoop(JCEnhancedForLoop tree) { |
565 public void visitForeachLoop(JCEnhancedForLoop tree) { |
567 visitVarDef(tree.var); |
566 visitVarDef(tree.var); |
568 ListBuffer<PendingExit> prevPendingExits = pendingExits; |
567 ListBuffer<PendingExit> prevPendingExits = pendingExits; |
569 scan(tree.expr); |
568 scan(tree.expr); |
570 pendingExits = new ListBuffer<PendingExit>(); |
569 pendingExits = new ListBuffer<>(); |
571 scanStat(tree.body); |
570 scanStat(tree.body); |
572 alive |= resolveContinues(tree); |
571 alive |= resolveContinues(tree); |
573 resolveBreaks(tree, prevPendingExits); |
572 resolveBreaks(tree, prevPendingExits); |
574 alive = true; |
573 alive = true; |
575 } |
574 } |
576 |
575 |
577 public void visitLabelled(JCLabeledStatement tree) { |
576 public void visitLabelled(JCLabeledStatement tree) { |
578 ListBuffer<PendingExit> prevPendingExits = pendingExits; |
577 ListBuffer<PendingExit> prevPendingExits = pendingExits; |
579 pendingExits = new ListBuffer<PendingExit>(); |
578 pendingExits = new ListBuffer<>(); |
580 scanStat(tree.body); |
579 scanStat(tree.body); |
581 alive |= resolveBreaks(tree, prevPendingExits); |
580 alive |= resolveBreaks(tree, prevPendingExits); |
582 } |
581 } |
583 |
582 |
584 public void visitSwitch(JCSwitch tree) { |
583 public void visitSwitch(JCSwitch tree) { |
585 ListBuffer<PendingExit> prevPendingExits = pendingExits; |
584 ListBuffer<PendingExit> prevPendingExits = pendingExits; |
586 pendingExits = new ListBuffer<PendingExit>(); |
585 pendingExits = new ListBuffer<>(); |
587 scan(tree.selector); |
586 scan(tree.selector); |
588 boolean hasDefault = false; |
587 boolean hasDefault = false; |
589 for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) { |
588 for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) { |
590 alive = true; |
589 alive = true; |
591 JCCase c = l.head; |
590 JCCase c = l.head; |
608 alive |= resolveBreaks(tree, prevPendingExits); |
607 alive |= resolveBreaks(tree, prevPendingExits); |
609 } |
608 } |
610 |
609 |
611 public void visitTry(JCTry tree) { |
610 public void visitTry(JCTry tree) { |
612 ListBuffer<PendingExit> prevPendingExits = pendingExits; |
611 ListBuffer<PendingExit> prevPendingExits = pendingExits; |
613 pendingExits = new ListBuffer<PendingExit>(); |
612 pendingExits = new ListBuffer<>(); |
614 for (JCTree resource : tree.resources) { |
613 for (JCTree resource : tree.resources) { |
615 if (resource instanceof JCVariableDecl) { |
614 if (resource instanceof JCVariableDecl) { |
616 JCVariableDecl vdecl = (JCVariableDecl) resource; |
615 JCVariableDecl vdecl = (JCVariableDecl) resource; |
617 visitVarDef(vdecl); |
616 visitVarDef(vdecl); |
618 } else if (resource instanceof JCExpression) { |
617 } else if (resource instanceof JCExpression) { |
739 } |
738 } |
740 public void analyzeTree(Env<AttrContext> env, JCTree tree, TreeMaker make) { |
739 public void analyzeTree(Env<AttrContext> env, JCTree tree, TreeMaker make) { |
741 try { |
740 try { |
742 attrEnv = env; |
741 attrEnv = env; |
743 Flow.this.make = make; |
742 Flow.this.make = make; |
744 pendingExits = new ListBuffer<PendingExit>(); |
743 pendingExits = new ListBuffer<>(); |
745 alive = true; |
744 alive = true; |
746 scan(tree); |
745 scan(tree); |
747 } finally { |
746 } finally { |
748 pendingExits = null; |
747 pendingExits = null; |
749 Flow.this.make = null; |
748 Flow.this.make = null; |
844 List<Type> thrownPrev = thrown; |
843 List<Type> thrownPrev = thrown; |
845 List<Type> caughtPrev = caught; |
844 List<Type> caughtPrev = caught; |
846 ListBuffer<FlowPendingExit> pendingExitsPrev = pendingExits; |
845 ListBuffer<FlowPendingExit> pendingExitsPrev = pendingExits; |
847 Lint lintPrev = lint; |
846 Lint lintPrev = lint; |
848 |
847 |
849 pendingExits = new ListBuffer<FlowPendingExit>(); |
848 pendingExits = new ListBuffer<>(); |
850 if (tree.name != names.empty) { |
849 if (tree.name != names.empty) { |
851 caught = List.nil(); |
850 caught = List.nil(); |
852 } |
851 } |
853 classDef = tree; |
852 classDef = tree; |
854 thrown = List.nil(); |
853 thrown = List.nil(); |
949 // leave caught unchanged. |
948 // leave caught unchanged. |
950 |
949 |
951 scan(tree.body); |
950 scan(tree.body); |
952 |
951 |
953 List<FlowPendingExit> exits = pendingExits.toList(); |
952 List<FlowPendingExit> exits = pendingExits.toList(); |
954 pendingExits = new ListBuffer<FlowPendingExit>(); |
953 pendingExits = new ListBuffer<>(); |
955 while (exits.nonEmpty()) { |
954 while (exits.nonEmpty()) { |
956 FlowPendingExit exit = exits.head; |
955 FlowPendingExit exit = exits.head; |
957 exits = exits.tail; |
956 exits = exits.tail; |
958 if (exit.thrown == null) { |
957 if (exit.thrown == null) { |
959 Assert.check(exit.tree.hasTag(RETURN)); |
958 Assert.check(exit.tree.hasTag(RETURN)); |
984 scan(tree.stats); |
983 scan(tree.stats); |
985 } |
984 } |
986 |
985 |
987 public void visitDoLoop(JCDoWhileLoop tree) { |
986 public void visitDoLoop(JCDoWhileLoop tree) { |
988 ListBuffer<FlowPendingExit> prevPendingExits = pendingExits; |
987 ListBuffer<FlowPendingExit> prevPendingExits = pendingExits; |
989 pendingExits = new ListBuffer<FlowPendingExit>(); |
988 pendingExits = new ListBuffer<>(); |
990 scan(tree.body); |
989 scan(tree.body); |
991 resolveContinues(tree); |
990 resolveContinues(tree); |
992 scan(tree.cond); |
991 scan(tree.cond); |
993 resolveBreaks(tree, prevPendingExits); |
992 resolveBreaks(tree, prevPendingExits); |
994 } |
993 } |
995 |
994 |
996 public void visitWhileLoop(JCWhileLoop tree) { |
995 public void visitWhileLoop(JCWhileLoop tree) { |
997 ListBuffer<FlowPendingExit> prevPendingExits = pendingExits; |
996 ListBuffer<FlowPendingExit> prevPendingExits = pendingExits; |
998 pendingExits = new ListBuffer<FlowPendingExit>(); |
997 pendingExits = new ListBuffer<>(); |
999 scan(tree.cond); |
998 scan(tree.cond); |
1000 scan(tree.body); |
999 scan(tree.body); |
1001 resolveContinues(tree); |
1000 resolveContinues(tree); |
1002 resolveBreaks(tree, prevPendingExits); |
1001 resolveBreaks(tree, prevPendingExits); |
1003 } |
1002 } |
1004 |
1003 |
1005 public void visitForLoop(JCForLoop tree) { |
1004 public void visitForLoop(JCForLoop tree) { |
1006 ListBuffer<FlowPendingExit> prevPendingExits = pendingExits; |
1005 ListBuffer<FlowPendingExit> prevPendingExits = pendingExits; |
1007 scan(tree.init); |
1006 scan(tree.init); |
1008 pendingExits = new ListBuffer<FlowPendingExit>(); |
1007 pendingExits = new ListBuffer<>(); |
1009 if (tree.cond != null) { |
1008 if (tree.cond != null) { |
1010 scan(tree.cond); |
1009 scan(tree.cond); |
1011 } |
1010 } |
1012 scan(tree.body); |
1011 scan(tree.body); |
1013 resolveContinues(tree); |
1012 resolveContinues(tree); |
1017 |
1016 |
1018 public void visitForeachLoop(JCEnhancedForLoop tree) { |
1017 public void visitForeachLoop(JCEnhancedForLoop tree) { |
1019 visitVarDef(tree.var); |
1018 visitVarDef(tree.var); |
1020 ListBuffer<FlowPendingExit> prevPendingExits = pendingExits; |
1019 ListBuffer<FlowPendingExit> prevPendingExits = pendingExits; |
1021 scan(tree.expr); |
1020 scan(tree.expr); |
1022 pendingExits = new ListBuffer<FlowPendingExit>(); |
1021 pendingExits = new ListBuffer<>(); |
1023 scan(tree.body); |
1022 scan(tree.body); |
1024 resolveContinues(tree); |
1023 resolveContinues(tree); |
1025 resolveBreaks(tree, prevPendingExits); |
1024 resolveBreaks(tree, prevPendingExits); |
1026 } |
1025 } |
1027 |
1026 |
1028 public void visitLabelled(JCLabeledStatement tree) { |
1027 public void visitLabelled(JCLabeledStatement tree) { |
1029 ListBuffer<FlowPendingExit> prevPendingExits = pendingExits; |
1028 ListBuffer<FlowPendingExit> prevPendingExits = pendingExits; |
1030 pendingExits = new ListBuffer<FlowPendingExit>(); |
1029 pendingExits = new ListBuffer<>(); |
1031 scan(tree.body); |
1030 scan(tree.body); |
1032 resolveBreaks(tree, prevPendingExits); |
1031 resolveBreaks(tree, prevPendingExits); |
1033 } |
1032 } |
1034 |
1033 |
1035 public void visitSwitch(JCSwitch tree) { |
1034 public void visitSwitch(JCSwitch tree) { |
1036 ListBuffer<FlowPendingExit> prevPendingExits = pendingExits; |
1035 ListBuffer<FlowPendingExit> prevPendingExits = pendingExits; |
1037 pendingExits = new ListBuffer<FlowPendingExit>(); |
1036 pendingExits = new ListBuffer<>(); |
1038 scan(tree.selector); |
1037 scan(tree.selector); |
1039 for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) { |
1038 for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) { |
1040 JCCase c = l.head; |
1039 JCCase c = l.head; |
1041 if (c.pat != null) { |
1040 if (c.pat != null) { |
1042 scan(c.pat); |
1041 scan(c.pat); |
1058 caught = chk.incl(ct.type, caught); |
1057 caught = chk.incl(ct.type, caught); |
1059 } |
1058 } |
1060 } |
1059 } |
1061 |
1060 |
1062 ListBuffer<FlowPendingExit> prevPendingExits = pendingExits; |
1061 ListBuffer<FlowPendingExit> prevPendingExits = pendingExits; |
1063 pendingExits = new ListBuffer<FlowPendingExit>(); |
1062 pendingExits = new ListBuffer<>(); |
1064 for (JCTree resource : tree.resources) { |
1063 for (JCTree resource : tree.resources) { |
1065 if (resource instanceof JCVariableDecl) { |
1064 if (resource instanceof JCVariableDecl) { |
1066 JCVariableDecl vdecl = (JCVariableDecl) resource; |
1065 JCVariableDecl vdecl = (JCVariableDecl) resource; |
1067 visitVarDef(vdecl); |
1066 visitVarDef(vdecl); |
1068 } else if (resource instanceof JCExpression) { |
1067 } else if (resource instanceof JCExpression) { |
1268 pendingExits = new ListBuffer<>(); |
1267 pendingExits = new ListBuffer<>(); |
1269 caught = tree.getDescriptorType(types).getThrownTypes(); |
1268 caught = tree.getDescriptorType(types).getThrownTypes(); |
1270 thrown = List.nil(); |
1269 thrown = List.nil(); |
1271 scan(tree.body); |
1270 scan(tree.body); |
1272 List<FlowPendingExit> exits = pendingExits.toList(); |
1271 List<FlowPendingExit> exits = pendingExits.toList(); |
1273 pendingExits = new ListBuffer<FlowPendingExit>(); |
1272 pendingExits = new ListBuffer<>(); |
1274 while (exits.nonEmpty()) { |
1273 while (exits.nonEmpty()) { |
1275 FlowPendingExit exit = exits.head; |
1274 FlowPendingExit exit = exits.head; |
1276 exits = exits.tail; |
1275 exits = exits.tail; |
1277 if (exit.thrown == null) { |
1276 if (exit.thrown == null) { |
1278 Assert.check(exit.tree.hasTag(RETURN)); |
1277 Assert.check(exit.tree.hasTag(RETURN)); |
1305 } |
1304 } |
1306 public void analyzeTree(Env<AttrContext> env, JCTree tree, TreeMaker make) { |
1305 public void analyzeTree(Env<AttrContext> env, JCTree tree, TreeMaker make) { |
1307 try { |
1306 try { |
1308 attrEnv = env; |
1307 attrEnv = env; |
1309 Flow.this.make = make; |
1308 Flow.this.make = make; |
1310 pendingExits = new ListBuffer<FlowPendingExit>(); |
1309 pendingExits = new ListBuffer<>(); |
1311 preciseRethrowTypes = new HashMap<Symbol, List<Type>>(); |
1310 preciseRethrowTypes = new HashMap<>(); |
1312 this.thrown = this.caught = null; |
1311 this.thrown = this.caught = null; |
1313 this.classDef = null; |
1312 this.classDef = null; |
1314 scan(tree); |
1313 scan(tree); |
1315 } finally { |
1314 } finally { |
1316 pendingExits = null; |
1315 pendingExits = null; |
1649 JCClassDecl classDefPrev = classDef; |
1648 JCClassDecl classDefPrev = classDef; |
1650 int firstadrPrev = firstadr; |
1649 int firstadrPrev = firstadr; |
1651 int nextadrPrev = nextadr; |
1650 int nextadrPrev = nextadr; |
1652 ListBuffer<P> pendingExitsPrev = pendingExits; |
1651 ListBuffer<P> pendingExitsPrev = pendingExits; |
1653 |
1652 |
1654 pendingExits = new ListBuffer<P>(); |
1653 pendingExits = new ListBuffer<>(); |
1655 if (tree.name != names.empty) { |
1654 if (tree.name != names.empty) { |
1656 firstadr = nextadr; |
1655 firstadr = nextadr; |
1657 } |
1656 } |
1658 classDef = tree; |
1657 classDef = tree; |
1659 try { |
1658 try { |
1824 ListBuffer<P> prevPendingExits = pendingExits; |
1823 ListBuffer<P> prevPendingExits = pendingExits; |
1825 FlowKind prevFlowKind = flowKind; |
1824 FlowKind prevFlowKind = flowKind; |
1826 flowKind = FlowKind.NORMAL; |
1825 flowKind = FlowKind.NORMAL; |
1827 final Bits initsSkip = new Bits(true); |
1826 final Bits initsSkip = new Bits(true); |
1828 final Bits uninitsSkip = new Bits(true); |
1827 final Bits uninitsSkip = new Bits(true); |
1829 pendingExits = new ListBuffer<P>(); |
1828 pendingExits = new ListBuffer<>(); |
1830 int prevErrors = getLogNumberOfErrors(); |
1829 int prevErrors = getLogNumberOfErrors(); |
1831 do { |
1830 do { |
1832 final Bits uninitsEntry = new Bits(uninits); |
1831 final Bits uninitsEntry = new Bits(uninits); |
1833 uninitsEntry.excludeFrom(nextadr); |
1832 uninitsEntry.excludeFrom(nextadr); |
1834 scan(tree.body); |
1833 scan(tree.body); |
1894 flowKind = FlowKind.NORMAL; |
1893 flowKind = FlowKind.NORMAL; |
1895 int nextadrPrev = nextadr; |
1894 int nextadrPrev = nextadr; |
1896 scan(tree.init); |
1895 scan(tree.init); |
1897 final Bits initsSkip = new Bits(true); |
1896 final Bits initsSkip = new Bits(true); |
1898 final Bits uninitsSkip = new Bits(true); |
1897 final Bits uninitsSkip = new Bits(true); |
1899 pendingExits = new ListBuffer<P>(); |
1898 pendingExits = new ListBuffer<>(); |
1900 int prevErrors = getLogNumberOfErrors(); |
1899 int prevErrors = getLogNumberOfErrors(); |
1901 do { |
1900 do { |
1902 final Bits uninitsEntry = new Bits(uninits); |
1901 final Bits uninitsEntry = new Bits(uninits); |
1903 uninitsEntry.excludeFrom(nextadr); |
1902 uninitsEntry.excludeFrom(nextadr); |
1904 if (tree.cond != null) { |
1903 if (tree.cond != null) { |
1944 scan(tree.expr); |
1943 scan(tree.expr); |
1945 final Bits initsStart = new Bits(inits); |
1944 final Bits initsStart = new Bits(inits); |
1946 final Bits uninitsStart = new Bits(uninits); |
1945 final Bits uninitsStart = new Bits(uninits); |
1947 |
1946 |
1948 letInit(tree.pos(), tree.var.sym); |
1947 letInit(tree.pos(), tree.var.sym); |
1949 pendingExits = new ListBuffer<P>(); |
1948 pendingExits = new ListBuffer<>(); |
1950 int prevErrors = getLogNumberOfErrors(); |
1949 int prevErrors = getLogNumberOfErrors(); |
1951 do { |
1950 do { |
1952 final Bits uninitsEntry = new Bits(uninits); |
1951 final Bits uninitsEntry = new Bits(uninits); |
1953 uninitsEntry.excludeFrom(nextadr); |
1952 uninitsEntry.excludeFrom(nextadr); |
1954 scan(tree.body); |
1953 scan(tree.body); |
1967 nextadr = nextadrPrev; |
1966 nextadr = nextadrPrev; |
1968 } |
1967 } |
1969 |
1968 |
1970 public void visitLabelled(JCLabeledStatement tree) { |
1969 public void visitLabelled(JCLabeledStatement tree) { |
1971 ListBuffer<P> prevPendingExits = pendingExits; |
1970 ListBuffer<P> prevPendingExits = pendingExits; |
1972 pendingExits = new ListBuffer<P>(); |
1971 pendingExits = new ListBuffer<>(); |
1973 scan(tree.body); |
1972 scan(tree.body); |
1974 resolveBreaks(tree, prevPendingExits); |
1973 resolveBreaks(tree, prevPendingExits); |
1975 } |
1974 } |
1976 |
1975 |
1977 public void visitSwitch(JCSwitch tree) { |
1976 public void visitSwitch(JCSwitch tree) { |
2217 final Bits prevInits = new Bits(inits); |
2216 final Bits prevInits = new Bits(inits); |
2218 int returnadrPrev = returnadr; |
2217 int returnadrPrev = returnadr; |
2219 ListBuffer<P> prevPending = pendingExits; |
2218 ListBuffer<P> prevPending = pendingExits; |
2220 try { |
2219 try { |
2221 returnadr = nextadr; |
2220 returnadr = nextadr; |
2222 pendingExits = new ListBuffer<P>(); |
2221 pendingExits = new ListBuffer<>(); |
2223 for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) { |
2222 for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) { |
2224 JCVariableDecl def = l.head; |
2223 JCVariableDecl def = l.head; |
2225 scan(def); |
2224 scan(def); |
2226 inits.incl(def.sym.adr); |
2225 inits.incl(def.sym.adr); |
2227 uninits.excl(def.sym.adr); |
2226 uninits.excl(def.sym.adr); |
2674 } |
2673 } |
2675 public void analyzeTree(Env<AttrContext> env, JCTree tree, TreeMaker make) { |
2674 public void analyzeTree(Env<AttrContext> env, JCTree tree, TreeMaker make) { |
2676 try { |
2675 try { |
2677 attrEnv = env; |
2676 attrEnv = env; |
2678 Flow.this.make = make; |
2677 Flow.this.make = make; |
2679 pendingExits = new ListBuffer<PendingExit>(); |
2678 pendingExits = new ListBuffer<>(); |
2680 scan(tree); |
2679 scan(tree); |
2681 } finally { |
2680 } finally { |
2682 pendingExits = null; |
2681 pendingExits = null; |
2683 Flow.this.make = null; |
2682 Flow.this.make = null; |
2684 } |
2683 } |