@Override
  public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element)
      throws IncorrectOperationException {
    try {
      if (!FileModificationService.getInstance().preparePsiElementForWrite(element)) return;

      final PsiJavaToken token = (PsiJavaToken) element;
      final PsiPolyadicExpression expression =
          SplitConditionUtil.findCondition(element, true, false);

      final PsiLambdaExpression lambdaExpression =
          PsiTreeUtil.getParentOfType(expression, PsiLambdaExpression.class);
      LOG.assertTrue(lambdaExpression != null);
      final String lambdaParameterName =
          lambdaExpression.getParameterList().getParameters()[0].getName();

      final PsiMethodCallExpression methodCallExpression =
          PsiTreeUtil.getParentOfType(expression, PsiMethodCallExpression.class);
      LOG.assertTrue(methodCallExpression != null, expression);

      PsiExpression lOperand = getLOperands(expression, token);
      PsiExpression rOperand = getROperands(expression, token);

      final Collection<PsiComment> comments =
          PsiTreeUtil.findChildrenOfType(expression, PsiComment.class);

      final PsiMethodCallExpression chainedCall =
          (PsiMethodCallExpression)
              JavaPsiFacade.getElementFactory(project)
                  .createExpressionFromText(
                      "a.filter(" + lambdaParameterName + " -> x)", expression);
      final PsiExpression argExpression = chainedCall.getArgumentList().getExpressions()[0];
      final PsiElement rReplaced =
          ((PsiLambdaExpression) argExpression).getBody().replace(rOperand);

      final PsiExpression compoundArg = methodCallExpression.getArgumentList().getExpressions()[0];

      final int separatorOffset = token.getTextOffset();
      for (PsiComment comment : comments) {
        if (comment.getTextOffset() < separatorOffset) {
          compoundArg.getParent().add(comment);
        } else {
          rReplaced.getParent().add(comment);
        }
      }

      ((PsiLambdaExpression) compoundArg).getBody().replace(lOperand);

      chainedCall.getMethodExpression().getQualifierExpression().replace(methodCallExpression);
      methodCallExpression.replace(chainedCall);
    } catch (IncorrectOperationException e) {
      LOG.error(e);
    }
  }
 static String createContainsExpressionText(
     @NotNull PsiMethodCallExpression call, @NotNull PsiJavaToken sign, boolean flipped) {
   final IElementType tokenType = sign.getTokenType();
   final PsiReferenceExpression methodExpression = call.getMethodExpression();
   final PsiExpression qualifierExpression = methodExpression.getQualifierExpression();
   final String qualifierText;
   if (qualifierExpression == null) {
     qualifierText = "";
   } else {
     qualifierText = qualifierExpression.getText();
   }
   final PsiExpressionList argumentList = call.getArgumentList();
   final PsiExpression expression = argumentList.getExpressions()[0];
   @NonNls
   final String newExpressionText = qualifierText + ".contains(" + expression.getText() + ')';
   if (tokenType.equals(JavaTokenType.EQEQ)) {
     return '!' + newExpressionText;
   } else if (!flipped
       && (tokenType.equals(JavaTokenType.LT) || tokenType.equals(JavaTokenType.LE))) {
     return '!' + newExpressionText;
   } else if (flipped
       && (tokenType.equals(JavaTokenType.GT) || tokenType.equals(JavaTokenType.GE))) {
     return '!' + newExpressionText;
   }
   return newExpressionText;
 }
