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; }
@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; }
@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); }
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); } }