From e21840d08b100025ecc5dbc77f81aaaa3111d837 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Mon, 25 Jan 2010 18:07:51 +0300 Subject: [PATCH] IDEA-50121 --- ...ForwardAction.java => SliceAnalysisParams.java} | 18 +++--- ...rwardAction.java => SliceDereferenceUsage.java} | 23 ++++--- .../com/intellij/slicer/SliceForwardAction.java | 2 +- .../src/com/intellij/slicer/SliceForwardForm.form | 35 +++++++++++ ...iceForwardAction.java => SliceForwardForm.java} | 26 +++++--- .../com/intellij/slicer/SliceForwardHandler.java | 70 ++++++++++++++++++++++ .../src/com/intellij/slicer/SliceHandler.java | 31 +++++++++- .../src/com/intellij/slicer/SliceLeafAnalyzer.java | 3 +- .../intellij/slicer/SliceLeafValueClassNode.java | 8 +-- .../intellij/slicer/SliceLeafValueRootNode.java | 6 +- .../src/com/intellij/slicer/SliceManager.java | 53 ++++++---------- .../src/com/intellij/slicer/SliceNode.java | 14 +++-- .../com/intellij/slicer/SliceNullnessAnalyzer.java | 9 ++- .../src/com/intellij/slicer/SliceRootNode.java | 10 ++-- .../src/com/intellij/slicer/SliceUsage.java | 18 +++--- .../intellij/slicer/SliceUsageCellRenderer.java | 25 +++++--- .../com/intellij/slicer/forward/SliceFUtil.java | 19 +++++- .../com/intellij/analysis/BaseAnalysisAction.java | 3 +- 18 files changed, 264 insertions(+), 109 deletions(-) copy java/java-impl/src/com/intellij/slicer/{SliceForwardAction.java => SliceAnalysisParams.java} (61%) copy java/java-impl/src/com/intellij/slicer/{SliceForwardAction.java => SliceDereferenceUsage.java} (53%) create mode 100644 java/java-impl/src/com/intellij/slicer/SliceForwardForm.form copy java/java-impl/src/com/intellij/slicer/{SliceForwardAction.java => SliceForwardForm.java} (60%) create mode 100644 java/java-impl/src/com/intellij/slicer/SliceForwardHandler.java diff --git a/java/java-impl/src/com/intellij/slicer/SliceForwardAction.java b/java/java-impl/src/com/intellij/slicer/SliceAnalysisParams.java similarity index 61% copy from java/java-impl/src/com/intellij/slicer/SliceForwardAction.java copy to java/java-impl/src/com/intellij/slicer/SliceAnalysisParams.java index 026363d8e3..b340650a58 100644 --- a/java/java-impl/src/com/intellij/slicer/SliceForwardAction.java +++ b/java/java-impl/src/com/intellij/slicer/SliceAnalysisParams.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2010 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,16 +15,16 @@ */ package com.intellij.slicer; -import com.intellij.codeInsight.CodeInsightActionHandler; -import com.intellij.codeInsight.actions.CodeInsightAction; +import com.intellij.analysis.AnalysisScope; /** - * @author cdr + * User: cdr */ -public class SliceForwardAction extends CodeInsightAction{ - private final SliceHandler myHandler = new SliceHandler(false); +public class SliceAnalysisParams { + public boolean dataFlowToThis = true; // to/from this + public boolean showInstanceDereferences = true; // show method calls or field access on the variable being analysed + public AnalysisScope scope; - protected CodeInsightActionHandler getHandler() { - return myHandler; + public SliceAnalysisParams() { } -} \ No newline at end of file +} diff --git a/java/java-impl/src/com/intellij/slicer/SliceForwardAction.java b/java/java-impl/src/com/intellij/slicer/SliceDereferenceUsage.java similarity index 53% copy from java/java-impl/src/com/intellij/slicer/SliceForwardAction.java copy to java/java-impl/src/com/intellij/slicer/SliceDereferenceUsage.java index 026363d8e3..a53baf82e1 100644 --- a/java/java-impl/src/com/intellij/slicer/SliceForwardAction.java +++ b/java/java-impl/src/com/intellij/slicer/SliceDereferenceUsage.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2010 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,16 +15,21 @@ */ package com.intellij.slicer; -import com.intellij.codeInsight.CodeInsightActionHandler; -import com.intellij.codeInsight.actions.CodeInsightAction; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiSubstitutor; +import com.intellij.util.Processor; +import org.jetbrains.annotations.NotNull; /** - * @author cdr + * User: cdr */ -public class SliceForwardAction extends CodeInsightAction{ - private final SliceHandler myHandler = new SliceHandler(false); +public class SliceDereferenceUsage extends SliceUsage { + public SliceDereferenceUsage(@NotNull PsiElement element, @NotNull SliceUsage parent, @NotNull PsiSubstitutor substitutor) { + super(element, parent, substitutor); + } - protected CodeInsightActionHandler getHandler() { - return myHandler; + @Override + public void processChildren(Processor processor) { + // no children } -} \ No newline at end of file +} diff --git a/java/java-impl/src/com/intellij/slicer/SliceForwardAction.java b/java/java-impl/src/com/intellij/slicer/SliceForwardAction.java index 026363d8e3..0136e13cc2 100644 --- a/java/java-impl/src/com/intellij/slicer/SliceForwardAction.java +++ b/java/java-impl/src/com/intellij/slicer/SliceForwardAction.java @@ -22,7 +22,7 @@ import com.intellij.codeInsight.actions.CodeInsightAction; * @author cdr */ public class SliceForwardAction extends CodeInsightAction{ - private final SliceHandler myHandler = new SliceHandler(false); + private final SliceHandler myHandler = new SliceForwardHandler(); protected CodeInsightActionHandler getHandler() { return myHandler; diff --git a/java/java-impl/src/com/intellij/slicer/SliceForwardForm.form b/java/java-impl/src/com/intellij/slicer/SliceForwardForm.form new file mode 100644 index 0000000000..b7489fe462 --- /dev/null +++ b/java/java-impl/src/com/intellij/slicer/SliceForwardForm.form @@ -0,0 +1,35 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/java/java-impl/src/com/intellij/slicer/SliceForwardAction.java b/java/java-impl/src/com/intellij/slicer/SliceForwardForm.java similarity index 60% copy from java/java-impl/src/com/intellij/slicer/SliceForwardAction.java copy to java/java-impl/src/com/intellij/slicer/SliceForwardForm.java index 026363d8e3..9c1a13fe8b 100644 --- a/java/java-impl/src/com/intellij/slicer/SliceForwardAction.java +++ b/java/java-impl/src/com/intellij/slicer/SliceForwardForm.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2010 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,16 +15,24 @@ */ package com.intellij.slicer; -import com.intellij.codeInsight.CodeInsightActionHandler; -import com.intellij.codeInsight.actions.CodeInsightAction; +import javax.swing.*; /** - * @author cdr + * User: cdr */ -public class SliceForwardAction extends CodeInsightAction{ - private final SliceHandler myHandler = new SliceHandler(false); +public class SliceForwardForm { + private JCheckBox myShowDerefs; + private JPanel myPanel; - protected CodeInsightActionHandler getHandler() { - return myHandler; + public void init(boolean showDerefs) { + myShowDerefs.setSelected(showDerefs); } -} \ No newline at end of file + + public boolean isToShowDerefs() { + return myShowDerefs.isSelected(); + } + + public JPanel getComponent() { + return myPanel; + } +} diff --git a/java/java-impl/src/com/intellij/slicer/SliceForwardHandler.java b/java/java-impl/src/com/intellij/slicer/SliceForwardHandler.java new file mode 100644 index 0000000000..4209ca70e3 --- /dev/null +++ b/java/java-impl/src/com/intellij/slicer/SliceForwardHandler.java @@ -0,0 +1,70 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.slicer; + +import com.intellij.analysis.AnalysisScope; +import com.intellij.analysis.AnalysisUIOptions; +import com.intellij.analysis.BaseAnalysisActionDialog; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleUtil; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; + +import javax.swing.*; + +/** + * @author cdr + */ +public class SliceForwardHandler extends SliceHandler { + public SliceForwardHandler() { + super(false); + } + + public SliceAnalysisParams askForParams(PsiElement element, boolean dataFlowToThis, SliceManager.StoredSettingsBean storedSettingsBean, String dialogTitle) { + AnalysisScope analysisScope = new AnalysisScope(element.getContainingFile()); + Module module = ModuleUtil.findModuleForPsiElement(element); + String name = module == null ? null : module.getName(); + + Project myProject = element.getProject(); + final SliceForwardForm form = new SliceForwardForm(); + form.init(storedSettingsBean.showDereferences); + + AnalysisUIOptions analysisUIOptions = new AnalysisUIOptions(); + analysisUIOptions.save(storedSettingsBean.analysisUIOptions); + + BaseAnalysisActionDialog dialog = new BaseAnalysisActionDialog(dialogTitle, "Analyze scope", myProject, analysisScope, name, true, + analysisUIOptions, + element) { + @Override + protected JComponent getAdditionalActionSettings(Project project) { + return form.getComponent(); + } + }; + dialog.show(); + if (!dialog.isOK()) return null; + + storedSettingsBean.analysisUIOptions.save(analysisUIOptions); + storedSettingsBean.showDereferences = form.isToShowDerefs(); + + AnalysisScope scope = dialog.getScope(analysisUIOptions, analysisScope, myProject, module); + + SliceAnalysisParams params = new SliceAnalysisParams(); + params.scope = scope; + params.dataFlowToThis = dataFlowToThis; + params.showInstanceDereferences = form.isToShowDerefs(); + return params; + } +} \ No newline at end of file diff --git a/java/java-impl/src/com/intellij/slicer/SliceHandler.java b/java/java-impl/src/com/intellij/slicer/SliceHandler.java index 1550267059..c4ba3ba779 100644 --- a/java/java-impl/src/com/intellij/slicer/SliceHandler.java +++ b/java/java-impl/src/com/intellij/slicer/SliceHandler.java @@ -15,10 +15,15 @@ */ package com.intellij.slicer; +import com.intellij.analysis.AnalysisScope; +import com.intellij.analysis.AnalysisUIOptions; +import com.intellij.analysis.BaseAnalysisActionDialog; import com.intellij.codeInsight.CodeInsightActionHandler; import com.intellij.codeInsight.TargetElementUtilBase; import com.intellij.codeInsight.hint.HintManager; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; @@ -44,7 +49,7 @@ public class SliceHandler implements CodeInsightActionHandler { } SliceManager sliceManager = SliceManager.getInstance(project); - sliceManager.slice(expression,myDataFlowToThis); + sliceManager.slice(expression,myDataFlowToThis, this); } public boolean startInWriteAction() { @@ -63,4 +68,28 @@ public class SliceHandler implements CodeInsightActionHandler { if (myDataFlowToThis && element instanceof PsiLiteralExpression) return null; return element; } + + public SliceAnalysisParams askForParams(PsiElement element, boolean dataFlowToThis, SliceManager.StoredSettingsBean storedSettingsBean, String dialogTitle) { + AnalysisScope analysisScope = new AnalysisScope(element.getContainingFile()); + Module module = ModuleUtil.findModuleForPsiElement(element); + String name = module == null ? null : module.getName(); + + Project myProject = element.getProject(); + AnalysisUIOptions analysisUIOptions = new AnalysisUIOptions(); + analysisUIOptions.save(storedSettingsBean.analysisUIOptions); + + BaseAnalysisActionDialog dialog = new BaseAnalysisActionDialog(dialogTitle, "Analyze scope", myProject, analysisScope, name, true, analysisUIOptions, + element); + dialog.show(); + if (!dialog.isOK()) return null; + + storedSettingsBean.analysisUIOptions.save(analysisUIOptions); + + AnalysisScope scope = dialog.getScope(analysisUIOptions, analysisScope, myProject, module); + + SliceAnalysisParams params = new SliceAnalysisParams(); + params.scope = scope; + params.dataFlowToThis = dataFlowToThis; + return params; + } } diff --git a/java/java-impl/src/com/intellij/slicer/SliceLeafAnalyzer.java b/java/java-impl/src/com/intellij/slicer/SliceLeafAnalyzer.java index 6b7787b17a..6352ae6605 100644 --- a/java/java-impl/src/com/intellij/slicer/SliceLeafAnalyzer.java +++ b/java/java-impl/src/com/intellij/slicer/SliceLeafAnalyzer.java @@ -126,7 +126,8 @@ public class SliceLeafAnalyzer { } }); - SliceLeafValueRootNode lvNode = new SliceLeafValueRootNode(root.getProject(), leafExpression, root, Collections.singletonList(newNode)); + SliceLeafValueRootNode lvNode = new SliceLeafValueRootNode(root.getProject(), leafExpression, root, Collections.singletonList(newNode), + oldRoot.getValue().params); root.myCachedChildren.add(lvNode); } return root; diff --git a/java/java-impl/src/com/intellij/slicer/SliceLeafValueClassNode.java b/java/java-impl/src/com/intellij/slicer/SliceLeafValueClassNode.java index 9005428a10..630d1cd483 100644 --- a/java/java-impl/src/com/intellij/slicer/SliceLeafValueClassNode.java +++ b/java/java-impl/src/com/intellij/slicer/SliceLeafValueClassNode.java @@ -16,17 +16,11 @@ package com.intellij.slicer; import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiElement; -import com.intellij.psi.util.PsiUtilBase; import com.intellij.ui.SimpleTextAttributes; -import com.intellij.usageView.UsageViewBundle; -import com.intellij.usages.Usage; -import com.intellij.usages.UsageInfo2UsageAdapter; import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.util.ArrayList; -import java.util.List; /** * User: cdr @@ -35,7 +29,7 @@ public class SliceLeafValueClassNode extends SliceLeafValueRootNode { private final String myClassName; public SliceLeafValueClassNode(@NotNull Project project, SliceNode root, String className) { - super(project, root.getValue().getElement(), root, new ArrayList()); + super(project, root.getValue().getElement(), root, new ArrayList(), root.getValue().params); myClassName = className; } diff --git a/java/java-impl/src/com/intellij/slicer/SliceLeafValueRootNode.java b/java/java-impl/src/com/intellij/slicer/SliceLeafValueRootNode.java index 57835824eb..82b714aeac 100644 --- a/java/java-impl/src/com/intellij/slicer/SliceLeafValueRootNode.java +++ b/java/java-impl/src/com/intellij/slicer/SliceLeafValueRootNode.java @@ -15,7 +15,6 @@ */ package com.intellij.slicer; -import com.intellij.analysis.AnalysisScope; import com.intellij.ide.projectView.PresentationData; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; @@ -35,8 +34,9 @@ import java.util.List; public class SliceLeafValueRootNode extends SliceNode implements MyColoredTreeCellRenderer { protected final List myCachedChildren; - public SliceLeafValueRootNode(@NotNull Project project, PsiElement leafExpression, SliceNode root, List children) { - super(project, new SliceUsage(leafExpression, new AnalysisScope(project)), root.targetEqualUsages, true); + public SliceLeafValueRootNode(@NotNull Project project, PsiElement leafExpression, SliceNode root, List children, + SliceAnalysisParams params) { + super(project, new SliceUsage(leafExpression, params), root.targetEqualUsages); myCachedChildren = children; } diff --git a/java/java-impl/src/com/intellij/slicer/SliceManager.java b/java/java-impl/src/com/intellij/slicer/SliceManager.java index 07f3126abb..1eea7a00c8 100644 --- a/java/java-impl/src/com/intellij/slicer/SliceManager.java +++ b/java/java-impl/src/com/intellij/slicer/SliceManager.java @@ -15,16 +15,12 @@ */ package com.intellij.slicer; -import com.intellij.analysis.AnalysisScope; import com.intellij.analysis.AnalysisUIOptions; -import com.intellij.analysis.BaseAnalysisActionDialog; import com.intellij.ide.impl.ContentManagerWatcher; import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.components.State; import com.intellij.openapi.components.Storage; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; @@ -46,17 +42,17 @@ import java.util.regex.Pattern; name = "SliceManager", storages = {@Storage(id = "other", file = "$WORKSPACE_FILE$")} ) -public class SliceManager implements PersistentStateComponent { +public class SliceManager implements PersistentStateComponent { private final Project myProject; private final ContentManager myBackContentManager; private final ContentManager myForthContentManager; private volatile boolean myCanceled; - private final Bean myStoredSettings = new Bean(); + private final StoredSettingsBean myStoredSettings = new StoredSettingsBean(); private static final String BACK_TOOLWINDOW_ID = "Analyze Dataflow to"; private static final String FORTH_TOOLWINDOW_ID = "Analyze Dataflow from"; - public static class Bean { - //public boolean includeTestSources = true; // to show in dialog + public static class StoredSettingsBean { + public boolean showDereferences = true; // to show in dataflow/from dialog public AnalysisUIOptions analysisUIOptions = new AnalysisUIOptions(); } @@ -66,13 +62,13 @@ public class SliceManager implements PersistentStateComponent public SliceManager(@NotNull Project project, @NotNull ToolWindowManager toolWindowManager, final PsiManager psiManager) { myProject = project; - ToolWindow toolWindow = toolWindowManager.registerToolWindow(BACK_TOOLWINDOW_ID, true, ToolWindowAnchor.BOTTOM, project); - myBackContentManager = toolWindow.getContentManager(); - new ContentManagerWatcher(toolWindow, myBackContentManager); + ToolWindow backToolWindow = toolWindowManager.registerToolWindow(BACK_TOOLWINDOW_ID, true, ToolWindowAnchor.BOTTOM, project); + myBackContentManager = backToolWindow.getContentManager(); + new ContentManagerWatcher(backToolWindow, myBackContentManager); - ToolWindow ftoolWindow = toolWindowManager.registerToolWindow(FORTH_TOOLWINDOW_ID, true, ToolWindowAnchor.BOTTOM, project); - myForthContentManager = ftoolWindow.getContentManager(); - new ContentManagerWatcher(ftoolWindow, myForthContentManager); + ToolWindow forthToolWindow = toolWindowManager.registerToolWindow(FORTH_TOOLWINDOW_ID, true, ToolWindowAnchor.BOTTOM, project); + myForthContentManager = forthToolWindow.getContentManager(); + new ContentManagerWatcher(forthToolWindow, myForthContentManager); psiManager.addPsiTreeChangeListener(new PsiTreeChangeAdapter() { @Override @@ -111,28 +107,15 @@ public class SliceManager implements PersistentStateComponent myCanceled = true; } - public void slice(@NotNull PsiElement element, boolean dataFlowToThis) { - doSlice(element, dataFlowToThis); - } - - private void doSlice(@NotNull PsiElement element, boolean dataFlowToThis) { - Module module = ModuleUtil.findModuleForPsiElement(element); - AnalysisUIOptions analysisUIOptions = new AnalysisUIOptions(); - analysisUIOptions.save(myStoredSettings.analysisUIOptions); - AnalysisScope analysisScope = new AnalysisScope(element.getContainingFile()); - String name = module == null ? null : module.getName(); + public void slice(@NotNull PsiElement element, boolean dataFlowToThis, SliceHandler handler) { String dialogTitle = getElementDescription((dataFlowToThis ? BACK_TOOLWINDOW_ID : FORTH_TOOLWINDOW_ID) + " ", element, null); dialogTitle = Pattern.compile("<[^<>]*>").matcher(dialogTitle).replaceAll(""); - - BaseAnalysisActionDialog dialog = new BaseAnalysisActionDialog(dialogTitle, "Analyze scope", myProject, analysisScope, name, true, analysisUIOptions, element); - dialog.show(); - if (!dialog.isOK()) return; + SliceAnalysisParams params = handler.askForParams(element, dataFlowToThis, myStoredSettings, dialogTitle); + if (params == null) return; - AnalysisScope scope = dialog.getScope(analysisUIOptions, analysisScope, myProject, module); - myStoredSettings.analysisUIOptions.save(analysisUIOptions); + SliceRootNode rootNode = new SliceRootNode(myProject, new DuplicateMap(), createRootUsage(element, params)); - SliceRootNode rootNode = new SliceRootNode(myProject, new DuplicateMap(), scope, createRootUsage(element, scope), dataFlowToThis); createToolWindow(dataFlowToThis, rootNode, false, getElementDescription(null, element, null)); } @@ -177,8 +160,8 @@ public class SliceManager implements PersistentStateComponent return ""+ (prefix == null ? "" : prefix) + StringUtil.first(desc, 100, true)+(suffix == null ? "" : suffix) + ""; } - public static SliceUsage createRootUsage(@NotNull PsiElement element, @NotNull AnalysisScope scope) { - return new SliceUsage(element, scope); + public static SliceUsage createRootUsage(@NotNull PsiElement element, @NotNull SliceAnalysisParams params) { + return new SliceUsage(element, params); } public void checkCanceled() throws ProcessCanceledException { @@ -202,11 +185,11 @@ public class SliceManager implements PersistentStateComponent } } - public Bean getState() { + public StoredSettingsBean getState() { return myStoredSettings; } - public void loadState(Bean state) { + public void loadState(StoredSettingsBean state) { myStoredSettings.analysisUIOptions.save(state.analysisUIOptions); } } diff --git a/java/java-impl/src/com/intellij/slicer/SliceNode.java b/java/java-impl/src/com/intellij/slicer/SliceNode.java index 1a6059eb2b..827b1444da 100644 --- a/java/java-impl/src/com/intellij/slicer/SliceNode.java +++ b/java/java-impl/src/com/intellij/slicer/SliceNode.java @@ -44,17 +44,15 @@ public class SliceNode extends AbstractTreeNode implements Duplicate protected final DuplicateMap targetEqualUsages; protected boolean changed; private int index; // my index in parent's mycachedchildren - protected final boolean dataFlowToThis; - protected SliceNode(@NotNull Project project, SliceUsage sliceUsage, @NotNull DuplicateMap targetEqualUsages, boolean dataFlowToThis) { + protected SliceNode(@NotNull Project project, SliceUsage sliceUsage, @NotNull DuplicateMap targetEqualUsages) { super(project, sliceUsage); this.targetEqualUsages = targetEqualUsages; - this.dataFlowToThis = dataFlowToThis; } SliceNode copy() { SliceUsage newUsage = getValue().copy(); - SliceNode newNode = new SliceNode(getProject(), newUsage, targetEqualUsages, dataFlowToThis); + SliceNode newNode = new SliceNode(getProject(), newUsage, targetEqualUsages); newNode.initialized = initialized; newNode.duplicate = duplicate; return newNode; @@ -96,7 +94,7 @@ public class SliceNode extends AbstractTreeNode implements Duplicate Processor processor = new Processor() { public boolean process(SliceUsage sliceUsage) { manager.checkCanceled(); - SliceNode node = new SliceNode(myProject, sliceUsage, targetEqualUsages, dataFlowToThis); + SliceNode node = new SliceNode(myProject, sliceUsage, targetEqualUsages); synchronized (children) { node.index = children.size(); children.add(node); @@ -105,7 +103,7 @@ public class SliceNode extends AbstractTreeNode implements Duplicate } }; - getValue().processChildren(processor, dataFlowToThis); + getValue().processChildren(processor); } }, new Runnable(){ public void run() { @@ -157,6 +155,10 @@ public class SliceNode extends AbstractTreeNode implements Duplicate if (duplicate != null) { presentation.setTooltip("Duplicate node"); } + + if (getValue() instanceof SliceDereferenceUsage) { + presentation.setTooltip("Variable dereferenced"); + } } } diff --git a/java/java-impl/src/com/intellij/slicer/SliceNullnessAnalyzer.java b/java/java-impl/src/com/intellij/slicer/SliceNullnessAnalyzer.java index 09b884e7b4..3657654a17 100644 --- a/java/java-impl/src/com/intellij/slicer/SliceNullnessAnalyzer.java +++ b/java/java-impl/src/com/intellij/slicer/SliceNullnessAnalyzer.java @@ -68,7 +68,8 @@ public class SliceNullnessAnalyzer { return oldNode.getDuplicate() == null && node(oldNode, map).nulls.contains(nullExpression) ? oldNode.copy() : null; } },null); - nullRoot.myCachedChildren.add(new SliceLeafValueRootNode(root.getProject(), nullExpression, nullRoot, Collections.singletonList(newRoot))); + nullRoot.myCachedChildren.add(new SliceLeafValueRootNode(root.getProject(), nullExpression, nullRoot, Collections.singletonList(newRoot), + oldRoot.getValue().params)); } } if (!result.notNulls.isEmpty()) { @@ -81,7 +82,8 @@ public class SliceNullnessAnalyzer { return oldNode.getDuplicate() == null && node(oldNode, map).notNulls.contains(expression) ? oldNode.copy() : null; } },null); - valueRoot.myCachedChildren.add(new SliceLeafValueRootNode(root.getProject(), expression, valueRoot, Collections.singletonList(newRoot))); + valueRoot.myCachedChildren.add(new SliceLeafValueRootNode(root.getProject(), expression, valueRoot, Collections.singletonList(newRoot), + oldRoot.getValue().params)); } } if (!result.unknown.isEmpty()) { @@ -94,7 +96,8 @@ public class SliceNullnessAnalyzer { return oldNode.getDuplicate() == null && node(oldNode, map).unknown.contains(expression) ? oldNode.copy() : null; } },null); - valueRoot.myCachedChildren.add(new SliceLeafValueRootNode(root.getProject(), expression, valueRoot, Collections.singletonList(newRoot))); + valueRoot.myCachedChildren.add(new SliceLeafValueRootNode(root.getProject(), expression, valueRoot, Collections.singletonList(newRoot), + oldRoot.getValue().params)); } } return root; diff --git a/java/java-impl/src/com/intellij/slicer/SliceRootNode.java b/java/java-impl/src/com/intellij/slicer/SliceRootNode.java index 44d09c2f46..bba0dc5d60 100644 --- a/java/java-impl/src/com/intellij/slicer/SliceRootNode.java +++ b/java/java-impl/src/com/intellij/slicer/SliceRootNode.java @@ -15,7 +15,6 @@ */ package com.intellij.slicer; -import com.intellij.analysis.AnalysisScope; import com.intellij.ide.projectView.PresentationData; import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.openapi.progress.ProgressIndicator; @@ -33,21 +32,20 @@ import java.util.List; public class SliceRootNode extends SliceNode { private final SliceUsage myRootUsage; - public SliceRootNode(@NotNull Project project, @NotNull DuplicateMap targetEqualUsages, - AnalysisScope scope, final SliceUsage rootUsage, boolean dataFlowToThis) { - super(project, new SliceUsage(rootUsage.getElement().getContainingFile(), scope), targetEqualUsages, dataFlowToThis); + public SliceRootNode(@NotNull Project project, @NotNull DuplicateMap targetEqualUsages, final SliceUsage rootUsage) { + super(project, new SliceUsage(rootUsage.getElement().getContainingFile(), rootUsage.params), targetEqualUsages); myRootUsage = rootUsage; } void switchToAllLeavesTogether(SliceUsage rootUsage) { - SliceNode node = new SliceNode(getProject(), rootUsage, targetEqualUsages, dataFlowToThis); + SliceNode node = new SliceNode(getProject(), rootUsage, targetEqualUsages); myCachedChildren = Collections.singletonList(node); } @Override SliceRootNode copy() { SliceUsage newUsage = getValue().copy(); - SliceRootNode newNode = new SliceRootNode(getProject(), new DuplicateMap(), getValue().getScope(), newUsage, dataFlowToThis); + SliceRootNode newNode = new SliceRootNode(getProject(), new DuplicateMap(), newUsage); newNode.initialized = initialized; newNode.duplicate = duplicate; return newNode; diff --git a/java/java-impl/src/com/intellij/slicer/SliceUsage.java b/java/java-impl/src/com/intellij/slicer/SliceUsage.java index e0aae8973b..e4c6b5374b 100644 --- a/java/java-impl/src/com/intellij/slicer/SliceUsage.java +++ b/java/java-impl/src/com/intellij/slicer/SliceUsage.java @@ -34,24 +34,24 @@ import org.jetbrains.annotations.NotNull; */ public class SliceUsage extends UsageInfo2UsageAdapter { private final SliceUsage myParent; - private final AnalysisScope myScope; + public final SliceAnalysisParams params; private final PsiSubstitutor mySubstitutor; public SliceUsage(@NotNull PsiElement element, @NotNull SliceUsage parent, @NotNull PsiSubstitutor substitutor) { super(new UsageInfo(element)); myParent = parent; mySubstitutor = substitutor; - myScope = parent.myScope; - assert myScope != null; + params = parent.params; + assert params != null; } - public SliceUsage(@NotNull PsiElement element, @NotNull AnalysisScope scope) { + public SliceUsage(@NotNull PsiElement element, @NotNull SliceAnalysisParams params) { super(new UsageInfo(element)); myParent = null; - myScope = scope; + this.params = params; mySubstitutor = PsiSubstitutor.EMPTY; } - public void processChildren(Processor processor, final boolean dataFlowToThis) { + public void processChildren(Processor processor) { final PsiElement element = getElement(); ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); //indicator.setText2("Searching for usages of "+ StringUtil.trimStart(SliceManager.getElementDescription(element),"")+""); @@ -70,7 +70,7 @@ public class SliceUsage extends UsageInfo2UsageAdapter { ApplicationManager.getApplication().runReadAction(new Runnable() { public void run() { - if (dataFlowToThis) { + if (params.dataFlowToThis) { SliceUtil.processUsagesFlownDownTo(element, uniqueProcessor, SliceUsage.this, mySubstitutor); } else { @@ -86,12 +86,12 @@ public class SliceUsage extends UsageInfo2UsageAdapter { @NotNull public AnalysisScope getScope() { - return myScope; + return params.scope; } SliceUsage copy() { PsiElement element = getUsageInfo().getElement(); - return getParent() == null ? new SliceUsage(element, getScope()) : new SliceUsage(element, getParent(),mySubstitutor); + return getParent() == null ? new SliceUsage(element, params) : new SliceUsage(element, getParent(),mySubstitutor); } public PsiSubstitutor getSubstitutor() { diff --git a/java/java-impl/src/com/intellij/slicer/SliceUsageCellRenderer.java b/java/java-impl/src/com/intellij/slicer/SliceUsageCellRenderer.java index f006bc63f1..f755a06d30 100644 --- a/java/java-impl/src/com/intellij/slicer/SliceUsageCellRenderer.java +++ b/java/java-impl/src/com/intellij/slicer/SliceUsageCellRenderer.java @@ -24,10 +24,10 @@ import com.intellij.ui.SimpleTextAttributes; import com.intellij.usageView.UsageTreeColors; import com.intellij.usageView.UsageTreeColorsScheme; import com.intellij.usages.TextChunk; -import com.intellij.usages.UsageInfo2UsageAdapter; import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; +import java.awt.*; /** * @author cdr @@ -57,10 +57,17 @@ public class SliceUsageCellRenderer extends ColoredTreeCellRenderer { } } - public void customizeCellRendererFor(UsageInfo2UsageAdapter sliceUsage) { + public void customizeCellRendererFor(SliceUsage sliceUsage) { + boolean isForcedLeaf = sliceUsage instanceof SliceDereferenceUsage; + TextChunk[] text = sliceUsage.getPresentation().getText(); for (TextChunk textChunk : text) { - append(textChunk.getText(), SimpleTextAttributes.fromTextAttributes(textChunk.getAttributes())); + SimpleTextAttributes attributes = SimpleTextAttributes.fromTextAttributes(textChunk.getAttributes()); + if (isForcedLeaf) { + attributes = attributes.derive(attributes.getStyle(), Color.LIGHT_GRAY, attributes.getBgColor(), attributes.getWaveColor()); + //attributes = attributes.derive(SimpleTextAttributes.STYLE_UNDERLINE, attributes.getBgColor(), attributes.getBgColor(), attributes.getWaveColor()); + } + append(textChunk.getText(), attributes); } PsiElement element = sliceUsage.getElement(); @@ -76,11 +83,15 @@ public class SliceUsageCellRenderer extends ColoredTreeCellRenderer { break; } } - String location = method != null ? PsiFormatUtil.formatMethod(method, PsiSubstitutor.EMPTY, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS | PsiFormatUtil.SHOW_CONTAINING_CLASS, PsiFormatUtil.SHOW_TYPE, 2) - : aClass != null ? PsiFormatUtil.formatClass(aClass, PsiFormatUtil.SHOW_NAME) - : null; + String location = method != null + ? PsiFormatUtil.formatMethod(method, PsiSubstitutor.EMPTY, PsiFormatUtil.SHOW_NAME | + PsiFormatUtil.SHOW_PARAMETERS | + PsiFormatUtil.SHOW_CONTAINING_CLASS, + PsiFormatUtil.SHOW_TYPE, 2) + : aClass != null ? PsiFormatUtil.formatClass(aClass, PsiFormatUtil.SHOW_NAME) : null; if (location != null) { - append(" in " + location, SimpleTextAttributes.GRAY_ATTRIBUTES); + SimpleTextAttributes attributes = SimpleTextAttributes.GRAY_ATTRIBUTES; + append(" in " + location, attributes); } } } diff --git a/java/java-impl/src/com/intellij/slicer/forward/SliceFUtil.java b/java/java-impl/src/com/intellij/slicer/forward/SliceFUtil.java index 052413a9c4..903cf3e4c2 100644 --- a/java/java-impl/src/com/intellij/slicer/forward/SliceFUtil.java +++ b/java/java-impl/src/com/intellij/slicer/forward/SliceFUtil.java @@ -22,6 +22,7 @@ import com.intellij.psi.search.searches.OverridingMethodsSearch; import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.MethodSignatureUtil; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.slicer.SliceDereferenceUsage; import com.intellij.slicer.SliceManager; import com.intellij.slicer.SliceUsage; import com.intellij.slicer.SliceUtil; @@ -111,7 +112,7 @@ public class SliceFUtil { for (Iterator iterator = superMethods.iterator(); iterator.hasNext(); ) { SliceManager.getInstance(method.getProject()).checkCanceled(); PsiMethod superMethod = iterator.next(); - if (superMethod instanceof PsiCompiledElement) { + if (!parent.params.scope.contains(superMethod)) { iterator.remove(); } } @@ -129,6 +130,9 @@ public class SliceFUtil { } for (PsiMethod implementor : implementors) { SliceManager.getInstance(method.getProject()).checkCanceled(); + if (!parent.params.scope.contains(implementor)) continue; + if (implementor instanceof PsiCompiledElement) implementor = (PsiMethod)implementor.getNavigationElement(); + PsiParameter[] parameters = implementor.getParameterList().getParameters(); if (index != -1 && index < parameters.length) { parametersToAnalyze.add(parameters[index]); @@ -186,14 +190,27 @@ public class SliceFUtil { } private static boolean processAssignmentTarget(PsiElement element, final SliceUsage parent, final Processor processor) { + if (!parent.params.scope.contains(element)) return true; + if (element instanceof PsiCompiledElement) element = element.getNavigationElement(); Pair pair = getAssignmentTarget(element, parent); if (pair != null) { SliceUsage usage = SliceUtil.createSliceUsage(element, parent, pair.getSecond()); return processor.process(usage); } + if (parent.params.showInstanceDereferences && isDereferenced(element)) { + SliceUsage usage = new SliceDereferenceUsage(element.getParent(), parent, parent.getSubstitutor()); + return processor.process(usage); + } return true; } + private static boolean isDereferenced(PsiElement element) { + if (!(element instanceof PsiReferenceExpression)) return false; + PsiElement parent = element.getParent(); + if (!(parent instanceof PsiReferenceExpression)) return false; + return ((PsiReferenceExpression)parent).getQualifierExpression() == element; + } + private static Pair getAssignmentTarget(PsiElement element, SliceUsage parentUsage) { element = complexify(element); PsiElement target = null; diff --git a/platform/lang-impl/src/com/intellij/analysis/BaseAnalysisAction.java b/platform/lang-impl/src/com/intellij/analysis/BaseAnalysisAction.java index 7d994ea09f..ed097f0ec9 100644 --- a/platform/lang-impl/src/com/intellij/analysis/BaseAnalysisAction.java +++ b/platform/lang-impl/src/com/intellij/analysis/BaseAnalysisAction.java @@ -50,8 +50,7 @@ public abstract class BaseAnalysisAction extends AnAction { public void update(AnActionEvent event) { Presentation presentation = event.getPresentation(); - presentation.setEnabled( - getInspectionScope(event.getDataContext()) != null); + presentation.setEnabled(getInspectionScope(event.getDataContext()) != null); } public void actionPerformed(AnActionEvent e) { -- 2.11.4.GIT