diff --git a/platform/usageView/src/com/intellij/usages/ReadWriteAccessUsageInfo2UsageAdapter.java b/platform/usageView/src/com/intellij/usages/ReadWriteAccessUsageInfo2UsageAdapter.java index 7b7a01add11b..7ae6f479dca5 100644 --- a/platform/usageView/src/com/intellij/usages/ReadWriteAccessUsageInfo2UsageAdapter.java +++ b/platform/usageView/src/com/intellij/usages/ReadWriteAccessUsageInfo2UsageAdapter.java @@ -15,7 +15,6 @@ */ package com.intellij.usages; -import com.intellij.ui.ComputableIcon; import com.intellij.usageView.UsageInfo; import com.intellij.util.PlatformIcons; @@ -32,13 +31,13 @@ public class ReadWriteAccessUsageInfo2UsageAdapter extends UsageInfo2UsageAdapte myAccessedForReading = accessedForReading; myAccessedForWriting = accessedForWriting; if (myAccessedForReading && myAccessedForWriting) { - myIcon = ComputableIcon.create(PlatformIcons.VARIABLE_RW_ACCESS); + myIcon = PlatformIcons.VARIABLE_RW_ACCESS; } else if (myAccessedForWriting) { - myIcon = ComputableIcon.create(PlatformIcons.VARIABLE_WRITE_ACCESS); // If icon is changed, don't forget to change UTCompositeUsageNode.getIcon(); + myIcon = PlatformIcons.VARIABLE_WRITE_ACCESS; // If icon is changed, don't forget to change UTCompositeUsageNode.getIcon(); } else if (myAccessedForReading){ - myIcon = ComputableIcon.create(PlatformIcons.VARIABLE_READ_ACCESS); // If icon is changed, don't forget to change UTCompositeUsageNode.getIcon(); + myIcon = PlatformIcons.VARIABLE_READ_ACCESS; // If icon is changed, don't forget to change UTCompositeUsageNode.getIcon(); } } diff --git a/platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java b/platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java index 36100fa37243..60205d4dbd03 100644 --- a/platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java +++ b/platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java @@ -30,11 +30,11 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.*; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Segment; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.reference.SoftReference; -import com.intellij.ui.ComputableIcon; import com.intellij.usageView.UsageInfo; import com.intellij.usages.rules.*; import com.intellij.util.IncorrectOperationException; @@ -67,63 +67,63 @@ public class UsageInfo2UsageAdapter implements UsageInModule, private final UsageInfo myUsageInfo; private final List myMergedUsageInfos = new SmartList(); // contains all merged infos, including myUsageInfo - private int myLineNumber; - private int myOffset = -1; - protected ComputableIcon myIcon; - private String myTooltipText; + private final int myLineNumber; + private final int myOffset; + protected Icon myIcon; private Reference myTextChunks; // allow to be gced and recreated on-demand because it requires a lot of memory public UsageInfo2UsageAdapter(@NotNull final UsageInfo usageInfo) { myUsageInfo = usageInfo; myMergedUsageInfos.add(usageInfo); - ApplicationManager.getApplication().runReadAction(new Runnable() { + Pair data = + ApplicationManager.getApplication().runReadAction(new Computable>() { @Override - public void run() { + public Pair compute() { PsiElement element = getElement(); - Document document = PsiDocumentManager.getInstance(getProject()).getDocument(element.getContainingFile()); - int startOffset = myUsageInfo.getNavigationOffset(); + PsiFile psiFile = usageInfo.getFile(); + Document document = psiFile == null ? null : PsiDocumentManager.getInstance(getProject()).getDocument(psiFile); - if (document != null) { - myLineNumber = getLineNumber(document, startOffset); - initChunks(); - } - else { // element over light virtual file - TextChunk[] chunks = { - new TextChunk(new TextAttributes(), element.getText()) - }; - myTextChunks = new SoftReference(chunks); - myOffset = element.getTextOffset(); - } - - if (element instanceof PsiFile) { - myIcon = null; + int offset; + int lineNumber; + if (document == null) { + // element over light virtual file + offset = element.getTextOffset(); + lineNumber = -1; } else { - myIcon = new ComputableIcon(new Computable() { - @Override - public Icon compute() { - PsiElement psiElement = getElement(); - return psiElement != null && psiElement.isValid() ? psiElement.getIcon(0) : null; - } - }); + offset = -1; + int startOffset = myUsageInfo.getNavigationOffset(); + lineNumber = getLineNumber(document, startOffset); } - - myTooltipText = usageInfo.getTooltipText(); + return Pair.create(offset, lineNumber); } }); + myOffset = data.first; + myLineNumber = data.second; myModificationStamp = getCurrentModificationStamp(); } - private static int getLineNumber(final Document document, final int startOffset) { + private static int getLineNumber(@NotNull Document document, final int startOffset) { if (document.getTextLength() == 0) return 0; if (startOffset >= document.getTextLength()) return document.getLineCount(); return document.getLineNumber(startOffset); } + @NotNull private TextChunk[] initChunks() { - PsiFile file = getPsiFile(); - TextChunk[] chunks = file == null ? TextChunk.EMPTY_ARRAY : ChunkExtractor.extractChunks(file, this); + PsiFile psiFile = getPsiFile(); + Document document = psiFile == null ? null : PsiDocumentManager.getInstance(getProject()).getDocument(psiFile); + TextChunk[] chunks; + if (document == null) { + // element over light virtual file + PsiElement element = getElement(); + chunks = new TextChunk[] {new TextChunk(new TextAttributes(), element.getText())}; + } + else { + chunks = ChunkExtractor.extractChunks(psiFile, this); + } + myTextChunks = new SoftReference(chunks); return chunks; } @@ -159,7 +159,9 @@ public class UsageInfo2UsageAdapter implements UsageInModule, FileEditor editor = FileEditorManager.getInstance(getProject()).getSelectedEditor(virtualFile); if (!(editor instanceof TextEditor)) return null; - return new TextEditorLocation(getUsageInfo().getSegment().getStartOffset(), (TextEditor)editor); + Segment segment = getUsageInfo().getSegment(); + if (segment == null) return null; + return new TextEditorLocation(segment.getStartOffset(), (TextEditor)editor); } @Override @@ -183,7 +185,7 @@ public class UsageInfo2UsageAdapter implements UsageInModule, } // must iterate in start offset order - public boolean processRangeMarkers(Processor processor) { + public boolean processRangeMarkers(@NotNull Processor processor) { for (UsageInfo usageInfo : myMergedUsageInfos) { Segment segment = usageInfo.getSegment(); if (segment != null && !processor.process(segment)) { @@ -242,6 +244,7 @@ public class UsageInfo2UsageAdapter implements UsageInModule, return offset; } + @NotNull private Project getProject() { return getUsageInfo().getProject(); } @@ -304,7 +307,7 @@ public class UsageInfo2UsageAdapter implements UsageInModule, } @Override - public boolean merge(MergeableUsage other) { + public boolean merge(@NotNull MergeableUsage other) { if (!(other instanceof UsageInfo2UsageAdapter)) return false; UsageInfo2UsageAdapter u2 = (UsageInfo2UsageAdapter)other; assert u2 != this; @@ -373,6 +376,11 @@ public class UsageInfo2UsageAdapter implements UsageInModule, return s1.getStartOffset() + shift1 - s2.getStartOffset() - shift2; } + @Override + public boolean equals(Object obj) { + return super.equals(obj); + } + @Override public void rename(String newName) throws IncorrectOperationException { final PsiReference reference = getUsageInfo().getReference(); @@ -415,7 +423,8 @@ public class UsageInfo2UsageAdapter implements UsageInModule, @Override @NotNull public TextChunk[] getText() { - TextChunk[] chunks = myTextChunks.get(); + Reference reference = myTextChunks; + TextChunk[] chunks = reference == null ? null : reference.get(); final long currentModificationStamp = getCurrentModificationStamp(); boolean isModified = currentModificationStamp != myModificationStamp; if (chunks == null || isValid() && isModified) { @@ -429,10 +438,6 @@ public class UsageInfo2UsageAdapter implements UsageInModule, @Override @NotNull public String getPlainText() { - //if (myRangeMarkers.isEmpty()) { // element over light virtual file - // return myTextChunks[0].getText(); - //} - int startOffset = getNavigationOffset(); final PsiElement element = getElement(); if (element != null && startOffset != -1) { @@ -458,11 +463,16 @@ public class UsageInfo2UsageAdapter implements UsageInModule, @Override public Icon getIcon() { - return myIcon != null ? myIcon.getIcon() : null; + Icon icon = myIcon; + if (icon == null) { + PsiElement psiElement = getElement(); + myIcon = icon = psiElement != null && psiElement.isValid() ? psiElement.getIcon(0) : null; + } + return icon; } @Override public String getTooltipText() { - return myTooltipText; + return myUsageInfo.getTooltipText(); } } diff --git a/platform/usageView/src/com/intellij/usages/impl/rules/FileGroupingRule.java b/platform/usageView/src/com/intellij/usages/impl/rules/FileGroupingRule.java index b461e5ec9ca1..b0f8b1ee55be 100644 --- a/platform/usageView/src/com/intellij/usages/impl/rules/FileGroupingRule.java +++ b/platform/usageView/src/com/intellij/usages/impl/rules/FileGroupingRule.java @@ -15,17 +15,16 @@ */ package com.intellij.usages.impl.rules; +import com.intellij.injected.editor.VirtualFileWindow; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Iconable; import com.intellij.openapi.vcs.FileStatus; import com.intellij.openapi.vcs.FileStatusManager; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; -import com.intellij.ui.ComputableIcon; import com.intellij.usages.NamedPresentably; import com.intellij.usages.Usage; import com.intellij.usages.UsageGroup; @@ -33,7 +32,6 @@ import com.intellij.usages.UsageView; import com.intellij.usages.rules.UsageGroupingRule; import com.intellij.usages.rules.UsageInFile; import com.intellij.util.IconUtil; -import com.intellij.injected.editor.VirtualFileWindow; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -62,7 +60,7 @@ public class FileGroupingRule implements UsageGroupingRule { private final Project myProject; private final VirtualFile myFile; private String myPresentableName; - private ComputableIcon myIcon; + private Icon myIcon; public FileUsageGroup(@NotNull Project project, @NotNull VirtualFile file) { myProject = project; @@ -78,12 +76,7 @@ public class FileGroupingRule implements UsageGroupingRule { @Override public void update() { if (isValid()) { - myIcon = new ComputableIcon(new Computable() { - @Override - public Icon compute() { - return getIconImpl(); - } - }); + myIcon = getIconImpl(); myPresentableName = myFile.getName(); } } @@ -103,7 +96,7 @@ public class FileGroupingRule implements UsageGroupingRule { @Override public Icon getIcon(boolean isOpen) { - return myIcon.getIcon(); + return myIcon; } @Override