migrate TreeStructureProvider to uiDataSnapshot

GitOrigin-RevId: 250632e2302977608c45a84079191519fa024b6d
This commit is contained in:
Gregory.Shrago
2024-08-12 12:03:28 +04:00
committed by intellij-monorepo-bot
parent 7b0461349c
commit 342245ef74
9 changed files with 65 additions and 81 deletions

View File

@@ -151,6 +151,7 @@ com.intellij.ide.projectView.TreeStructureProvider
- com.intellij.openapi.project.PossiblyDumbAware
- getData(java.util.Collection,java.lang.String):java.lang.Object
- a:modify(com.intellij.ide.util.treeView.AbstractTreeNode,java.util.Collection,com.intellij.ide.projectView.ViewSettings):java.util.Collection
- uiDataSnapshot(com.intellij.openapi.actionSystem.DataSink,java.util.Collection):V
com.intellij.ide.projectView.ViewSettings
- com.intellij.ide.util.treeView.NodeOptions
- sf:DEFAULT:com.intellij.ide.projectView.ViewSettings

View File

@@ -2,6 +2,7 @@
package com.intellij.ide.projectView;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.openapi.actionSystem.DataSink;
import com.intellij.openapi.extensions.ProjectExtensionPointName;
import com.intellij.openapi.project.PossiblyDumbAware;
import org.jetbrains.annotations.ApiStatus;
@@ -35,6 +36,17 @@ public interface TreeStructureProvider extends PossiblyDumbAware {
@NotNull Collection<AbstractTreeNode<?>> children,
ViewSettings settings);
/**
* Override to populate UI data snapshot for the selection.
* Or implement a {@link com.intellij.openapi.actionSystem.UiDataRule} instead.
*
* @see com.intellij.openapi.actionSystem.UiDataProvider
*/
default void uiDataSnapshot(@NotNull DataSink sink,
@NotNull Collection<? extends AbstractTreeNode<?>> selection) {
DataSink.uiDataSnapshot(sink, dataId -> getData(selection, dataId));
}
/**
* Returns a user data object of the specified type for the specified selection in the
* project view.
@@ -45,7 +57,7 @@ public interface TreeStructureProvider extends PossiblyDumbAware {
* @return the data object, or null if no data object can be returned by this provider.
* @see com.intellij.openapi.actionSystem.DataProvider
*
* @deprecated Use {@link com.intellij.openapi.actionSystem.UiDataRule} instead.
* @deprecated Use {@link #uiDataSnapshot(DataSink, Collection)} instead.
*/
@Deprecated(forRemoval = true)
default @Nullable Object getData(@NotNull Collection<? extends AbstractTreeNode<?>> selected, @NotNull String dataId) {

View File

@@ -16016,8 +16016,8 @@ f:com.intellij.ide.projectView.impl.CompoundProjectViewNodeDecorator
f:com.intellij.ide.projectView.impl.CompoundTreeStructureProvider
- com.intellij.ide.projectView.TreeStructureProvider
- s:get(com.intellij.openapi.project.Project):com.intellij.ide.projectView.TreeStructureProvider
- getData(java.util.Collection,java.lang.String):java.lang.Object
- modify(com.intellij.ide.util.treeView.AbstractTreeNode,java.util.Collection,com.intellij.ide.projectView.ViewSettings):java.util.Collection
- uiDataSnapshot(com.intellij.openapi.actionSystem.DataSink,java.util.Collection):V
f:com.intellij.ide.projectView.impl.DirectoryUrl
- com.intellij.ide.projectView.impl.AbstractUrl
- <init>(java.lang.String,java.lang.String):V

View File

@@ -337,10 +337,15 @@ public abstract class AbstractProjectViewPane implements UiCompatibleDataProvide
navigatables.isEmpty() ? null : navigatables.toArray(Navigatable.EMPTY_NAVIGATABLE_ARRAY));
}
if (myTreeStructure instanceof AbstractTreeStructureBase treeStructure) {
//noinspection unchecked
List<AbstractTreeNode<?>> selection = (List)ContainerUtil.filterIsInstance(
selectedUserObjects, AbstractTreeNode.class);
DataSink.uiDataSnapshot(sink, o -> treeStructure.getDataFromProviders(selection, o));
List<TreeStructureProvider> providers = treeStructure.getProviders();
if (providers != null && !providers.isEmpty()) {
//noinspection unchecked
List<AbstractTreeNode<?>> selection = (List)ContainerUtil.filterIsInstance(
selectedUserObjects, AbstractTreeNode.class);
for (TreeStructureProvider provider : ContainerUtil.reverse(providers)) {
provider.uiDataSnapshot(sink, selection);
}
}
}
sink.set(CommonDataKeys.PROJECT, myProject);
sink.set(PlatformCoreDataKeys.SELECTED_ITEMS, selectedUserObjects);

