From 821918824e1be1fdc1f3f9c2923c616a531df755 Mon Sep 17 00:00:00 2001 From: Sergey Prigogin Date: Sun, 29 Apr 2012 22:43:37 -0700 Subject: [PATCH] Bug 378023 - Error markers are not removed when a checker is disabled --- .../codan/internal/core/CheckersRegistry.java | 2 +- .../cdt/codan/internal/core/CodanRunner.java | 108 +++++++++++++++--- .../cdt/codan/internal/core/Messages.java | 3 +- .../codan/internal/core/Messages.properties | 3 +- .../ui/preferences/CodanPreferencePage.java | 14 ++- 5 files changed, 107 insertions(+), 23 deletions(-) diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CheckersRegistry.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CheckersRegistry.java index f3188488243..6e34549c8a8 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CheckersRegistry.java +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CheckersRegistry.java @@ -416,7 +416,7 @@ public class CheckersRegistry implements Iterable, ICheckersRegistry { // We need to check problem enablement in a particular profile. IProblem problem = resourceProfile.findProblem(p.getId()); if (problem == null) - throw new IllegalArgumentException(p.getId() + "is not registered"); //$NON-NLS-1$ + throw new IllegalArgumentException(p.getId() + " is not registered"); //$NON-NLS-1$ if (!problem.isEnabled()) return false; if (checker instanceof AbstractCheckerWithProblemPreferences) { diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanRunner.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanRunner.java index ac33b50c173..02cda147d9c 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanRunner.java +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanRunner.java @@ -11,17 +11,31 @@ *******************************************************************************/ package org.eclipse.cdt.codan.internal.core; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + import org.eclipse.cdt.codan.core.CodanCorePlugin; import org.eclipse.cdt.codan.core.model.CheckerLaunchMode; import org.eclipse.cdt.codan.core.model.IChecker; import org.eclipse.cdt.codan.core.model.ICheckerInvocationContext; +import org.eclipse.cdt.codan.core.model.ICodanProblemMarker; +import org.eclipse.cdt.codan.core.model.IProblem; +import org.eclipse.cdt.codan.core.model.IProblemProfile; import org.eclipse.cdt.codan.core.model.IRunnableInEditorChecker; import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceRuleFactory; +import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubMonitor; import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.core.runtime.jobs.Job; import org.eclipse.osgi.util.NLS; /** @@ -59,19 +73,19 @@ public class CodanRunner { CheckerLaunchMode checkerLaunchMode, IProgressMonitor monitor) { CheckersRegistry chegistry = CheckersRegistry.getInstance(); int checkers = chegistry.getCheckersSize(); - int memsize = 0; + IResource[] children = null; if (resource instanceof IContainer) { try { - IResource[] members = ((IContainer) resource).members(); - memsize = members.length; + children = ((IContainer) resource).members(); } catch (CoreException e) { CodanCorePlugin.log(e); } } - int tick = 1000; + int numChildren = children == null ? 0 : children.length; + int childWeight = 10; // System.err.println("processing " + resource); - monitor.beginTask(NLS.bind(Messages.CodanRunner_Code_Analysis_On, resource.getFullPath().toString()), - checkers + memsize * tick); + monitor.beginTask(NLS.bind(Messages.CodanRunner_Code_analysis_on, resource.getFullPath().toString()), + checkers * (1 + numChildren * childWeight)); try { CheckersTimeStats.getInstance().checkerStart(CheckersTimeStats.ALL); ICheckerInvocationContext context = new CheckerInvocationContext(resource); @@ -109,22 +123,80 @@ public class CodanRunner { //CheckersTimeStats.getInstance().printStats(); } - if (resource instanceof IContainer - && (checkerLaunchMode == CheckerLaunchMode.RUN_ON_FULL_BUILD || checkerLaunchMode == CheckerLaunchMode.RUN_ON_DEMAND)) { - try { - IResource[] members = ((IContainer) resource).members(); - for (int i = 0; i < members.length; i++) { - if (monitor.isCanceled()) - return; - IResource member = members[i]; - processResource(member, null, checkerLaunchMode, new SubProgressMonitor(monitor, tick)); - } - } catch (CoreException e) { - CodanCorePlugin.log(e); + if (children != null && + (checkerLaunchMode == CheckerLaunchMode.RUN_ON_FULL_BUILD || checkerLaunchMode == CheckerLaunchMode.RUN_ON_DEMAND)) { + for (IResource child : children) { + if (monitor.isCanceled()) + return; + processResource(child, null, checkerLaunchMode, new SubProgressMonitor(monitor, childWeight)); } } } finally { monitor.done(); } } + + public static void asynchronouslyRemoveMarkersForDisabledProblems(final IResource resource) { + Job job = new Job(Messages.CodanRunner_Update_markers) { + @Override + protected IStatus run(IProgressMonitor monitor) { + removeMarkersForDisabledProblems(resource, monitor); + return Status.OK_STATUS; + } + }; + IResourceRuleFactory ruleFactory = ResourcesPlugin.getWorkspace().getRuleFactory(); + job.setRule(ruleFactory.markerRule(resource)); + job.setSystem(true); + job.schedule(); + } + + public static void removeMarkersForDisabledProblems(IResource resource, IProgressMonitor monitor) { + CheckersRegistry chegistry = CheckersRegistry.getInstance(); + Set markerTypes = new HashSet(); + for (IChecker checker : chegistry) { + Collection problems = chegistry.getRefProblems(checker); + for (IProblem problem : problems) { + markerTypes.add(problem.getMarkerType()); + } + } + try { + removeMarkersForDisabledProblems(chegistry, markerTypes, resource, monitor); + } catch (CoreException e) { + CodanCorePlugin.log(e); + } + } + + private static void removeMarkersForDisabledProblems(CheckersRegistry chegistry, + Set markerTypes, IResource resource, IProgressMonitor monitor) throws CoreException { + IResource[] children = null; + if (resource instanceof IContainer) { + children = ((IContainer) resource).members(); + } + int numChildren = children == null ? 0 : children.length; + int childWeight = 10; + SubMonitor progress = SubMonitor.convert(monitor, 1 + numChildren * childWeight); + IProblemProfile resourceProfile = null; + for (String markerType : markerTypes) { + IMarker[] markers = resource.findMarkers(markerType, false, IResource.DEPTH_ZERO); + for (IMarker marker : markers) { + String problemId = (String) marker.getAttribute(ICodanProblemMarker.ID); + if (resourceProfile == null) { + resourceProfile = chegistry.getResourceProfile(resource); + } + IProblem problem = resourceProfile.findProblem(problemId); + if (problem != null && !problem.isEnabled()) { + marker.delete(); + } + } + } + progress.worked(1); + if (children != null) { + for (IResource child : children) { + if (monitor.isCanceled()) + return; + removeMarkersForDisabledProblems(chegistry, markerTypes, child, + progress.newChild(childWeight)); + } + } + } } diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/Messages.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/Messages.java index 755e06d2cca..1ef0028db06 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/Messages.java +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/Messages.java @@ -25,7 +25,8 @@ class Messages extends NLS { public static String CodanApplication_Options; public static String CodanApplication_Usage; public static String CodanApplication_verbose_option; - public static String CodanRunner_Code_Analysis_On; + public static String CodanRunner_Code_analysis_on; + public static String CodanRunner_Update_markers; static { NLS.initializeMessages(Messages.class.getName(), Messages.class); diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/Messages.properties b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/Messages.properties index 5b81389a957..6d601390946 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/Messages.properties +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/Messages.properties @@ -17,4 +17,5 @@ CodanApplication_Usage=Usage: [options] ... CodanApplication_Options=Options: CodanApplication_all_option= -all - run on all projects in workspace CodanApplication_verbose_option= -verbose - print verbose build information -CodanRunner_Code_Analysis_On=Code analysis on {0} +CodanRunner_Code_analysis_on=Code analysis on {0} +CodanRunner_Update_markers=Updating error markers diff --git a/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/internal/ui/preferences/CodanPreferencePage.java b/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/internal/ui/preferences/CodanPreferencePage.java index 60f6ddfeb1d..062a395ba4e 100644 --- a/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/internal/ui/preferences/CodanPreferencePage.java +++ b/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/internal/ui/preferences/CodanPreferencePage.java @@ -19,10 +19,12 @@ import org.eclipse.cdt.codan.core.CodanRuntime; import org.eclipse.cdt.codan.core.model.ICheckersRegistry; import org.eclipse.cdt.codan.core.model.IProblem; import org.eclipse.cdt.codan.core.model.IProblemProfile; +import org.eclipse.cdt.codan.internal.core.CodanRunner; import org.eclipse.cdt.codan.internal.ui.CodanUIActivator; import org.eclipse.cdt.codan.internal.ui.CodanUIMessages; import org.eclipse.cdt.codan.internal.ui.dialogs.CustomizeProblemDialog; import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.layout.GridDataFactory; @@ -154,8 +156,16 @@ public class CodanPreferencePage extends FieldEditorOverlayPage implements IWork @Override public boolean performOk() { saveWidgetValues(); - getRegistry().updateProfile((IResource) getElement(), null); - return super.performOk(); + IResource resource = (IResource) getElement(); + getRegistry().updateProfile(resource, null); + boolean success = super.performOk(); + if (success) { + if (resource == null) { + resource = ResourcesPlugin.getWorkspace().getRoot(); + } + CodanRunner.asynchronouslyRemoveMarkersForDisabledProblems(resource); + } + return success; } private void saveWidgetValues() {