Search in sources :

Example 1 with FieldConflictsResolver

use of com.intellij.refactoring.util.FieldConflictsResolver in project intellij-community by JetBrains.

the class IntroduceVariableBase method introduce.

public static PsiVariable introduce(final Project project, final PsiExpression expr, final Editor editor, final PsiElement anchorStatement, final PsiExpression[] occurrences, final IntroduceVariableSettings settings) {
    final PsiElement container = anchorStatement.getParent();
    PsiElement child = anchorStatement;
    final boolean isInsideLoop = RefactoringUtil.isLoopOrIf(container);
    if (!isInsideLoop) {
        child = locateAnchor(child);
        if (isFinalVariableOnLHS(expr)) {
            child = child.getNextSibling();
        }
    }
    final PsiElement anchor = child == null ? anchorStatement : child;
    boolean tempDeleteSelf = false;
    final boolean replaceSelf = settings.isReplaceLValues() || !RefactoringUtil.isAssignmentLHS(expr);
    final PsiElement exprParent = expr.getParent();
    if (!isInsideLoop) {
        if (exprParent instanceof PsiExpressionStatement && anchor.equals(anchorStatement)) {
            PsiElement parent = exprParent.getParent();
            if (parent instanceof PsiCodeBlock || //fabrique
            parent instanceof PsiCodeFragment) {
                tempDeleteSelf = true;
            }
        }
        tempDeleteSelf &= replaceSelf;
    }
    final boolean deleteSelf = tempDeleteSelf;
    final boolean replaceLoop = isInsideLoop ? exprParent instanceof PsiExpressionStatement : container instanceof PsiLambdaExpression && exprParent == container;
    final int col = editor != null ? editor.getCaretModel().getLogicalPosition().column : 0;
    final int line = editor != null ? editor.getCaretModel().getLogicalPosition().line : 0;
    if (deleteSelf) {
        if (editor != null) {
            LogicalPosition pos = new LogicalPosition(line, col);
            editor.getCaretModel().moveToLogicalPosition(pos);
        }
    }
    final PsiCodeBlock newDeclarationScope = PsiTreeUtil.getParentOfType(container, PsiCodeBlock.class, false);
    final FieldConflictsResolver fieldConflictsResolver = new FieldConflictsResolver(settings.getEnteredName(), newDeclarationScope);
    SmartPsiElementPointer<PsiVariable> pointer = ApplicationManager.getApplication().runWriteAction(new Computable<SmartPsiElementPointer<PsiVariable>>() {

        @Override
        public SmartPsiElementPointer<PsiVariable> compute() {
            try {
                PsiStatement statement = null;
                if (!isInsideLoop && deleteSelf) {
                    statement = (PsiStatement) exprParent;
                }
                final PsiExpression expr1 = fieldConflictsResolver.fixInitializer(expr);
                PsiExpression initializer = RefactoringUtil.unparenthesizeExpression(expr1);
                final SmartTypePointer selectedType = SmartTypePointerManager.getInstance(project).createSmartTypePointer(settings.getSelectedType());
                initializer = simplifyVariableInitializer(initializer, selectedType.getType());
                PsiType type = stripNullabilityAnnotationsFromTargetType(selectedType, project);
                PsiDeclarationStatement declaration = JavaPsiFacade.getInstance(project).getElementFactory().createVariableDeclarationStatement(settings.getEnteredName(), type, initializer, container);
                if (!isInsideLoop) {
                    declaration = addDeclaration(declaration, initializer);
                    LOG.assertTrue(expr1.isValid());
                    if (deleteSelf) {
                        final PsiElement lastChild = statement.getLastChild();
                        if (lastChild instanceof PsiComment) {
                            // keep trailing comment
                            declaration.addBefore(lastChild, null);
                        }
                        statement.delete();
                        if (editor != null) {
                            LogicalPosition pos = new LogicalPosition(line, col);
                            editor.getCaretModel().moveToLogicalPosition(pos);
                            editor.getCaretModel().moveToOffset(declaration.getTextRange().getEndOffset());
                            editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
                            editor.getSelectionModel().removeSelection();
                        }
                    }
                }
                PsiExpression ref = JavaPsiFacade.getInstance(project).getElementFactory().createExpressionFromText(settings.getEnteredName(), null);
                if (settings.isReplaceAllOccurrences()) {
                    ArrayList<PsiElement> array = new ArrayList<>();
                    for (PsiExpression occurrence : occurrences) {
                        if (deleteSelf && occurrence.equals(expr))
                            continue;
                        if (occurrence.equals(expr)) {
                            occurrence = expr1;
                        }
                        if (occurrence != null) {
                            occurrence = RefactoringUtil.outermostParenthesizedExpression(occurrence);
                        }
                        if (settings.isReplaceLValues() || !RefactoringUtil.isAssignmentLHS(occurrence)) {
                            array.add(replace(occurrence, ref, project));
                        }
                    }
                    if (!deleteSelf && replaceSelf && expr1 instanceof PsiPolyadicExpression && expr1.isValid() && !expr1.isPhysical()) {
                        array.add(replace(expr1, ref, project));
                    }
                    if (editor != null) {
                        final PsiElement[] replacedOccurences = PsiUtilCore.toPsiElementArray(array);
                        highlightReplacedOccurences(project, editor, replacedOccurences);
                    }
                } else {
                    if (!deleteSelf && replaceSelf) {
                        replace(expr1, ref, project);
                    }
                }
                declaration = (PsiDeclarationStatement) RefactoringUtil.putStatementInLoopBody(declaration, container, anchorStatement, replaceSelf && replaceLoop);
                declaration = (PsiDeclarationStatement) JavaCodeStyleManager.getInstance(project).shortenClassReferences(declaration);
                PsiVariable var = (PsiVariable) declaration.getDeclaredElements()[0];
                PsiUtil.setModifierProperty(var, PsiModifier.FINAL, settings.isDeclareFinal());
                fieldConflictsResolver.fix();
                return SmartPointerManager.getInstance(project).createSmartPsiElementPointer(var);
            } catch (IncorrectOperationException e) {
                LOG.error(e);
            }
            return null;
        }

        private PsiDeclarationStatement addDeclaration(PsiDeclarationStatement declaration, PsiExpression initializer) {
            if (anchor instanceof PsiDeclarationStatement) {
                final PsiElement[] declaredElements = ((PsiDeclarationStatement) anchor).getDeclaredElements();
                if (declaredElements.length > 1) {
                    final int[] usedFirstVar = new int[] { -1 };
                    initializer.accept(new JavaRecursiveElementWalkingVisitor() {

                        @Override
                        public void visitReferenceExpression(PsiReferenceExpression expression) {
                            final int i = ArrayUtilRt.find(declaredElements, expression.resolve());
                            if (i > -1) {
                                usedFirstVar[0] = Math.max(i, usedFirstVar[0]);
                            }
                            super.visitReferenceExpression(expression);
                        }
                    });
                    if (usedFirstVar[0] > -1) {
                        final PsiVariable psiVariable = (PsiVariable) declaredElements[usedFirstVar[0]];
                        psiVariable.normalizeDeclaration();
                        final PsiDeclarationStatement parDeclarationStatement = PsiTreeUtil.getParentOfType(psiVariable, PsiDeclarationStatement.class);
                        return (PsiDeclarationStatement) container.addAfter(declaration, parDeclarationStatement);
                    }
                }
            }
            return (PsiDeclarationStatement) container.addBefore(declaration, anchor);
        }
    });
    return pointer != null ? pointer.getElement() : null;
}
Also used : FieldConflictsResolver(com.intellij.refactoring.util.FieldConflictsResolver) IncorrectOperationException(com.intellij.util.IncorrectOperationException)