View File

@@ -4,11 +4,13 @@ package com.intellij.ide.projectView.impl;
import com.intellij.ide.projectView.TreeStructureProvider;
import com.intellij.ide.projectView.ViewSettings;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.openapi.actionSystem.DataSink;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.util.containers.ContainerUtil;
import one.util.streamex.StreamEx;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -48,7 +50,7 @@ public final class CompoundTreeStructureProvider implements TreeStructureProvide
for (TreeStructureProvider provider : EP.getExtensions(myProject)) {
try {
children = provider.modify(parent, children, settings);
if (children.stream().anyMatch(Objects::isNull)) {
if (ContainerUtil.exists(children, Objects::isNull)) {
LOG.warn("null child provided by " + provider);
children = StreamEx.of(children).nonNull().toImmutableList();
}
@@ -68,20 +70,17 @@ public final class CompoundTreeStructureProvider implements TreeStructureProvide
}
@Override
public @Nullable Object getData(@NotNull Collection<? extends AbstractTreeNode<?>> selection, @NotNull String dataId) {
if (!myProject.isDisposed() && !selection.isEmpty()) {
for (TreeStructureProvider provider : EP.getExtensions(myProject)) {
try {
Object data = provider.getData(selection, dataId);
if (data != null) return data;
}
catch (IndexNotReadyException | ProcessCanceledException ignore) {
}
catch (Exception exception) {
LOG.warn("unexpected error in " + provider, exception);
}
public void uiDataSnapshot(@NotNull DataSink sink, @NotNull Collection<? extends AbstractTreeNode<?>> selection) {
if (myProject.isDisposed() || selection.isEmpty()) return;
for (TreeStructureProvider provider : ContainerUtil.reverse(EP.getExtensions(myProject))) {
try {
provider.uiDataSnapshot(sink, selection);
}
catch (IndexNotReadyException | ProcessCanceledException ignore) {
}
catch (Exception exception) {
LOG.warn("unexpected error in " + provider, exception);
}
}
return null;
}
}

View File

@@ -4,9 +4,6 @@ package com.intellij.ide.util.treeView;
import com.intellij.ide.projectView.SettingsProvider;
import com.intellij.ide.projectView.TreeStructureProvider;
import com.intellij.ide.projectView.ViewSettings;
import com.intellij.openapi.actionSystem.CompositeDataProvider;
import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.actionSystem.PlatformCoreDataKeys;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressManager;
@@ -15,7 +12,6 @@ import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -92,20 +88,6 @@ public abstract class AbstractTreeStructureBase extends AbstractTreeStructure {
@Deprecated(forRemoval = true)
@ApiStatus.Internal
public @Nullable Object getDataFromProviders(@NotNull List<AbstractTreeNode<?>> selectedNodes, @NotNull String dataId) {
List<TreeStructureProvider> providers = getProvidersDumbAware();
if (providers.isEmpty()) {
return null;
}
if (PlatformCoreDataKeys.BGT_DATA_PROVIDER.is(dataId)) {
List<DataProvider> bgtProviders = ContainerUtil.mapNotNull(providers, o -> (DataProvider)o.getData(selectedNodes, dataId));
return CompositeDataProvider.compose(bgtProviders);
}
for (TreeStructureProvider treeStructureProvider : providers) {
Object fromProvider = treeStructureProvider.getData(selectedNodes, dataId);
if (fromProvider != null) {
return fromProvider;
}
}
return null;
}

View File

@@ -8,6 +8,7 @@ import com.intellij.ide.DeleteProvider;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.IdeView;
import com.intellij.ide.projectView.ProjectViewNode;
import com.intellij.ide.projectView.TreeStructureProvider;
import com.intellij.ide.projectView.impl.ModuleGroup;
import com.intellij.ide.projectView.impl.ProjectAbstractTreeStructureBase;
import com.intellij.ide.projectView.impl.nodes.LibraryGroupElement;
@@ -375,7 +376,12 @@ public class CommanderPanel extends JPanel {
sink.set(PlatformDataKeys.DELETE_ELEMENT_PROVIDER, myDeleteElementProvider);
if (myProjectTreeStructure != null) {
DataSink.uiDataSnapshot(sink, dataId -> myProjectTreeStructure.getDataFromProviders(selection, dataId));
List<TreeStructureProvider> providers = myProjectTreeStructure.getProviders();
if (providers != null && !providers.isEmpty()) {
for (TreeStructureProvider provider : ContainerUtil.reverse(providers)) {
provider.uiDataSnapshot(sink, selection);
}
}
}
sink.lazy(CommonDataKeys.PSI_ELEMENT, () -> {
return getNodeElement(ContainerUtil.getOnlyItem(selection));

View File

@@ -7,8 +7,7 @@ import com.intellij.ide.projectView.impl.nodes.PsiFileNode;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.lang.properties.*;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.actionSystem.PlatformCoreDataKeys;
import com.intellij.openapi.actionSystem.DataSink;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.project.DumbAware;
@@ -101,32 +100,25 @@ public class ResourceBundleGrouper implements TreeStructureProvider, DumbAware {
}
@Override
public Object getData(@NotNull Collection<? extends AbstractTreeNode<?>> selected, @NotNull String dataId) {
if (PlatformCoreDataKeys.BGT_DATA_PROVIDER.is(dataId)) {
return (DataProvider)slowId -> getSlowData(selected, slowId);
}
return null;
}
private static Object getSlowData(@NotNull Collection<? extends AbstractTreeNode<?>> selected, @NotNull String dataId) {
if (PlatformDataKeys.DELETE_ELEMENT_PROVIDER.is(dataId)) {
for (AbstractTreeNode<?> selectedElement : selected) {
public void uiDataSnapshot(@NotNull DataSink sink, @NotNull Collection<? extends AbstractTreeNode<?>> selection) {
sink.lazy(PlatformDataKeys.DELETE_ELEMENT_PROVIDER, () -> {
for (AbstractTreeNode<?> selectedElement : selection) {
Object element = selectedElement.getValue();
if (element instanceof ResourceBundle) {
return new ResourceBundleDeleteProvider();
}
}
}
else if (ResourceBundle.ARRAY_DATA_KEY.is(dataId)) {
return null;
});
sink.lazy(ResourceBundle.ARRAY_DATA_KEY, () -> {
List<ResourceBundle> selectedElements = new ArrayList<>();
for (AbstractTreeNode<?> node : selected) {
final Object value = node.getValue();
for (AbstractTreeNode<?> node : selection) {
Object value = node.getValue();
if (value instanceof ResourceBundle) {
selectedElements.add((ResourceBundle)value);
}
}
return selectedElements.isEmpty() ? null : selectedElements.toArray(new ResourceBundle[0]);
}
return null;
});
}
}

View File

@@ -8,10 +8,7 @@ import com.intellij.ide.projectView.ViewSettings;
import com.intellij.ide.projectView.impl.nodes.BasePsiNode;
import com.intellij.ide.util.DeleteHandler;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.openapi.actionSystem.ActionUpdateThread;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiClassOwner;
@@ -85,26 +82,16 @@ public final class FormMergerTreeStructureProvider implements TreeStructureProvi
}
@Override
public Object getData(@NotNull Collection<? extends AbstractTreeNode<?>> selected, @NotNull String dataId) {
if (Form.DATA_KEY.is(dataId)) {
List<Form> result = new ArrayList<>();
for (AbstractTreeNode<?> node : selected) {
if (node instanceof FormNode) {
result.add(((FormNode)node).getValue());
}
}
if (!result.isEmpty()) {
return result.toArray(new Form[0]);
}
}
else if (PlatformDataKeys.DELETE_ELEMENT_PROVIDER.is(dataId)) {
for (AbstractTreeNode<?> node : selected) {
if (node instanceof FormNode) {
return new MyDeleteProvider(selected);
}
}
}
return null;
public void uiDataSnapshot(@NotNull DataSink sink,
@NotNull Collection<? extends AbstractTreeNode<?>> selection) {
List<FormNode> nodes = ContainerUtil.filterIsInstance(selection, FormNode.class);
if (nodes.isEmpty()) return;
sink.lazy(Form.DATA_KEY, () -> {
return ContainerUtil.map2Array(nodes, Form.class, o -> o.getValue());
});
sink.lazy(PlatformDataKeys.DELETE_ELEMENT_PROVIDER, () -> {
return new MyDeleteProvider(selection);
});
}
private static Collection<PsiFile> convertToFiles(Collection<? extends BasePsiNode<? extends PsiElement>> formNodes) {