2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com
.intellij
.slicer
;
18 import com
.intellij
.ide
.util
.treeView
.AbstractTreeBuilder
;
19 import com
.intellij
.ide
.util
.treeView
.AlphaComparator
;
20 import com
.intellij
.ide
.util
.treeView
.NodeDescriptor
;
21 import com
.intellij
.openapi
.progress
.ProgressManager
;
22 import com
.intellij
.openapi
.project
.Project
;
23 import com
.intellij
.openapi
.ui
.Messages
;
24 import com
.intellij
.openapi
.util
.Comparing
;
25 import com
.intellij
.openapi
.util
.Ref
;
26 import com
.intellij
.psi
.PsiElement
;
27 import com
.intellij
.psi
.PsiFile
;
28 import org
.jetbrains
.annotations
.Nullable
;
31 import javax
.swing
.tree
.DefaultTreeModel
;
32 import java
.util
.Collection
;
33 import java
.util
.Comparator
;
38 public class SliceTreeBuilder
extends AbstractTreeBuilder
{
39 public boolean splitByLeafExpressions
;
40 public final boolean dataFlowToThis
;
41 private static final Comparator
<NodeDescriptor
> SLICE_NODE_COMPARATOR
= new Comparator
<NodeDescriptor
>() {
42 public int compare(NodeDescriptor o1
, NodeDescriptor o2
) {
43 if (!(o1
instanceof SliceNode
) || !(o2
instanceof SliceNode
)) {
44 return AlphaComparator
.INSTANCE
.compare(o1
, o2
);
46 SliceNode node1
= (SliceNode
)o1
;
47 SliceNode node2
= (SliceNode
)o2
;
48 SliceUsage usage1
= node1
.getValue();
49 SliceUsage usage2
= node2
.getValue();
51 PsiElement element1
= usage1
.getElement();
52 PsiElement element2
= usage2
.getElement();
54 PsiFile file1
= element1
== null ?
null : element1
.getContainingFile();
55 PsiFile file2
= element2
== null ?
null : element2
.getContainingFile();
57 if (file1
== null) return file2
== null ?
0 : 1;
58 if (file2
== null) return -1;
61 return element1
.getTextOffset() - element2
.getTextOffset();
64 return Comparing
.compare(file1
.getName(), file2
.getName());
68 public SliceTreeBuilder(JTree tree
, Project project
, boolean dataFlowToThis
, final SliceNode rootNode
) {
69 super(tree
, (DefaultTreeModel
)tree
.getModel(), new SliceTreeStructure(project
, rootNode
), SLICE_NODE_COMPARATOR
, false);
70 this.dataFlowToThis
= dataFlowToThis
;
74 protected boolean isAutoExpandNode(NodeDescriptor nodeDescriptor
) {
78 public void switchToSplittedNodes() {
79 final SliceRootNode root
= (SliceRootNode
)getRootNode().getUserObject();
81 Collection
<PsiElement
> leaves
= calcLeafExpressions(root
);
82 if (leaves
== null) return; //cancelled
84 if (leaves
.isEmpty()) {
85 Messages
.showErrorDialog("Unable to find leaf expressions to group by", "Cannot group");
90 root
.restructureByLeaves(leaves
);
92 splitByLeafExpressions
= true;
93 root
.targetEqualUsages
.clear();
95 getUpdater().cancelAllRequests();
96 getUpdater().addSubtreeToUpdateByElement(root
);
99 @Nullable("null means canceled")
100 public static Collection
<PsiElement
> calcLeafExpressions(final SliceRootNode root
) {
101 final Ref
<Collection
<PsiElement
>> leafExpressions
= Ref
.create(null);
102 boolean b
= ProgressManager
.getInstance().runProcessWithProgressSynchronously(new Runnable() {
104 Collection
<PsiElement
> l
= SliceLeafAnalyzer
.calcLeafExpressions(root
);
105 leafExpressions
.set(l
);
107 }, "Expanding all nodes... (may very well take the whole day)", true, root
.getProject());
110 Collection
<PsiElement
> leaves
= leafExpressions
.get();
114 public void switchToUnsplittedNodes() {
115 SliceRootNode root
= (SliceRootNode
)getRootNode().getUserObject();
116 SliceLeafValueRootNode valueNode
= (SliceLeafValueRootNode
)root
.myCachedChildren
.get(0);
117 SliceNode rootNode
= valueNode
.myCachedChildren
.get(0);
119 root
.switchToAllLeavesTogether(rootNode
.getValue());
121 splitByLeafExpressions
= false;
122 root
.targetEqualUsages
.clear();
124 getUpdater().cancelAllRequests();
125 getUpdater().addSubtreeToUpdateByElement(root
);