public void visitForStatement(GrForStatement forStatement) { final GrForClause clause = forStatement.getClause(); processForLoopInitializer(clause); InstructionImpl start = startNode(forStatement); addForLoopBreakingEdge(forStatement, clause); flushForeachLoopVariable(clause); final GrStatement body = forStatement.getBody(); if (body != null) { InstructionImpl bodyInstruction = startNode(body); body.accept(this); finishNode(bodyInstruction); } checkPending(start); // check for breaks targeted here if (clause instanceof GrTraditionalForClause) { acceptNullable(((GrTraditionalForClause) clause).getUpdate()); } if (myHead != null) addEdge(myHead, start); // loop interruptFlow(); finishNode(start); }
@Override protected void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { final GrMethodCallExpression expression = (GrMethodCallExpression) element; final GrClosableBlock block = expression.getClosureArguments()[0]; final GrParameterList parameterList = block.getParameterList(); final GrParameter[] parameters = parameterList.getParameters(); String var; if (parameters.length == 1) { var = parameters[0].getText(); var = StringUtil.replace(var, GrModifier.DEF, ""); } else { var = "it"; } final GrExpression invokedExpression = expression.getInvokedExpression(); GrExpression qualifier = ((GrReferenceExpression) invokedExpression).getQualifierExpression(); final GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(element.getProject()); if (qualifier == null) { qualifier = elementFactory.createExpressionFromText("this"); } StringBuilder builder = new StringBuilder(); builder.append("for (").append(var).append(" in ").append(qualifier.getText()).append(") {\n"); String text = block.getText(); final PsiElement blockArrow = block.getArrow(); int index; if (blockArrow != null) { index = blockArrow.getStartOffsetInParent() + blockArrow.getTextLength(); } else { index = 1; } while (index < text.length() && Character.isWhitespace(text.charAt(index))) index++; text = text.substring(index, text.length() - 1); builder.append(text); builder.append("}"); final GrStatement statement = elementFactory.createStatementFromText(builder.toString()); GrForStatement forStatement = (GrForStatement) expression.replaceWithStatement(statement); final GrForClause clause = forStatement.getClause(); GrVariable variable = clause.getDeclaredVariable(); forStatement = updateReturnStatements(forStatement); if (variable == null) return; if (ApplicationManager.getApplication().isUnitTestMode()) return; final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project); final Document doc = documentManager.getDocument(element.getContainingFile()); if (doc == null) return; documentManager.doPostponedOperationsAndUnblockDocument(doc); editor.getCaretModel().moveToOffset(variable.getTextOffset()); new VariableInplaceRenamer(variable, editor).performInplaceRename(); }
private static boolean forInStatementsAreEquivalent( @NotNull GrForStatement statement1, @NotNull GrForStatement statement2) { final GrForClause clause1 = statement1.getClause(); final GrForClause clause2 = statement2.getClause(); if (!forClausesAreEquivalent(clause1, clause2)) { return false; } final GrStatement body1 = statement1.getBody(); final GrStatement body2 = statement2.getBody(); return statementsAreEquivalent(body1, body2); }
@Override public void visitForStatement(GrForStatement forStatement) { // final StringBuilder builder = new StringBuilder(); builder.append("for("); final GrForClause clause = forStatement.getClause(); ExpressionContext forContext = context.extend(); if (clause instanceof GrForInClause) { final GrExpression expression = ((GrForInClause) clause).getIteratedExpression(); final GrVariable declaredVariable = clause.getDeclaredVariable(); LOG.assertTrue(declaredVariable != null); writeVariableWithoutSemicolonAndInitializer(builder, declaredVariable, context); builder.append(" : "); if (expression != null) { final ExpressionContext context = forContext.copy(); writeExpression(expression, builder, context); } } else if (clause instanceof GrTraditionalForClause) { final GrTraditionalForClause cl = (GrTraditionalForClause) clause; final GrCondition initialization = cl.getInitialization(); final GrExpression condition = cl.getCondition(); final GrExpression update = cl.getUpdate(); if (initialization instanceof GrParameter) { StringBuilder partBuilder = new StringBuilder(); writeVariableWithoutSemicolonAndInitializer( partBuilder, (GrParameter) initialization, context); final GrExpression initializer = ((GrParameter) initialization).getInitializerGroovy(); if (initializer != null) { final ExpressionContext partContext = forContext.copy(); partBuilder.append(" = "); writeExpression(initializer, partBuilder, partContext); for (String statement : partContext.myStatements) { builder.append(statement).append(", "); } builder.append(partBuilder); } } else if (initialization != null) { StringBuilder partBuilder = new StringBuilder(); final ExpressionContext partContext = forContext.copy(); genForPart(builder, initialization, new CodeBlockGenerator(partBuilder, partContext, null)); } builder.append(';'); if (condition != null) { genForPart(builder, condition, forContext.copy()); // todo??? } builder.append(';'); if (update != null) { genForPart(builder, update, forContext.copy()); } } builder.append(')'); final GrStatement body = forStatement.getBody(); if (body != null) { body.accept(new CodeBlockGenerator(builder, forContext, null)); } }
private static GrForStatement updateReturnStatements(GrForStatement forStatement) { GrStatement body = forStatement.getBody(); assert body != null; final Set<String> usedLabels = ContainerUtil.newHashSet(); final Ref<Boolean> needLabel = Ref.create(false); body.accept( new GroovyRecursiveElementVisitor() { private int myLoops = 0; @Override public void visitReturnStatement(GrReturnStatement returnStatement) { if (returnStatement.getReturnValue() != null) return; if (myLoops > 0) needLabel.set(true); } @Override public void visitLabeledStatement(GrLabeledStatement labeledStatement) { super.visitLabeledStatement(labeledStatement); usedLabels.add(labeledStatement.getName()); } @Override public void visitForStatement(GrForStatement forStatement) { myLoops++; super.visitForStatement(forStatement); myLoops--; } @Override public void visitWhileStatement(GrWhileStatement whileStatement) { myLoops++; super.visitWhileStatement(whileStatement); myLoops--; } @Override public void visitClosure(GrClosableBlock closure) { // don't go into closures } @Override public void visitAnonymousClassDefinition( 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(GrReturnStatement returnStatement) { if (returnStatement.getReturnValue() == null) { returnStatement.replaceWithStatement(continueStatement); } } @Override public void visitClosure(GrClosableBlock closure) { // don't go into closures } @Override public void visitAnonymousClassDefinition( GrAnonymousClassDefinition anonymousClassDefinition) { // don't go into anonymous } }); return forStatement; }