Search in sources :

Example 1 with AddNullableNotNullAnnotationFix

use of com.intellij.codeInsight.intention.impl.AddNullableNotNullAnnotationFix in project intellij-community by JetBrains.

the class ExtractMethodProcessor method doExtract.

public void doExtract() throws IncorrectOperationException {
    PsiMethod newMethod = generateEmptyMethod();
    myExpression = myInputVariables.replaceWrappedReferences(myElements, myExpression);
    renameInputVariables();
    LOG.assertTrue(myElements[0].isValid());
    PsiCodeBlock body = newMethod.getBody();
    myMethodCall = generateMethodCall(null, true);
    LOG.assertTrue(myElements[0].isValid());
    final PsiStatement exitStatementCopy = prepareMethodBody(newMethod, true);
    if (myExpression == null) {
        if (myNeedChangeContext && isNeedToChangeCallContext()) {
            for (PsiElement element : myElements) {
                ChangeContextUtil.encodeContextInfo(element, false);
            }
        }
        if (myNullConditionalCheck) {
            final String varName = myOutputVariable.getName();
            if (isDeclaredInside(myOutputVariable)) {
                declareVariableAtMethodCallLocation(varName);
            } else {
                PsiExpressionStatement assignmentExpression = (PsiExpressionStatement) myElementFactory.createStatementFromText(varName + "=x;", null);
                assignmentExpression = (PsiExpressionStatement) addToMethodCallLocation(assignmentExpression);
                myMethodCall = (PsiMethodCallExpression) ((PsiAssignmentExpression) assignmentExpression.getExpression()).getRExpression().replace(myMethodCall);
            }
            declareNecessaryVariablesAfterCall(myOutputVariable);
            PsiIfStatement ifStatement;
            if (myHasReturnStatementOutput) {
                ifStatement = (PsiIfStatement) myElementFactory.createStatementFromText("if (" + varName + "==null) return null;", null);
            } else if (myGenerateConditionalExit) {
                if (myFirstExitStatementCopy instanceof PsiReturnStatement && ((PsiReturnStatement) myFirstExitStatementCopy).getReturnValue() != null) {
                    ifStatement = (PsiIfStatement) myElementFactory.createStatementFromText("if (" + varName + "==null) return null;", null);
                } else {
                    ifStatement = (PsiIfStatement) myElementFactory.createStatementFromText("if (" + varName + "==null) " + myFirstExitStatementCopy.getText(), null);
                }
            } else {
                ifStatement = (PsiIfStatement) myElementFactory.createStatementFromText("if (" + varName + "==null) return;", null);
            }
            ifStatement = (PsiIfStatement) addToMethodCallLocation(ifStatement);
            CodeStyleManager.getInstance(myProject).reformat(ifStatement);
        } else if (myNotNullConditionalCheck) {
            String varName = myOutputVariable != null ? myOutputVariable.getName() : "x";
            varName = declareVariableAtMethodCallLocation(varName, myReturnType instanceof PsiPrimitiveType ? ((PsiPrimitiveType) myReturnType).getBoxedType(myCodeFragmentMember) : myReturnType);
            addToMethodCallLocation(myElementFactory.createStatementFromText("if (" + varName + " != null) return " + varName + ";", null));
        } else if (myGenerateConditionalExit) {
            PsiIfStatement ifStatement = (PsiIfStatement) myElementFactory.createStatementFromText("if (a) b;", null);
            ifStatement = (PsiIfStatement) addToMethodCallLocation(ifStatement);
            myMethodCall = (PsiMethodCallExpression) ifStatement.getCondition().replace(myMethodCall);
            myFirstExitStatementCopy = (PsiStatement) ifStatement.getThenBranch().replace(myFirstExitStatementCopy);
            CodeStyleManager.getInstance(myProject).reformat(ifStatement);
        } else if (myOutputVariable != null || isArtificialOutputUsed()) {
            boolean toDeclare = isArtificialOutputUsed() ? !(myArtificialOutputVariable instanceof PsiField) : isDeclaredInside(myOutputVariable);
            String name = isArtificialOutputUsed() ? myArtificialOutputVariable.getName() : myOutputVariable.getName();
            if (!toDeclare) {
                PsiExpressionStatement statement = (PsiExpressionStatement) myElementFactory.createStatementFromText(name + "=x;", null);
                statement = (PsiExpressionStatement) myStyleManager.reformat(statement);
                statement = (PsiExpressionStatement) addToMethodCallLocation(statement);
                PsiAssignmentExpression assignment = (PsiAssignmentExpression) statement.getExpression();
                myMethodCall = (PsiMethodCallExpression) assignment.getRExpression().replace(myMethodCall);
            } else {
                declareVariableAtMethodCallLocation(name);
            }
        } else if (myHasReturnStatementOutput) {
            PsiStatement statement = myElementFactory.createStatementFromText("return x;", null);
            statement = (PsiStatement) addToMethodCallLocation(statement);
            myMethodCall = (PsiMethodCallExpression) ((PsiReturnStatement) statement).getReturnValue().replace(myMethodCall);
        } else {
            PsiStatement statement = myElementFactory.createStatementFromText("x();", null);
            statement = (PsiStatement) addToMethodCallLocation(statement);
            myMethodCall = (PsiMethodCallExpression) ((PsiExpressionStatement) statement).getExpression().replace(myMethodCall);
        }
        if (myHasReturnStatement && !myHasReturnStatementOutput && !hasNormalExit()) {
            PsiStatement statement = myElementFactory.createStatementFromText("return;", null);
            addToMethodCallLocation(statement);
        } else if (!myGenerateConditionalExit && exitStatementCopy != null) {
            addToMethodCallLocation(exitStatementCopy);
        }
        if (!myNullConditionalCheck && !myNotNullConditionalCheck) {
            declareNecessaryVariablesAfterCall(myOutputVariable);
        }
        deleteExtracted();
    } else {
        PsiExpression expression2Replace = myExpression;
        if (myExpression instanceof PsiAssignmentExpression) {
            expression2Replace = ((PsiAssignmentExpression) myExpression).getRExpression();
        } else if (myExpression instanceof PsiPostfixExpression || myExpression instanceof PsiPrefixExpression) {
            final IElementType elementType = myExpression instanceof PsiPostfixExpression ? ((PsiPostfixExpression) myExpression).getOperationTokenType() : ((PsiPrefixExpression) myExpression).getOperationTokenType();
            if (elementType == JavaTokenType.PLUSPLUS || elementType == JavaTokenType.MINUSMINUS) {
                PsiExpression operand = myExpression instanceof PsiPostfixExpression ? ((PsiPostfixExpression) myExpression).getOperand() : ((PsiPrefixExpression) myExpression).getOperand();
                expression2Replace = ((PsiBinaryExpression) myExpression.replace(myElementFactory.createExpressionFromText(operand.getText() + " + x", operand))).getROperand();
            }
        }
        myExpression = (PsiExpression) IntroduceVariableBase.replace(expression2Replace, myMethodCall, myProject);
        myMethodCall = PsiTreeUtil.getParentOfType(myExpression.findElementAt(myExpression.getText().indexOf(myMethodCall.getText())), PsiMethodCallExpression.class);
        declareNecessaryVariablesAfterCall(myOutputVariable);
    }
    if (myAnchor instanceof PsiField) {
        ((PsiField) myAnchor).normalizeDeclaration();
    }
    adjustFinalParameters(newMethod);
    int i = 0;
    for (VariableData data : myVariableDatum) {
        if (!data.passAsParameter)
            continue;
        final PsiParameter psiParameter = newMethod.getParameterList().getParameters()[i++];
        final PsiType paramType = psiParameter.getType();
        for (PsiReference reference : ReferencesSearch.search(psiParameter, new LocalSearchScope(body))) {
            final PsiElement element = reference.getElement();
            if (element != null) {
                final PsiElement parent = element.getParent();
                if (parent instanceof PsiTypeCastExpression) {
                    final PsiTypeCastExpression typeCastExpression = (PsiTypeCastExpression) parent;
                    final PsiTypeElement castType = typeCastExpression.getCastType();
                    if (castType != null && Comparing.equal(castType.getType(), paramType)) {
                        RedundantCastUtil.removeCast(typeCastExpression);
                    }
                }
            }
        }
    }
    if (myNullness != null && PsiUtil.resolveClassInType(newMethod.getReturnType()) != null && PropertiesComponent.getInstance(myProject).getBoolean(ExtractMethodDialog.EXTRACT_METHOD_GENERATE_ANNOTATIONS, true)) {
        final NullableNotNullManager notNullManager = NullableNotNullManager.getInstance(myProject);
        AddNullableNotNullAnnotationFix annotationFix;
        switch(myNullness) {
            case NOT_NULL:
                annotationFix = new AddNullableNotNullAnnotationFix(notNullManager.getDefaultNotNull(), newMethod);
                break;
            case NULLABLE:
                annotationFix = new AddNullableNotNullAnnotationFix(notNullManager.getDefaultNullable(), newMethod);
                break;
            default:
                annotationFix = null;
        }
        if (annotationFix != null) {
            annotationFix.invoke(myProject, myTargetClass.getContainingFile(), newMethod, newMethod);
        }
    }
    myExtractedMethod = addExtractedMethod(newMethod);
    if (isNeedToChangeCallContext() && myNeedChangeContext) {
        ChangeContextUtil.decodeContextInfo(myExtractedMethod, myTargetClass, RefactoringChangeUtil.createThisExpression(myManager, null));
        if (myMethodCall.resolveMethod() != myExtractedMethod) {
            final PsiReferenceExpression methodExpression = myMethodCall.getMethodExpression();
            RefactoringChangeUtil.qualifyReference(methodExpression, myExtractedMethod, PsiUtil.getEnclosingStaticElement(methodExpression, myTargetClass) != null ? myTargetClass : null);
        }
    }
}
Also used : NullableNotNullManager(com.intellij.codeInsight.NullableNotNullManager) LocalSearchScope(com.intellij.psi.search.LocalSearchScope) IElementType(com.intellij.psi.tree.IElementType) AddNullableNotNullAnnotationFix(com.intellij.codeInsight.intention.impl.AddNullableNotNullAnnotationFix)

Aggregations

NullableNotNullManager (com.intellij.codeInsight.NullableNotNullManager)1 AddNullableNotNullAnnotationFix (com.intellij.codeInsight.intention.impl.AddNullableNotNullAnnotationFix)1 LocalSearchScope (com.intellij.psi.search.LocalSearchScope)1 IElementType (com.intellij.psi.tree.IElementType)1