mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
project structure error highlighting: show warnings with quickfixes for unused project libraries
This commit is contained in:
-5
@@ -86,11 +86,6 @@ public class GeneralProjectSettingsElement extends ProjectStructureElement {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean highlightIfUnused() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "project:general";
|
||||
|
||||
+1
-1
@@ -552,7 +552,7 @@ public class ModulesConfigurator implements ModulesProvider, ModuleEditor.Change
|
||||
if (module == moduleEditor.getModule() && Comparing.strEqual(moduleEditor.getName(), oldName)) {
|
||||
moduleEditor.setModuleName(name);
|
||||
moduleEditor.updateCompilerOutputPathChanged(ProjectStructureConfigurable.getInstance(myProject).getProjectConfig().getCompilerOutputUrl(), name);
|
||||
myContext.getDaemonAnalyzer().queueUpdate(new ModuleProjectStructureElement(myContext, module), true, false);
|
||||
myContext.getDaemonAnalyzer().queueUpdate(new ModuleProjectStructureElement(myContext, module));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -37,7 +37,7 @@ public class ArtifactErrorPanel {
|
||||
private JPanel myMainPanel;
|
||||
private JButton myFixButton;
|
||||
private JLabel myErrorLabel;
|
||||
private List<ConfigurationErrorQuickFix> myCurrentQuickFixes;
|
||||
private List<? extends ConfigurationErrorQuickFix> myCurrentQuickFixes;
|
||||
private String myErrorText;
|
||||
|
||||
public ArtifactErrorPanel(final ArtifactEditorImpl artifactEditor) {
|
||||
@@ -83,7 +83,7 @@ public class ArtifactErrorPanel {
|
||||
artifactEditor.queueValidation();
|
||||
}
|
||||
|
||||
public void showError(@NotNull String message, @NotNull List<ConfigurationErrorQuickFix> quickFixes) {
|
||||
public void showError(@NotNull String message, @NotNull List<? extends ConfigurationErrorQuickFix> quickFixes) {
|
||||
myErrorLabel.setVisible(true);
|
||||
final String errorText = "<html>" + message + "</html>";
|
||||
if (myErrorLabel.isShowing()) {
|
||||
|
||||
-5
@@ -128,11 +128,6 @@ public class ArtifactProjectStructureElement extends ProjectStructureElement {
|
||||
return myOriginalArtifact.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean highlightIfUnused() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPresentableName() {
|
||||
return "Artifact '" + getActualArtifactName() + "'";
|
||||
|
||||
+1
-1
@@ -73,7 +73,7 @@ public class ArtifactValidationManagerImpl implements Disposable {
|
||||
if (problemDescriptions != null) {
|
||||
for (ProjectStructureProblemDescription description : problemDescriptions) {
|
||||
final String message = description.getMessage();
|
||||
List<ConfigurationErrorQuickFix> quickFixes = Collections.emptyList();
|
||||
List<? extends ConfigurationErrorQuickFix> quickFixes = Collections.emptyList();
|
||||
if (description instanceof ArtifactProblemDescription) {
|
||||
final ArtifactProblemDescription artifactProblem = (ArtifactProblemDescription)description;
|
||||
quickFixes = artifactProblem.getFixes();
|
||||
|
||||
+1
-1
@@ -82,7 +82,7 @@ public class ArtifactsStructureConfigurable extends BaseStructureConfigurable {
|
||||
context.getModulesConfigurator().addAllModuleChangeListener(new ModuleEditor.ChangeListener() {
|
||||
public void moduleStateChanged(ModifiableRootModel moduleRootModel) {
|
||||
for (ProjectStructureElement element : getProjectStructureElements()) {
|
||||
myContext.getDaemonAnalyzer().queueUpdate(element, true, false);
|
||||
myContext.getDaemonAnalyzer().queueUpdate(element);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
+1
-1
@@ -110,7 +110,7 @@ public class ArtifactsStructureConfigurableContextImpl implements ArtifactsStruc
|
||||
}
|
||||
|
||||
public void queueValidation(Artifact artifact) {
|
||||
myContext.getDaemonAnalyzer().queueUpdate(getOrCreateArtifactElement(artifact), true, false);
|
||||
myContext.getDaemonAnalyzer().queueUpdate(getOrCreateArtifactElement(artifact));
|
||||
}
|
||||
|
||||
public CompositePackagingElement<?> getRootElement(@NotNull Artifact artifact) {
|
||||
|
||||
+12
@@ -32,6 +32,7 @@ import com.intellij.openapi.roots.libraries.*;
|
||||
import com.intellij.openapi.roots.libraries.ui.OrderRoot;
|
||||
import com.intellij.openapi.roots.ui.configuration.classpath.ClasspathPanel;
|
||||
import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesModifiableModel;
|
||||
import com.intellij.openapi.roots.ui.configuration.projectRoot.ModuleStructureConfigurable;
|
||||
import com.intellij.openapi.ui.popup.PopupStep;
|
||||
import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
@@ -41,6 +42,7 @@ import com.intellij.util.ParameterizedRunnable;
|
||||
import com.intellij.util.PathUtil;
|
||||
import com.intellij.util.PlatformIcons;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.*;
|
||||
@@ -199,4 +201,14 @@ public class LibraryEditingUtil {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static List<Module> getSuitableModules(@NotNull ModuleStructureConfigurable rootConfigurable, final @Nullable LibraryType type) {
|
||||
final List<Module> modules = new ArrayList<Module>();
|
||||
for (Module module : rootConfigurable.getModules()) {
|
||||
if (type == null || type.isSuitableModule(module, rootConfigurable.getFacetConfigurator())) {
|
||||
modules.add(module);
|
||||
}
|
||||
}
|
||||
return modules;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-12
@@ -21,7 +21,6 @@ import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.fileChooser.FileChooser;
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.libraries.Library;
|
||||
@@ -111,23 +110,13 @@ public class CreateNewLibraryAction extends DumbAwareAction {
|
||||
rootConfigurable.selectNodeInTree(libraryNode);
|
||||
}
|
||||
|
||||
private static List<Module> getSuitableModules(@NotNull ModuleStructureConfigurable rootConfigurable, final @Nullable LibraryType type) {
|
||||
final List<Module> modules = new ArrayList<Module>();
|
||||
for (Module module : rootConfigurable.getModules()) {
|
||||
if (type == null || type.isSuitableModule(module, rootConfigurable.getFacetConfigurator())) {
|
||||
modules.add(module);
|
||||
}
|
||||
}
|
||||
return modules;
|
||||
}
|
||||
|
||||
public static AnAction[] createActionOrGroup(@NotNull String text, @NotNull BaseLibrariesConfigurable librariesConfigurable, final @NotNull Project project) {
|
||||
final LibraryType<?>[] extensions = LibraryType.EP_NAME.getExtensions();
|
||||
List<LibraryType<?>> suitableTypes = new ArrayList<LibraryType<?>>();
|
||||
if (librariesConfigurable instanceof ProjectLibrariesConfigurable) {
|
||||
final ModuleStructureConfigurable configurable = ModuleStructureConfigurable.getInstance(project);
|
||||
for (LibraryType<?> extension : extensions) {
|
||||
if (!getSuitableModules(configurable, extension).isEmpty()) {
|
||||
if (!LibraryEditingUtil.getSuitableModules(configurable, extension).isEmpty()) {
|
||||
suitableTypes.add(extension);
|
||||
}
|
||||
}
|
||||
|
||||
+13
-2
@@ -26,6 +26,7 @@ import com.intellij.openapi.roots.impl.libraries.LibraryImpl;
|
||||
import com.intellij.openapi.roots.libraries.Library;
|
||||
import com.intellij.openapi.roots.libraries.LibraryTable;
|
||||
import com.intellij.openapi.roots.libraries.LibraryTablePresentation;
|
||||
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
|
||||
import com.intellij.openapi.roots.ui.configuration.artifacts.UsageInArtifact;
|
||||
import com.intellij.openapi.roots.ui.configuration.libraries.LibraryEditingUtil;
|
||||
import com.intellij.openapi.roots.ui.configuration.libraryEditor.CreateNewLibraryAction;
|
||||
@@ -51,6 +52,14 @@ public abstract class BaseLibrariesConfigurable extends BaseStructureConfigurabl
|
||||
super(project);
|
||||
}
|
||||
|
||||
public static BaseLibrariesConfigurable getInstance(@NotNull Project project, @NotNull String tableLevel) {
|
||||
if (tableLevel.equals(LibraryTablesRegistrar.PROJECT_LEVEL)) {
|
||||
return ProjectLibrariesConfigurable.getInstance(project);
|
||||
}
|
||||
else {
|
||||
return GlobalLibrariesConfigurable.getInstance(project);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract LibraryTablePresentation getLibraryTablePresentation();
|
||||
|
||||
@@ -208,8 +217,10 @@ public abstract class BaseLibrariesConfigurable extends BaseStructureConfigurabl
|
||||
}
|
||||
}
|
||||
|
||||
public void removeLibraryNode(@NotNull Library library) {
|
||||
final MyNode node = findNodeByObject(myRoot, library);
|
||||
public void removeLibrary(@NotNull LibraryProjectStructureElement element) {
|
||||
getModelProvider().getModifiableModel().removeLibrary(element.getLibrary());
|
||||
myContext.getDaemonAnalyzer().removeElement(element);
|
||||
final MyNode node = findNodeByObject(myRoot, element.getLibrary());
|
||||
if (node != null) {
|
||||
removePaths(TreeUtil.getPathFromRoot(node));
|
||||
}
|
||||
|
||||
+7
-9
@@ -61,14 +61,14 @@ public class ChangeLibraryLevelAction extends ChangeLibraryLevelActionBase {
|
||||
final ProjectStructureElement selectedElement = mySourceConfigurable.getSelectedElement();
|
||||
if (!(selectedElement instanceof LibraryProjectStructureElement)) return;
|
||||
final StructureConfigurableContext context = mySourceConfigurable.myContext;
|
||||
final Library originalLibrary = ((LibraryProjectStructureElement)selectedElement).getLibrary();
|
||||
final LibraryEx oldLibrary = (LibraryEx)context.getLibrary(originalLibrary.getName(), mySourceConfigurable.getLevel());
|
||||
final LibraryProjectStructureElement libraryElement = (LibraryProjectStructureElement)selectedElement;
|
||||
final LibraryEx oldLibrary = (LibraryEx)context.getLibrary(libraryElement.getLibrary().getName(), mySourceConfigurable.getLevel());
|
||||
LOG.assertTrue(oldLibrary != null);
|
||||
final Library newLibrary = doCopy(oldLibrary);
|
||||
if (newLibrary == null) return;
|
||||
|
||||
final ModulesConfigurator configurator = context.getModulesConfigurator();
|
||||
final Collection<ProjectStructureElementUsage> usages = context.getDaemonAnalyzer().getUsages(selectedElement);
|
||||
final Collection<ProjectStructureElementUsage> usages = context.getDaemonAnalyzer().getUsages(libraryElement);
|
||||
for (ProjectStructureElementUsage usage : usages) {
|
||||
if (usage instanceof UsageInModuleClasspath) {
|
||||
final Module module = ((UsageInModuleClasspath)usage).getModule();
|
||||
@@ -80,16 +80,14 @@ public class ChangeLibraryLevelAction extends ChangeLibraryLevelActionBase {
|
||||
}
|
||||
}
|
||||
else if (usage instanceof UsageInArtifact) {
|
||||
final PackagingElement<?> libraryElement = PackagingElementFactory.getInstance().createLibraryFiles(newLibrary.getName(),
|
||||
newLibrary.getTable().getTableLevel(), null);
|
||||
((UsageInArtifact)usage).replaceElement(libraryElement);
|
||||
final PackagingElement<?> newLibraryElement = PackagingElementFactory.getInstance().createLibraryFiles(newLibrary.getName(),
|
||||
newLibrary.getTable().getTableLevel(), null);
|
||||
((UsageInArtifact)usage).replaceElement(newLibraryElement);
|
||||
}
|
||||
}
|
||||
|
||||
if (!myCopy) {
|
||||
mySourceConfigurable.getModelProvider().getModifiableModel().removeLibrary(originalLibrary);
|
||||
context.getDaemonAnalyzer().removeElement(selectedElement);
|
||||
mySourceConfigurable.removeLibraryNode(originalLibrary);
|
||||
mySourceConfigurable.removeLibrary(libraryElement);
|
||||
}
|
||||
ProjectStructureConfigurable.getInstance(myProject).selectProjectOrGlobalLibrary(newLibrary, true);
|
||||
}
|
||||
|
||||
-9
@@ -323,7 +323,6 @@ public class ModuleStructureConfigurable extends BaseStructureConfigurable imple
|
||||
((DefaultTreeModel)myTree.getModel()).reload(parent);
|
||||
}
|
||||
myContext.getDaemonAnalyzer().removeElement(new LibraryProjectStructureElement(myContext, library));
|
||||
// TODO: myContext.invalidateModules(myContext.myLibraryDependencyCache.get(library.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -469,14 +468,6 @@ public class ModuleStructureConfigurable extends BaseStructureConfigurable imple
|
||||
}
|
||||
modelProxy.addLibraryEntry(library);
|
||||
myContext.getDaemonAnalyzer().queueUpdate(new ModuleProjectStructureElement(myContext, module));
|
||||
/* TODO
|
||||
Set<String> modules = myContext.myLibraryDependencyCache.get(library.getName());
|
||||
if (modules == null) {
|
||||
modules = new HashSet<String>();
|
||||
myContext.myLibraryDependencyCache.put(library.getName(), modules);
|
||||
}
|
||||
modules.add(module.getName());
|
||||
*/
|
||||
myTree.repaint();
|
||||
}
|
||||
|
||||
|
||||
-5
@@ -43,11 +43,6 @@ public class FacetProjectStructureElement extends ProjectStructureElement {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean highlightIfUnused() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPresentableName() {
|
||||
return "Facet '" + myFacet.getName() + "' in module '" + myFacet.getModule().getName() + "'";
|
||||
|
||||
+49
-4
@@ -1,6 +1,8 @@
|
||||
package com.intellij.openapi.roots.ui.configuration.projectRoot.daemon;
|
||||
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectBundle;
|
||||
import com.intellij.openapi.roots.JavadocOrderRootType;
|
||||
import com.intellij.openapi.roots.OrderRootType;
|
||||
import com.intellij.openapi.roots.impl.libraries.LibraryEx;
|
||||
@@ -8,18 +10,19 @@ import com.intellij.openapi.roots.impl.libraries.LibraryImpl;
|
||||
import com.intellij.openapi.roots.libraries.Library;
|
||||
import com.intellij.openapi.roots.libraries.LibraryTable;
|
||||
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
|
||||
import com.intellij.openapi.roots.ui.configuration.ChooseModulesDialog;
|
||||
import com.intellij.openapi.roots.ui.configuration.ModuleEditor;
|
||||
import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable;
|
||||
import com.intellij.openapi.roots.ui.configuration.libraries.LibraryEditingUtil;
|
||||
import com.intellij.openapi.roots.ui.configuration.libraryEditor.ExistingLibraryEditor;
|
||||
import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesModifiableModel;
|
||||
import com.intellij.openapi.roots.ui.configuration.projectRoot.LibraryConfigurable;
|
||||
import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext;
|
||||
import com.intellij.openapi.roots.ui.configuration.projectRoot.*;
|
||||
import com.intellij.openapi.ui.NamedConfigurable;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -126,11 +129,18 @@ public class LibraryProjectStructureElement extends ProjectStructureElement {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean highlightIfUnused() {
|
||||
public boolean shouldShowWarningIfUnused() {
|
||||
final LibraryTable libraryTable = myLibrary.getTable();
|
||||
return libraryTable != null && LibraryTablesRegistrar.PROJECT_LEVEL.equals(libraryTable.getTableLevel());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProjectStructureProblemDescription createUnusedElementWarning() {
|
||||
final List<ConfigurationErrorQuickFix> fixes = Arrays.asList(new AddLibraryToDependenciesFix(), new RemoveLibraryFix());
|
||||
return new ProjectStructureProblemDescription(getPresentableName() + " is not used", null, createPlace(), fixes,
|
||||
ProjectStructureProblemType.warning("unused-library"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPresentableName() {
|
||||
return "Library '" + myLibrary.getName() + "'";
|
||||
@@ -175,4 +185,39 @@ public class LibraryProjectStructureElement extends ProjectStructureElement {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class AddLibraryToDependenciesFix extends ConfigurationErrorQuickFix {
|
||||
private AddLibraryToDependenciesFix() {
|
||||
super("Add to Dependencies...");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performFix() {
|
||||
final Project project = myContext.getProject();
|
||||
final ModuleStructureConfigurable moduleStructureConfigurable = ModuleStructureConfigurable.getInstance(project);
|
||||
final List<Module> modules = LibraryEditingUtil.getSuitableModules(moduleStructureConfigurable, ((LibraryEx)myLibrary).getType());
|
||||
if (modules.isEmpty()) return;
|
||||
final ChooseModulesDialog dlg = new ChooseModulesDialog(project, modules, ProjectBundle.message("choose.modules.dialog.title"),
|
||||
ProjectBundle
|
||||
.message("choose.modules.dialog.description", myLibrary.getName()));
|
||||
dlg.show();
|
||||
if (dlg.isOK()) {
|
||||
final List<Module> chosenModules = dlg.getChosenElements();
|
||||
for (Module module : chosenModules) {
|
||||
moduleStructureConfigurable.addLibraryOrderEntry(module, myLibrary);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class RemoveLibraryFix extends ConfigurationErrorQuickFix {
|
||||
private RemoveLibraryFix() {
|
||||
super("Remove Library");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performFix() {
|
||||
BaseLibrariesConfigurable.getInstance(myContext.getProject(), myLibrary.getTable().getTableLevel()).removeLibrary(LibraryProjectStructureElement.this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-5
@@ -129,11 +129,6 @@ public class ModuleProjectStructureElement extends ProjectStructureElement {
|
||||
return myModule.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean highlightIfUnused() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPresentableName() {
|
||||
return "Module '" + myModule.getName() + "'";
|
||||
|
||||
+44
-1
@@ -26,6 +26,8 @@ public class ProjectStructureDaemonAnalyzer implements Disposable {
|
||||
private final MultiValuesMap<ProjectStructureElement, ProjectStructureElementUsage> mySourceElement2Usages = new MultiValuesMap<ProjectStructureElement, ProjectStructureElementUsage>();
|
||||
private final MultiValuesMap<ProjectStructureElement, ProjectStructureElementUsage> myContainingElement2Usages = new MultiValuesMap<ProjectStructureElement, ProjectStructureElementUsage>();
|
||||
private final Set<ProjectStructureElement> myElementWithNotCalculatedUsages = new HashSet<ProjectStructureElement>();
|
||||
private final Set<ProjectStructureElement> myElementsToShowWarningIfUnused = new HashSet<ProjectStructureElement>();
|
||||
private final Map<ProjectStructureElement, ProjectStructureProblemDescription> myWarningsAboutUnused = new HashMap<ProjectStructureElement, ProjectStructureProblemDescription>();
|
||||
private final MergingUpdateQueue myAnalyzerQueue;
|
||||
private final EventDispatcher<ProjectStructureDaemonAnalyzerListener> myDispatcher = EventDispatcher.create(ProjectStructureDaemonAnalyzerListener.class);
|
||||
private final AtomicBoolean myStopped = new AtomicBoolean(false);
|
||||
@@ -71,6 +73,9 @@ public class ProjectStructureDaemonAnalyzer implements Disposable {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("updating problems for " + element);
|
||||
}
|
||||
final ProjectStructureProblemDescription warning = myWarningsAboutUnused.get(element);
|
||||
if (warning != null)
|
||||
problemsHolder.registerProblem(warning);
|
||||
myProblemHolders.put(element, problemsHolder);
|
||||
myDispatcher.getMulticaster().problemsChanged(element);
|
||||
}
|
||||
@@ -108,6 +113,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable {
|
||||
addUsage(usage);
|
||||
}
|
||||
myElementWithNotCalculatedUsages.remove(element);
|
||||
reportUnusedElements();
|
||||
}
|
||||
|
||||
private static void invokeLater(Runnable runnable) {
|
||||
@@ -125,11 +131,16 @@ public class ProjectStructureDaemonAnalyzer implements Disposable {
|
||||
if (collectUsages) {
|
||||
myElementWithNotCalculatedUsages.add(element);
|
||||
}
|
||||
if (element.shouldShowWarningIfUnused()) {
|
||||
myElementsToShowWarningIfUnused.add(element);
|
||||
}
|
||||
myAnalyzerQueue.queue(new AnalyzeElementUpdate(element, check, collectUsages));
|
||||
}
|
||||
|
||||
public void removeElement(ProjectStructureElement element) {
|
||||
myElementWithNotCalculatedUsages.remove(element);
|
||||
myElementsToShowWarningIfUnused.remove(element);
|
||||
myWarningsAboutUnused.remove(element);
|
||||
myProblemHolders.remove(element);
|
||||
final Collection<ProjectStructureElementUsage> usages = mySourceElement2Usages.removeAll(element);
|
||||
if (usages != null) {
|
||||
@@ -139,10 +150,42 @@ public class ProjectStructureDaemonAnalyzer implements Disposable {
|
||||
}
|
||||
removeUsagesInElement(element);
|
||||
myDispatcher.getMulticaster().problemsChanged(element);
|
||||
reportUnusedElements();
|
||||
}
|
||||
|
||||
private void reportUnusedElements() {
|
||||
if (!myElementWithNotCalculatedUsages.isEmpty()) return;
|
||||
|
||||
for (ProjectStructureElement element : myElementsToShowWarningIfUnused) {
|
||||
final ProjectStructureProblemDescription warning;
|
||||
final Collection<ProjectStructureElementUsage> usages = mySourceElement2Usages.get(element);
|
||||
if (usages == null || usages.isEmpty()) {
|
||||
warning = element.createUnusedElementWarning();
|
||||
}
|
||||
else {
|
||||
warning = null;
|
||||
}
|
||||
|
||||
final ProjectStructureProblemDescription old = myWarningsAboutUnused.put(element, warning);
|
||||
ProjectStructureProblemsHolderImpl holder = myProblemHolders.get(element);
|
||||
if (holder == null) {
|
||||
holder = new ProjectStructureProblemsHolderImpl();
|
||||
myProblemHolders.put(element, holder);
|
||||
}
|
||||
if (old != null) {
|
||||
holder.removeProblem(old);
|
||||
}
|
||||
if (warning != null) {
|
||||
holder.registerProblem(warning);
|
||||
}
|
||||
if (old != null || warning != null) {
|
||||
myDispatcher.getMulticaster().problemsChanged(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isUnused(ProjectStructureElement element) {
|
||||
if (!element.highlightIfUnused()) {
|
||||
if (!element.shouldShowWarningIfUnused()) {
|
||||
return false;
|
||||
}
|
||||
if (!myElementWithNotCalculatedUsages.isEmpty()) {
|
||||
|
||||
+11
-1
@@ -2,6 +2,7 @@ package com.intellij.openapi.roots.ui.configuration.projectRoot.daemon;
|
||||
|
||||
import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -23,7 +24,16 @@ public abstract class ProjectStructureElement {
|
||||
|
||||
public abstract List<ProjectStructureElementUsage> getUsagesInElement();
|
||||
|
||||
public abstract boolean highlightIfUnused();
|
||||
|
||||
public boolean shouldShowWarningIfUnused() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ProjectStructureProblemDescription createUnusedElementWarning() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public abstract boolean equals(Object obj);
|
||||
|
||||
+3
-3
@@ -27,13 +27,13 @@ public class ProjectStructureProblemDescription {
|
||||
private final String myMessage;
|
||||
private final String myDescription;
|
||||
private final PlaceInProjectStructure myPlace;
|
||||
private final List<ConfigurationErrorQuickFix> myFixes;
|
||||
private final List<? extends ConfigurationErrorQuickFix> myFixes;
|
||||
private final ProjectStructureProblemType myProblemType;
|
||||
|
||||
public ProjectStructureProblemDescription(@NotNull String message,
|
||||
@Nullable String description,
|
||||
@NotNull PlaceInProjectStructure place,
|
||||
@NotNull List<ConfigurationErrorQuickFix> fixes,
|
||||
@NotNull List<? extends ConfigurationErrorQuickFix> fixes,
|
||||
@NotNull ProjectStructureProblemType problemType) {
|
||||
myMessage = message;
|
||||
myDescription = description;
|
||||
@@ -51,7 +51,7 @@ public class ProjectStructureProblemDescription {
|
||||
return myDescription;
|
||||
}
|
||||
|
||||
public List<ConfigurationErrorQuickFix> getFixes() {
|
||||
public List<? extends ConfigurationErrorQuickFix> getFixes() {
|
||||
return myFixes;
|
||||
}
|
||||
|
||||
|
||||
+6
@@ -70,6 +70,12 @@ public class ProjectStructureProblemsHolderImpl implements ProjectStructureProbl
|
||||
return myProblemDescriptions != null && !myProblemDescriptions.isEmpty();
|
||||
}
|
||||
|
||||
public void removeProblem(@NotNull ProjectStructureProblemDescription description) {
|
||||
if (myProblemDescriptions != null) {
|
||||
myProblemDescriptions.remove(description);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public List<ProjectStructureProblemDescription> getProblemDescriptions() {
|
||||
return myProblemDescriptions;
|
||||
|
||||
-5
@@ -43,11 +43,6 @@ public class SdkProjectStructureElement extends ProjectStructureElement {
|
||||
return mySdk.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean highlightIfUnused() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPresentableName() {
|
||||
return "SDK '" + mySdk.getName() + "'";
|
||||
|
||||
@@ -312,6 +312,8 @@ project.roots.plain.mode.action.text.enabled=Show Module Groups
|
||||
project.roots.tooltip.library.misconfigured=Library ''{0}'' has broken paths.
|
||||
project.roots.error.message.invalid.classes.roots=invalid classes {0, choice, 1#root|2#roots}
|
||||
project.roots.error.message.invalid.source.javadoc.roots=invalid source/javadoc {0, choice, 1#root|2#roots}
|
||||
choose.modules.dialog.title=Choose modules
|
||||
choose.modules.dialog.description=Library '' {0}'' will be added to the selected modules.
|
||||
project.roots.tooltip.unused=''{0}'' is unused.
|
||||
project.roots.javadoc.tab.description=Manage external JavaDocs attached to this module. External JavaDoc override JavaDoc annotations you might have in your module.
|
||||
project.roots.output.compiler.title=Compiler output
|
||||
|
||||
Reference in New Issue
Block a user