mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
project structure: delete unused 'Analyze' action
It was never enabled, works very inefficiently in big projects and we now have module dependencies diagram instead.
This commit is contained in:
+1
-14
@@ -37,7 +37,6 @@ import com.intellij.openapi.roots.ui.OrderEntryAppearanceService;
|
||||
import com.intellij.openapi.roots.ui.configuration.LibraryTableModifiableModelProvider;
|
||||
import com.intellij.openapi.roots.ui.configuration.ModuleConfigurationState;
|
||||
import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable;
|
||||
import com.intellij.openapi.roots.ui.configuration.dependencyAnalysis.AnalyzeDependenciesDialog;
|
||||
import com.intellij.openapi.roots.ui.configuration.libraries.LibraryEditingUtil;
|
||||
import com.intellij.openapi.roots.ui.configuration.libraryEditor.EditExistingLibraryDialog;
|
||||
import com.intellij.openapi.roots.ui.configuration.projectRoot.ConvertModuleLibraryToRepositoryLibraryAction;
|
||||
@@ -86,8 +85,8 @@ import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
import static com.intellij.openapi.wm.IdeFocusManager.getGlobalInstance;
|
||||
|
||||
@@ -366,8 +365,6 @@ public class ClasspathPanelImpl extends JPanel implements ClasspathPanel {
|
||||
|
||||
|
||||
private JComponent createTableWithButtons() {
|
||||
final boolean isAnalyzeShown = false;
|
||||
|
||||
final ClasspathPanelAction removeAction = new ClasspathPanelAction(this) {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -375,13 +372,6 @@ public class ClasspathPanelImpl extends JPanel implements ClasspathPanel {
|
||||
}
|
||||
};
|
||||
|
||||
final AnActionButton analyzeButton = new AnActionButton(ProjectBundle.message("classpath.panel.analyze"), null, IconUtil.getAnalyzeIcon()) {
|
||||
@Override
|
||||
public void actionPerformed(@NotNull AnActionEvent e) {
|
||||
AnalyzeDependenciesDialog.show(getRootModel().getModule());
|
||||
}
|
||||
};
|
||||
|
||||
//addButton.setShortcut(CustomShortcutSet.fromString("alt A", "INSERT"));
|
||||
//removeButton.setShortcut(CustomShortcutSet.fromString("alt DELETE"));
|
||||
//upButton.setShortcut(CustomShortcutSet.fromString("alt UP"));
|
||||
@@ -466,9 +456,6 @@ public class ClasspathPanelImpl extends JPanel implements ClasspathPanel {
|
||||
.setMoveDownActionUpdater(moveUpDownUpdater)
|
||||
.setMoveDownActionName("Move Down (disabled if items are shown in sorted order)")
|
||||
.addExtraAction(myEditButton);
|
||||
if (isAnalyzeShown) {
|
||||
decorator.addExtraAction(analyzeButton);
|
||||
}
|
||||
|
||||
final JPanel panel = decorator.createPanel();
|
||||
myRemoveButton = ToolbarDecorator.findRemoveButton(panel);
|
||||
|
||||
-799
@@ -1,799 +0,0 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.openapi.roots.ui.configuration.dependencyAnalysis;
|
||||
|
||||
import com.intellij.ProjectTopics;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ide.DataManager;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.actionSystem.ex.ComboBoxAction;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleType;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.roots.ModuleRootEvent;
|
||||
import com.intellij.openapi.roots.ModuleRootListener;
|
||||
import com.intellij.openapi.roots.ModuleSourceOrderEntry;
|
||||
import com.intellij.openapi.roots.OrderEntry;
|
||||
import com.intellij.openapi.roots.ui.CellAppearanceEx;
|
||||
import com.intellij.openapi.roots.ui.OrderEntryAppearanceService;
|
||||
import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable;
|
||||
import com.intellij.openapi.ui.MasterDetailsComponent;
|
||||
import com.intellij.openapi.ui.NamedConfigurable;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.ui.*;
|
||||
import com.intellij.ui.components.JBScrollPane;
|
||||
import com.intellij.ui.treeStructure.Tree;
|
||||
import com.intellij.util.PathUtil;
|
||||
import com.intellij.util.messages.MessageBusConnection;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.util.ui.tree.TreeUtil;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import javax.swing.tree.DefaultTreeModel;
|
||||
import javax.swing.tree.TreePath;
|
||||
import javax.swing.tree.TreeSelectionModel;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The classpath details component
|
||||
*/
|
||||
public class AnalyzeDependenciesComponent extends MasterDetailsComponent {
|
||||
/**
|
||||
* Data key for order path element
|
||||
*/
|
||||
public static final DataKey<ModuleDependenciesAnalyzer.OrderPathElement> ORDER_PATH_ELEMENT_KEY = DataKey.create("ORDER_PATH_ELEMENT");
|
||||
/**
|
||||
* The module being analyzed
|
||||
*/
|
||||
private final Module myModule;
|
||||
/**
|
||||
* The settings for UI mode
|
||||
*/
|
||||
private final AnalyzeDependenciesSettings mySettings;
|
||||
/**
|
||||
* The cached analyzed classpaths for this module
|
||||
*/
|
||||
private final HashMap<Pair<ClasspathType, Boolean>, ModuleDependenciesAnalyzer> myClasspaths =
|
||||
new HashMap<>();
|
||||
|
||||
/**
|
||||
* The message bus connection to use
|
||||
*/
|
||||
private final MessageBusConnection myMessageBusConnection;
|
||||
|
||||
/**
|
||||
* The constructor
|
||||
*
|
||||
* @param module the module to analyze
|
||||
*/
|
||||
public AnalyzeDependenciesComponent(Module module) {
|
||||
myModule = module;
|
||||
mySettings = AnalyzeDependenciesSettings.getInstance(myModule.getProject());
|
||||
initTree();
|
||||
init();
|
||||
getSplitter().setProportion(0.3f);
|
||||
myMessageBusConnection = myModule.getProject().getMessageBus().connect();
|
||||
myMessageBusConnection.subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootListener() {
|
||||
@Override
|
||||
public void rootsChanged(@NotNull ModuleRootEvent event) {
|
||||
myClasspaths.clear();
|
||||
updateTree();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void disposeUIResources() {
|
||||
if (myMessageBusConnection != null) {
|
||||
myMessageBusConnection.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize components
|
||||
*/
|
||||
private void init() {
|
||||
myTree.setCellRenderer(new ColoredTreeCellRenderer() {
|
||||
@Override
|
||||
public void customizeCellRenderer(JTree tree,
|
||||
Object value,
|
||||
boolean selected,
|
||||
boolean expanded,
|
||||
boolean leaf,
|
||||
int row,
|
||||
boolean hasFocus) {
|
||||
//if(getBackground() == null) {
|
||||
// setBackground(UIUtil.getTreeTextBackground());
|
||||
//}
|
||||
if (value instanceof MyNode && !(value instanceof MyRootNode)) {
|
||||
final MyNode node = (MyNode)value;
|
||||
PathNode<?> n = (PathNode<?>)node.getUserObject();
|
||||
CellAppearanceEx a = n.getAppearance(selected, node.isDisplayInBold());
|
||||
a.customize(this);
|
||||
}
|
||||
}
|
||||
});
|
||||
myTree.setShowsRootHandles(false);
|
||||
myTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
|
||||
reloadTree();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected List<AnAction> createActions(boolean fromPopup) {
|
||||
if (fromPopup) {
|
||||
return super.createActions(true);
|
||||
}
|
||||
|
||||
List<AnAction> rc = new ArrayList<>();
|
||||
rc.add(new ClasspathTypeAction());
|
||||
rc.add(new SdkFilterAction());
|
||||
rc.add(new UrlModeAction());
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Nls
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return "Classpath Details";
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload tree
|
||||
*/
|
||||
public void reloadTree() {
|
||||
myRoot.removeAllChildren();
|
||||
ModuleDependenciesAnalyzer a = getAnalyzer();
|
||||
if (mySettings.isUrlMode()) {
|
||||
for (ModuleDependenciesAnalyzer.UrlExplanation urlExplanation : a.getUrls()) {
|
||||
myRoot.add(new MyNode(new UrlNode(urlExplanation)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (ModuleDependenciesAnalyzer.OrderEntryExplanation explanation : a.getOrderEntries()) {
|
||||
myRoot.add(new MyNode(new OrderEntryNode(explanation)));
|
||||
}
|
||||
}
|
||||
((DefaultTreeModel)myTree.getModel()).reload(myRoot);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the analyzer for the current settings
|
||||
*/
|
||||
public ModuleDependenciesAnalyzer getAnalyzer() {
|
||||
final Pair<ClasspathType, Boolean> key = Pair.create(getClasspathType(), mySettings.isSdkIncluded());
|
||||
ModuleDependenciesAnalyzer a = myClasspaths.get(key);
|
||||
if (a == null) {
|
||||
a = new ModuleDependenciesAnalyzer(myModule, !mySettings.isTest(), !mySettings.isRuntime(), mySettings.isSdkIncluded());
|
||||
myClasspaths.put(key, a);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the current classpath type from settings
|
||||
*/
|
||||
private ClasspathType getClasspathType() {
|
||||
return mySettings.isRuntime() ?
|
||||
(mySettings.isTest() ? ClasspathType.TEST_RUNTIME : ClasspathType.PRODUCTION_RUNTIME) :
|
||||
(mySettings.isTest() ? ClasspathType.TEST_COMPILE : ClasspathType.PRODUCTION_COMPILE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Schedule updating the tree
|
||||
*/
|
||||
void updateTree() {
|
||||
// TODO make loading in the background if there will be significant delays on big projects
|
||||
reloadTree();
|
||||
}
|
||||
|
||||
/**
|
||||
* The action that allows navigating to the path element
|
||||
*/
|
||||
static class NavigateAction extends DumbAwareAction {
|
||||
|
||||
/**
|
||||
* The constructor
|
||||
*/
|
||||
NavigateAction() {
|
||||
super("Navigate to ...", "Navigate to place where path element is defined", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void actionPerformed(@NotNull AnActionEvent e) {
|
||||
final Module module = e.getData(LangDataKeys.MODULE);
|
||||
if (module == null) {
|
||||
return;
|
||||
}
|
||||
final ModuleDependenciesAnalyzer.OrderPathElement element = e.getData(ORDER_PATH_ELEMENT_KEY);
|
||||
if (element instanceof ModuleDependenciesAnalyzer.OrderEntryPathElement) {
|
||||
final ModuleDependenciesAnalyzer.OrderEntryPathElement o = (ModuleDependenciesAnalyzer.OrderEntryPathElement)element;
|
||||
final OrderEntry entry = o.entry();
|
||||
final Module m = entry.getOwnerModule();
|
||||
ProjectStructureConfigurable.getInstance(module.getProject()).selectOrderEntry(m, entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for nodes
|
||||
*
|
||||
* @param <T> the actual explanation type
|
||||
*/
|
||||
abstract class PathNode<T extends ModuleDependenciesAnalyzer.Explanation> extends NamedConfigurable<T> implements DataProvider {
|
||||
/**
|
||||
* The cut off length, after which URLs are not shown (only suffix)
|
||||
*/
|
||||
public static final int CUTOFF_LENGTH = 80;
|
||||
|
||||
/**
|
||||
* The explanation
|
||||
*/
|
||||
protected final T myExplanation;
|
||||
/**
|
||||
* The tree with explanation
|
||||
*/
|
||||
private Tree myExplanationTree;
|
||||
|
||||
/**
|
||||
* The constructor
|
||||
*
|
||||
* @param explanation the wrapped explanation
|
||||
*/
|
||||
PathNode(T explanation) {
|
||||
myExplanation = explanation;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public T getEditableObject() {
|
||||
return myExplanation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a created tree component (to be used as
|
||||
*/
|
||||
private JComponent createTreeComponent() {
|
||||
myExplanationTree = new Tree(new DefaultTreeModel(buildTree()));
|
||||
myExplanationTree.setRootVisible(false);
|
||||
myExplanationTree.setCellRenderer(new ExplanationTreeRenderer());
|
||||
DataManager.registerDataProvider(myExplanationTree, this);
|
||||
TreeUtil.expandAll(myExplanationTree);
|
||||
final NavigateAction navigateAction = new NavigateAction();
|
||||
navigateAction.registerCustomShortcutSet(new CustomShortcutSet(CommonShortcuts.DOUBLE_CLICK_1.getShortcuts()[0]), myExplanationTree);
|
||||
DefaultActionGroup group = new DefaultActionGroup();
|
||||
group.addAction(navigateAction);
|
||||
PopupHandler.installUnknownPopupHandler(myExplanationTree, group, ActionManager.getInstance());
|
||||
return new JBScrollPane(myExplanationTree);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Object getData(@NotNull @NonNls String dataId) {
|
||||
if (CommonDataKeys.PROJECT.is(dataId)) {
|
||||
return myModule.getProject();
|
||||
}
|
||||
if (LangDataKeys.MODULE.is(dataId)) {
|
||||
return myModule;
|
||||
}
|
||||
TreePath selectionPath = myExplanationTree.getSelectionPath();
|
||||
DefaultMutableTreeNode node = selectionPath == null ? null : (DefaultMutableTreeNode)selectionPath.getLastPathComponent();
|
||||
Object o = node == null ? null : node.getUserObject();
|
||||
if (o instanceof ModuleDependenciesAnalyzer.OrderPathElement) {
|
||||
if (ORDER_PATH_ELEMENT_KEY.is(dataId)) {
|
||||
return o;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build tree for the dependencies
|
||||
*
|
||||
* @return a tree model
|
||||
*/
|
||||
private DefaultMutableTreeNode buildTree() {
|
||||
DefaultMutableTreeNode root = new DefaultMutableTreeNode("ROOT");
|
||||
for (ModuleDependenciesAnalyzer.OrderPath orderPath : myExplanation.paths()) {
|
||||
addDependencyPath(root, orderPath, 0);
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the dependency path
|
||||
*
|
||||
* @param parent the parent to which path is added
|
||||
* @param orderPath the order entry path
|
||||
* @param i the position in the path
|
||||
*/
|
||||
private void addDependencyPath(DefaultMutableTreeNode parent,
|
||||
ModuleDependenciesAnalyzer.OrderPath orderPath,
|
||||
int i) {
|
||||
if (i >= orderPath.entries().size()) {
|
||||
return;
|
||||
}
|
||||
ModuleDependenciesAnalyzer.OrderPathElement e = orderPath.entries().get(i);
|
||||
int sz = parent.getChildCount();
|
||||
DefaultMutableTreeNode n;
|
||||
if (sz == 0) {
|
||||
n = null;
|
||||
}
|
||||
else {
|
||||
n = (DefaultMutableTreeNode)parent.getChildAt(sz - 1);
|
||||
if (!n.getUserObject().equals(e)) {
|
||||
n = null;
|
||||
}
|
||||
}
|
||||
if (n == null) {
|
||||
n = new DefaultMutableTreeNode(e);
|
||||
parent.add(n);
|
||||
}
|
||||
addDependencyPath(n, orderPath, i + 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void setDisplayName(String name) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public JComponent createOptionsPanel() {
|
||||
final JComponent tree = createTreeComponent();
|
||||
JPanel panel = new JPanel(new BorderLayout());
|
||||
JLabel paths = new JLabel("Available Through Paths:");
|
||||
paths.setDisplayedMnemonic('P');
|
||||
paths.setLabelFor(tree);
|
||||
panel.add(paths, BorderLayout.NORTH);
|
||||
panel.add(tree, BorderLayout.CENTER);
|
||||
return panel;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getHelpTopic() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean isModified() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void apply() throws ConfigurationException {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* Get appearance for rendering in master list
|
||||
*
|
||||
* @param selected true if selected
|
||||
* @param bold true if bold
|
||||
* @return the result appearance
|
||||
*/
|
||||
public abstract CellAppearanceEx getAppearance(boolean selected, boolean bold);
|
||||
|
||||
/**
|
||||
* @retrun the string cut so it would fit the banner (the prefix is dropped)
|
||||
*/
|
||||
protected String suffixForBanner(String p) {
|
||||
if (p.length() > CUTOFF_LENGTH) {
|
||||
p = "..." + p.substring(p.length() - CUTOFF_LENGTH);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* @retrun the string cut so it would fit the banner (the suffix is dropped)
|
||||
*/
|
||||
protected String prefixForBanner(String p) {
|
||||
if (p.length() > CUTOFF_LENGTH) {
|
||||
p = p.substring(0, CUTOFF_LENGTH) + "...";
|
||||
}
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cell renderer for explanation tree
|
||||
*/
|
||||
static class ExplanationTreeRenderer extends ColoredTreeCellRenderer {
|
||||
@Override
|
||||
public void customizeCellRenderer(JTree tree,
|
||||
Object value,
|
||||
boolean selected,
|
||||
boolean expanded,
|
||||
boolean leaf,
|
||||
int row,
|
||||
boolean hasFocus) {
|
||||
DefaultMutableTreeNode n = (DefaultMutableTreeNode)value;
|
||||
final Object userObject = n.getUserObject();
|
||||
if (!(userObject instanceof ModuleDependenciesAnalyzer.OrderPathElement)) {
|
||||
return;
|
||||
}
|
||||
ModuleDependenciesAnalyzer.OrderPathElement e = (ModuleDependenciesAnalyzer.OrderPathElement)userObject;
|
||||
final CellAppearanceEx appearance = e.getAppearance(selected);
|
||||
appearance.customize(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The entry node in URL node
|
||||
*/
|
||||
class UrlNode extends PathNode<ModuleDependenciesAnalyzer.UrlExplanation> {
|
||||
|
||||
/**
|
||||
* The constructor
|
||||
*
|
||||
* @param url the wrapped explanation
|
||||
*/
|
||||
UrlNode(ModuleDependenciesAnalyzer.UrlExplanation url) {
|
||||
super(url);
|
||||
setNameFieldShown(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public CellAppearanceEx getAppearance(boolean selected, final boolean isBold) {
|
||||
return new CellAppearanceEx() {
|
||||
@Override
|
||||
public void customize(@NotNull SimpleColoredComponent component) {
|
||||
component.setIcon(getIcon());
|
||||
final Font font = UIUtil.getTreeFont();
|
||||
if (isBold) {
|
||||
component.setFont(font.deriveFont(Font.BOLD));
|
||||
}
|
||||
else {
|
||||
component.setFont(font.deriveFont(Font.PLAIN));
|
||||
}
|
||||
final String p = PathUtil.toPresentableUrl(getEditableObject().url());
|
||||
component.append(PathUtil.getFileName(p),
|
||||
isBold ? SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES : SimpleTextAttributes.REGULAR_ATTRIBUTES);
|
||||
component.append(" (" + PathUtil.getParentPath(p) + ")", SimpleTextAttributes.GRAYED_ATTRIBUTES);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customize(@NotNull final HtmlListCellRenderer renderer) {
|
||||
throw new UnsupportedOperationException("Rendering in combo box not supported yet.");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return getDisplayName();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getBannerSlogan() {
|
||||
final VirtualFile f = myExplanation.getLocalFile();
|
||||
String p = f == null ? myExplanation.url() : f.getPath();
|
||||
p = suffixForBanner(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
private Icon getIcon() {
|
||||
return myExplanation.getIcon();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Nls
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return myExplanation.url();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The wrapper for order entries
|
||||
*/
|
||||
class OrderEntryNode extends PathNode<ModuleDependenciesAnalyzer.OrderEntryExplanation> {
|
||||
|
||||
/**
|
||||
* The constructor
|
||||
*
|
||||
* @param orderEntryExplanation the explanation to wrap
|
||||
*/
|
||||
OrderEntryNode(ModuleDependenciesAnalyzer.OrderEntryExplanation orderEntryExplanation) {
|
||||
super(orderEntryExplanation);
|
||||
setNameFieldShown(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public CellAppearanceEx getAppearance(boolean selected, final boolean isBold) {
|
||||
if (myExplanation.entry() instanceof ModuleSourceOrderEntry) {
|
||||
ModuleSourceOrderEntry e = (ModuleSourceOrderEntry)myExplanation.entry();
|
||||
if (e.getOwnerModule() == myModule) {
|
||||
return new CellAppearanceEx() {
|
||||
@Override
|
||||
public void customize(@NotNull SimpleColoredComponent component) {
|
||||
component.setIcon(ModuleType.get(myModule).getIcon());
|
||||
component.append("<This Module>", SimpleTextAttributes.SYNTHETIC_ATTRIBUTES);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customize(@NotNull final HtmlListCellRenderer renderer) {
|
||||
throw new UnsupportedOperationException("Rendering in combo box not supported yet.");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return "<This Module>";
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
return OrderEntryAppearanceService.getInstance().forModule(e.getOwnerModule());
|
||||
}
|
||||
}
|
||||
return OrderEntryAppearanceService.getInstance().forOrderEntry(myModule.getProject(), myExplanation.entry(), selected);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getBannerSlogan() {
|
||||
if (myExplanation.entry() instanceof ModuleSourceOrderEntry) {
|
||||
ModuleSourceOrderEntry e = (ModuleSourceOrderEntry)myExplanation.entry();
|
||||
return prefixForBanner("Module " + e.getOwnerModule().getName());
|
||||
}
|
||||
else {
|
||||
final String p = myExplanation.entry().getPresentableName() + " in module " + myExplanation.entry().getOwnerModule().getName();
|
||||
return suffixForBanner(p);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Nls
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return myExplanation.entry().getPresentableName();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The action that allows including and excluding SDK entries from analysis
|
||||
*/
|
||||
private class SdkFilterAction extends ToggleAction {
|
||||
|
||||
/**
|
||||
* The constructor
|
||||
*/
|
||||
SdkFilterAction() {
|
||||
super("Include SDK", "If selected, the SDK classes are included", AllIcons.Nodes.PpJdk);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean isSelected(@NotNull AnActionEvent e) {
|
||||
return mySettings.isSdkIncluded();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void setSelected(@NotNull AnActionEvent e, boolean state) {
|
||||
mySettings.setIncludeSdk(state);
|
||||
updateTree();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The action that allows switching class path between URL and order entry modes
|
||||
*/
|
||||
private class UrlModeAction extends ToggleAction {
|
||||
/**
|
||||
* The constructor
|
||||
*/
|
||||
UrlModeAction() {
|
||||
super("Use URL mode", "If selected, the URLs are displayed, otherwise order entries", AllIcons.Nodes.Folder);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean isSelected(@NotNull AnActionEvent e) {
|
||||
return mySettings.isUrlMode();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void setSelected(@NotNull AnActionEvent e, boolean state) {
|
||||
mySettings.setUrlMode(state);
|
||||
updateTree();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Classpath type action for the analyze classpath
|
||||
*/
|
||||
private class ClasspathTypeAction extends ComboBoxAction {
|
||||
/**
|
||||
* The filter action group
|
||||
*/
|
||||
DefaultActionGroup myItems;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@NotNull
|
||||
@Override
|
||||
protected DefaultActionGroup createPopupActionGroup(JComponent button) {
|
||||
if (myItems == null) {
|
||||
myItems = new DefaultActionGroup(null, true);
|
||||
for (final ClasspathType classpathType : ClasspathType.values()) {
|
||||
myItems.addAction(new DumbAwareAction(classpathType.getDescription()) {
|
||||
@Override
|
||||
public void actionPerformed(@NotNull AnActionEvent e) {
|
||||
mySettings.setRuntime(classpathType.isRuntime());
|
||||
mySettings.setTest(classpathType.isTest());
|
||||
updateTree();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return myItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void update(@NotNull AnActionEvent e) {
|
||||
final Presentation presentation = e.getPresentation();
|
||||
updateText(presentation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the text for the combobox
|
||||
*
|
||||
* @param presentation the presentaiton to update
|
||||
*/
|
||||
private void updateText(Presentation presentation) {
|
||||
final ClasspathType classpathType = getClasspathType();
|
||||
String t = classpathType.getDescription();
|
||||
presentation.setText(t);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The enumeration type that represents classpath entry filter
|
||||
*/
|
||||
private enum ClasspathType {
|
||||
/**
|
||||
* The production compile mode
|
||||
*/
|
||||
PRODUCTION_COMPILE(false, false, "Production Compile"),
|
||||
/**
|
||||
* The production runtime mode
|
||||
*/
|
||||
PRODUCTION_RUNTIME(false, true, "Production Runtime"),
|
||||
/**
|
||||
* The test runtime mode
|
||||
*/
|
||||
TEST_RUNTIME(true, true, "Test Runtime"),
|
||||
/**
|
||||
* The test compile mode
|
||||
*/
|
||||
TEST_COMPILE(true, false, "Test Compile");
|
||||
|
||||
/**
|
||||
* true, if test mode
|
||||
*/
|
||||
final private boolean myIsTest;
|
||||
/**
|
||||
* true, if runtime mode
|
||||
*/
|
||||
final private boolean myIsRuntime;
|
||||
/**
|
||||
* The description text
|
||||
*/
|
||||
final private String myDescription;
|
||||
|
||||
/**
|
||||
* The constructor
|
||||
*
|
||||
* @param isTest true if the test mode
|
||||
* @param isRuntime true if the runtime ode
|
||||
* @param description the description text
|
||||
*/
|
||||
ClasspathType(boolean isTest, boolean isRuntime, String description) {
|
||||
myIsTest = isTest;
|
||||
myIsRuntime = isRuntime;
|
||||
myDescription = description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the test mode
|
||||
*/
|
||||
public boolean isTest() {
|
||||
return myIsTest;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the runtime mode
|
||||
*/
|
||||
public boolean isRuntime() {
|
||||
return myIsRuntime;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return myDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the description for the entry
|
||||
*/
|
||||
public String getDescription() {
|
||||
return myDescription;
|
||||
}
|
||||
}
|
||||
}
|
||||
-88
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
* 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.openapi.roots.ui.configuration.dependencyAnalysis;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* The dialog that allows examining dependencies
|
||||
*/
|
||||
public class AnalyzeDependenciesDialog extends DialogWrapper {
|
||||
/**
|
||||
* The analyzer component
|
||||
*/
|
||||
private final AnalyzeDependenciesComponent myComponent;
|
||||
|
||||
/**
|
||||
* The constructor
|
||||
*
|
||||
* @param module the dialog that allows analyzing dependencies
|
||||
*/
|
||||
protected AnalyzeDependenciesDialog(Module module) {
|
||||
super(module.getProject(), true);
|
||||
setTitle("Analyze Dependencies for " + module.getName());
|
||||
setModal(false);
|
||||
myComponent = new AnalyzeDependenciesComponent(module);
|
||||
Disposer.register(myDisposable, new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
myComponent.disposeUIResources();
|
||||
}
|
||||
});
|
||||
setOKButtonText("Close");
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@NotNull
|
||||
@Override
|
||||
protected Action[] createActions() {
|
||||
return new Action[]{getOKAction()};
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected JComponent createCenterPanel() {
|
||||
return myComponent.createComponent();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected String getDimensionServiceKey() {
|
||||
return getClass().getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the dialog
|
||||
*
|
||||
* @param module the module to use
|
||||
*/
|
||||
public static void show(Module module) {
|
||||
new AnalyzeDependenciesDialog(module).show();
|
||||
}
|
||||
}
|
||||
-133
@@ -1,133 +0,0 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.openapi.roots.ui.configuration.dependencyAnalysis;
|
||||
|
||||
import com.intellij.openapi.components.*;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* The default mode for classpath details settings
|
||||
*/
|
||||
@State(name = "AnalyzeDependenciesSettings", storages = @Storage(StoragePathMacros.WORKSPACE_FILE))
|
||||
public class AnalyzeDependenciesSettings implements PersistentStateComponent<AnalyzeDependenciesSettings.State> {
|
||||
/**
|
||||
* The current state
|
||||
*/
|
||||
private State myState = new State();
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public State getState() {
|
||||
return myState;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void loadState(@NotNull State state) {
|
||||
if (state == null) {
|
||||
state = new State();
|
||||
}
|
||||
myState = state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set runtime flag
|
||||
*
|
||||
* @param value the value to se
|
||||
*/
|
||||
public void setRuntime(boolean value) {
|
||||
myState.IS_RUNTIME = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set test flag
|
||||
*
|
||||
* @param value the value to se
|
||||
*/
|
||||
public void setTest(boolean value) {
|
||||
myState.IS_TEST = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set include sdk flag
|
||||
*
|
||||
* @param value the value to se
|
||||
*/
|
||||
public void setIncludeSdk(boolean value) {
|
||||
myState.INCLUDE_SDK = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true, if runtime classpath should be analyzed
|
||||
*/
|
||||
public boolean isRuntime() {
|
||||
return myState.IS_RUNTIME;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true, if sdk classes should be also checked
|
||||
*/
|
||||
public boolean isSdkIncluded() {
|
||||
return myState.INCLUDE_SDK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true, if test classes should be included
|
||||
*/
|
||||
public boolean isTest() {
|
||||
return myState.IS_TEST;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true, if classpath analysis is done in term or urls. false if in term of order entries
|
||||
*/
|
||||
public boolean isUrlMode() {
|
||||
return myState.IS_URL_MODE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set url mode
|
||||
*
|
||||
* @param value true, if classpath analysis is done in term or urls. false if in term of order entries
|
||||
*/
|
||||
public void setUrlMode(boolean value) {
|
||||
myState.IS_URL_MODE = value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get project instance
|
||||
*
|
||||
* @param project the context project
|
||||
* @return the created instance
|
||||
*/
|
||||
public static AnalyzeDependenciesSettings getInstance(Project project) {
|
||||
return ServiceManager.getService(project, AnalyzeDependenciesSettings.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* The state object for settings
|
||||
*/
|
||||
public static class State {
|
||||
/**
|
||||
* If true, runtime dependencies are shown, otherwise compile-time
|
||||
*/
|
||||
boolean IS_RUNTIME = true;
|
||||
/**
|
||||
* If true, test dependencies are shown, otherwise production dependencies only
|
||||
*/
|
||||
boolean IS_TEST = true;
|
||||
/**
|
||||
* If true, the JDK entries are included as well
|
||||
*/
|
||||
boolean INCLUDE_SDK = false;
|
||||
/**
|
||||
* Are urls or order entry used
|
||||
*/
|
||||
boolean IS_URL_MODE = true;
|
||||
}
|
||||
}
|
||||
-475
@@ -1,475 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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.openapi.roots.ui.configuration.dependencyAnalysis;
|
||||
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ide.presentation.VirtualFilePresentation;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.roots.*;
|
||||
import com.intellij.openapi.roots.ui.CellAppearanceEx;
|
||||
import com.intellij.openapi.roots.ui.OrderEntryAppearanceService;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Analyzer for module classpath. It uses order enumerator to get classpath details.
|
||||
*/
|
||||
public class ModuleDependenciesAnalyzer {
|
||||
/**
|
||||
* The current module
|
||||
*/
|
||||
private final Module myModule;
|
||||
/**
|
||||
* If true production classpath is analyzed. If false, the test classpath.
|
||||
*/
|
||||
private final boolean myProduction;
|
||||
/**
|
||||
* If true the compilation classpath is analyzed. If false, the test classpath.
|
||||
*/
|
||||
private final boolean myCompile;
|
||||
/**
|
||||
* If true, SDK classes are included in the classpath.
|
||||
*/
|
||||
private final boolean mySdk;
|
||||
/**
|
||||
* The order entry explanations
|
||||
*/
|
||||
private final List<OrderEntryExplanation> myOrderEntries = new ArrayList<>();
|
||||
/**
|
||||
* The url explanations
|
||||
*/
|
||||
private final List<UrlExplanation> myUrls = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* The constructor (it creates explanations immediately
|
||||
*
|
||||
* @param module the context module
|
||||
* @param production the production/test flag
|
||||
* @param compile the compile/runtime flag
|
||||
* @param sdk the include sdk paths
|
||||
*/
|
||||
public ModuleDependenciesAnalyzer(Module module, boolean production, boolean compile, boolean sdk) {
|
||||
myModule = module;
|
||||
myProduction = production;
|
||||
myCompile = compile;
|
||||
mySdk = sdk;
|
||||
analyze();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return url explanations
|
||||
*/
|
||||
public List<UrlExplanation> getUrls() {
|
||||
return Collections.unmodifiableList(myUrls);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return order entry explanations
|
||||
*/
|
||||
public List<OrderEntryExplanation> getOrderEntries() {
|
||||
return Collections.unmodifiableList(myOrderEntries);
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyze module classpath
|
||||
*/
|
||||
private void analyze() {
|
||||
OrderEnumerator e = ModuleRootManager.getInstance(myModule).orderEntries();
|
||||
e.recursively();
|
||||
if (!mySdk) {
|
||||
e.withoutSdk();
|
||||
}
|
||||
if (myCompile) {
|
||||
e.compileOnly();
|
||||
}
|
||||
else {
|
||||
e.runtimeOnly();
|
||||
}
|
||||
if (myProduction) {
|
||||
e.productionOnly();
|
||||
}
|
||||
final Map<String, List<OrderPath>> urlExplanations = new LinkedHashMap<>();
|
||||
final OrderRootsEnumerator classes = e.classes();
|
||||
if (myCompile) {
|
||||
classes.withoutSelfModuleOutput();
|
||||
}
|
||||
for (String url : classes.getUrls()) {
|
||||
if (!urlExplanations.containsKey(url)) {
|
||||
urlExplanations.put(url, new ArrayList<>());
|
||||
}
|
||||
}
|
||||
final Map<OrderEntry, List<OrderPath>> orderExplanations = new LinkedHashMap<>();
|
||||
new PathWalker(urlExplanations, orderExplanations).examine(myModule, 0);
|
||||
for (Map.Entry<OrderEntry, List<OrderPath>> entry : orderExplanations.entrySet()) {
|
||||
myOrderEntries.add(new OrderEntryExplanation(entry.getKey(), entry.getValue()));
|
||||
}
|
||||
for (Map.Entry<String, List<OrderPath>> entry : urlExplanations.entrySet()) {
|
||||
myUrls.add(new UrlExplanation(entry.getKey(), entry.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The walker for the class paths. It walks the entire module classpath
|
||||
*/
|
||||
private class PathWalker {
|
||||
/**
|
||||
* The explanations for urls
|
||||
*/
|
||||
private final Map<String, List<OrderPath>> myUrlExplanations;
|
||||
/**
|
||||
* The explanations for order entries
|
||||
*/
|
||||
private final Map<OrderEntry, List<OrderPath>> myOrderExplanations;
|
||||
/**
|
||||
* The current stack
|
||||
*/
|
||||
private final ArrayList<OrderPathElement> myStack = new ArrayList<>();
|
||||
/**
|
||||
* Visited modules (in order to detect cyclic dependencies)
|
||||
*/
|
||||
private final HashSet<Module> myVisited = new HashSet<>();
|
||||
|
||||
/**
|
||||
* The constructor
|
||||
*
|
||||
* @param urlExplanations the url explanations to accumulate
|
||||
* @param orderExplanations the explanations for order entries
|
||||
*/
|
||||
PathWalker(Map<String, List<OrderPath>> urlExplanations,
|
||||
Map<OrderEntry, List<OrderPath>> orderExplanations) {
|
||||
myUrlExplanations = urlExplanations;
|
||||
myOrderExplanations = orderExplanations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Examine the specified module
|
||||
*
|
||||
* @param m the module to examine
|
||||
* @param level the level of the examination
|
||||
*/
|
||||
void examine(final Module m, final int level) {
|
||||
if (myVisited.contains(m)) {
|
||||
return;
|
||||
}
|
||||
myVisited.add(m);
|
||||
try {
|
||||
final OrderEnumerator e = ModuleRootManager.getInstance(m).orderEntries();
|
||||
if (!mySdk || level != 0) {
|
||||
e.withoutSdk();
|
||||
}
|
||||
if (myCompile && level != 0) {
|
||||
e.exportedOnly();
|
||||
}
|
||||
if (myProduction) {
|
||||
e.productionOnly();
|
||||
}
|
||||
if (myCompile) {
|
||||
e.compileOnly();
|
||||
}
|
||||
else {
|
||||
e.runtimeOnly();
|
||||
}
|
||||
e.forEach(orderEntry -> {
|
||||
myStack.add(new OrderEntryPathElement(orderEntry));
|
||||
try {
|
||||
if (orderEntry instanceof ModuleOrderEntry) {
|
||||
ModuleOrderEntry o = (ModuleOrderEntry)orderEntry;
|
||||
examine(o.getModule(), level + 1);
|
||||
}
|
||||
else if (orderEntry instanceof ModuleSourceOrderEntry) {
|
||||
if (!myProduction || !myCompile) {
|
||||
CompilerModuleExtension e1 = CompilerModuleExtension.getInstance(m);
|
||||
final OrderPath p = new OrderPath(myStack);
|
||||
for (String u : e1.getOutputRootUrls(!myCompile ? !myProduction : level > 0 && !myProduction)) {
|
||||
addUrlPath(p, u);
|
||||
}
|
||||
addEntryPath(orderEntry, p);
|
||||
}
|
||||
}
|
||||
else {
|
||||
final OrderPath p = new OrderPath(myStack);
|
||||
for (String u : orderEntry.getUrls(OrderRootType.CLASSES)) {
|
||||
addUrlPath(p, u);
|
||||
}
|
||||
addEntryPath(orderEntry, p);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
myStack.remove(myStack.size() - 1);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
finally {
|
||||
myVisited.remove(m);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add url path
|
||||
*
|
||||
* @param p the path to add
|
||||
* @param u the url to update
|
||||
*/
|
||||
private void addUrlPath(OrderPath p, String u) {
|
||||
final List<OrderPath> orderPaths = myUrlExplanations.get(u);
|
||||
if (orderPaths != null) {
|
||||
orderPaths.add(p);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add order entry explanation
|
||||
*
|
||||
* @param orderEntry the order entry to explain
|
||||
* @param p the path that explain order entry
|
||||
*/
|
||||
private void addEntryPath(OrderEntry orderEntry, OrderPath p) {
|
||||
List<OrderPath> paths = myOrderExplanations.get(orderEntry);
|
||||
if (paths == null) {
|
||||
paths = new ArrayList<>();
|
||||
myOrderExplanations.put(orderEntry, paths);
|
||||
}
|
||||
paths.add(p);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The path consisting of order entry path.
|
||||
*/
|
||||
public static class OrderPath {
|
||||
/**
|
||||
* The immutable list of path elements. The first element in the list is an order entry actually included in the current module.
|
||||
*/
|
||||
private final List<OrderPathElement> myEntries;
|
||||
|
||||
/**
|
||||
* The constructor
|
||||
*
|
||||
* @param entries the list of entries (will be copied and wrapped)
|
||||
*/
|
||||
public OrderPath(List<OrderPathElement> entries) {
|
||||
this.myEntries = Collections.unmodifiableList(new ArrayList<>(entries));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the immutable list of path elements. The first element in the list is an order entry actually included in the current module.
|
||||
*/
|
||||
public List<OrderPathElement> entries() {
|
||||
return myEntries;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return myEntries.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof OrderPath)) {
|
||||
return false;
|
||||
}
|
||||
return myEntries.equals(((OrderPath)obj).myEntries);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The a entry in the path. The implementation should support {@link #equals(Object)} and {@link #hashCode()} methods.
|
||||
*/
|
||||
public static abstract class OrderPathElement {
|
||||
/**
|
||||
* Get appearance for path element
|
||||
*
|
||||
* @param isSelected true if the element is selected
|
||||
* @return the appearance to use for rendering
|
||||
*/
|
||||
@NotNull
|
||||
public abstract CellAppearanceEx getAppearance(boolean isSelected);
|
||||
}
|
||||
|
||||
/**
|
||||
* The order entry path element
|
||||
*/
|
||||
public static class OrderEntryPathElement extends OrderPathElement {
|
||||
/**
|
||||
* The order entry
|
||||
*/
|
||||
private final OrderEntry myEntry;
|
||||
|
||||
/**
|
||||
* The constructor
|
||||
*
|
||||
* @param entry the order entry
|
||||
*/
|
||||
public OrderEntryPathElement(OrderEntry entry) {
|
||||
this.myEntry = entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the order entry
|
||||
*/
|
||||
public OrderEntry entry() {
|
||||
return myEntry;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return myEntry.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof OrderEntryPathElement)) {
|
||||
return false;
|
||||
}
|
||||
OrderEntryPathElement o = (OrderEntryPathElement)obj;
|
||||
return o.myEntry == myEntry;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return myEntry.getPresentableName();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@NotNull
|
||||
@Override
|
||||
public CellAppearanceEx getAppearance(boolean isSelected) {
|
||||
return OrderEntryAppearanceService.getInstance().forOrderEntry(myEntry.getOwnerModule().getProject(), myEntry, isSelected);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The base class for explanations
|
||||
*/
|
||||
public static class Explanation {
|
||||
/**
|
||||
* The paths that refer to the path element
|
||||
*/
|
||||
public final List<OrderPath> myPaths;
|
||||
|
||||
/**
|
||||
* The explanation for the path
|
||||
*
|
||||
* @param paths the paths to analyze (the list is wrapped)
|
||||
*/
|
||||
Explanation(List<OrderPath> paths) {
|
||||
this.myPaths = Collections.unmodifiableList(paths);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the paths that refer to the path element
|
||||
*/
|
||||
public List<OrderPath> paths() {
|
||||
return myPaths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The explanation for
|
||||
*/
|
||||
public static class OrderEntryExplanation extends Explanation {
|
||||
/**
|
||||
* The URL in the path
|
||||
*/
|
||||
private final OrderEntry myEntry;
|
||||
|
||||
/**
|
||||
* The explanation for the path
|
||||
*
|
||||
* @param entry the explained order entry
|
||||
* @param paths the paths to analyze
|
||||
*/
|
||||
OrderEntryExplanation(OrderEntry entry, List<OrderPath> paths) {
|
||||
super(paths);
|
||||
myEntry = entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the explained entry
|
||||
*/
|
||||
public OrderEntry entry() {
|
||||
return myEntry;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The explanation for url
|
||||
*/
|
||||
public static class UrlExplanation extends Explanation {
|
||||
/**
|
||||
* The URL in the path
|
||||
*/
|
||||
private final String myUrl;
|
||||
|
||||
/**
|
||||
* The explanation for the path
|
||||
*
|
||||
* @param url the url for the order entry
|
||||
* @param paths the paths to analyze
|
||||
*/
|
||||
UrlExplanation(String url, List<OrderPath> paths) {
|
||||
super(paths);
|
||||
myUrl = url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the explained url
|
||||
*/
|
||||
public String url() {
|
||||
return myUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return icon for the classpath
|
||||
*/
|
||||
@Nullable
|
||||
public Icon getIcon() {
|
||||
VirtualFile file = getLocalFile();
|
||||
return file == null ? AllIcons.General.Error : VirtualFilePresentation.getIcon(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the local file
|
||||
*/
|
||||
@Nullable
|
||||
public VirtualFile getLocalFile() {
|
||||
VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(myUrl);
|
||||
if (file != null) {
|
||||
file = VfsUtil.getLocalFile(file);
|
||||
}
|
||||
return file;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -327,7 +327,6 @@ find.usages.action.text=Find Usages
|
||||
dependencies.used.in.popup.title=Used in
|
||||
project.language.level=<html><b>Project language level:</b><br>This language level is default for all project modules.<br>\
|
||||
A module specific language level can be configured for each of the modules as required.</html>
|
||||
classpath.panel.analyze=Analyze
|
||||
classpath.panel.navigate.action.text=Navigate
|
||||
output.tab.title=Output
|
||||
project.roots.module.banner.text=Module ''{0}''
|
||||
|
||||
@@ -204,8 +204,6 @@
|
||||
|
||||
<applicationService serviceInterface="com.intellij.openapi.roots.ui.configuration.libraries.LibraryPresentationManager"
|
||||
serviceImplementation="com.intellij.openapi.roots.ui.configuration.libraries.impl.LibraryPresentationManagerImpl"/>
|
||||
<projectService serviceInterface="com.intellij.openapi.roots.ui.configuration.dependencyAnalysis.AnalyzeDependenciesSettings"
|
||||
serviceImplementation="com.intellij.openapi.roots.ui.configuration.dependencyAnalysis.AnalyzeDependenciesSettings"/>
|
||||
<projectService serviceImplementation="com.intellij.ide.bookmarks.BookmarkManager"/>
|
||||
|
||||
<daemon.highlightInfoFilter implementation="com.intellij.debugger.engine.evaluation.DebuggerHighlightFilter"/>
|
||||
|
||||
Reference in New Issue
Block a user