show "101 sub classes found so far" instead of just "classes found" to be able to tell if the search is finished; removed special unit-test-only mode from GotoImplementationHandler

This commit is contained in:
Alexey Kudravtsev
2016-05-13 13:03:02 +03:00
parent 7b037bf9c0
commit a6ec1597be
11 changed files with 104 additions and 55 deletions
@@ -410,9 +410,10 @@ public class MarkerType {
@Override
public String getCaption(int size) {
String suffix = isFinished() ? "" : " so far";
return myClass.isInterface()
? CodeInsightBundle.message("goto.implementation.chooserTitle", myClass.getName(), size)
: DaemonBundle.message("navigation.title.subclass", myClass.getName(), size);
? CodeInsightBundle.message("goto.implementation.chooserTitle", myClass.getName(), size, suffix)
: DaemonBundle.message("navigation.title.subclass", myClass.getName(), size, suffix);
}
@Override
@@ -15,15 +15,18 @@
*/
package com.intellij.navigation;
import com.intellij.codeInsight.navigation.GotoImplementationHandler;
import com.intellij.codeInsight.navigation.GotoTargetHandler;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiMethod;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.testFramework.fixtures.CodeInsightTestUtil;
import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase;
import java.util.Arrays;
public class GotoImplementationHandlerTest extends JavaCodeInsightFixtureTestCase {
public void testMultipleImplsFromAbstractCall() {
PsiFile file = myFixture.addFileToProject("Foo.java", "public abstract class Hello {\n" +
@@ -211,6 +214,12 @@ public class GotoImplementationHandlerTest extends JavaCodeInsightFixtureTestCas
final PsiElement[] impls = getTargets(file);
assertEquals(2, impls.length);
// target are non-deterministic now
Arrays.sort(impls, (o1, o2) -> {
String name1 = ((PsiMethod)o1).getContainingClass().getName();
String name2 = ((PsiMethod)o2).getContainingClass().getName();
return StringUtil.compare(name1, name2, false);
});
final PsiElement method = impls[0];
assertTrue(method instanceof PsiMethod);
final PsiClass aClass = ((PsiMethod)method).getContainingClass();
@@ -219,7 +228,7 @@ public class GotoImplementationHandlerTest extends JavaCodeInsightFixtureTestCas
}
private PsiElement[] getTargets(PsiFile file) {
GotoTargetHandler.GotoData gotoData = new GotoImplementationHandler().getSourceAndTargetElements(myFixture.getEditor(), file);
GotoTargetHandler.GotoData gotoData = CodeInsightTestUtil.gotoImplementation(myFixture.getEditor(), file);
assertNotNull(gotoData);
return gotoData.targets;
}
@@ -51,6 +51,7 @@ public abstract class BackgroundUpdaterTask<T> extends Task.Backgroundable {
private final Object lock = new Object();
private volatile boolean myCanceled;
private volatile boolean myFinished;
public BackgroundUpdaterTask(Project project, String title, boolean canBeCancelled) {
super(project, title, canBeCancelled);
@@ -143,7 +144,17 @@ public abstract class BackgroundUpdaterTask<T> extends Task.Backgroundable {
@Override
public void onSuccess() {
onFinished();
myPopup.setCaption(getCaption(getCurrentSize()));
paintBusy(false);
}
@Override
protected void onFinished() {
myFinished = true;
}
public boolean isFinished() {
return myFinished;
}
}
@@ -19,7 +19,6 @@ package com.intellij.codeInsight.navigation;
import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.codeInsight.TargetElementUtil;
import com.intellij.ide.util.PsiElementListCellRenderer;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
@@ -31,9 +30,7 @@ import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public class GotoImplementationHandler extends GotoTargetHandler {
@@ -48,45 +45,28 @@ public class GotoImplementationHandler extends GotoTargetHandler {
int offset = editor.getCaretModel().getOffset();
PsiElement source = TargetElementUtil.getInstance().findTargetElement(editor, ImplementationSearcher.getFlags(), offset);
if (source == null) return null;
final GotoData gotoData;
final PsiReference reference = TargetElementUtil.findReference(editor, offset);
final TargetElementUtil instance = TargetElementUtil.getInstance();
if (!ApplicationManager.getApplication().isUnitTestMode()) {
gotoData = new GotoData(source, new ImplementationSearcher.FirstImplementationsSearcher(){
@Override
protected boolean accept(PsiElement element) {
return instance.acceptImplementationForReference(reference, element);
}
PsiElement[] targets = new ImplementationSearcher.FirstImplementationsSearcher() {
@Override
protected boolean accept(PsiElement element) {
return instance.acceptImplementationForReference(reference, element);
}
@Override
protected boolean canShowPopupWithOneItem(PsiElement element) {
return false;
}
}.searchImplementations(editor, source, offset), Collections.<AdditionalAction>emptyList());
gotoData.listUpdaterTask = new ImplementationsUpdaterTask(gotoData, editor, offset, reference);
} else {
gotoData = new GotoData(source, new ImplementationSearcher(){
@Override
protected PsiElement[] filterElements(PsiElement element, PsiElement[] targetElements, int offset) {
final List<PsiElement> result = new ArrayList<PsiElement>();
for (PsiElement targetElement : targetElements) {
if (instance.acceptImplementationForReference(reference, targetElement)) {
result.add(targetElement);
}
}
return result.toArray(new PsiElement[result.size()]);
}
}.searchImplementations(editor, source, offset),
Collections.<AdditionalAction>emptyList());
}
@Override
protected boolean canShowPopupWithOneItem(PsiElement element) {
return false;
}
}.searchImplementations(editor, source, offset);
GotoData gotoData = new GotoData(source, targets, Collections.emptyList());
gotoData.listUpdaterTask = new ImplementationsUpdaterTask(gotoData, editor, offset, reference);
return gotoData;
}
@NotNull
@Override
protected String getChooserTitle(PsiElement sourceElement, String name, int length) {
return CodeInsightBundle.message("goto.implementation.chooserTitle", name, length);
@NotNull
protected String getChooserTitle(PsiElement sourceElement, String name, int length, boolean finished) {
return CodeInsightBundle.message("goto.implementation.chooserTitle", name, length, finished ? "" : " so far");
}
@NotNull
@@ -108,7 +88,7 @@ public class GotoImplementationHandler extends GotoTargetHandler {
private final Map<Object, PsiElementListCellRenderer> renderers = new HashMap<Object, PsiElementListCellRenderer>();
private final PsiReference myReference;
public ImplementationsUpdaterTask(@NotNull GotoData gotoData, @NotNull Editor editor, int offset, final PsiReference reference) {
ImplementationsUpdaterTask(@NotNull GotoData gotoData, @NotNull Editor editor, int offset, final PsiReference reference) {
super(gotoData.source.getProject(), ImplementationSearcher.SEARCHING_FOR_IMPLEMENTATIONS);
myEditor = editor;
myOffset = offset;
@@ -140,7 +120,7 @@ public class GotoImplementationHandler extends GotoTargetHandler {
@Override
public String getCaption(int size) {
return getChooserTitle(myGotoData.source, ((PsiNamedElement)myGotoData.source).getName(), size);
return getChooserTitle(myGotoData.source, ((PsiNamedElement)myGotoData.source).getName(), size, isFinished());
}
}
}
@@ -25,6 +25,7 @@ import com.intellij.ide.util.PsiElementListCellRenderer;
import com.intellij.navigation.ItemPresentation;
import com.intellij.navigation.NavigationItem;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ex.util.EditorUtil;
import com.intellij.openapi.extensions.Extensions;
@@ -59,6 +60,7 @@ import java.util.*;
import java.util.List;
public abstract class GotoTargetHandler implements CodeInsightActionHandler {
private static final Logger LOG = Logger.getInstance("#" + GotoTargetHandler.class.getName());
private static final PsiElementListCellRenderer ourDefaultTargetElementRenderer = new DefaultPsiElementListCellRenderer();
private final DefaultListCellRenderer myActionElementRenderer = new ActionCellRenderer();
@@ -73,7 +75,7 @@ public abstract class GotoTargetHandler implements CodeInsightActionHandler {
try {
GotoData gotoData = getSourceAndTargetElements(editor, file);
if (gotoData != null && gotoData.source != null) {
if (gotoData != null) {
show(project, editor, file, gotoData);
}
}
@@ -113,7 +115,7 @@ public abstract class GotoTargetHandler implements CodeInsightActionHandler {
}
final String name = ((PsiNamedElement)gotoData.source).getName();
final String title = getChooserTitle(gotoData.source, name, targets.length);
final String title = getChooserTitle(gotoData.source, name, targets.length, gotoData.listUpdaterTask.isFinished());
if (shouldSortTargets()) {
Arrays.sort(targets, createComparator(gotoData.renderers, gotoData));
@@ -265,10 +267,20 @@ public abstract class GotoTargetHandler implements CodeInsightActionHandler {
}
@NotNull
protected abstract String getChooserTitle(PsiElement sourceElement, String name, int length);
@Deprecated // use getChooserTitle(PsiElement, String, int, boolean) instead
protected String getChooserTitle(PsiElement sourceElement, String name, int length) {
LOG.warn("Please override getChooserTitle(PsiElement, String, int, boolean) instead");
return "";
}
@NotNull
protected String getChooserTitle(PsiElement sourceElement, String name, int length, boolean finished) {
return getChooserTitle(sourceElement, name, length);
}
@NotNull
protected String getFindUsagesTitle(PsiElement sourceElement, String name, int length) {
return getChooserTitle(sourceElement, name, length);
return getChooserTitle(sourceElement, name, length, true);
}
@NotNull
@@ -97,12 +97,13 @@ public class GotoTestOrCodeHandler extends GotoTargetHandler {
@NotNull
@Override
protected String getChooserTitle(PsiElement sourceElement, String name, int length) {
protected String getChooserTitle(PsiElement sourceElement, String name, int length, boolean finished) {
String suffix = finished ? "" : " so far";
if (TestFinderHelper.isTest(sourceElement)) {
return CodeInsightBundle.message("goto.test.chooserTitle.subject", name, length);
return CodeInsightBundle.message("goto.test.chooserTitle.subject", name, length, suffix);
}
else {
return CodeInsightBundle.message("goto.test.chooserTitle.test", name, length);
return CodeInsightBundle.message("goto.test.chooserTitle.test", name, length, suffix);
}
}
@@ -283,13 +283,13 @@ javadoc.method.specified.by=Specified by:
javadoc.external.fetch.error.message=Cannot fetch remote documentation: internal error
searching.for.implementations=Searching For Implementations...
goto.implementation.chooserTitle=<html><body>Choose Implementation of <b>{0}</b> ({1} found)</body></html>
goto.implementation.chooserTitle=<html><body>Choose Implementation of <b>{0}</b> ({1} found{2})</body></html>
goto.implementation.findUsages.title=Implementations of {0}
goto.implementation.notFound=No implementations found
goto.test.chooserTitle.test=<html><body>Choose Test for <b>{0}</b> ({1} found)</body></html>
goto.test.chooserTitle.test=<html><body>Choose Test for <b>{0}</b> ({1} found{2})</body></html>
goto.test.findUsages.test.title=Tests for {0}
goto.test.chooserTitle.subject=<html><body>Choose Test Subject for <b>{0}</b> ({1} found)</body></html>
goto.test.chooserTitle.subject=<html><body>Choose Test Subject for <b>{0}</b> ({1} found{2})</body></html>
goto.test.findUsages.subject.title=Test Subjects for {0}
goto.test.notFound=No test subjects found
@@ -40,7 +40,7 @@ navigation.title.super.method=Choose Super Method of {0}
navigation.findUsages.title.super.method=Super Methods of {0}
navigation.title.implementation.method=<html><body>Choose Implementation of <b>{0}</b> ({1} methods found)</body></html>
navigation.title.overrider.method=<html><body>Choose Overriding Method of <b>{0}</b> ({1} methods found)</body></html>
navigation.title.subclass=<html><body>Choose Subclass of <b>{0}</b> ({1} classes found)</body></html>
navigation.title.subclass=<html><body>Choose Subclass of <b>{0}</b> ({1} classes found{2})</body></html>
performing.code.analysis=Performing code analysis
inspection.extended.description=more...
inspection.collapse.description=less...
@@ -23,6 +23,8 @@ import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInsight.lookup.Lookup;
import com.intellij.codeInsight.lookup.LookupManager;
import com.intellij.codeInsight.lookup.impl.LookupImpl;
import com.intellij.codeInsight.navigation.GotoImplementationHandler;
import com.intellij.codeInsight.navigation.GotoTargetHandler;
import com.intellij.codeInsight.template.Template;
import com.intellij.codeInsight.template.TemplateManager;
import com.intellij.codeInsight.template.impl.TemplateManagerImpl;
@@ -39,14 +41,23 @@ import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.refactoring.rename.inplace.VariableInplaceRenameHandler;
import com.intellij.testFramework.TestDataFile;
import com.intellij.ui.components.JBList;
import com.intellij.ui.popup.AbstractPopup;
import com.intellij.ui.popup.ComponentPopupBuilderImpl;
import com.intellij.ui.speedSearch.NameFilteringListModel;
import com.intellij.util.Function;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -254,4 +265,28 @@ public class CodeInsightTestUtil {
}
});
}
@NotNull
@TestOnly
public static GotoTargetHandler.GotoData gotoImplementation(Editor editor, PsiFile file) {
GotoTargetHandler.GotoData data = new GotoImplementationHandler().getSourceAndTargetElements(editor, file);
if (data.listUpdaterTask != null) {
JBList list = new JBList();
list.setModel(new NameFilteringListModel(list, Function.ID, Condition.FALSE, String::new));
JBPopup popup = new ComponentPopupBuilderImpl(list, null).createPopup();
data.listUpdaterTask.init((AbstractPopup)popup, list, new Ref<>());
data.listUpdaterTask.queue();
try {
while (!data.listUpdaterTask.isFinished()) {
UIUtil.dispatchAllInvocationEvents();
}
}
finally {
Disposer.dispose(popup);
}
}
return data;
}
}
@@ -58,7 +58,7 @@ public class GroovyGotoSuperHandler extends GotoTargetHandler implements Languag
@NotNull
@Override
protected String getChooserTitle(PsiElement sourceElement, String name, int length) {
protected String getChooserTitle(PsiElement sourceElement, String name, int length, boolean finished) {
return CodeInsightBundle.message("goto.super.method.chooser.title");
}
@@ -17,7 +17,6 @@
package org.jetbrains.plugins.groovy;
import com.intellij.codeInsight.navigation.GotoImplementationHandler;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.vfs.VfsUtil;
@@ -26,6 +25,7 @@ import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.testFramework.PsiTestUtil;
import com.intellij.testFramework.fixtures.CodeInsightTestUtil;
import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase;
import com.intellij.testFramework.fixtures.TempDirTestFixture;
import com.intellij.testFramework.fixtures.impl.TempDirTestFixtureImpl;
@@ -55,7 +55,7 @@ public class GroovyGotoImplementationTest extends JavaCodeInsightFixtureTestCase
PsiFile inProject = myFixture.addFileToProject("Foo.groovy", "class <caret>Foo {}\n class Bar extends Foo {}");
myFixture.configureFromExistingVirtualFile(inProject.getVirtualFile());
final PsiElement[] impls = new GotoImplementationHandler().getSourceAndTargetElements(myFixture.getEditor(), inProject).targets;
final PsiElement[] impls = CodeInsightTestUtil.gotoImplementation(myFixture.getEditor(), inProject).targets;
assertEquals(1, impls.length);
}
finally {