Beispiel #3
0
 private Pair<PsiVariable, PsiType> findVariable(final PsiElement element) {
   PsiVariable variable = null;
   if (element instanceof PsiIdentifier) {
     if (element.getParent() instanceof PsiVariable) {
       variable = (PsiVariable) element.getParent();
     }
   } else if (element instanceof PsiJavaToken) {
     final PsiJavaToken token = (PsiJavaToken) element;
     if (token.getTokenType() != JavaTokenType.EQ) return null;
     if (token.getParent() instanceof PsiVariable) {
       variable = (PsiVariable) token.getParent();
     }
   }
   if (variable == null) {
     return null;
   }
   variableName = variable.getName();
   final PsiExpression initializer = variable.getInitializer();
   if (initializer == null) return null;
   final PsiType variableType = variable.getType();
   final PsiType initializerType = initializer.getType();
   if (!(variableType instanceof PsiClassType)) return null;
   final PsiClassType variableClassType = (PsiClassType) variableType;
   if (!variableClassType.isRaw()) return null;
   if (!(initializerType instanceof PsiClassType)) return null;
   final PsiClassType initializerClassType = (PsiClassType) initializerType;
   if (initializerClassType.isRaw()) return null;
   final PsiClassType.ClassResolveResult variableResolveResult =
       variableClassType.resolveGenerics();
   final PsiClassType.ClassResolveResult initializerResolveResult =
       initializerClassType.resolveGenerics();
   if (initializerResolveResult.getElement() == null) return null;
   final PsiSubstitutor targetSubstitutor =
       TypeConversionUtil.getClassSubstitutor(
           variableResolveResult.getElement(),
           initializerResolveResult.getElement(),
           initializerResolveResult.getSubstitutor());
   if (targetSubstitutor == null) return null;
   PsiType type =
       JavaPsiFacade.getInstance(variable.getProject())
           .getElementFactory()
           .createType(variableResolveResult.getElement(), targetSubstitutor);
   newTypeName = type.getCanonicalText();
   return Pair.create(variable, type);
 }
