From f8729fa9bec20c067f74f24ce166e8f2e7d18a79 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Wed, 4 Oct 2017 03:02:08 +0300 Subject: [PATCH] a better SOE fix discovered (since 29/12/2011) --- .../java/JavaAnonymousClassTreeElement.java | 6 +- .../JavaAnonymousClassesNodeProvider.java | 4 +- .../impl/java/JavaClassTreeElement.java | 27 ++++---- .../impl/java/JavaFileTreeElement.java | 3 +- .../JavaInheritedMembersNodeProvider.java | 61 +++++++++---------- .../impl/java/PsiMethodTreeElement.java | 8 ++- .../smartTree/CachingChildrenTreeNode.java | 5 ++ 7 files changed, 57 insertions(+), 57 deletions(-) diff --git a/java/java-structure-view/src/com/intellij/ide/structureView/impl/java/JavaAnonymousClassTreeElement.java b/java/java-structure-view/src/com/intellij/ide/structureView/impl/java/JavaAnonymousClassTreeElement.java index 2905a6ffaa4d..c754b81eee43 100644 --- a/java/java-structure-view/src/com/intellij/ide/structureView/impl/java/JavaAnonymousClassTreeElement.java +++ b/java/java-structure-view/src/com/intellij/ide/structureView/impl/java/JavaAnonymousClassTreeElement.java @@ -21,7 +21,6 @@ import com.intellij.psi.PsiClass; import com.intellij.util.PlatformIcons; import javax.swing.*; -import java.util.Set; /** * @author Konstantin Bulenkov @@ -32,9 +31,8 @@ public class JavaAnonymousClassTreeElement extends JavaClassTreeElement { private String myName; private String myBaseName; - public JavaAnonymousClassTreeElement(PsiAnonymousClass aClass, Set parents) { - super(aClass, false, parents); - //parents.add(aClass.getSuperClass()); + public JavaAnonymousClassTreeElement(PsiAnonymousClass aClass) { + super(aClass, false); } @Override diff --git a/java/java-structure-view/src/com/intellij/ide/structureView/impl/java/JavaAnonymousClassesNodeProvider.java b/java/java-structure-view/src/com/intellij/ide/structureView/impl/java/JavaAnonymousClassesNodeProvider.java index b890774dd5d0..1ce81d5ad725 100644 --- a/java/java-structure-view/src/com/intellij/ide/structureView/impl/java/JavaAnonymousClassesNodeProvider.java +++ b/java/java-structure-view/src/com/intellij/ide/structureView/impl/java/JavaAnonymousClassesNodeProvider.java @@ -27,10 +27,8 @@ import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.util.PropertyOwner; import com.intellij.openapi.util.SystemInfo; import com.intellij.psi.PsiAnonymousClass; -import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.util.PlatformIcons; -import com.intellij.util.containers.hash.HashSet; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -56,7 +54,7 @@ public class JavaAnonymousClassesNodeProvider implements FileStructureNodeProvid if (elements.length > 0) { List result = new ArrayList<>(elements.length); for (PsiElement element : elements) { - result.add(new JavaAnonymousClassTreeElement((PsiAnonymousClass)element, new HashSet<>())); + result.add(new JavaAnonymousClassTreeElement((PsiAnonymousClass)element)); } return result; } diff --git a/java/java-structure-view/src/com/intellij/ide/structureView/impl/java/JavaClassTreeElement.java b/java/java-structure-view/src/com/intellij/ide/structureView/impl/java/JavaClassTreeElement.java index 062fae0c0bc2..03751ee3f4b0 100644 --- a/java/java-structure-view/src/com/intellij/ide/structureView/impl/java/JavaClassTreeElement.java +++ b/java/java-structure-view/src/com/intellij/ide/structureView/impl/java/JavaClassTreeElement.java @@ -27,12 +27,15 @@ import java.util.*; * @author Konstantin Bulenkov */ public class JavaClassTreeElement extends JavaClassTreeElementBase { - private final Set myParents; - public JavaClassTreeElement(PsiClass cls, boolean inherited, Set parents) { + public JavaClassTreeElement(PsiClass cls, boolean inherited) { super(inherited, cls); - myParents = parents; - myParents.add(cls); + } + + /** @noinspection unused*/ + @Deprecated + public JavaClassTreeElement(PsiClass cls, boolean inherited, Set parents) { + this(cls, inherited); } @Override @@ -48,12 +51,10 @@ public class JavaClassTreeElement extends JavaClassTreeElementBase { LinkedHashSet members = getOwnChildren(aClass); List children = new ArrayList<>(members.size()); - //aClass.processDeclarations(new AddAllMembersProcessor(inherited, aClass), ResolveState.initial(), null, aClass); - for (PsiElement child : members) { if (!child.isValid()) continue; - if (child instanceof PsiClass && !myParents.contains((PsiClass)child)) { - children.add(new JavaClassTreeElement((PsiClass)child, false, myParents)); + if (child instanceof PsiClass) { + children.add(new JavaClassTreeElement((PsiClass)child, false)); } else if (child instanceof PsiField) { children.add(new PsiFieldTreeElement((PsiField)child, false)); @@ -87,17 +88,15 @@ public class JavaClassTreeElement extends JavaClassTreeElementBase { } } - public Set getParents() { - return myParents; - } - @Override public String getPresentableText() { - return getElement().getName(); + PsiClass o = getElement(); + return o == null ? "" : o.getName(); } @Override public boolean isPublic() { - return getElement().getParent() instanceof PsiFile || super.isPublic(); + PsiClass o = getElement(); + return o != null && o.getParent() instanceof PsiFile || super.isPublic(); } } diff --git a/java/java-structure-view/src/com/intellij/ide/structureView/impl/java/JavaFileTreeElement.java b/java/java-structure-view/src/com/intellij/ide/structureView/impl/java/JavaFileTreeElement.java index cff0a7334ae2..38202e626701 100644 --- a/java/java-structure-view/src/com/intellij/ide/structureView/impl/java/JavaFileTreeElement.java +++ b/java/java-structure-view/src/com/intellij/ide/structureView/impl/java/JavaFileTreeElement.java @@ -25,7 +25,6 @@ import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.HashSet; public class JavaFileTreeElement extends PsiTreeElementBase implements ItemPresentation { public JavaFileTreeElement(PsiClassOwner file) { @@ -46,7 +45,7 @@ public class JavaFileTreeElement extends PsiTreeElementBase imple PsiClass[] classes = element.getClasses(); ArrayList result = new ArrayList<>(); for (PsiClass aClass : classes) { - result.add(new JavaClassTreeElement(aClass, false, new HashSet<>())); + result.add(new JavaClassTreeElement(aClass, false)); } return result; diff --git a/java/java-structure-view/src/com/intellij/ide/structureView/impl/java/JavaInheritedMembersNodeProvider.java b/java/java-structure-view/src/com/intellij/ide/structureView/impl/java/JavaInheritedMembersNodeProvider.java index eb75c735c642..f3e1a045621f 100644 --- a/java/java-structure-view/src/com/intellij/ide/structureView/impl/java/JavaInheritedMembersNodeProvider.java +++ b/java/java-structure-view/src/com/intellij/ide/structureView/impl/java/JavaInheritedMembersNodeProvider.java @@ -31,40 +31,39 @@ public class JavaInheritedMembersNodeProvider extends InheritedMembersNodeProvid @NotNull @Override public Collection provideNodes(@NotNull TreeElement node) { - if (node instanceof JavaClassTreeElement) { - final PsiClass aClass = ((JavaClassTreeElement)node).getElement(); - if (aClass == null) return Collections.emptyList(); + if (!(node instanceof JavaClassTreeElement)) return Collections.emptyList(); - Collection inherited = new LinkedHashSet<>(); - Collection ownChildren = JavaClassTreeElement.getOwnChildren(aClass); + JavaClassTreeElement classNode = (JavaClassTreeElement)node; + final PsiClass aClass = classNode.getElement(); + if (aClass == null) return Collections.emptyList(); - aClass.processDeclarations(new AddAllMembersProcessor(inherited, aClass), ResolveState.initial(), null, aClass); - inherited.removeAll(ownChildren); - if (aClass instanceof PsiAnonymousClass) { - final PsiElement element = ((PsiAnonymousClass)aClass).getBaseClassReference().resolve(); - if (element instanceof PsiClass) { - ContainerUtil.addAll(inherited, ((PsiClass)element).getInnerClasses()); - } + Collection inherited = new LinkedHashSet<>(); + Collection ownChildren = JavaClassTreeElement.getOwnChildren(aClass); + + aClass.processDeclarations(new AddAllMembersProcessor(inherited, aClass), ResolveState.initial(), null, aClass); + inherited.removeAll(ownChildren); + if (aClass instanceof PsiAnonymousClass) { + final PsiElement element = ((PsiAnonymousClass)aClass).getBaseClassReference().resolve(); + if (element instanceof PsiClass) { + ContainerUtil.addAll(inherited, ((PsiClass)element).getInnerClasses()); } - List array = new ArrayList<>(); - for (PsiElement child : inherited) { - if (!child.isValid()) continue; - final Set parents = ((JavaClassTreeElement)node).getParents(); - if (child instanceof PsiClass && !parents.contains(child)) { - array.add(new JavaClassTreeElement((PsiClass)child, true, parents)); - } - else if (child instanceof PsiField) { - array.add(new PsiFieldTreeElement((PsiField)child, true)); - } - else if (child instanceof PsiMethod) { - array.add(new PsiMethodTreeElement((PsiMethod)child, true)); - } - else if (child instanceof PsiClassInitializer) { - array.add(new ClassInitializerTreeElement((PsiClassInitializer)child)); - } - } - return array; } - return Collections.emptyList(); + List array = new ArrayList<>(); + for (PsiElement child : inherited) { + if (!child.isValid()) continue; + if (child instanceof PsiClass) { + array.add(new JavaClassTreeElement((PsiClass)child, true)); + } + else if (child instanceof PsiField) { + array.add(new PsiFieldTreeElement((PsiField)child, true)); + } + else if (child instanceof PsiMethod) { + array.add(new PsiMethodTreeElement((PsiMethod)child, true)); + } + else if (child instanceof PsiClassInitializer) { + array.add(new ClassInitializerTreeElement((PsiClassInitializer)child)); + } + } + return array; } } diff --git a/java/java-structure-view/src/com/intellij/ide/structureView/impl/java/PsiMethodTreeElement.java b/java/java-structure-view/src/com/intellij/ide/structureView/impl/java/PsiMethodTreeElement.java index 31581cdbb6d5..c23bc68b6ace 100644 --- a/java/java-structure-view/src/com/intellij/ide/structureView/impl/java/PsiMethodTreeElement.java +++ b/java/java-structure-view/src/com/intellij/ide/structureView/impl/java/PsiMethodTreeElement.java @@ -28,11 +28,13 @@ import com.intellij.psi.*; import com.intellij.psi.search.searches.SuperMethodsSearch; import com.intellij.psi.util.MethodSignatureBackedByPsiMethod; import com.intellij.psi.util.PsiFormatUtil; -import com.intellij.util.Function; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; import static com.intellij.psi.util.PsiFormatUtilBase.*; @@ -65,7 +67,7 @@ public class PsiMethodTreeElement extends JavaClassTreeElementBase im element.accept(new JavaRecursiveElementWalkingVisitor(){ @Override public void visitClass(PsiClass aClass) { if (!(aClass instanceof PsiAnonymousClass) && !(aClass instanceof PsiTypeParameter)) { - result.add(new JavaClassTreeElement(aClass, isInherited(), new HashSet<>(Arrays.asList(aClass.getSupers())))); + result.add(new JavaClassTreeElement(aClass, isInherited())); } } }); diff --git a/platform/structure-view-impl/src/com/intellij/ide/util/treeView/smartTree/CachingChildrenTreeNode.java b/platform/structure-view-impl/src/com/intellij/ide/util/treeView/smartTree/CachingChildrenTreeNode.java index 824fb15538df..3ec82ebafd98 100644 --- a/platform/structure-view-impl/src/com/intellij/ide/util/treeView/smartTree/CachingChildrenTreeNode.java +++ b/platform/structure-view-impl/src/com/intellij/ide/util/treeView/smartTree/CachingChildrenTreeNode.java @@ -22,6 +22,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.Project; import com.intellij.pom.Navigatable; +import com.intellij.util.containers.JBIterable; import gnu.trove.THashMap; import org.jetbrains.annotations.NotNull; @@ -59,6 +60,10 @@ public abstract class CachingChildrenTreeNode extends AbstractTreeNode parents = JBIterable.generate(this, o -> o.getParent()); + if (parents.map(o -> o.getValue()).contains(node.getValue())) { + return; + } ensureChildrenAreInitialized(); myChildren.add(node); node.setParent(this);