Example 2 with FieldConflictsResolver

use of com.intellij.refactoring.util.FieldConflictsResolver in project intellij-community by JetBrains.

the class JavaIntroduceParameterMethodUsagesProcessor method processChangeMethodSignature.

public boolean processChangeMethodSignature(IntroduceParameterData data, UsageInfo usage, UsageInfo[] usages) throws IncorrectOperationException {
    if (!(usage.getElement() instanceof PsiMethod) || !isJavaUsage(usage))
        return true;
    PsiMethod method = (PsiMethod) usage.getElement();
    final FieldConflictsResolver fieldConflictsResolver = new FieldConflictsResolver(data.getParameterName(), method.getBody());
    final MethodJavaDocHelper javaDocHelper = new MethodJavaDocHelper(method);
    PsiElementFactory factory = JavaPsiFacade.getInstance(data.getProject()).getElementFactory();
    final PsiClass superClass = data.getMethodToSearchFor().getContainingClass();
    final PsiClass containingClass = method.getContainingClass();
    final PsiSubstitutor substitutor = superClass != null && containingClass != null ? TypeConversionUtil.getSuperClassSubstitutor(superClass, containingClass, PsiSubstitutor.EMPTY) : PsiSubstitutor.EMPTY;
    PsiParameter parameter = factory.createParameter(data.getParameterName(), substitutor.substitute(data.getForcedType()));
    PsiUtil.setModifierProperty(parameter, PsiModifier.FINAL, data.isDeclareFinal());
    final PsiParameterList parameterList = method.getParameterList();
    final PsiParameter[] parameters = parameterList.getParameters();
    data.getParametersToRemove().forEachDescending(new TIntProcedure() {

        public boolean execute(final int paramNum) {
            try {
                PsiParameter param = parameters[paramNum];
                PsiDocTag tag = javaDocHelper.getTagForParameter(param);
                if (tag != null) {
                    tag.delete();
                }
                param.delete();
            } catch (IncorrectOperationException e) {
                LOG.error(e);
            }
            return true;
        }
    });
    final PsiParameter anchorParameter = getAnchorParameter(method);
    parameter = (PsiParameter) parameterList.addAfter(parameter, anchorParameter);
    JavaCodeStyleManager.getInstance(data.getProject()).shortenClassReferences(parameter);
    final PsiDocTag tagForAnchorParameter = javaDocHelper.getTagForParameter(anchorParameter);
    javaDocHelper.addParameterAfter(data.getParameterName(), tagForAnchorParameter);
    fieldConflictsResolver.fix();
    return false;
}
Also used : TIntProcedure(gnu.trove.TIntProcedure) PsiDocTag(com.intellij.psi.javadoc.PsiDocTag) MethodJavaDocHelper(com.intellij.refactoring.util.javadoc.MethodJavaDocHelper) FieldConflictsResolver(com.intellij.refactoring.util.FieldConflictsResolver) IncorrectOperationException(com.intellij.util.IncorrectOperationException)

Aggregations

FieldConflictsResolver (com.intellij.refactoring.util.FieldConflictsResolver)2 IncorrectOperationException (com.intellij.util.IncorrectOperationException)2 PsiDocTag (com.intellij.psi.javadoc.PsiDocTag)1 MethodJavaDocHelper (com.intellij.refactoring.util.javadoc.MethodJavaDocHelper)1 TIntProcedure (gnu.trove.TIntProcedure)1