blob: eb06160d4280144be4bc97af5d0db9c64a96b2c9 [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 com.intellij.usageView;
import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.GeneratedSourcesFilter;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.StatusBar;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.psi.ElementDescriptionUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiReference;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.util.MoveRenameUsageInfo;
import com.intellij.refactoring.util.NonCodeUsageInfo;
import com.intellij.usages.Usage;
import com.intellij.usages.UsageInfo2UsageAdapter;
import com.intellij.usages.UsageView;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;
public class UsageViewUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.usageView.UsageViewUtil");
private UsageViewUtil() { }
public static String createNodeText(PsiElement element) {
return ElementDescriptionUtil.getElementDescription(element, UsageViewNodeTextLocation.INSTANCE);
}
public static String getShortName(final PsiElement psiElement) {
LOG.assertTrue(psiElement.isValid(), psiElement);
return ElementDescriptionUtil.getElementDescription(psiElement, UsageViewShortNameLocation.INSTANCE);
}
public static String getLongName(final PsiElement psiElement) {
LOG.assertTrue(psiElement.isValid(), psiElement);
return ElementDescriptionUtil.getElementDescription(psiElement, UsageViewLongNameLocation.INSTANCE);
}
public static String getType(@NotNull PsiElement psiElement) {
return ElementDescriptionUtil.getElementDescription(psiElement, UsageViewTypeLocation.INSTANCE);
}
public static boolean hasNonCodeUsages(UsageInfo[] usages) {
for (UsageInfo usage : usages) {
if (usage.isNonCodeUsage) return true;
}
return false;
}
public static boolean hasUsagesInGeneratedCode(UsageInfo[] usages, Project project) {
GeneratedSourcesFilter[] filters = GeneratedSourcesFilter.EP_NAME.getExtensions();
for (UsageInfo usage : usages) {
VirtualFile file = usage.getVirtualFile();
if (file != null) {
for (GeneratedSourcesFilter filter : filters) {
if (filter.isGeneratedSource(file, project)) {
return true;
}
}
}
}
return false;
}
public static boolean hasReadOnlyUsages(UsageInfo[] usages) {
for (UsageInfo usage : usages) {
if (!usage.isWritable()) return true;
}
return false;
}
public static UsageInfo[] removeDuplicatedUsages(@NotNull UsageInfo[] usages) {
Set<UsageInfo> set = new LinkedHashSet<UsageInfo>(Arrays.asList(usages));
// Replace duplicates of move rename usage infos in injections from non code usages of master files
String newTextInNonCodeUsage = null;
for(UsageInfo usage:usages) {
if (!(usage instanceof NonCodeUsageInfo)) continue;
newTextInNonCodeUsage = ((NonCodeUsageInfo)usage).newText;
break;
}
if (newTextInNonCodeUsage != null) {
for(UsageInfo usage:usages) {
if (!(usage instanceof MoveRenameUsageInfo)) continue;
PsiFile file = usage.getFile();
if (file != null) {
PsiElement context = InjectedLanguageManager.getInstance(file.getProject()).getInjectionHost(file);
if (context != null) {
PsiElement usageElement = usage.getElement();
if (usageElement == null) continue;
PsiReference psiReference = usage.getReference();
if (psiReference == null) continue;
int injectionOffsetInMasterFile = InjectedLanguageManager.getInstance(usageElement.getProject()).injectedToHost(usageElement, usageElement.getTextOffset());
TextRange rangeInElement = usage.getRangeInElement();
assert rangeInElement != null : usage;
TextRange range = rangeInElement.shiftRight(injectionOffsetInMasterFile);
PsiFile containingFile = context.getContainingFile();
if (containingFile == null) continue; //move package to another package
set.remove(
NonCodeUsageInfo.create(
containingFile,
range.getStartOffset(),
range.getEndOffset(),
((MoveRenameUsageInfo)usage).getReferencedElement(),
newTextInNonCodeUsage
)
);
}
}
}
}
return set.toArray(new UsageInfo[set.size()]);
}
@NotNull
public static UsageInfo[] toUsageInfoArray(@NotNull final Collection<? extends UsageInfo> collection) {
final int size = collection.size();
return size == 0 ? UsageInfo.EMPTY_ARRAY : collection.toArray(new UsageInfo[size]);
}
@NotNull
public static PsiElement[] toElements(@NotNull UsageInfo[] usageInfos) {
return ContainerUtil.map2Array(usageInfos, PsiElement.class, new Function<UsageInfo, PsiElement>() {
@Override
public PsiElement fun(UsageInfo info) {
return info.getElement();
}
});
}
public static void navigateTo(@NotNull UsageInfo info, boolean requestFocus) {
int offset = info.getNavigationOffset();
VirtualFile file = info.getVirtualFile();
Project project = info.getProject();
if (file != null) {
FileEditorManager.getInstance(project).openTextEditor(new OpenFileDescriptor(project, file, offset), requestFocus);
}
}
public static Set<UsageInfo> getNotExcludedUsageInfos(final UsageView usageView) {
Set<Usage> excludedUsages = usageView.getExcludedUsages();
Set<UsageInfo> usageInfos = new LinkedHashSet<UsageInfo>();
for (Usage usage : usageView.getUsages()) {
if (usage instanceof UsageInfo2UsageAdapter && !excludedUsages.contains(usage)) {
UsageInfo usageInfo = ((UsageInfo2UsageAdapter)usage).getUsageInfo();
usageInfos.add(usageInfo);
}
}
return usageInfos;
}
public static boolean reportNonRegularUsages(UsageInfo[] usages, final Project project) {
boolean inGeneratedCode = hasUsagesInGeneratedCode(usages, project);
if (hasNonCodeUsages(usages) || inGeneratedCode) {
StatusBar statusBar = WindowManager.getInstance().getStatusBar(project);
if (statusBar != null) {
statusBar.setInfo(inGeneratedCode ? RefactoringBundle.message("occurrences.found.in.comments.strings.non.java.files.and.generated.code")
: RefactoringBundle.message("occurrences.found.in.comments.strings.and.non.java.files"));
}
return true;
}
return false;
}
}