Beispiel #4
0
 public static @NotNull PsiType getOOType(PsiType left, PsiType right, PsiJavaToken op) {
   if (op == null) return NoType;
   String methodname = OOMethods.binary.get(op.getText());
   if (methodname != null && right != null) {
     PsiType res = resolveMethod(left, methodname, right);
     if (res == null) res = resolveMethod(right, methodname + OOMethods.revSuffix, left);
     if (res != null)
       if (OOMethods.compareTo.equals(methodname)) return PsiType.BOOLEAN;
       else return res;
   }
   return NoType;
 }
 public static boolean areParenthesesNeeded(PsiJavaToken sign, PsiExpression rhs) {
   if (rhs instanceof PsiPolyadicExpression) {
     final PsiPolyadicExpression binaryExpression = (PsiPolyadicExpression) rhs;
     final int precedence1 = getPrecedenceForOperator(binaryExpression.getOperationTokenType());
     final IElementType signTokenType = sign.getTokenType();
     final IElementType newOperatorToken = tokenMap.get(signTokenType);
     final int precedence2 = getPrecedenceForOperator(newOperatorToken);
     return precedence1 >= precedence2 || !isCommutativeOperator(newOperatorToken);
   } else {
     return rhs instanceof PsiConditionalExpression;
   }
 }
 private void checkSetterNeeded(final PsiExpression operand, final PsiJavaToken sign) {
   final IElementType tokenType = sign.getTokenType();
   if (!tokenType.equals(JavaTokenType.PLUSPLUS)
       && !tokenType.equals(JavaTokenType.MINUSMINUS)) {
     return;
   }
   if (isProhibitedReference(operand)) {
     final PsiField field = getReferencedField(operand);
     if (!hasSetter(field) && !isStaticFinal(field)) {
       fieldsNeedingSetter.add(field);
     }
   }
 }
 @Override
 public void visitPostfixExpression(@NotNull PsiPostfixExpression postfixExpression) {
   if (read || written) {
     return;
   }
   super.visitPostfixExpression(postfixExpression);
   final PsiJavaToken operationSign = postfixExpression.getOperationSign();
   final IElementType tokenType = operationSign.getTokenType();
   if (!tokenType.equals(JavaTokenType.PLUSPLUS)
       && !tokenType.equals(JavaTokenType.MINUSMINUS)) {
     return;
   }
   final PsiExpression operand = postfixExpression.getOperand();
   if (!(operand instanceof PsiReferenceExpression)) {
     return;
   }
   final PsiReferenceExpression referenceExpression = (PsiReferenceExpression) operand;
   final PsiElement target = referenceExpression.resolve();
   if (!variable.equals(target)) {
     return;
   }
   written = true;
 }
 @Nullable
 private static String buildFromOffsetText(PsiExpression expression, PsiLocalVariable variable)
     throws IncorrectOperationException {
   expression = ParenthesesUtils.stripParentheses(expression);
   if (expression == null) {
     return null;
   }
   final String expressionText = expression.getText();
   final String variableName = variable.getName();
   if (expressionText.equals(variableName)) {
     final PsiExpression initialValue = variable.getInitializer();
     if (initialValue == null) {
       return null;
     }
     return initialValue.getText();
   }
   if (expression instanceof PsiBinaryExpression) {
     final PsiBinaryExpression binaryExpression = (PsiBinaryExpression) expression;
     final PsiExpression lhs = binaryExpression.getLOperand();
     final PsiExpression rhs = binaryExpression.getROperand();
     final String rhsText = buildFromOffsetText(rhs, variable);
     final PsiJavaToken sign = binaryExpression.getOperationSign();
     final IElementType tokenType = sign.getTokenType();
     if (ExpressionUtils.isZero(lhs)) {
       if (tokenType.equals(JavaTokenType.MINUS)) {
         return '-' + rhsText;
       }
       return rhsText;
     }
     final String lhsText = buildFromOffsetText(lhs, variable);
     if (ExpressionUtils.isZero(rhs)) {
       return lhsText;
     }
     return collapseConstant(lhsText + sign.getText() + rhsText, variable);
   }
   return collapseConstant(expression.getText(), variable);
 }
 @Nullable
 public static PsiExpression findExpressionInRange(PsiFile file, int startOffset, int endOffset) {
   if (!file.getViewProvider().getLanguages().contains(StdLanguages.JAVA)) return null;
   PsiExpression expression =
       findElementInRange(file, startOffset, endOffset, PsiExpression.class);
   if (expression == null && findStatementsInRange(file, startOffset, endOffset).length == 0) {
     PsiElement element2 = file.getViewProvider().findElementAt(endOffset - 1, StdLanguages.JAVA);
     if (element2 instanceof PsiJavaToken) {
       final PsiJavaToken token = (PsiJavaToken) element2;
       final IElementType tokenType = token.getTokenType();
       if (tokenType.equals(JavaTokenType.SEMICOLON)) {
         expression =
             findElementInRange(
                 file, startOffset, element2.getTextRange().getStartOffset(), PsiExpression.class);
       }
     }
   }
   if (expression == null && findStatementsInRange(file, startOffset, endOffset).length == 0) {
     PsiElement element =
         PsiTreeUtil.skipSiblingsBackward(file.findElementAt(endOffset), PsiWhiteSpace.class);
     if (element != null) {
       element =
           PsiTreeUtil.skipSiblingsBackward(
               element.getLastChild(), PsiWhiteSpace.class, PsiComment.class);
       if (element != null) {
         final int newEndOffset = element.getTextRange().getEndOffset();
         if (newEndOffset < endOffset) {
           expression = findExpressionInRange(file, startOffset, newEndOffset);
         }
       }
     }
   }
   if (expression instanceof PsiReferenceExpression
       && expression.getParent() instanceof PsiMethodCallExpression) return null;
   return expression;
 }
 @Nullable
 static PsiPolyadicExpression getSubexpression(
     PsiPolyadicExpression expression, PsiJavaToken token) {
   final PsiExpression[] operands = expression.getOperands();
   if (operands.length == 2) {
     return expression;
   }
   for (int i = 1; i < operands.length; i++) {
     final PsiExpression operand = operands[i];
     final PsiJavaToken currentToken = expression.getTokenBeforeOperand(operand);
     if (currentToken == token) {
       final String binaryExpressionText =
           operands[i - 1].getText() + ' ' + token.getText() + ' ' + operand.getText();
       final PsiElementFactory factory = JavaPsiFacade.getElementFactory(expression.getProject());
       return (PsiPolyadicExpression)
           factory.createExpressionFromText(binaryExpressionText, expression);
     }
   }
   return null;
 }
 private static boolean canBeReplacedByContains(
     PsiExpression lhs, PsiJavaToken sign, PsiExpression rhs, boolean flipped) {
   final PsiMethodCallExpression callExpression = (PsiMethodCallExpression) lhs;
   if (!isIndexOfCall(callExpression)) {
     return false;
   }
   final Object object = ExpressionUtils.computeConstantExpression(rhs);
   if (!(object instanceof Integer)) {
     return false;
   }
   final Integer integer = (Integer) object;
   final int constant = integer.intValue();
   final IElementType tokenType = sign.getTokenType();
   if (flipped) {
     if (constant == -1
         && (JavaTokenType.NE.equals(tokenType)
             || JavaTokenType.LT.equals(tokenType)
             || JavaTokenType.EQEQ.equals(tokenType)
             || JavaTokenType.GE.equals(tokenType))) {
       return true;
     } else if (constant == 0
         && (JavaTokenType.LE.equals(tokenType) || JavaTokenType.GT.equals(tokenType))) {
       return true;
     }
   } else {
     if (constant == -1
         && (JavaTokenType.NE.equals(tokenType)
             || JavaTokenType.GT.equals(tokenType)
             || JavaTokenType.EQEQ.equals(tokenType)
             || JavaTokenType.LE.equals(tokenType))) {
       return true;
     } else if (constant == 0
         && (JavaTokenType.GE.equals(tokenType) || JavaTokenType.LT.equals(tokenType))) {
       return true;
     }
   }
   return false;
 }
  public List<TextRange> select(
      PsiElement e, CharSequence editorText, int cursorOffset, Editor editor) {
    List<TextRange> result = new ArrayList<TextRange>();

    PsiElement parent = e.getParent();

    if (!(parent instanceof PsiCodeBlock) && !(parent instanceof PsiBlockStatement)
        || parent instanceof JspCodeBlock) {
      return result;
    }

    PsiElement startElement = e;
    PsiElement endElement = e;

    while (startElement.getPrevSibling() != null) {
      PsiElement sibling = startElement.getPrevSibling();

      if (sibling instanceof PsiJavaToken) {
        PsiJavaToken token = (PsiJavaToken) sibling;
        if (token.getTokenType() == JavaTokenType.LBRACE) {
          break;
        }
      }

      if (sibling instanceof PsiWhiteSpace) {
        PsiWhiteSpace whiteSpace = (PsiWhiteSpace) sibling;

        String[] strings = LineTokenizer.tokenize(whiteSpace.getText().toCharArray(), false);
        if (strings.length > 2) {
          break;
        }
      }

      startElement = sibling;
    }

    while (startElement instanceof PsiWhiteSpace) {
      startElement = startElement.getNextSibling();
    }

    while (endElement.getNextSibling() != null) {
      PsiElement sibling = endElement.getNextSibling();

      if (sibling instanceof PsiJavaToken) {
        PsiJavaToken token = (PsiJavaToken) sibling;
        if (token.getTokenType() == JavaTokenType.RBRACE) {
          break;
        }
      }

      if (sibling instanceof PsiWhiteSpace) {
        PsiWhiteSpace whiteSpace = (PsiWhiteSpace) sibling;

        String[] strings = LineTokenizer.tokenize(whiteSpace.getText().toCharArray(), false);
        if (strings.length > 2) {
          break;
        }
      }

      endElement = sibling;
    }

    while (endElement instanceof PsiWhiteSpace) {
      endElement = endElement.getPrevSibling();
    }

    result.addAll(
        expandToWholeLine(
            editorText,
            new TextRange(
                startElement.getTextRange().getStartOffset(),
                endElement.getTextRange().getEndOffset())));

    return result;
  }
  public boolean processUsage(
      @NotNull EncapsulateFieldUsageInfo usage,
      @NotNull EncapsulateFieldsDescriptor descriptor,
      PsiMethod setter,
      PsiMethod getter) {
    final PsiElement element = usage.getElement();
    if (!(element instanceof PsiReferenceExpression)) return false;

    final FieldDescriptor fieldDescriptor = usage.getFieldDescriptor();
    PsiField field = fieldDescriptor.getField();
    boolean processGet = descriptor.isToEncapsulateGet();
    boolean processSet =
        descriptor.isToEncapsulateSet() && !field.hasModifierProperty(PsiModifier.FINAL);
    if (!processGet && !processSet) return true;
    PsiElementFactory factory =
        JavaPsiFacade.getInstance(descriptor.getTargetClass().getProject()).getElementFactory();

    try {
      final PsiReferenceExpression expr = (PsiReferenceExpression) element;
      final PsiElement parent = expr.getParent();
      if (parent instanceof PsiAssignmentExpression
          && expr.equals(((PsiAssignmentExpression) parent).getLExpression())) {
        PsiAssignmentExpression assignment = (PsiAssignmentExpression) parent;
        if (assignment.getRExpression() == null) return true;
        PsiJavaToken opSign = assignment.getOperationSign();
        IElementType opType = opSign.getTokenType();
        if (opType == JavaTokenType.EQ) {
          {
            if (!processSet) return true;
            final PsiExpression setterArgument = assignment.getRExpression();

            PsiMethodCallExpression methodCall =
                createSetterCall(
                    fieldDescriptor, setterArgument, expr, descriptor.getTargetClass(), setter);

            if (methodCall != null) {
              assignment.replace(methodCall);
            }
            // TODO: check if value is used!!!
          }
        } else if (opType == JavaTokenType.ASTERISKEQ
            || opType == JavaTokenType.DIVEQ
            || opType == JavaTokenType.PERCEQ
            || opType == JavaTokenType.PLUSEQ
            || opType == JavaTokenType.MINUSEQ
            || opType == JavaTokenType.LTLTEQ
            || opType == JavaTokenType.GTGTEQ
            || opType == JavaTokenType.GTGTGTEQ
            || opType == JavaTokenType.ANDEQ
            || opType == JavaTokenType.OREQ
            || opType == JavaTokenType.XOREQ) {
          {
            // Q: side effects of qualifier??!

            String opName = opSign.getText();
            LOG.assertTrue(StringUtil.endsWithChar(opName, '='));
            opName = opName.substring(0, opName.length() - 1);

            PsiExpression getExpr = expr;
            if (processGet) {
              final PsiMethodCallExpression getterCall =
                  createGetterCall(fieldDescriptor, expr, descriptor.getTargetClass(), getter);
              if (getterCall != null) {
                getExpr = getterCall;
              }
            }

            @NonNls String text = "a" + opName + "b";
            PsiBinaryExpression binExpr =
                (PsiBinaryExpression) factory.createExpressionFromText(text, expr);
            binExpr.getLOperand().replace(getExpr);
            binExpr.getROperand().replace(assignment.getRExpression());

            PsiExpression setExpr;
            if (processSet) {
              setExpr =
                  createSetterCall(
                      fieldDescriptor, binExpr, expr, descriptor.getTargetClass(), setter);
            } else {
              text = "a = b";
              PsiAssignmentExpression assignment1 =
                  (PsiAssignmentExpression) factory.createExpressionFromText(text, null);
              assignment1.getLExpression().replace(expr);
              assignment1.getRExpression().replace(binExpr);
              setExpr = assignment1;
            }

            assignment.replace(setExpr);
            // TODO: check if value is used!!!
          }
        }
      } else if (RefactoringUtil.isPlusPlusOrMinusMinus(parent)) {
        IElementType sign;
        if (parent instanceof PsiPrefixExpression) {
          sign = ((PsiPrefixExpression) parent).getOperationTokenType();
        } else {
          sign = ((PsiPostfixExpression) parent).getOperationTokenType();
        }

        PsiExpression getExpr = expr;
        if (processGet) {
          final PsiMethodCallExpression getterCall =
              createGetterCall(fieldDescriptor, expr, descriptor.getTargetClass(), getter);
          if (getterCall != null) {
            getExpr = getterCall;
          }
        }

        @NonNls String text;
        if (sign == JavaTokenType.PLUSPLUS) {
          text = "a+1";
        } else {
          text = "a-1";
        }
        PsiBinaryExpression binExpr =
            (PsiBinaryExpression) factory.createExpressionFromText(text, null);
        binExpr.getLOperand().replace(getExpr);

        PsiExpression setExpr;
        if (processSet) {
          setExpr =
              createSetterCall(fieldDescriptor, binExpr, expr, descriptor.getTargetClass(), setter);
        } else {
          text = "a = b";
          PsiAssignmentExpression assignment =
              (PsiAssignmentExpression) factory.createExpressionFromText(text, null);
          assignment.getLExpression().replace(expr);
          assignment.getRExpression().replace(binExpr);
          setExpr = assignment;
        }
        parent.replace(setExpr);
      } else {
        if (!processGet) return true;
        PsiMethodCallExpression methodCall =
            createGetterCall(fieldDescriptor, expr, descriptor.getTargetClass(), getter);

        if (methodCall != null) {
          expr.replace(methodCall);
        }
      }
    } catch (IncorrectOperationException e) {
      LOG.error(e);
    }
    return true;
  }
 @Override
 public void doFix(Project project, ProblemDescriptor descriptor)
     throws IncorrectOperationException {
   final PsiExpression expression = (PsiExpression) descriptor.getPsiElement();
   final PsiType type = expression.getType();
   if (type == null) {
     return;
   }
   final PsiPrimitiveType unboxedType = PsiPrimitiveType.getUnboxedType(type);
   if (unboxedType == null) {
     return;
   }
   final String newExpressionText = buildNewExpressionText(expression, unboxedType);
   final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
   final PsiElementFactory factory = psiFacade.getElementFactory();
   final PsiElement parent = expression.getParent();
   final String expressionText = expression.getText();
   if (parent instanceof PsiPrefixExpression && !unboxedType.equalsToText("boolean")) {
     final PsiPrefixExpression prefixExpression = (PsiPrefixExpression) parent;
     final IElementType tokenType = prefixExpression.getOperationTokenType();
     if (JavaTokenType.PLUSPLUS.equals(tokenType)) {
       replaceExpression(prefixExpression, expressionText + '=' + newExpressionText + "+1");
     } else if (JavaTokenType.MINUSMINUS.equals(tokenType)) {
       replaceExpression(prefixExpression, expressionText + '=' + newExpressionText + "-1");
     } else {
       replaceExpression(
           prefixExpression, prefixExpression.getOperationSign().getText() + newExpressionText);
     }
   } else if (parent instanceof PsiPostfixExpression) {
     final PsiPostfixExpression postfixExpression = (PsiPostfixExpression) parent;
     final IElementType tokenType = postfixExpression.getOperationTokenType();
     final PsiElement grandParent = postfixExpression.getParent();
     if (grandParent instanceof PsiExpressionStatement) {
       if (JavaTokenType.PLUSPLUS.equals(tokenType)) {
         replaceExpression(postfixExpression, expressionText + '=' + newExpressionText + "+1");
       } else if (JavaTokenType.MINUSMINUS.equals(tokenType)) {
         replaceExpression(postfixExpression, expressionText + '=' + newExpressionText + "-1");
       }
     } else {
       final PsiElement element = postfixExpression.replace(postfixExpression.getOperand());
       final PsiStatement statement = PsiTreeUtil.getParentOfType(element, PsiStatement.class);
       if (statement == null) {
         return;
       }
       final PsiStatement newStatement;
       if (JavaTokenType.PLUSPLUS.equals(tokenType)) {
         newStatement =
             factory.createStatementFromText(
                 expressionText + '=' + newExpressionText + "+1;", statement);
       } else {
         newStatement =
             factory.createStatementFromText(
                 expressionText + '=' + newExpressionText + "-1;", statement);
       }
       final PsiElement greatGrandParent = statement.getParent();
       greatGrandParent.addAfter(newStatement, statement);
     }
   } else if (parent instanceof PsiAssignmentExpression) {
     final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression) parent;
     final PsiExpression lExpression = assignmentExpression.getLExpression();
     if (expression.equals(lExpression)) {
       final PsiJavaToken operationSign = assignmentExpression.getOperationSign();
       final String operationSignText = operationSign.getText();
       final char sign = operationSignText.charAt(0);
       final PsiExpression rExpression = assignmentExpression.getRExpression();
       if (rExpression == null) {
         return;
       }
       final String text =
           lExpression.getText() + '=' + newExpressionText + sign + rExpression.getText();
       final PsiExpression newExpression =
           factory.createExpressionFromText(text, assignmentExpression);
       assignmentExpression.replace(newExpression);
     } else {
       replaceExpression(expression, newExpressionText);
     }
   } else {
     replaceExpression(expression, newExpressionText);
   }
 }