void (GrForStatement forStatement) { GrStatement body = forStatement.getBody(); assert body != null; final Set<String> usedLabels = new HashSet<>(); final Ref<Boolean> needLabel = Ref.create(false); body.accept(new GroovyRecursiveElementVisitor() { private int myLoops = 0; @Override public void visitReturnStatement(@NotNull GrReturnStatement returnStatement) { if (returnStatement.getReturnValue() != null) return; if (myLoops > 0) needLabel.set(true); } @Override public void visitLabeledStatement(@NotNull GrLabeledStatement labeledStatement) { super.visitLabeledStatement(labeledStatement); usedLabels.add(labeledStatement.getName()); } @Override public void visitForStatement(@NotNull GrForStatement forStatement) { myLoops++; super.visitForStatement(forStatement); myLoops--; } @Override public void visitWhileStatement(@NotNull GrWhileStatement whileStatement) { myLoops++; super.visitWhileStatement(whileStatement); myLoops--; } @Override public void visitClosure(@NotNull GrClosableBlock closure) { //don't go into closures } @Override public void visitAnonymousClassDefinition(@NotNull GrAnonymousClassDefinition anonymousClassDefinition) { //don't go into anonymous } }); GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(forStatement.getProject()); final String continueText; if (needLabel.get()) { int i = 0; String label = OUTER; while (usedLabels.contains(label)) { label = OUTER + i; i++; } continueText = "continue "+ label; GrLabeledStatement labeled = (GrLabeledStatement)factory.createStatementFromText(label + ": while (true){}"); labeled.getStatement().replaceWithStatement(forStatement); labeled = forStatement.replaceWithStatement(labeled); forStatement = (GrForStatement)labeled.getStatement(); body = forStatement.getBody(); assert body != null; } else { continueText = "continue"; } final GrStatement continueStatement = factory.createStatementFromText(continueText); body.accept(new GroovyRecursiveElementVisitor() { @Override public void visitReturnStatement(@NotNull GrReturnStatement returnStatement) { if (returnStatement.getReturnValue() == null) { returnStatement.replaceWithStatement(continueStatement); } } @Override public void visitClosure(@NotNull GrClosableBlock closure) { //don't go into closures } @Override public void visitAnonymousClassDefinition(@NotNull GrAnonymousClassDefinition anonymousClassDefinition) { //don't go into anonymous } }); }