示例#1
0
  public void processIntention(@NotNull PsiElement element) throws IncorrectOperationException {
    final GrIfStatement parentStatement = (GrIfStatement) element;
    assert parentStatement != null;
    final GrStatement parentThenBranch = (GrStatement) parentStatement.getThenBranch();
    final GrIfStatement childStatement =
        (GrIfStatement) ConditionalUtils.stripBraces(parentThenBranch);

    final GrExpression childCondition = (GrExpression) childStatement.getCondition();
    final String childConditionText;
    if (ParenthesesUtils.getPrecendence(childCondition) > ParenthesesUtils.AND_PRECEDENCE) {
      childConditionText = '(' + childCondition.getText() + ')';
    } else {
      childConditionText = childCondition.getText();
    }

    final GrExpression parentCondition = (GrExpression) parentStatement.getCondition();
    final String parentConditionText;
    if (ParenthesesUtils.getPrecendence(parentCondition) > ParenthesesUtils.AND_PRECEDENCE) {
      parentConditionText = '(' + parentCondition.getText() + ')';
    } else {
      parentConditionText = parentCondition.getText();
    }

    final GrStatement childThenBranch = (GrStatement) childStatement.getThenBranch();
    @NonNls
    final String statement =
        "if(" + parentConditionText + "&&" + childConditionText + ')' + childThenBranch.getText();
    IntentionUtils.replaceStatement(statement, parentStatement);
  }
  @Override
  protected void processIntention(@NotNull PsiElement element, Project project, Editor editor)
      throws IncorrectOperationException {
    PsiElement parent = element.getParent();

    if (!"if".equals(element.getText()) || !(parent instanceof GrIfStatement)) {
      throw new IncorrectOperationException("Not invoked on an if");
    }
    GrIfStatement parentIf = (GrIfStatement) parent;
    GroovyPsiElementFactory groovyPsiElementFactory = GroovyPsiElementFactory.getInstance(project);

    GrExpression condition = parentIf.getCondition();
    if (condition == null) {
      throw new IncorrectOperationException("Invoked on an if with empty condition");
    }

    GrExpression negatedCondition = null;
    if (condition instanceof GrUnaryExpression) {
      GrUnaryExpression unaryCondition = (GrUnaryExpression) condition;
      if ("!".equals(unaryCondition.getOperationToken().getText())) {
        negatedCondition = stripParenthesis(unaryCondition.getOperand());
      }
    }

    if (negatedCondition == null) {
      // Now check whether this is a simple expression
      condition = stripParenthesis(condition);
      String negatedExpressionText;
      if (condition instanceof GrCallExpression || condition instanceof GrReferenceExpression) {
        negatedExpressionText = "!" + condition.getText();
      } else {
        negatedExpressionText = "!(" + condition.getText() + ")";
      }
      negatedCondition =
          groovyPsiElementFactory.createExpressionFromText(negatedExpressionText, parentIf);
    }

    GrStatement thenBranch = parentIf.getThenBranch();
    final boolean thenIsNotEmpty = isNotEmpty(thenBranch);

    String newIfText = "if (" + negatedCondition.getText() + ") {}";
    if (thenIsNotEmpty) {
      newIfText += " else {}";
    }

    GrIfStatement newIf =
        (GrIfStatement)
            groovyPsiElementFactory.createStatementFromText(newIfText, parentIf.getContext());
    generateElseBranchTextAndRemoveTailStatements(parentIf, newIf);

    if (thenIsNotEmpty) {
      final GrStatement elseBranch = newIf.getElseBranch();
      assert elseBranch != null;
      elseBranch.replaceWithStatement(thenBranch);
    }

    parentIf.replace(newIf);
  }
 /**
  * Convert an expression into something which can be put inside ( a && b ) Wrap in parenthesis, if
  * necessary
  *
  * @param expression
  * @return a string representing the expression
  */
 @NotNull
 private static String getStringToPutIntoAndExpression(GrExpression expression) {
   String expressionText = expression.getText();
   if (ParenthesesUtils.AND_PRECEDENCE < ParenthesesUtils.getPrecendence(expression)) {
     expressionText = "(" + expressionText + ")";
   }
   return expressionText;
 }
  @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 String calculateReplacementExpression(GrConditionalExpression exp) {
    final GrExpression thenExpression = exp.getThenBranch();
    final GrExpression elseExpression = exp.getElseBranch();
    final GrExpression condition = exp.getCondition();

    if (isFalse(thenExpression) && isTrue(elseExpression)) {
      return BoolUtils.getNegatedExpressionText(condition);
    } else {
      return condition.getText();
    }
  }
 @Override
 public void doFix(Project project, ProblemDescriptor descriptor)
     throws IncorrectOperationException {
   final PsiElement referenceName = descriptor.getPsiElement();
   final GrReferenceExpression invokedExpression =
       (GrReferenceExpression) referenceName.getParent();
   final GrMethodCallExpression callExpression =
       (GrMethodCallExpression) invokedExpression.getParent();
   final GrArgumentList args = callExpression.getArgumentList();
   final GrExpression arg = args.getExpressionArguments()[0];
   replaceExpression(
       callExpression,
       invokedExpression.getQualifierExpression().getText() + '[' + arg.getText() + ']');
 }
 private static void generateNameByExpr(
     GrExpression expr,
     Set<String> possibleNames,
     NameValidator validator,
     boolean forStaticVariable) {
   if (expr instanceof GrReferenceExpression
       && ((GrReferenceExpression) expr).getReferenceName() != null) {
     if (PsiUtil.isThisReference(expr)) {
       possibleNames.add(validator.validateName("thisInstance", true));
     }
     if (PsiUtil.isSuperReference(expr)) {
       possibleNames.add(validator.validateName("superInstance", true));
     }
     GrReferenceExpression refExpr = (GrReferenceExpression) expr;
     String name = refExpr.getReferenceName();
     if (name != null && name.toUpperCase().equals(name)) {
       possibleNames.add(validator.validateName(name.toLowerCase(), true));
     } else {
       generateCamelNames(possibleNames, validator, name);
     }
     if (expr.getText().equals(name)) {
       possibleNames.remove(name);
     }
   }
   if (expr instanceof GrMethodCallExpression) {
     generateNameByExpr(
         ((GrMethodCallExpression) expr).getInvokedExpression(),
         possibleNames,
         validator,
         forStaticVariable);
   }
   if (expr instanceof GrLiteral) {
     final Object value = ((GrLiteral) expr).getValue();
     if (value instanceof String) {
       generateNameByString(
           possibleNames, (String) value, validator, forStaticVariable, expr.getProject());
     }
   }
 }
 private static boolean isTrue(GrExpression expression) {
   @NonNls final String text = expression.getText();
   return "true".equals(text);
 }
  public static void generateBody(
      ExtractInfoHelper helper, boolean isVoid, StringBuilder buffer, boolean forceReturn) {
    VariableInfo[] outputInfos = helper.getOutputVariableInfos();

    ParameterInfo[] infos = helper.getParameterInfos();

    Set<String> declaredVars = new HashSet<String>();
    for (ParameterInfo info : infos) {
      declaredVars.add(info.getName());
    }

    for (VariableInfo info : mustAddVariableDeclaration(helper.getStatements(), outputInfos)) {
      declaredVars.add(info.getName());
    }

    List<VariableInfo> genDecl = new ArrayList<VariableInfo>();
    final Collection<GrVariable> outside =
        collectUsedLocalVarsOrParamsDeclaredOutside(helper.getStatements());

    for (final GrVariable variable : outside) {
      if (!declaredVars.contains(variable.getName())) {
        genDecl.add(
            new VariableInfo() {
              @NotNull
              @Override
              public String getName() {
                return variable.getName();
              }

              @Override
              public PsiType getType() {
                return variable.getDeclaredType();
              }
            });
      }
    }
    final List<GrStatement> statements =
        generateVarDeclarations(genDecl, helper.getProject(), null);
    for (GrStatement statement : statements) {
      buffer.append(statement.getText()).append('\n');
    }

    if (!isSingleExpression(helper.getStatements()) || statements.size() > 0) {
      for (PsiElement element : helper.getInnerElements()) {
        buffer.append(element.getText());
      }
      // append return statement
      if (!isVoid && outputInfos.length > 0) {
        buffer.append('\n');
        if (forceReturn) {
          buffer.append("return ");
        }
        if (outputInfos.length > 1) buffer.append('[');
        for (VariableInfo info : outputInfos) {
          buffer.append(info.getName()).append(", ");
        }
        buffer.delete(buffer.length() - 2, buffer.length());
        if (outputInfos.length > 1) buffer.append(']');
      }
    } else {
      GrExpression expr = (GrExpression) PsiUtil.skipParentheses(helper.getStatements()[0], false);
      boolean addReturn = !isVoid && forceReturn;
      if (addReturn) {
        buffer.append("return ");
        expr = ApplicationStatementUtil.convertToMethodCallExpression(expr);
        buffer.append(expr.getText());
      } else {
        buffer.append(expr != null ? expr.getText() : "");
      }
    }
  }
  @NotNull
  private Collection<? extends MavenRemoteRepository> findMavenRemoteRepositories(
      @Nullable GrClosableBlock repositoriesBlock) {
    Set<MavenRemoteRepository> myRemoteRepositories = ContainerUtil.newHashSet();
    for (GrMethodCall repo :
        PsiTreeUtil.getChildrenOfTypeAsList(repositoriesBlock, GrMethodCall.class)) {

      final String expressionText = repo.getInvokedExpression().getText();
      if ("mavenCentral".equals(expressionText)) {
        myRemoteRepositories.add(mavenCentralRemoteRepository);
      } else if ("mavenRepo".equals(expressionText)) {
        for (GrNamedArgument namedArgument : repo.getNamedArguments()) {
          if ("url".equals(namedArgument.getLabelName())) {
            URI urlArgumentValue = resolveUriFromSimpleExpression(namedArgument.getExpression());
            if (urlArgumentValue != null) {
              String textUri = urlArgumentValue.toString();
              myRemoteRepositories.add(
                  new MavenRemoteRepository(textUri, null, textUri, null, null, null));
            }
            break;
          }
        }
      } else if ("maven".equals(expressionText) && repo.getClosureArguments().length > 0) {
        List<GrApplicationStatement> applicationStatementList =
            PsiTreeUtil.getChildrenOfTypeAsList(
                repo.getClosureArguments()[0], GrApplicationStatement.class);
        if (!applicationStatementList.isEmpty()) {
          GrApplicationStatement statement = applicationStatementList.get(0);
          if (statement == null) continue;
          GrExpression expression = statement.getInvokedExpression();

          if ("url".equals(expression.getText())) {
            URI urlArgumentValue =
                resolveUriFromSimpleExpression(statement.getExpressionArguments()[0]);
            if (urlArgumentValue != null) {
              String textUri = urlArgumentValue.toString();
              myRemoteRepositories.add(
                  new MavenRemoteRepository(textUri, null, textUri, null, null, null));
            }
          }
        }

        List<GrAssignmentExpression> assignmentExpressionList =
            PsiTreeUtil.getChildrenOfTypeAsList(
                repo.getClosureArguments()[0], GrAssignmentExpression.class);
        if (!assignmentExpressionList.isEmpty()) {
          GrAssignmentExpression statement = assignmentExpressionList.get(0);
          if (statement == null) continue;
          GrExpression expression = statement.getLValue();

          if ("url".equals(expression.getText())) {
            URI urlArgumentValue = resolveUriFromSimpleExpression(statement.getRValue());
            if (urlArgumentValue != null) {
              String textUri = urlArgumentValue.toString();
              myRemoteRepositories.add(
                  new MavenRemoteRepository(textUri, null, textUri, null, null, null));
            }
          }
        }
      }
    }

    return myRemoteRepositories;
  }
  @Nullable
  public static GrExpression replaceExpression(
      GrExpression oldExpr, GrExpression newExpr, boolean removeUnnecessaryParentheses) {
    PsiElement oldParent = oldExpr.getParent();
    if (oldParent == null) throw new PsiInvalidElementAccessException(oldExpr);

    if (!(oldExpr instanceof GrApplicationStatement)) {
      newExpr = ApplicationStatementUtil.convertToMethodCallExpression(newExpr);
    }

    // Remove unnecessary parentheses
    if (removeUnnecessaryParentheses
        && oldParent instanceof GrParenthesizedExpression
        && !(oldParent.getParent() instanceof GrArgumentLabel)) {
      return ((GrExpression) oldParent)
          .replaceWithExpression(newExpr, removeUnnecessaryParentheses);
    }

    // regexes cannot be after identifier , try to replace it with simple string
    if (getRegexAtTheBeginning(newExpr) != null && isAfterIdentifier(oldExpr)) {
      final PsiElement copy = newExpr.copy();
      final GrLiteral regex = getRegexAtTheBeginning(copy);
      LOG.assertTrue(regex != null);
      final GrLiteral stringLiteral = GrStringUtil.createStringFromRegex(regex);
      if (regex == copy) {
        return oldExpr.replaceWithExpression(stringLiteral, removeUnnecessaryParentheses);
      } else {
        regex.replace(stringLiteral);
        return oldExpr.replaceWithExpression((GrExpression) copy, removeUnnecessaryParentheses);
      }
    }

    GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(oldExpr.getProject());
    if (oldParent instanceof GrStringInjection) {
      if (newExpr instanceof GrString
          || newExpr instanceof GrLiteral && ((GrLiteral) newExpr).getValue() instanceof String) {
        return GrStringUtil.replaceStringInjectionByLiteral(
            (GrStringInjection) oldParent, (GrLiteral) newExpr);
      } else {
        newExpr = factory.createExpressionFromText("{" + newExpr.getText() + "}");
        oldParent.getNode().replaceChild(oldExpr.getNode(), newExpr.getNode());
        return newExpr;
      }
    }

    if (PsiTreeUtil.getParentOfType(oldExpr, GrStringInjection.class, false, GrCodeBlock.class)
        != null) {
      final PsiElement replaced = oldExpr.replace(newExpr);
      final GrStringInjection stringInjection =
          PsiTreeUtil.getParentOfType(replaced, GrStringInjection.class);
      GrStringUtil.wrapInjection(stringInjection);
      assert stringInjection != null;
      return stringInjection.getClosableBlock();
    }

    // check priorities
    if (oldParent instanceof GrExpression && !(oldParent instanceof GrParenthesizedExpression)) {
      GrExpression addedParenth =
          addParenthesesIfNeeded(newExpr, oldExpr, (GrExpression) oldParent);
      if (newExpr != addedParenth) {
        return oldExpr.replaceWithExpression(addedParenth, removeUnnecessaryParentheses);
      }
    }

    // if replace closure argument with expression
    // we should add the expression in arg list
    if (oldExpr instanceof GrClosableBlock
        && !(newExpr instanceof GrClosableBlock)
        && oldParent instanceof GrMethodCallExpression
        && ArrayUtil.contains(
            oldExpr, ((GrMethodCallExpression) oldParent).getClosureArguments())) {
      return ((GrMethodCallExpression) oldParent)
          .replaceClosureArgument((GrClosableBlock) oldExpr, newExpr);
    }

    newExpr = (GrExpression) oldExpr.replace(newExpr);

    // if newExpr is the first grand child of command argument list we should replace command arg
    // list with parenthesised arg list.
    // In other case the code will be broken. So we try to find wrapping command arg list counting
    // levels. After arg list replace we go inside it
    // to find target parenthesised expression.
    if (newExpr instanceof GrParenthesizedExpression && isFirstChild(newExpr)) {
      int parentCount = 0;

      PsiElement element = oldParent;
      while (element != null && !(element instanceof GrCommandArgumentList)) {
        if (element instanceof GrCodeBlock || element instanceof GrParenthesizedExpression) break;
        if (element instanceof PsiFile) break;

        final PsiElement parent = element.getParent();
        if (parent == null) break;
        if (!isFirstChild(element)) break;

        element = parent;
        parentCount++;
      }

      if (element instanceof GrCommandArgumentList) {
        final GrCommandArgumentList commandArgList = (GrCommandArgumentList) element;

        final PsiElement parent = commandArgList.getParent();
        LOG.assertTrue(parent instanceof GrApplicationStatement);

        final GrMethodCall methodCall =
            factory.createMethodCallByAppCall((GrApplicationStatement) parent);
        final GrMethodCall newCall = (GrMethodCall) parent.replace(methodCall);

        PsiElement result = newCall.getArgumentList().getAllArguments()[0];

        for (int i = 0; i < parentCount; i++) {
          result = PsiUtil.skipWhitespacesAndComments(result.getFirstChild(), true);
        }

        LOG.assertTrue(result instanceof GrParenthesizedExpression);
        return (GrExpression) result;
      }
    }
    return newExpr;
  }
 private static boolean textOfExpressionsIsEquivalent(
     GrExpression expToCompare1, GrExpression expToCompare2) {
   final String text1 = expToCompare1.getText();
   final String text2 = expToCompare2.getText();
   return text1.equals(text2);
 }
 @SuppressWarnings({"ConstantConditions"})
 public static boolean expressionsAreEquivalent(
     @Nullable GrExpression exp1, @Nullable GrExpression exp2) {
   if (exp1 == null && exp2 == null) {
     return true;
   }
   if (exp1 == null || exp2 == null) {
     return false;
   }
   GrExpression expToCompare1 = (GrExpression) PsiUtil.skipParentheses(exp1, false);
   GrExpression expToCompare2 = (GrExpression) PsiUtil.skipParentheses(exp2, false);
   final int type1 = getExpressionType(expToCompare1);
   final int type2 = getExpressionType(expToCompare2);
   if (type1 != type2) {
     return false;
   }
   switch (type1) {
     case THIS_EXPRESSION:
     case SUPER_EXPRESSION:
       return true;
     case LITERAL_EXPRESSION:
     case REFERENCE_EXPRESSION:
       final String text1 = expToCompare1.getText();
       final String text2 = expToCompare2.getText();
       return text1.equals(text2);
     case CALL_EXPRESSION:
       return methodCallExpressionsAreEquivalent(
           (GrMethodCall) expToCompare1, (GrMethodCall) expToCompare2);
     case NEW_EXPRESSION:
       return newExpressionsAreEquivalent(
           (GrNewExpression) expToCompare1, (GrNewExpression) expToCompare2);
     case ARRAY_LITERAL_EXPRESSION:
       return arrayDeclarationsAreEquivalent(
           (GrArrayDeclaration) expToCompare1, (GrArrayDeclaration) expToCompare2);
     case PREFIX_EXPRESSION:
       return prefixExpressionsAreEquivalent(
           (GrUnaryExpression) expToCompare1, (GrUnaryExpression) expToCompare2);
     case POSTFIX_EXPRESSION:
       return postfixExpressionsAreEquivalent(
           (GrUnaryExpression) expToCompare1, (GrUnaryExpression) expToCompare2);
     case BINARY_EXPRESSION:
       return binaryExpressionsAreEquivalent(
           (GrBinaryExpression) expToCompare1, (GrBinaryExpression) expToCompare2);
     case ASSIGNMENT_EXPRESSION:
       return assignmentExpressionsAreEquivalent(
           (GrAssignmentExpression) expToCompare1, (GrAssignmentExpression) expToCompare2);
     case CONDITIONAL_EXPRESSION:
       return conditionalExpressionsAreEquivalent(
           (GrConditionalExpression) expToCompare1, (GrConditionalExpression) expToCompare2);
     case ELVIS_EXPRESSION:
       return elvisExpressionsAreEquivalent(
           (GrElvisExpression) expToCompare1, (GrElvisExpression) expToCompare2);
     case RANGE_EXPRESSION:
       return rangeExpressionsAreEquivalent(
           (GrRangeExpression) expToCompare1, (GrRangeExpression) expToCompare2);
     case TYPE_CAST_EXPRESSION:
       return typecastExpressionsAreEquivalent(
           (GrTypeCastExpression) expToCompare1, (GrTypeCastExpression) expToCompare2);
     case SAFE_CAST_EXPRESSION:
       return safecastExpressionsAreEquivalent(
           (GrSafeCastExpression) expToCompare1, (GrSafeCastExpression) expToCompare2);
     case INSTANCEOF_EXPRESSION:
       return instanceofExpressionsAreEquivalent(
           (GrInstanceOfExpression) expToCompare1, (GrInstanceOfExpression) expToCompare2);
     case INDEX_EXPRESSION:
       return indexExpressionsAreEquivalent(
           (GrIndexProperty) expToCompare1, (GrIndexProperty) expToCompare2);
     case LIST_OR_MAP_EXPRESSION:
       return listOrMapExpressionsAreEquivalent(
           (GrListOrMap) expToCompare1, (GrListOrMap) expToCompare2);
     case CLOSABLE_BLOCK_EXPRESSION:
       return closableBlockExpressionsAreEquivalent(
           (GrClosableBlock) expToCompare1, (GrClosableBlock) expToCompare2);
     case PROPERTY_SELECTION_EXPRESSION:
       return textOfExpressionsIsEquivalent(expToCompare1, expToCompare2); // todo
     default:
       return false;
   }
 }