blob: 9e799cb127bd12caba27738a1bf4e893a0127871 [file] [log] [blame]
/*
* 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);
}
}
}