[execution & split mode] IJPL-184406 Avoid NPE in monolith when working with run content descriptor id

GitOrigin-RevId: 24ce2dbd9220541c6c3395d27b9a60aacf814eb2
This commit is contained in:
Nikita Katkov
2025-09-16 17:16:59 +02:00
committed by intellij-monorepo-bot
parent 4c239d0fe1
commit 8814dc5702
4 changed files with 35 additions and 13 deletions

View File

@@ -3,6 +3,7 @@ package com.intellij.execution
import com.intellij.execution.ui.RunContentDescriptor
import com.intellij.platform.kernel.ids.BackendValueIdType
import com.intellij.platform.kernel.ids.findValueById
import com.intellij.platform.rpc.UID
import kotlinx.serialization.Serializable
import org.jetbrains.annotations.ApiStatus
@@ -11,5 +12,10 @@ import org.jetbrains.annotations.ApiStatus
@Serializable
class RunContentDescriptorIdImpl(override val uid: UID) : RunContentDescriptorId
@ApiStatus.Internal
fun RunContentDescriptorId.findContentValue(): RunContentDescriptor? {
return findValueById(this, type = RunContentDescriptorIdType)
}
@ApiStatus.Internal
object RunContentDescriptorIdType : BackendValueIdType<RunContentDescriptorId, RunContentDescriptor>(::RunContentDescriptorIdImpl)

View File

@@ -21,6 +21,7 @@ import com.intellij.openapi.actionSystem.PlatformCoreDataKeys
import com.intellij.openapi.application.AppUIExecutor
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.EDT
import com.intellij.openapi.diagnostic.thisLogger
import com.intellij.openapi.options.advanced.AdvancedSettings
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Disposer
@@ -48,6 +49,7 @@ import kotlinx.coroutines.future.await
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.annotations.NotNull
import java.awt.KeyboardFocusManager
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentLinkedDeque
@@ -146,9 +148,14 @@ class RunContentManagerImpl(private val project: Project) : RunContentManager {
}
@ApiStatus.Internal
override fun registerRunContentDescriptor(descriptor: RunContentDescriptor) {
descriptors[descriptor.id] = descriptor
Disposer.register(descriptor, Disposable { descriptors.remove(descriptor.id) })
override fun registerRunContentDescriptor(@NotNull descriptor: RunContentDescriptor) {
val runContentDescriptorId = descriptor.id
if (runContentDescriptorId == null) {
thisLogger().warn("ContentDescriptorId was not assigned to descriptor $descriptor")
return
}
descriptors[runContentDescriptorId] = descriptor
Disposer.register(descriptor, Disposable { descriptors.remove(runContentDescriptorId) })
}
@ApiStatus.Internal

View File

@@ -42,6 +42,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.stream.Collectors;
import static com.intellij.execution.RunContentDescriptorIdImplKt.findContentValue;
import static com.intellij.execution.dashboard.RunDashboardCustomizer.CUSTOMIZER_EP_NAME;
import static com.intellij.execution.dashboard.RunDashboardServiceIdKt.findValue;
import static com.intellij.platform.kernel.ids.BackendGlobalIdsKt.storeValueGlobally;
@@ -619,9 +620,7 @@ public final class RunDashboardManagerImpl implements RunDashboardManager, Persi
}
private @Nullable RunnerAndConfigurationSettings findSettings(@NotNull RunContentDescriptorId descriptorId) {
Collection<RunContentDescriptor> descriptors =
RunContentManager.getInstance(myProject).getRunContentDescriptors();
RunContentDescriptor descriptor = ContainerUtil.find(descriptors, it -> descriptorId.equals(it.getId()));
RunContentDescriptor descriptor = getDescriptorById(descriptorId, myProject);
if (descriptor == null) return null;
RunnerAndConfigurationSettings settings = findSettings(descriptor);
@@ -638,6 +637,20 @@ public final class RunDashboardManagerImpl implements RunDashboardManager, Persi
return settings;
}
private static @Nullable RunContentDescriptor getDescriptorById(@NotNull RunContentDescriptorId descriptorId, @NotNull Project project) {
RunContentDescriptor descriptor = null;
if (descriptorId instanceof RunContentDescriptorIdImpl impl) {
descriptor = findContentValue(impl);
}
if (descriptor == null) {
Collection<RunContentDescriptor> descriptors =
RunContentManager.getInstance(project).getRunContentDescriptors();
descriptor = ContainerUtil.find(descriptors, it -> descriptorId.equals(it.getId()));
if (descriptor == null) return null;
}
return descriptor;
}
private @Nullable RunnerAndConfigurationSettings findSettings(@NotNull RunContentDescriptor descriptor) {
Set<ExecutionEnvironment> environments = ExecutionManagerImpl.getInstance(myProject).getExecutionEnvironments(descriptor);
ExecutionEnvironment environment = ContainerUtil.getFirstItem(environments);
@@ -896,9 +909,7 @@ public final class RunDashboardManagerImpl implements RunDashboardManager, Persi
RunContentDescriptorId descriptorId = myDescriptorId;
if (descriptorId == null) return null;
Collection<RunContentDescriptor> descriptors =
RunContentManager.getInstance(mySettings.getConfiguration().getProject()).getRunContentDescriptors();
return ContainerUtil.find(descriptors, descriptor -> descriptorId.equals(descriptor.getId()));
return getDescriptorById(descriptorId, mySettings.getConfiguration().getProject());
}
void setDescriptorId(@Nullable RunContentDescriptorId descriptorId) {
@@ -955,9 +966,7 @@ public final class RunDashboardManagerImpl implements RunDashboardManager, Persi
@Override
public @Nullable RunContentDescriptor getDescriptor() {
Collection<RunContentDescriptor> descriptors =
RunContentManager.getInstance(mySettings.getConfiguration().getProject()).getRunContentDescriptors();
return ContainerUtil.find(descriptors, descriptor -> myDescriptorId.equals(descriptor.getId()));
return getDescriptorById(myDescriptorId, mySettings.getConfiguration().getProject());
}
@Override

View File

@@ -56,7 +56,7 @@ public class RunContentDescriptor implements Disposable {
private Content myContent;
private String myContentToolWindowId;
private RunContentDescriptorId myId;
private RunContentDescriptorId myId = null;
private final AnAction @NotNull [] myRestartActions;
private final @Nullable Runnable myActivationCallback;