mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Better fix for KTIJ-11594 File Nesting configured for Kotlin files makes files disappear from the Project View
it doesn't introduce regression like KTIJ-27970 GitOrigin-RevId: 8c63baeb436df4bf60dd5d1459984d7e38a0d3cf
This commit is contained in:
committed by
intellij-monorepo-bot
parent
7b96d01ca8
commit
cea7ba643a
@@ -1012,7 +1012,7 @@
|
||||
<codeInsight.surroundWithRangeAdjuster implementation="com.intellij.codeInsight.generation.surroundWith.XmlSurroundWithRangeAdjuster"/>
|
||||
<liveTemplateSubstitutor implementation="com.intellij.codeInsight.template.impl.JavaTemplateSubstitutor"/>
|
||||
<defaultLiveTemplates file="liveTemplates/Java"/>
|
||||
<treeStructureProvider implementation="com.intellij.ide.projectView.impl.ClassesTreeStructureProvider" order="last, after NestingTreeStructureProvider"/>
|
||||
<treeStructureProvider id="ClassesTreeStructureProvider" implementation="com.intellij.ide.projectView.impl.ClassesTreeStructureProvider" order="last, after NestingTreeStructureProvider"/>
|
||||
<importFilteringRule implementation="com.intellij.usages.impl.rules.ImportFilteringRule"/>
|
||||
<usageContextPanelProvider implementation="com.intellij.usageView.UsageContextDataflowFromPanel$Provider"/>
|
||||
<usageContextPanelProvider implementation="com.intellij.usageView.UsageContextDataflowToPanel$Provider"/>
|
||||
|
||||
+18
-9
@@ -6,6 +6,7 @@ import com.intellij.ide.projectView.ProjectViewNode;
|
||||
import com.intellij.ide.projectView.SelectableTreeStructureProvider;
|
||||
import com.intellij.ide.projectView.ViewSettings;
|
||||
import com.intellij.ide.projectView.impl.nodes.ClassTreeNode;
|
||||
import com.intellij.ide.projectView.impl.nodes.FileNodeWithNestedFileNodes;
|
||||
import com.intellij.ide.projectView.impl.nodes.PsiFileNode;
|
||||
import com.intellij.ide.util.treeView.AbstractTreeNode;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
@@ -27,6 +28,7 @@ import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class ClassesTreeStructureProvider implements SelectableTreeStructureProvider, DumbAware {
|
||||
@@ -68,10 +70,13 @@ public class ClassesTreeStructureProvider implements SelectableTreeStructureProv
|
||||
|
||||
if (classOwner instanceof PsiCompiledElement || fileInRoots(file)) {
|
||||
PsiClass[] classes = ReadAction.compute(classOwner::getClasses);
|
||||
Collection<? extends AbstractTreeNode<?>> nestedFileNodes = child instanceof FileNodeWithNestedFileNodes
|
||||
? ((FileNodeWithNestedFileNodes)child).getNestedFileNodes()
|
||||
: Collections.emptyList();
|
||||
if (classes.length == 1 && isClassForTreeNode(file, classes[0])) {
|
||||
result.add(new ClassTreeNode(myProject, classes[0], settings1, child.getChildren()));
|
||||
result.add(new ClassTreeNode(myProject, classes[0], settings1, nestedFileNodes));
|
||||
} else {
|
||||
result.add(new PsiClassOwnerTreeNode(classOwner, settings1, child.getChildren()));
|
||||
result.add(new PsiClassOwnerTreeNode(classOwner, settings1, nestedFileNodes));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -143,28 +148,32 @@ public class ClassesTreeStructureProvider implements SelectableTreeStructureProv
|
||||
return element instanceof PsiClass && ClassUtil.isTopLevelClass((PsiClass)element);
|
||||
}
|
||||
|
||||
private static class PsiClassOwnerTreeNode extends PsiFileNode {
|
||||
@NotNull
|
||||
private final Collection<? extends AbstractTreeNode<?>> myMandatoryChildren;
|
||||
private static class PsiClassOwnerTreeNode extends PsiFileNode implements FileNodeWithNestedFileNodes {
|
||||
private final @NotNull Collection<? extends AbstractTreeNode<?>> myNestedFileNodes;
|
||||
|
||||
PsiClassOwnerTreeNode(@NotNull PsiClassOwner classOwner,
|
||||
ViewSettings settings,
|
||||
@NotNull Collection<? extends AbstractTreeNode<?>> mandatoryChildren) {
|
||||
@NotNull Collection<? extends AbstractTreeNode<?>> nestedFileNodes) {
|
||||
super(classOwner.getProject(), classOwner, settings);
|
||||
|
||||
myMandatoryChildren = mandatoryChildren;
|
||||
myNestedFileNodes = nestedFileNodes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<? extends AbstractTreeNode<?>> getNestedFileNodes() {
|
||||
return myNestedFileNodes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<AbstractTreeNode<?>> getChildrenImpl() {
|
||||
List<AbstractTreeNode<?>> result = new ArrayList<>(myMandatoryChildren);
|
||||
List<AbstractTreeNode<?>> result = new ArrayList<>(myNestedFileNodes);
|
||||
PsiFile value = getValue();
|
||||
if (value instanceof PsiClassOwner) {
|
||||
ViewSettings settings = getSettings();
|
||||
|
||||
PsiUnnamedClass unnamedClass = JavaUnnamedClassUtil.getUnnamedClassFor(value);
|
||||
if (unnamedClass != null) {
|
||||
result.addAll(ClassTreeNode.computeChildren(unnamedClass, settings, myProject, true, ContainerUtil.emptyList()));
|
||||
result.addAll(ClassTreeNode.computeChildren(unnamedClass, settings, myProject, true));
|
||||
} else {
|
||||
for (PsiClass aClass : ((PsiClassOwner)value).getClasses()) {
|
||||
if (!(aClass instanceof SyntheticElement)) {
|
||||
|
||||
@@ -22,8 +22,8 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class ClassTreeNode extends BasePsiMemberNode<PsiClass> {
|
||||
private final Collection<? extends AbstractTreeNode<?>> myMandatoryChildren;
|
||||
public class ClassTreeNode extends BasePsiMemberNode<PsiClass> implements FileNodeWithNestedFileNodes {
|
||||
private final Collection<? extends AbstractTreeNode<?>> myNestedFileNodes;
|
||||
private boolean isAlwaysExpand;
|
||||
|
||||
public ClassTreeNode(Project project, @NotNull PsiClass value, ViewSettings viewSettings) {
|
||||
@@ -33,25 +33,29 @@ public class ClassTreeNode extends BasePsiMemberNode<PsiClass> {
|
||||
public ClassTreeNode(Project project,
|
||||
@NotNull PsiClass value,
|
||||
ViewSettings viewSettings,
|
||||
@NotNull Collection<? extends AbstractTreeNode<?>> mandatoryChildren) {
|
||||
@NotNull Collection<? extends AbstractTreeNode<?>> nestedFileNodes) {
|
||||
super(project, value, viewSettings);
|
||||
myMandatoryChildren = mandatoryChildren;
|
||||
myNestedFileNodes = nestedFileNodes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<? extends AbstractTreeNode<?>> getNestedFileNodes() {
|
||||
return myNestedFileNodes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<AbstractTreeNode<?>> getChildrenImpl() {
|
||||
PsiClass parent = getValue();
|
||||
return computeChildren(parent, this.getSettings(), this.getProject(), this.isShowInnerClasses(), this.myMandatoryChildren);
|
||||
ArrayList<AbstractTreeNode<?>> result = new ArrayList<>(myNestedFileNodes);
|
||||
result.addAll(computeChildren(getValue(), this.getSettings(), this.getProject(), this.isShowInnerClasses()));
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@ApiStatus.Internal
|
||||
public static List<AbstractTreeNode<?>> computeChildren(PsiClass parent,
|
||||
ViewSettings settings,
|
||||
Project project,
|
||||
boolean showInnerClasses,
|
||||
Collection<? extends AbstractTreeNode<?>> mandatoryChildren) {
|
||||
List<AbstractTreeNode<?>> treeNodes = new ArrayList<>(mandatoryChildren);
|
||||
public static @NotNull List<AbstractTreeNode<?>> computeChildren(PsiClass parent,
|
||||
ViewSettings settings,
|
||||
Project project,
|
||||
boolean showInnerClasses) {
|
||||
List<AbstractTreeNode<?>> treeNodes = new ArrayList<>();
|
||||
if (parent != null) {
|
||||
try {
|
||||
boolean showMembers = settings.isShowMembers();
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.ide.projectView.impl.nodes;
|
||||
|
||||
import com.intellij.ide.projectView.TreeStructureProvider;
|
||||
import com.intellij.ide.projectView.impl.NestingTreeStructureProvider;
|
||||
import com.intellij.ide.util.treeView.AbstractTreeNode;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* A file node in the Project View, which may be a parent node for other file nodes, thanks to the
|
||||
* <a href="https://www.jetbrains.com/help/idea/file-nesting-dialog.html">file nesting</a> feature.
|
||||
* <p>
|
||||
* This class is used in the following way:
|
||||
* <ul>
|
||||
* <li>{@link NestingTreeStructureProvider} may replace {@link PsiFileNode} with {@link NestingTreeNode} if the corresponding file must
|
||||
* show up as a parent for some other files according to the configured nesting rules.
|
||||
* {@link NestingTreeNode} implements {@link FileNodeWithNestedFileNodes}</li>
|
||||
* <li>Other {@link TreeStructureProvider} implementations may want to replace some file nodes with technology-specific nodes
|
||||
* in order to have a special presentation and optionally to show the file structure ('Show members' feature of the Project View).
|
||||
* Examples:
|
||||
* <ul>
|
||||
* <li>{@link com.intellij.ide.projectView.impl.ClassesTreeStructureProvider} handles Java, Groovy, Kotlin files</li>
|
||||
* <li>{@link org.jetbrains.kotlin.idea.projectView.KotlinExpandNodeProjectViewProvider} handles Kotlin files once again</li>
|
||||
* <li>{@link com.goide.tree.GoTreeStructureProvider} for Go</li>
|
||||
* <li>{@link org.jetbrains.plugins.scala.projectView.ScalaTreeStructureProvider} for Scala</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>Not to lose the nested files, such {@link TreeStructureProvider} implementations check if the node,
|
||||
* which they are going to replace, is an instance of {@link FileNodeWithNestedFileNodes}.
|
||||
* If so, they make sure that the children of the replacement node include {@link #getNestedFileNodes()} of the original node</li>
|
||||
* <li>For the replacement node, it makes sense to implement {@link FileNodeWithNestedFileNodes} as well,
|
||||
* in case some other {@link TreeStructureProvider} decides to replace it once again</li>
|
||||
* </ul>
|
||||
*/
|
||||
public interface FileNodeWithNestedFileNodes {
|
||||
Collection<? extends AbstractTreeNode<?>> getNestedFileNodes();
|
||||
}
|
||||
+16
-11
@@ -8,13 +8,14 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Objects;
|
||||
|
||||
public final class NestingTreeNode extends PsiFileNode {
|
||||
@NotNull private final Collection<? extends PsiFileNode> myChildNodes;
|
||||
public final class NestingTreeNode extends PsiFileNode implements FileNodeWithNestedFileNodes {
|
||||
private final @NotNull Collection<? extends PsiFileNode> myNestedFileNodes;
|
||||
|
||||
public NestingTreeNode(@NotNull final PsiFileNode originalNode, @NotNull final Collection<? extends PsiFileNode> childNodes) {
|
||||
super(originalNode.getProject(), originalNode.getValue(), originalNode.getSettings());
|
||||
myChildNodes = childNodes;
|
||||
public NestingTreeNode(@NotNull PsiFileNode originalNode, @NotNull Collection<? extends PsiFileNode> nestedFileNodes) {
|
||||
super(originalNode.getProject(), Objects.requireNonNull(originalNode.getValue()), originalNode.getSettings());
|
||||
myNestedFileNodes = nestedFileNodes;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -28,20 +29,24 @@ public final class NestingTreeNode extends PsiFileNode {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<AbstractTreeNode<?>> getChildrenImpl() {
|
||||
final ArrayList<AbstractTreeNode<?>> result = new ArrayList<>(myChildNodes.size());
|
||||
for (PsiFileNode node : myChildNodes) {
|
||||
public @NotNull Collection<AbstractTreeNode<?>> getNestedFileNodes() {
|
||||
ArrayList<AbstractTreeNode<?>> result = new ArrayList<>(myNestedFileNodes.size());
|
||||
for (PsiFileNode node : myNestedFileNodes) {
|
||||
PsiFile value = node.getValue();
|
||||
if (value != null) {
|
||||
result.add(new PsiFileNode(node.getProject(), value, node.getSettings()));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
final Collection<AbstractTreeNode<?>> superChildren = super.getChildrenImpl();
|
||||
@Override
|
||||
public Collection<AbstractTreeNode<?>> getChildrenImpl() {
|
||||
ArrayList<AbstractTreeNode<?>> result = new ArrayList<>(getNestedFileNodes());
|
||||
Collection<AbstractTreeNode<?>> superChildren = super.getChildrenImpl();
|
||||
if (superChildren != null) {
|
||||
result.addAll(superChildren);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -49,7 +54,7 @@ public final class NestingTreeNode extends PsiFileNode {
|
||||
public boolean contains(@NotNull final VirtualFile file) {
|
||||
if (super.contains(file)) return true;
|
||||
|
||||
for (PsiFileNode node : myChildNodes) {
|
||||
for (PsiFileNode node : myNestedFileNodes) {
|
||||
final PsiFile psiFile = node.getValue();
|
||||
if (psiFile != null && file.equals(psiFile.getVirtualFile())) {
|
||||
return true;
|
||||
|
||||
+7
-4
@@ -5,6 +5,7 @@ package org.jetbrains.kotlin.idea.projectView
|
||||
import com.intellij.ide.projectView.PresentationData
|
||||
import com.intellij.ide.projectView.ViewSettings
|
||||
import com.intellij.ide.projectView.impl.nodes.AbstractPsiBasedNode
|
||||
import com.intellij.ide.projectView.impl.nodes.FileNodeWithNestedFileNodes
|
||||
import com.intellij.ide.util.treeView.AbstractTreeNode
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
@@ -16,8 +17,8 @@ class KtClassOrObjectTreeNode(
|
||||
project: Project?,
|
||||
ktClassOrObject: KtClassOrObject,
|
||||
viewSettings: ViewSettings,
|
||||
private val mandatoryChildren: Collection<AbstractTreeNode<*>>
|
||||
) : AbstractPsiBasedNode<KtClassOrObject>(project, ktClassOrObject, viewSettings) {
|
||||
private val nestedFileNodes: Collection<AbstractTreeNode<*>>
|
||||
) : AbstractPsiBasedNode<KtClassOrObject>(project, ktClassOrObject, viewSettings), FileNodeWithNestedFileNodes {
|
||||
|
||||
// this constructor is kept for plugin API compatibility
|
||||
constructor(
|
||||
@@ -28,11 +29,13 @@ class KtClassOrObjectTreeNode(
|
||||
|
||||
override fun extractPsiFromValue(): PsiElement? = value
|
||||
|
||||
override fun getNestedFileNodes(): Collection<AbstractTreeNode<*>> = nestedFileNodes
|
||||
|
||||
override fun getChildrenImpl(): Collection<AbstractTreeNode<*>> =
|
||||
if (value != null && settings.isShowMembers) {
|
||||
mandatoryChildren + value.getStructureDeclarations().toNodes(settings)
|
||||
nestedFileNodes + value.getStructureDeclarations().toNodes(settings)
|
||||
} else {
|
||||
mandatoryChildren
|
||||
nestedFileNodes
|
||||
}
|
||||
|
||||
override fun updateImpl(data: PresentationData) {
|
||||
|
||||
+7
-4
@@ -3,6 +3,7 @@ package org.jetbrains.kotlin.idea.projectView
|
||||
|
||||
import com.intellij.ide.projectView.ViewSettings
|
||||
import com.intellij.ide.projectView.impl.nodes.AbstractPsiBasedNode
|
||||
import com.intellij.ide.projectView.impl.nodes.FileNodeWithNestedFileNodes
|
||||
import com.intellij.ide.projectView.impl.nodes.PsiFileNode
|
||||
import com.intellij.ide.util.treeView.AbstractTreeNode
|
||||
import com.intellij.openapi.project.Project
|
||||
@@ -14,14 +15,16 @@ class KtFileTreeNode(
|
||||
project: Project?,
|
||||
val ktFile: KtFile,
|
||||
viewSettings: ViewSettings,
|
||||
private val mandatoryChildren: Collection<AbstractTreeNode<*>>
|
||||
) : PsiFileNode(project, ktFile, viewSettings) {
|
||||
private val nestedFileNodes: Collection<AbstractTreeNode<*>>
|
||||
) : PsiFileNode(project, ktFile, viewSettings), FileNodeWithNestedFileNodes {
|
||||
|
||||
override fun getNestedFileNodes(): Collection<AbstractTreeNode<*>> = nestedFileNodes
|
||||
|
||||
override fun getChildrenImpl(): Collection<AbstractTreeNode<*>> =
|
||||
if (settings.isShowMembers) {
|
||||
mandatoryChildren + ktFile.toDeclarationsNodes(settings)
|
||||
nestedFileNodes + ktFile.toDeclarationsNodes(settings)
|
||||
} else {
|
||||
mandatoryChildren
|
||||
nestedFileNodes
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+7
-4
@@ -4,6 +4,7 @@ package org.jetbrains.kotlin.idea.projectView
|
||||
import com.intellij.ide.projectView.PresentationData
|
||||
import com.intellij.ide.projectView.ViewSettings
|
||||
import com.intellij.ide.projectView.impl.nodes.AbstractPsiBasedNode
|
||||
import com.intellij.ide.projectView.impl.nodes.FileNodeWithNestedFileNodes
|
||||
import com.intellij.ide.util.treeView.AbstractTreeNode
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.project.Project
|
||||
@@ -30,8 +31,8 @@ class KtInternalFileTreeNode(
|
||||
project: Project?,
|
||||
lightClass: KtLightClass,
|
||||
viewSettings: ViewSettings,
|
||||
private val mandatoryChildren: Collection<AbstractTreeNode<*>>
|
||||
) : AbstractPsiBasedNode<KtLightClass>(project, lightClass, viewSettings) {
|
||||
private val nestedFileNodes: Collection<AbstractTreeNode<*>>
|
||||
) : AbstractPsiBasedNode<KtLightClass>(project, lightClass, viewSettings), FileNodeWithNestedFileNodes {
|
||||
|
||||
private val navigatablePsiElement: SmartPsiElementPointer<KtElement>? by lazy {
|
||||
val ktClsFile = value?.navigationElement as? KtClsFile
|
||||
@@ -75,11 +76,13 @@ class KtInternalFileTreeNode(
|
||||
|
||||
override fun extractPsiFromValue(): PsiElement? = navigatablePsiElement?.element ?: value
|
||||
|
||||
override fun getNestedFileNodes(): Collection<AbstractTreeNode<*>> = nestedFileNodes
|
||||
|
||||
override fun getChildrenImpl(): Collection<AbstractTreeNode<*>> {
|
||||
if (!settings.isShowMembers) return mandatoryChildren
|
||||
if (!settings.isShowMembers) return nestedFileNodes
|
||||
|
||||
val members = (extractPsiFromValue() as? KtFile)?.toDeclarationsNodes(settings)
|
||||
return if (members.isNullOrEmpty()) mandatoryChildren else mandatoryChildren + members
|
||||
return if (members.isNullOrEmpty()) nestedFileNodes else nestedFileNodes + members
|
||||
}
|
||||
|
||||
override fun canRepresent(element: Any?): Boolean {
|
||||
|
||||
+5
-6
@@ -5,6 +5,7 @@ package org.jetbrains.kotlin.idea.projectView
|
||||
import com.intellij.ide.projectView.SelectableTreeStructureProvider
|
||||
import com.intellij.ide.projectView.TreeStructureProvider
|
||||
import com.intellij.ide.projectView.ViewSettings
|
||||
import com.intellij.ide.projectView.impl.nodes.FileNodeWithNestedFileNodes
|
||||
import com.intellij.ide.util.treeView.AbstractTreeNode
|
||||
import com.intellij.openapi.project.DumbAware
|
||||
import com.intellij.openapi.project.Project
|
||||
@@ -12,7 +13,6 @@ import com.intellij.openapi.roots.ProjectRootManager
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import org.jetbrains.kotlin.asJava.classes.KtExtensibleLightClass
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
||||
import org.jetbrains.kotlin.idea.KotlinIconProvider
|
||||
@@ -35,19 +35,18 @@ class KotlinExpandNodeProjectViewProvider : TreeStructureProvider, DumbAware {
|
||||
for (child in children) {
|
||||
val value = child.value
|
||||
val ktFile = value?.asKtFile()
|
||||
val nestedFileNodes = (child as? FileNodeWithNestedFileNodes)?.nestedFileNodes ?: emptyList()
|
||||
|
||||
// TODO: drop filter as far as get KTIJ-11594 fixed
|
||||
val mandatoryChildren = child.children.filter { it.value !is KtExtensibleLightClass }
|
||||
if (ktFile != null) {
|
||||
val mainClass = KotlinIconProvider.getSingleClass(ktFile)
|
||||
if (mainClass != null) {
|
||||
result.add(KtClassOrObjectTreeNode(ktFile.project, mainClass, settings, mandatoryChildren))
|
||||
result.add(KtClassOrObjectTreeNode(ktFile.project, mainClass, settings, nestedFileNodes))
|
||||
} else {
|
||||
result.add(KtFileTreeNode(ktFile.project, ktFile, settings, mandatoryChildren))
|
||||
result.add(KtFileTreeNode(ktFile.project, ktFile, settings, nestedFileNodes))
|
||||
}
|
||||
} else {
|
||||
if (value is KtLightClass) {
|
||||
result.add(KtInternalFileTreeNode(value.project, value, settings, mandatoryChildren))
|
||||
result.add(KtInternalFileTreeNode(value.project, value, settings, nestedFileNodes))
|
||||
} else {
|
||||
result.add(child)
|
||||
}
|
||||
|
||||
+10
@@ -73,6 +73,16 @@ public class K2ProjectViewTestGenerated extends AbstractK2ProjectViewTest {
|
||||
runTest("../idea/tests/testData/projectView/FacadeInternalWithNameClashAndSources2.test");
|
||||
}
|
||||
|
||||
@TestMetadata("FileNestingWithMembers.test")
|
||||
public void testFileNestingWithMembers() throws Exception {
|
||||
runTest("../idea/tests/testData/projectView/FileNestingWithMembers.test");
|
||||
}
|
||||
|
||||
@TestMetadata("FileNestingWithoutMembers.test")
|
||||
public void testFileNestingWithoutMembers() throws Exception {
|
||||
runTest("../idea/tests/testData/projectView/FileNestingWithoutMembers.test");
|
||||
}
|
||||
|
||||
@TestMetadata("MultifileFacadeInternalClass.test")
|
||||
public void testMultifileFacadeInternalClass() throws Exception {
|
||||
runTest("../idea/tests/testData/projectView/MultifileFacadeInternalClass.test");
|
||||
|
||||
+19
@@ -1,7 +1,10 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.kotlin.idea.projectView
|
||||
|
||||
import com.intellij.ide.projectView.impl.ProjectViewFileNestingService
|
||||
import com.intellij.ide.projectView.impl.ProjectViewFileNestingService.NestingRule
|
||||
import com.intellij.ide.projectView.impl.nodes.AbstractPsiBasedNode
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.openapi.vfs.JarFileSystem
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.projectView.TestProjectTreeStructure
|
||||
@@ -25,6 +28,9 @@ abstract class AbstractKotlinProjectViewTest : KotlinMultiFileHeavyProjectTestCa
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
treeStructure = TestProjectTreeStructure(project, testRootDisposable)
|
||||
|
||||
val initialNestingRules = ProjectViewFileNestingService.getInstance().rules
|
||||
Disposer.register(testRootDisposable) { ProjectViewFileNestingService.getInstance().rules = initialNestingRules }
|
||||
}
|
||||
|
||||
override fun doMultiFileTest(testDataPath: String, globalDirectives: Directives) {
|
||||
@@ -34,6 +40,15 @@ abstract class AbstractKotlinProjectViewTest : KotlinMultiFileHeavyProjectTestCa
|
||||
}
|
||||
treeStructure.isShowMembers = globalDirectives.getBooleanValue("SHOW_MEMBERS")
|
||||
|
||||
globalDirectives.listValues("NESTING_RULE")?.forEach { rule ->
|
||||
rule.split("->").let {
|
||||
val parentSuffix = it[0]
|
||||
val childSuffix = it[1]
|
||||
val nestingService = ProjectViewFileNestingService.getInstance()
|
||||
nestingService.setRules(nestingService.rules + NestingRule(parentSuffix, childSuffix))
|
||||
}
|
||||
}
|
||||
|
||||
FilenameIndex.processFilesByName(path.name, true, GlobalSearchScope.allScope(project), processor)
|
||||
val resultFile = processor.foundValue ?: error("$path file is not found")
|
||||
|
||||
@@ -44,6 +59,10 @@ abstract class AbstractKotlinProjectViewTest : KotlinMultiFileHeavyProjectTestCa
|
||||
val tree = pane.tree
|
||||
PlatformTestUtil.waitWhileBusy(tree)
|
||||
|
||||
globalDirectives.listValues("EXPAND_ROW")?.forEach {
|
||||
PlatformTestUtil.expand(tree, it.toInt())
|
||||
}
|
||||
|
||||
val node = TreeUtil.findNode(tree.model.root as DefaultMutableTreeNode) {
|
||||
val userObject = it.userObject
|
||||
userObject is PsiElement && userObject.containingFile?.virtualFile == resultFile ||
|
||||
|
||||
+10
@@ -73,6 +73,16 @@ public class KotlinProjectViewTestGenerated extends AbstractKotlinProjectViewTes
|
||||
runTest("testData/projectView/FacadeInternalWithNameClashAndSources2.test");
|
||||
}
|
||||
|
||||
@TestMetadata("FileNestingWithMembers.test")
|
||||
public void testFileNestingWithMembers() throws Exception {
|
||||
runTest("testData/projectView/FileNestingWithMembers.test");
|
||||
}
|
||||
|
||||
@TestMetadata("FileNestingWithoutMembers.test")
|
||||
public void testFileNestingWithoutMembers() throws Exception {
|
||||
runTest("testData/projectView/FileNestingWithoutMembers.test");
|
||||
}
|
||||
|
||||
@TestMetadata("MultifileFacadeInternalClass.test")
|
||||
public void testMultifileFacadeInternalClass() throws Exception {
|
||||
runTest("testData/projectView/MultifileFacadeInternalClass.test");
|
||||
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.kotlin.idea.projectView
|
||||
|
||||
import com.intellij.ide.projectView.impl.ProjectViewFileNestingService.NestingRule
|
||||
import com.intellij.projectView.NestedFilesInProjectViewTest
|
||||
import com.intellij.testFramework.fixtures.BasePlatformTestCase
|
||||
|
||||
// TODO fix KTIJ-11594 without introducing KTIJ-27970
|
||||
abstract class NestedFilesInProjectViewTest : BasePlatformTestCase() {
|
||||
private fun doTest(showMembers: Boolean, expectedTree: String) {
|
||||
myFixture.addFileToProject("Foo.kt", "class Foo {val foo = 0}")
|
||||
myFixture.addFileToProject("Bar.kt", "class Bar1 {val bar1 = 0}\nclass Bar2 {val bar2 = 0}")
|
||||
myFixture.addFileToProject("Foo.txt", "")
|
||||
myFixture.addFileToProject("Bar.txt", "")
|
||||
NestedFilesInProjectViewTest.doTest(myFixture, listOf(NestingRule(".kt", ".txt")), showMembers, expectedTree)
|
||||
}
|
||||
|
||||
fun testWithoutMembers() = doTest(
|
||||
false,
|
||||
"""
|
||||
| -Bar.kt
|
||||
| Bar.txt
|
||||
| -Foo
|
||||
| Foo.txt
|
||||
|""".trimMargin()
|
||||
)
|
||||
|
||||
fun testWithMembers() = doTest(
|
||||
true,
|
||||
"""
|
||||
| -Bar.kt
|
||||
| Bar.txt
|
||||
| -Bar1
|
||||
| bar1
|
||||
| -Bar2
|
||||
| bar2
|
||||
| -Foo
|
||||
| Foo.txt
|
||||
| foo
|
||||
|""".trimMargin()
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// PATH: Foo.kt
|
||||
// SHOW_MEMBERS: TRUE
|
||||
|
||||
// NESTING_RULE: .kt->.txt
|
||||
// NESTING_RULE: .kt->Impl.kt
|
||||
|
||||
// EXPAND_ROW: 1
|
||||
// EXPAND_ROW: 5
|
||||
// EXPAND_ROW: 4
|
||||
|
||||
// FILE: Foo.kt
|
||||
class Foo {val foo = 0}
|
||||
|
||||
// FILE: FooImpl.kt
|
||||
class FooImpl {val fooImpl = 0}
|
||||
|
||||
// FILE: Foo.txt
|
||||
|
||||
// FILE: Bar.kt
|
||||
class Bar1 {val bar1 = 0}
|
||||
class Bar2 {val bar2 = 0}
|
||||
|
||||
// FILE: BarImpl.kt
|
||||
class BarImpl1 {val barImpl1 = 0}
|
||||
class BarImpl2 {val barImpl2 = 0}
|
||||
|
||||
// FILE: Bar.txt
|
||||
@@ -0,0 +1,25 @@
|
||||
Node: Foo
|
||||
User object class: KtClassOrObjectTreeNode
|
||||
|
||||
Value: CLASS
|
||||
Value file: src/Foo.kt
|
||||
|
||||
Navigation item #0: CLASS
|
||||
Navigation item file #0: src/Foo.kt
|
||||
|
||||
|
||||
-Project
|
||||
-PsiDirectory: src
|
||||
-Bar.kt
|
||||
Bar.txt
|
||||
+Bar1
|
||||
-Bar2
|
||||
bar2
|
||||
-BarImpl.kt
|
||||
+BarImpl1
|
||||
+BarImpl2
|
||||
-[Foo]
|
||||
Foo.txt
|
||||
+FooImpl
|
||||
foo
|
||||
+External Libraries
|
||||
@@ -0,0 +1,25 @@
|
||||
// PATH: Foo.kt
|
||||
// SHOW_MEMBERS: FALSE
|
||||
|
||||
// NESTING_RULE: .kt->.txt
|
||||
// NESTING_RULE: .kt->Impl.kt
|
||||
|
||||
// EXPAND_ROW: 1
|
||||
|
||||
// FILE: Foo.kt
|
||||
class Foo {val foo = 0}
|
||||
|
||||
// FILE: FooImpl.kt
|
||||
class FooImpl {val fooImpl = 0}
|
||||
|
||||
// FILE: Foo.txt
|
||||
|
||||
// FILE: Bar.kt
|
||||
class Bar1 {val bar1 = 0}
|
||||
class Bar2 {val bar2 = 0}
|
||||
|
||||
// FILE: BarImpl.kt
|
||||
class BarImpl1 {val barImpl1 = 0}
|
||||
class BarImpl2 {val barImpl2 = 0}
|
||||
|
||||
// FILE: Bar.txt
|
||||
@@ -0,0 +1,19 @@
|
||||
Node: Foo
|
||||
User object class: KtClassOrObjectTreeNode
|
||||
|
||||
Value: CLASS
|
||||
Value file: src/Foo.kt
|
||||
|
||||
Navigation item #0: CLASS
|
||||
Navigation item file #0: src/Foo.kt
|
||||
|
||||
|
||||
-Project
|
||||
-PsiDirectory: src
|
||||
-Bar.kt
|
||||
Bar.txt
|
||||
BarImpl.kt
|
||||
-[Foo]
|
||||
Foo.txt
|
||||
FooImpl
|
||||
+External Libraries
|
||||
@@ -178,7 +178,7 @@
|
||||
implementationClass="org.jetbrains.kotlin.psi.psiUtil.KtStringTemplateExpressionManipulator"/>
|
||||
|
||||
<treeStructureProvider implementation="org.jetbrains.kotlin.idea.projectView.KotlinSelectInProjectViewProvider"/>
|
||||
<treeStructureProvider implementation="org.jetbrains.kotlin.idea.projectView.KotlinExpandNodeProjectViewProvider" order="last, after NestingTreeStructureProvider"/>
|
||||
<treeStructureProvider implementation="org.jetbrains.kotlin.idea.projectView.KotlinExpandNodeProjectViewProvider" order="last, after ClassesTreeStructureProvider"/>
|
||||
|
||||
<qualifiedNameProvider implementation="org.jetbrains.kotlin.idea.actions.KotlinQualifiedNameProvider"/>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user