public void visitIfStatement(GrIfStatement ifStatement) {
    InstructionImpl ifInstruction = startNode(ifStatement);

    final GrCondition condition = ifStatement.getCondition();
    final GrStatement thenBranch = ifStatement.getThenBranch();
    final GrStatement elseBranch = ifStatement.getElseBranch();

    InstructionImpl conditionEnd = null;
    InstructionImpl thenEnd = null;
    InstructionImpl elseEnd = null;

    if (condition != null) {
      condition.accept(this);
      conditionEnd = myHead;
    }

    List<GotoInstruction> negations = collectAndRemoveAllPendingNegations(ifStatement);

    if (thenBranch != null) {
      thenBranch.accept(this);
      handlePossibleReturn(thenBranch);
      thenEnd = myHead;
      interruptFlow();
      readdPendingEdge(ifStatement);
    }

    myHead = reduceAllNegationsIntoInstruction(ifStatement, negations);
    if (myHead == null && conditionEnd != null) {
      myHead = conditionEnd;
    }
    if (elseBranch != null) {
      elseBranch.accept(this);
      handlePossibleReturn(elseBranch);
      elseEnd = myHead;
      interruptFlow();
    }

    if (thenBranch != null || elseBranch != null) {
      if (thenEnd != null || elseEnd != null || elseBranch == null) {
        final InstructionImpl end = new IfEndInstruction(ifStatement);
        addNode(end);

        if (thenEnd != null) {
          addEdge(thenEnd, end);
        }

        if (elseEnd != null) {
          addEdge(elseEnd, end);
        } else if (elseBranch == null) {
          addEdge(conditionEnd != null ? conditionEnd : ifInstruction, end);
        }
      }
    }

    finishNode(ifInstruction);
  }
예제 #2
0
  private static Collection<GrVariable> collectUsedLocalVarsOrParamsDeclaredOutside(
      GrStatement[] statements) {
    final Collection<GrVariable> result = new HashSet<GrVariable>();

    final int start = statements[0].getTextRange().getStartOffset();
    final int end = statements[statements.length - 1].getTextRange().getEndOffset();

    final GroovyRecursiveElementVisitor visitor =
        new GroovyRecursiveElementVisitor() {
          @Override
          public void visitReferenceExpression(GrReferenceExpression ref) {
            final PsiElement resolved = ref.resolve();
            if ((resolved instanceof GrParameter || GroovyRefactoringUtil.isLocalVariable(resolved))
                && resolved.isPhysical()) {
              final int offset = resolved.getTextRange().getStartOffset();
              // var is declared outside of selected code
              if (offset < start || end <= offset) {
                result.add((GrVariable) resolved);
              }
            }
          }
        };

    for (GrStatement statement : statements) {
      statement.accept(visitor);
    }

    return result;
  }
  @Override
  public void visitCaseSection(GrCaseSection caseSection) {
    for (GrCaseLabel label : caseSection.getCaseLabels()) {
      GrExpression value = label.getValue();
      if (value != null) {
        value.accept(this);
      }
    }

    final GrStatement[] statements = caseSection.getStatements();

    // infer 'may be return' position
    int i;
    for (i = statements.length - 1; i >= 0 && statements[i] instanceof GrBreakStatement; i--) {}

    for (int j = 0; j < statements.length; j++) {
      GrStatement statement = statements[j];
      statement.accept(this);
      if (j == i) handlePossibleReturn(statement);
    }

    if (myHead != null) {
      addPendingEdge(caseSection, myHead);
    }
  }
  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);
  }
 public static PsiField[] findUsedFieldsWithGetters(
     GrStatement[] statements, PsiClass containingClass) {
   if (containingClass == null) return PsiField.EMPTY_ARRAY;
   final FieldSearcher searcher = new FieldSearcher(containingClass);
   for (GrStatement statement : statements) {
     statement.accept(searcher);
   }
   return searcher.getResult();
 }
 public void visitStatementOwner(GrStatementOwner owner, boolean shouldInsertReturnNull) {
   boolean hasLineFeed = false;
   for (PsiElement e = owner.getFirstChild(); e != null; e = e.getNextSibling()) {
     if (e instanceof GrStatement) {
       ((GrStatement) e).accept(this);
       hasLineFeed = false;
     } else if (TokenSets.COMMENT_SET.contains(e.getNode().getElementType())) {
       builder.append(e.getText());
     } else if (org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isLineFeed(e)) {
       hasLineFeed = true;
       if (IN_TEST) {
         builder.append(genSameLineFeed(e.getText()));
       } else {
         builder.append(e.getText());
       }
     }
   }
   if (shouldInsertReturnNull) {
     if (!hasLineFeed) {
       builder.append('\n');
     }
     builder.append("return null;\n");
   }
 }
  @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;
  }