1717
1818import org .jspecify .annotations .Nullable ;
1919
20+ import java .util .function .Supplier ;
21+
2022public class Repeat {
2123
2224 /**
@@ -29,20 +31,25 @@ public static TreeVisitor<?, ExecutionContext> repeatUntilStable(TreeVisitor<?,
2931 return repeatUntilStable (v , 3 );
3032 }
3133
34+ public static TreeVisitor <?, ExecutionContext > repeatUntilStable (Supplier <TreeVisitor <?, ExecutionContext >> v ) {
35+ return repeatUntilStable (v , 3 );
36+ }
37+
3238 /**
3339 * Returns a new visitor which runs the supplied visitor in a loop until no more changes are made, or the maximum
3440 * number of cycles is reached.
3541 * Convenient when a visitor is designed to recursively apply itself to a tree to achieve its desired result.
3642 * Stops early if the visitor ceases to make changes to the tree before the maximum number of cycles is reached.
3743 */
3844 public static TreeVisitor <?, ExecutionContext > repeatUntilStable (TreeVisitor <?, ExecutionContext > v , int maxCycles ) {
45+ return repeatUntilStable (() -> v , maxCycles );
46+ }
47+
48+ public static TreeVisitor <?, ExecutionContext > repeatUntilStable (Supplier <TreeVisitor <?, ExecutionContext >> vp , int maxCycles ) {
3949 return new TreeVisitor <Tree , ExecutionContext >() {
50+
4051 @ Override
4152 public @ Nullable Tree visit (@ Nullable Tree tree , ExecutionContext ctx ) {
42- if (tree instanceof SourceFile && !v .isAcceptable ((SourceFile ) tree , ctx )) {
43- return tree ;
44- }
45-
4653 if (tree != null && !(tree instanceof SourceFile ) && getCursor ().isRoot ()) {
4754 throw new IllegalArgumentException (
4855 String .format (
@@ -56,6 +63,10 @@ public static TreeVisitor<?, ExecutionContext> repeatUntilStable(TreeVisitor<?,
5663 Tree previous = tree ;
5764 Tree current = null ;
5865 for (int i = 0 ; i < maxCycles ; i ++) {
66+ TreeVisitor <?, ExecutionContext > v = vp .get ();
67+ if (tree instanceof SourceFile && !v .isAcceptable ((SourceFile ) tree , ctx )) {
68+ return tree ;
69+ }
5970 current = v .visit (previous , ctx );
6071 if (current == previous ) {
6172 break ;
@@ -68,13 +79,13 @@ public static TreeVisitor<?, ExecutionContext> repeatUntilStable(TreeVisitor<?,
6879
6980 @ Override
7081 public @ Nullable Tree visit (@ Nullable Tree tree , ExecutionContext ctx , Cursor parent ) {
71- if (tree instanceof SourceFile && !v .isAcceptable ((SourceFile ) tree , ctx )) {
72- return tree ;
73- }
74-
7582 Tree previous = tree ;
7683 Tree current = null ;
7784 for (int i = 0 ; i < maxCycles ; i ++) {
85+ final TreeVisitor <?, ExecutionContext > v = vp .get ();
86+ if (tree instanceof SourceFile && !v .isAcceptable ((SourceFile ) tree , ctx )) {
87+ return tree ;
88+ }
7889 current = v .visit (previous , ctx , parent );
7990 if (current == previous ) {
8091 break ;
0 commit comments