blob: 63cb15b6060f08fd16af27ae06909441fd78e0db [file] [log] [blame]
/*
* Copyright 2000-2014 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 org.jetbrains.plugins.groovy.refactoring.inline;
import com.intellij.lang.refactoring.InlineHandler;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.PsiSubstitutor;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.util.PsiFormatUtil;
import com.intellij.psi.util.PsiFormatUtilBase;
import com.intellij.refactoring.util.CommonRefactoringUtil;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrAssignmentExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle;
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil;
import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceHandlerBase;
/**
* @author Max Medvedev
*/
public class GrVariableInliner implements InlineHandler.Inliner {
private final GrExpression myTempExpr;
public GrVariableInliner(GrVariable variable, InlineHandler.Settings settings) {
GrExpression initializer;
if (settings instanceof InlineLocalVarSettings) {
initializer = ((InlineLocalVarSettings)settings).getInitializer();
}
else {
initializer = variable.getInitializerGroovy();
PsiUtil.LOG.assertTrue(initializer != null);
}
myTempExpr = GrIntroduceHandlerBase.insertExplicitCastIfNeeded(variable, initializer);
}
@Override
@Nullable
public MultiMap<PsiElement, String> getConflicts(@NotNull PsiReference reference, @NotNull PsiElement referenced) {
MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();
GrExpression expr = (GrExpression)reference.getElement();
if (expr.getParent() instanceof GrAssignmentExpression) {
GrAssignmentExpression parent = (GrAssignmentExpression)expr.getParent();
if (expr.equals(parent.getLValue())) {
conflicts.putValue(expr, GroovyRefactoringBundle.message("local.varaible.is.lvalue"));
}
}
if ((referenced instanceof GrAccessorMethod || referenced instanceof GrField) && expr instanceof GrReferenceExpression) {
final GroovyResolveResult resolveResult = ((GrReferenceExpression)expr).advancedResolve();
if (resolveResult.getElement() instanceof GrAccessorMethod && !resolveResult.isInvokedOnProperty()) {
final PsiElement parent = expr.getParent();
if (!(parent instanceof GrCall && parent instanceof GrExpression)) {
conflicts.putValue(expr, GroovyRefactoringBundle.message("reference.to.accessor.0.is.used", CommonRefactoringUtil.htmlEmphasize(PsiFormatUtil.formatMethod(
(GrAccessorMethod)resolveResult.getElement(), PsiSubstitutor.EMPTY, PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_PARAMETERS, PsiFormatUtilBase.SHOW_TYPE))));
}
}
}
return conflicts;
}
@Override
public void inlineUsage(@NotNull final UsageInfo usage, @NotNull final PsiElement referenced) {
inlineReference(usage, referenced, myTempExpr);
}
static void inlineReference(UsageInfo usage, PsiElement referenced, GrExpression initializer) {
if (initializer == null) return;
GrExpression exprToBeReplaced = (GrExpression)usage.getElement();
if (exprToBeReplaced == null) return;
if ((referenced instanceof GrAccessorMethod || referenced instanceof GrField) && exprToBeReplaced instanceof GrReferenceExpression) {
final GroovyResolveResult resolveResult = ((GrReferenceExpression)exprToBeReplaced).advancedResolve();
if (resolveResult.getElement() instanceof GrAccessorMethod && !resolveResult.isInvokedOnProperty()) {
final PsiElement parent = exprToBeReplaced.getParent();
if (parent instanceof GrCall && parent instanceof GrExpression) {
exprToBeReplaced = (GrExpression)parent;
}
else {
return;
}
}
}
GrExpression newExpr = exprToBeReplaced.replaceWithExpression((GrExpression)initializer.copy(), true);
final Project project = usage.getProject();
JavaCodeStyleManager.getInstance(project).shortenClassReferences(newExpr);
Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor();
GroovyRefactoringUtil.highlightOccurrences(project, editor, new PsiElement[]{newExpr});
WindowManager.getInstance().getStatusBar(project).setInfo(GroovyRefactoringBundle.message("press.escape.to.remove.the.highlighting"));
}
}