[java-execution] IDEA-327658 Freeze due to non-cancelable RA in ShowAffectedTestsAction.findMethods.

- do not run until it calls explicitly

GitOrigin-RevId: 17ed84ad5ed3d675898a50fea547c21c265270b9
This commit is contained in:
Mikhail Pyltsin
2023-10-12 16:00:59 +02:00
committed by intellij-monorepo-bot
parent cdae8b8138
commit 87e2d5c58f
3 changed files with 13 additions and 84 deletions

View File

@@ -280,6 +280,7 @@ error.no.scratch.file.associated.with.configuration=No scratch file associated w
error.associated.scratch.file.not.found=Associated scratch file not found
java.scratch=Java Scratch
configuration.for.java.scratch.files=Configuration for Java scratch files
test.discovery.find.affected.tests=Find affected tests...
test.discovery.show.affected.tests=Show affected tests
test.discovery.parametrized=Parametrized
test.discovery.unused.test.data.tab.title=Unused Test Data

View File

@@ -5,64 +5,23 @@ import com.intellij.execution.testDiscovery.actions.ShowAffectedTestsAction;
import com.intellij.ide.DataManager;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.compiler.JavaCompilerBundle;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vcs.changes.*;
import com.intellij.psi.PsiMethod;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ChangeListDecorator;
import com.intellij.openapi.vcs.changes.LocalChangeList;
import com.intellij.ui.ColoredTreeCellRenderer;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.Alarm;
import com.intellij.util.io.PowerStatus;
import com.intellij.util.messages.MessageBusConnection;
import com.intellij.util.ui.EdtInvocationManager;
import com.intellij.util.ui.NamedColorUtil;
import org.jetbrains.annotations.NotNull;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import static com.intellij.ui.SimpleTextAttributes.STYLE_UNDERLINE;
final class AffectedTestsInChangeListPainter implements ChangeListDecorator {
private final Project myProject;
private final Alarm myAlarm;
private final AtomicReference<Set<String>> myChangeListsToShow = new AtomicReference<>(Collections.emptySet());
public AffectedTestsInChangeListPainter(@NotNull Project project) {
myProject = project;
ChangeListListener changeListListener = new ChangeListAdapter() {
@Override
public void changeListsChanged() {
scheduleUpdate();
}
@Override
public void changeListUpdateDone() {
scheduleUpdate();
}
@Override
public void defaultListChanged(ChangeList oldDefaultList, ChangeList newDefaultList, boolean automatic) {
scheduleUpdate();
}
};
myAlarm = new Alarm(Alarm.ThreadToUse.POOLED_THREAD, project);
MessageBusConnection connection = myProject.getMessageBus().connect();
connection.subscribe(ChangeListListener.TOPIC, changeListListener);
DumbService.getInstance(myProject).runWhenSmart(() -> scheduleUpdate());
}
private void scheduleRefresh() {
if (!myProject.isDisposed()) {
ChangesViewManager.getInstance(myProject).scheduleRefresh();
}
}
private static int updateDelay() {
return PowerStatus.getPowerStatus() == PowerStatus.AC ? 50 : 300;
}
@Override
@@ -74,46 +33,12 @@ final class AffectedTestsInChangeListPainter implements ChangeListDecorator {
if (!Registry.is("show.affected.tests.in.changelists")) return;
if (!ShowAffectedTestsAction.isEnabled(myProject)) return;
if (changeList.getChanges().isEmpty()) return;
if (!myChangeListsToShow.get().contains(changeList.getId())) return;
renderer.append(", ", SimpleTextAttributes.GRAYED_ATTRIBUTES);
renderer.append(JavaCompilerBundle.message("test.discovery.show.affected.tests"), new SimpleTextAttributes(STYLE_UNDERLINE,
NamedColorUtil.getInactiveTextColor()), (Runnable)() -> {
renderer.append(JavaCompilerBundle.message("test.discovery.find.affected.tests"), new SimpleTextAttributes(STYLE_UNDERLINE, NamedColorUtil.getInactiveTextColor()), (Runnable)() -> {
DataContext dataContext = DataManager.getInstance().getDataContext(renderer.getTree());
Change[] changes = changeList.getChanges().toArray(Change.EMPTY_CHANGE_ARRAY);
ShowAffectedTestsAction.showDiscoveredTestsByChanges(myProject, changes, changeList.getName(), dataContext);
});
}
private void scheduleUpdate() {
if (!Registry.is("show.affected.tests.in.changelists")) return;
if (!ShowAffectedTestsAction.isEnabled(myProject)) return;
myAlarm.cancelAllRequests();
if (!myAlarm.isDisposed()) {
myAlarm.addRequest(() -> update(), updateDelay());
}
}
private void update() {
myChangeListsToShow.set(
ChangeListManager.getInstance(myProject).getChangeLists().stream()
.filter(list -> !list.getChanges().isEmpty())
.map(list -> {
Collection<Change> changes = list.getChanges();
PsiMethod[] methods = ShowAffectedTestsAction.findMethods(myProject, changes.toArray(Change.EMPTY_CHANGE_ARRAY));
List<String> paths = ShowAffectedTestsAction.getRelativeAffectedPaths(myProject, changes);
if (methods.length == 0 && paths.isEmpty()) return null;
Ref<String> ref = Ref.create();
ShowAffectedTestsAction.processMethods(myProject, methods, paths, (clazz, method, parameter) -> {
ref.set(list.getId());
return false;
});
return ref.get();
}).filter(Objects::nonNull).collect(Collectors.toSet())
);
EdtInvocationManager.getInstance().invokeLater(this::scheduleRefresh);
}
}

View File

@@ -1,11 +1,9 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.execution.testDiscovery.actions;
import com.intellij.CommonBundle;
import com.intellij.codeInsight.actions.VcsFacadeImpl;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.Executor;
import com.intellij.execution.JavaTestConfigurationWithDiscoverySupport;
import com.intellij.execution.Location;
import com.intellij.execution.*;
import com.intellij.execution.actions.ConfigurationContext;
import com.intellij.execution.actions.RunConfigurationProducer;
import com.intellij.execution.executors.DefaultRunExecutor;
@@ -206,11 +204,16 @@ public class ShowAffectedTestsAction extends AnAction {
@NotNull DataContext dataContext) {
DiscoveredTestsTree tree = showTree(project, dataContext, title, ActionPlaces.UNKNOWN);
FeatureUsageTracker.getInstance().triggerFeatureUsed("test.discovery.selected.changes");
tree.getEmptyText().setText(CommonBundle.message("tree.node.loading"));
ApplicationManager.getApplication().executeOnPooledThread(() -> {
PsiMethod[] methods = findMethods(project, changes);
List<String> filePaths = getRelativeAffectedPaths(project, Arrays.asList(changes));
processMethodsAsync(project, methods, filePaths, createTreeProcessor(tree), () -> tree.setPaintBusy(false));
processMethodsAsync(project, methods, filePaths, createTreeProcessor(tree), () ->
{
tree.setPaintBusy(false);
tree.getEmptyText().setText(ExecutionBundle.message("no.tests.captured.for.0", title));
});
});
}