IDEA-378858 Rewrite Persistence TW using Logical Structure model

GitOrigin-RevId: 16b1bdd15c36f99121da6ab46131e31c540c360e
This commit is contained in:
Anton Kozub
2025-09-04 19:30:21 +00:00
committed by intellij-monorepo-bot
parent 5ce68af573
commit 46fefbe18c
4 changed files with 55 additions and 30 deletions
@@ -8,6 +8,7 @@ import com.intellij.ide.structureView.customRegions.CustomRegionTreeElement;
import com.intellij.ide.structureView.impl.StructureViewFactoryImpl;
import com.intellij.ide.structureView.impl.common.PsiTreeElementBase;
import com.intellij.ide.structureView.logical.LogicalStructureDataKeys;
import com.intellij.ide.structureView.logical.impl.LogicalStructureElementsVisitor;
import com.intellij.ide.structureView.logical.impl.LogicalStructureViewModel;
import com.intellij.ide.structureView.logical.impl.LogicalStructureViewTreeElement;
import com.intellij.ide.structureView.logical.model.LogicalPsiDescription;
@@ -473,7 +474,7 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre
if (psiDescriptions == null) {
psiDescriptions = logicalStructureViewModel.getAssembledModel().getLogicalPsiDescriptions();
}
return logicalStructureViewModel.visitPathForLogicalElementSelection(treeElement, element, psiDescriptions);
return LogicalStructureElementsVisitor.INSTANCE.visitPathForLogicalElementSelection(treeElement, element, psiDescriptions);
}
return visitPathForElementSelection(path, element, editorOffset, state);
}
@@ -0,0 +1,44 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.ide.structureView.logical.impl
import com.intellij.ide.structureView.StructureViewTreeElement
import com.intellij.ide.structureView.logical.ExternalElementsProvider
import com.intellij.ide.structureView.logical.model.ExtendedLogicalObject
import com.intellij.ide.structureView.logical.model.LogicalPsiDescription
import com.intellij.psi.PsiElement
import com.intellij.ui.tree.TreeVisitor
import org.jetbrains.annotations.ApiStatus
@ApiStatus.Internal
object LogicalStructureElementsVisitor {
fun visitPathForLogicalElementSelection(treeElement: StructureViewTreeElement, element: Any?, psiDescriptions: Set<LogicalPsiDescription>): TreeVisitor.Action {
if (element !is PsiElement) return TreeVisitor.Action.SKIP_CHILDREN
if (treeElement is ElementsBuilder.LogicalGroupStructureElement<*>) {
if (treeElement.grouper is ExternalElementsProvider<*, *>) {
return TreeVisitor.Action.SKIP_CHILDREN
}
return TreeVisitor.Action.CONTINUE
}
if (treeElement is ElementsBuilder.OtherStructureElement<*>) {
return TreeVisitor.Action.CONTINUE
}
val targetElement = psiDescriptions.firstNotNullOfOrNull {
it.getSuitableElement(element)
} ?: return TreeVisitor.Action.SKIP_CHILDREN
if (treeElement is ElementsBuilder.PsiElementStructureElement<*>) {
if (treeElement.element == targetElement) {
return TreeVisitor.Action.INTERRUPT
}
(treeElement.getLogicalAssembledModel().model as? ExtendedLogicalObject)?.let {
if (it.canRepresentPsiElement(targetElement)) return TreeVisitor.Action.INTERRUPT
}
if (treeElement.element?.containingFile != targetElement.containingFile) {
return TreeVisitor.Action.SKIP_CHILDREN
}
return TreeVisitor.Action.CONTINUE
}
return TreeVisitor.Action.SKIP_CHILDREN
}
}
@@ -18,7 +18,6 @@ import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiTarget
import com.intellij.ui.SimpleTextAttributes
import com.intellij.ui.tree.TreeVisitor
import org.jetbrains.annotations.ApiStatus
import java.util.concurrent.CompletableFuture
import java.util.concurrent.ConcurrentHashMap
@@ -75,32 +74,6 @@ class LogicalStructureViewModel private constructor(psiFile: PsiFile, editor: Ed
return null
}
fun visitPathForLogicalElementSelection(treeElement: StructureViewTreeElement, element: Any?, psiDescriptions: Set<LogicalPsiDescription>): TreeVisitor.Action {
if (element !is PsiElement) return TreeVisitor.Action.SKIP_CHILDREN
if (treeElement is ElementsBuilder.LogicalGroupStructureElement<*>) {
if (treeElement.grouper is ExternalElementsProvider<*, *>) {
return TreeVisitor.Action.SKIP_CHILDREN
}
return TreeVisitor.Action.CONTINUE
}
val targetElement = psiDescriptions.firstNotNullOfOrNull {
it.getSuitableElement(element)
} ?: return TreeVisitor.Action.SKIP_CHILDREN
if (treeElement is ElementsBuilder.PsiElementStructureElement<*>) {
if (treeElement.element == targetElement) {
return TreeVisitor.Action.INTERRUPT
}
(treeElement.getLogicalAssembledModel().model as? ExtendedLogicalObject)?.let {
if (it.canRepresentPsiElement(targetElement)) return TreeVisitor.Action.INTERRUPT
}
if (treeElement.element?.containingFile != targetElement.containingFile) {
return TreeVisitor.Action.SKIP_CHILDREN
}
return TreeVisitor.Action.CONTINUE
}
return TreeVisitor.Action.SKIP_CHILDREN
}
private fun getModel(element: StructureViewTreeElement): Any? {
return when (element) {
is ElementsBuilder.LogicalGroupStructureElement<*> -> element.grouper
@@ -123,7 +96,8 @@ interface LogicalStructureViewTreeElement<T> : StructureViewTreeElement {
}
private class ElementsBuilder {
@ApiStatus.Internal
class ElementsBuilder {
private val typePresentationService = TypePresentationService.getService()
private val groupElements: MutableMap<LogicalStructureAssembledModel<*>, MutableMap<ExternalElementsProvider<*, *>, LogicalGroupStructureElement<*>>> = ConcurrentHashMap()
@@ -197,7 +171,7 @@ private class ElementsBuilder {
}
}
private fun getPresentationData(model: Any): PresentationData {
fun getPresentationData(model: Any): PresentationData {
val presentationProvider = LogicalModelPresentationProvider.getForObject(model)
if (presentationProvider == null) {
return PresentationData(
@@ -67,6 +67,12 @@ class LogicalStructureAssembledModel<T> private constructor(
result.add(model)
}
}
if (model is LogicalContainer<*>) {
model.getElements().forEach { child ->
if (child == null) return@forEach
result.addAll(getLogicalPsiDescriptions(child))
}
}
for (provider in LogicalStructureElementsProvider.getProviders(model)) {
if (provider is LogicalPsiDescription) {
if (!provider.isAskChildren()) {