/* * Copyright 2000-2011 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.siyeh.ipp.expression; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.util.PropertyUtil; import com.intellij.util.IncorrectOperationException; import com.siyeh.ipp.base.Intention; import com.siyeh.ipp.base.PsiElementEditorPredicate; import com.siyeh.ipp.base.PsiElementPredicate; import com.siyeh.ipp.psiutils.PsiSelectionSearcher; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; /** * @author Konstantin Bulenkov */ public class FlipSetterCallIntention extends Intention { protected void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { final Project project = element.getProject(); final Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); if (editor != null) { final List<PsiMethodCallExpression> methodCalls = PsiSelectionSearcher.searchElementsInSelection(editor, project, PsiMethodCallExpression.class, false); if (methodCalls.size() > 0) { for (PsiMethodCallExpression call : methodCalls) { flipCall(call); } editor.getSelectionModel().removeSelection(); return; } } if (element instanceof PsiMethodCallExpression) { flipCall((PsiMethodCallExpression)element); } } @NotNull protected PsiElementPredicate getElementPredicate() { return new SetterCallPredicate(); } private static void flipCall(PsiMethodCallExpression call) { final PsiExpression qualifierExpression1 = call.getMethodExpression().getQualifierExpression(); if (qualifierExpression1 == null) { return; } final PsiExpression[] arguments = call.getArgumentList().getExpressions(); if (arguments.length != 1) { return; } final PsiExpression argument = arguments[0]; if (!(argument instanceof PsiMethodCallExpression)) { return; } final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)argument; final PsiExpression qualifierExpression2 = methodCallExpression.getMethodExpression().getQualifierExpression(); if (qualifierExpression2 == null) { return; } final PsiMethod setter = call.resolveMethod(); final PsiMethod getter = methodCallExpression.resolveMethod(); final PsiMethod get = PropertyUtil.getReversePropertyMethod(setter); final PsiMethod set = PropertyUtil.getReversePropertyMethod(getter); if (get == null || set == null) { return; } final String text = qualifierExpression2.getText() + "." + set.getName() + "(" + qualifierExpression1.getText() + "." + get.getName() + "())"; final PsiExpression newExpression = JavaPsiFacade.getElementFactory(call.getProject()).createExpressionFromText(text, call); call.replace(newExpression); } private static boolean isSetGetMethodCall(PsiElement element) { if (!(element instanceof PsiMethodCallExpression)) { return false; } final PsiMethodCallExpression call1 = (PsiMethodCallExpression)element; final PsiExpression[] arguments = call1.getArgumentList().getExpressions(); if (arguments.length != 1) { return false; } final PsiExpression argument = arguments[0]; if (!(argument instanceof PsiMethodCallExpression)) { return false; } final PsiMethodCallExpression call2 = (PsiMethodCallExpression)argument; final PsiMethod setter = call1.resolveMethod(); final PsiMethod getter = call2.resolveMethod(); final PsiMethod get = PropertyUtil.getReversePropertyMethod(setter); final PsiMethod set = PropertyUtil.getReversePropertyMethod(getter); if (setter == null || getter == null || get == null || set == null) { return false; } //check types compatibility final PsiParameter[] parameters = setter.getParameterList().getParameters(); if (parameters.length != 1) { return false; } final PsiParameter parameter = parameters[0]; return parameter.getType().equals(getter.getReturnType()); } private static class SetterCallPredicate extends PsiElementEditorPredicate { @Override public boolean satisfiedBy(PsiElement element, @Nullable Editor editor) { if (editor != null && editor.getSelectionModel().hasSelection()) { final List<PsiMethodCallExpression> list = PsiSelectionSearcher.searchElementsInSelection(editor, element.getProject(), PsiMethodCallExpression.class, false); for (PsiMethodCallExpression methodCallExpression : list) { if (isSetGetMethodCall(methodCallExpression)) { return true; } } } return isSetGetMethodCall(element); } } }