blob: 210b8d36313d8a4acd6eded22069af368a63700a [file] [log] [blame]
/*
* Copyright 2000-2009 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.intellij.refactoring.turnRefsToSuper;
import com.intellij.lang.findUsages.DescriptiveNameUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Ref;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewDescriptor;
import com.intellij.usageView.UsageViewUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
public class TurnRefsToSuperProcessor extends TurnRefsToSuperProcessorBase {
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.turnRefsToSuper.TurnRefsToSuperProcessor");
private PsiClass mySuper;
public TurnRefsToSuperProcessor(Project project,
@NotNull PsiClass aClass,
@NotNull PsiClass aSuper,
boolean replaceInstanceOf) {
super(project, replaceInstanceOf, aSuper.getName());
myClass = aClass;
mySuper = aSuper;
}
protected String getCommandName() {
return RefactoringBundle.message("turn.refs.to.super.command",
DescriptiveNameUtil.getDescriptiveName(myClass), DescriptiveNameUtil.getDescriptiveName(mySuper));
}
@NotNull
protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) {
return new RefsToSuperViewDescriptor(myClass, mySuper);
}
private void setClasses(@NotNull final PsiClass aClass, @NotNull final PsiClass aSuper) {
myClass = aClass;
mySuper = aSuper;
}
@NotNull
protected UsageInfo[] findUsages() {
final PsiReference[] refs = ReferencesSearch.search(myClass, GlobalSearchScope.projectScope(myProject), false).toArray(new PsiReference[0]);
final ArrayList<UsageInfo> result = detectTurnToSuperRefs(refs, new ArrayList<UsageInfo>());
final UsageInfo[] usageInfos = result.toArray(new UsageInfo[result.size()]);
return UsageViewUtil.removeDuplicatedUsages(usageInfos);
}
protected void refreshElements(final PsiElement[] elements) {
LOG.assertTrue(elements.length == 2 && elements[0] instanceof PsiClass && elements[1] instanceof PsiClass);
setClasses ((PsiClass) elements[0], (PsiClass) elements[1]);
}
protected boolean preprocessUsages(@NotNull Ref<UsageInfo[]> refUsages) {
if (!ApplicationManager.getApplication().isUnitTestMode() && refUsages.get().length == 0) {
String message = RefactoringBundle.message("no.usages.can.be.replaced", myClass.getQualifiedName(), mySuper.getQualifiedName());
Messages.showInfoMessage(myProject, message, TurnRefsToSuperHandler.REFACTORING_NAME);
return false;
}
return super.preprocessUsages(refUsages);
}
protected boolean canTurnToSuper(final PsiElement refElement) {
return super.canTurnToSuper(refElement) &&
JavaPsiFacade.getInstance(myProject).getResolveHelper().isAccessible(mySuper, refElement, null);
}
protected void performRefactoring(UsageInfo[] usages) {
try {
final PsiClass aSuper = mySuper;
processTurnToSuperRefs(usages, aSuper);
} catch (IncorrectOperationException e) {
LOG.error(e);
}
performVariablesRenaming();
}
protected boolean isInSuper(PsiElement member) {
if (!(member instanceof PsiMember)) return false;
final PsiManager manager = member.getManager();
if (InheritanceUtil.isInheritorOrSelf(mySuper, ((PsiMember)member).getContainingClass(), true)) return true;
if (member instanceof PsiField) {
final PsiClass containingClass = ((PsiField) member).getContainingClass();
LanguageLevel languageLevel = PsiUtil.getLanguageLevel(member);
if (manager.areElementsEquivalent(containingClass, JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().getArrayClass(languageLevel))) {
return true;
}
} else if (member instanceof PsiMethod) {
return mySuper.findMethodBySignature((PsiMethod) member, true) != null;
}
return false;
}
protected boolean isSuperInheritor(PsiClass aClass) {
return InheritanceUtil.isInheritorOrSelf(mySuper, aClass, true);
}
public PsiClass getSuper() {
return mySuper;
}
public PsiClass getTarget() {
return myClass;
}
public boolean isReplaceInstanceOf() {
return myReplaceInstanceOf;
}
@NotNull
protected Collection<? extends PsiElement> getElementsToWrite(@NotNull final UsageViewDescriptor descriptor) {
return Collections.emptyList(); // neither myClass nor mySuper are subject to change, it's just references that are going to change
}
}