diff --git a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/model/CxxModelsCache.java b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/model/CxxModelsCache.java index 9ab45f7435a..14c397542f9 100644 --- a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/model/CxxModelsCache.java +++ b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/model/CxxModelsCache.java @@ -45,7 +45,7 @@ public class CxxModelsCache { if (!(celement instanceof ITranslationUnit)) return null; // not a C/C++ file this.file = file; - System.err.println("Making ast for "+file); + //System.err.println("Making ast for "+file); tu = (ITranslationUnit) celement; index = CCorePlugin.getIndexManager().getIndex(tu.getCProject()); // lock the index for read access diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ICheckersRegistry.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ICheckersRegistry.java index 3dd7133dea4..677489b4cf8 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ICheckersRegistry.java +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ICheckersRegistry.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.cdt.codan.core.model; +import java.util.Collection; import java.util.Iterator; import org.eclipse.core.resources.IResource; @@ -25,75 +26,106 @@ import org.eclipse.core.resources.IResource; public interface ICheckersRegistry extends Iterable { /** * Iterator for registered checkers + * * @return */ public abstract Iterator iterator(); /** * Add another checker + * * @param checker */ public abstract void addChecker(IChecker checker); /** - * Add problem p with default category by category id into default profile, category must exists in default profile - * @param p - problem - * @param categoryId - category id + * Add problem p with default category by category id into default profile, + * category must exists in default profile + * + * @param p + * - problem + * @param categoryId + * - category id */ public abstract void addProblem(IProblem p, String categoryId); /** - * Add subcategory with id categoryId into parent category, - * if parent does not exist in default, profile - if not will be added to the root - * @param category - new category - * @param parentCategoryId - parent category id + * Add subcategory with id categoryId into parent category, if parent does + * not exist in default, profile - if not will be added to the root + * + * @param category + * - new category + * @param parentCategoryId + * - parent category id */ - public abstract void addCategory(IProblemCategory category, String parentCategoryId); + public abstract void addCategory(IProblemCategory category, + String parentCategoryId); /** - * Add problem reference to a checker, i.e. claim that checker can produce this problem. - * If checker does not claim any problems it cannot be enabled. - * @param c - checker - * @param p - problem + * Add problem reference to a checker, i.e. claim that checker can produce + * this problem. If checker does not claim any problems it cannot be + * enabled. + * + * @param c + * - checker + * @param p + * - problem */ - public abstract void addRefProblem(IChecker c, IProblem p); + public void addRefProblem(IChecker c, IProblem p); /** - * Get default profile, default profile is kind of "Installation Default". Always the same, comes from default in checker extensions + * Return collection of problem that this checker can produce + * + * @param checker + * @return + */ + public Collection getRefProblems(IChecker checker); + + /** + * Get default profile, default profile is kind of "Installation Default". + * Always the same, comes from default in checker extensions + * * @return */ public abstract IProblemProfile getDefaultProfile(); /** * Get workspace profile. User can change setting for workspace profile. + * * @return profile */ public abstract IProblemProfile getWorkspaceProfile(); /** - * Get resource profile. For example given directory can have different profile - * than parent project. + * Get resource profile. For example given directory can have different + * profile than parent project. * - * @param element - resource + * @param element + * - resource * @return profile */ public abstract IProblemProfile getResourceProfile(IResource element); /** - * Returns profile working copy for given resource element. (If profile is not - * specified for given element it will search for parent resource and so on). + * Returns profile working copy for given resource element. (If profile is + * not specified for given element it will search for parent resource and so + * on). + * * @param element * @return */ - public abstract IProblemProfile getResourceProfileWorkingCopy(IResource element); + public abstract IProblemProfile getResourceProfileWorkingCopy( + IResource element); /** - * Set profile for resource. + * Set profile for resource. + * * @noreference This method is not intended to be referenced by clients. * @param resource * - resource * @param profile * - problems profile */ - public abstract void updateProfile(IResource resource, IProblemProfile profile); + public abstract void updateProfile(IResource resource, + IProblemProfile profile); } \ No newline at end of file diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CheckersRegisry.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CheckersRegisry.java index f7ec159d7ac..d0030e42a9a 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CheckersRegisry.java +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CheckersRegisry.java @@ -14,6 +14,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; + import org.eclipse.cdt.codan.core.CodanCorePlugin; import org.eclipse.cdt.codan.core.PreferenceConstants; import org.eclipse.cdt.codan.core.model.CodanSeverity; @@ -420,4 +421,11 @@ public class CheckersRegisry implements Iterable, ICheckersRegistry { // no problem is enabled for this checker, skip the checker return false; } + + /** + * @return + */ + public int getCheckersSize() { + return checkers.size(); + } } diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanApplication.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanApplication.java index b258c149c92..01841129f12 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanApplication.java +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanApplication.java @@ -9,6 +9,7 @@ import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.equinox.app.IApplication; import org.eclipse.equinox.app.IApplicationContext; @@ -25,7 +26,8 @@ public class CodanApplication implements IApplication { private boolean all = false; public Object start(IApplicationContext context) throws Exception { - String[] args = (String[]) context.getArguments().get("application.args"); //$NON-NLS-1$ + String[] args = (String[]) context.getArguments().get( + "application.args"); //$NON-NLS-1$ if (args == null || args.length == 0) { help(); return EXIT_OK; @@ -35,24 +37,27 @@ public class CodanApplication implements IApplication { CodanRuntime runtime = CodanRuntime.getInstance(); runtime.setProblemReporter(new CodanMarkerProblemReporter() { @Override - public void reportProblem(String id, int severity, IFile file, int lineNumber, int startChar, int endChar, - String message) { - System.out.println(file.getLocation() + ":" + lineNumber + ": " + message); + public void reportProblem(String id, int severity, IFile file, + int lineNumber, int startChar, int endChar, String message) { + System.out.println(file.getLocation() + ":" + lineNumber + ": " + + message); } }); IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); if (all) { log("Launching analysis on workspace"); - root.accept(codanBuilder.new CodanResourceVisitor()); + codanBuilder.processResource(root, new NullProgressMonitor()); } else { for (String project : projects) { log("Launching analysis on project " + project); IProject wProject = root.getProject(project); if (!wProject.exists()) { - System.err.println("Error: project " + project + " does not exist"); + System.err.println("Error: project " + project + + " does not exist"); continue; } - wProject.accept(codanBuilder.new CodanResourceVisitor()); + codanBuilder.processResource(wProject, + new NullProgressMonitor()); } } return EXIT_OK; @@ -62,7 +67,8 @@ public class CodanApplication implements IApplication { * @param string */ private void log(String string) { - if (verbose) System.err.println(string); + if (verbose) + System.err.println(string); } /** diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanBuilder.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanBuilder.java index 1a94cedd8a6..fa1ba61e9a9 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanBuilder.java +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanBuilder.java @@ -19,49 +19,43 @@ import org.eclipse.cdt.codan.core.model.ICodanBuilder; import org.eclipse.cdt.codan.core.model.IProblemReporter; import org.eclipse.cdt.codan.core.model.IProblemReporterPersistent; import org.eclipse.cdt.codan.core.model.IRunnableInEditorChecker; -import org.eclipse.cdt.codan.internal.core.model.CodanMarkerProblemReporter; +import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.resources.IResourceDeltaVisitor; -import org.eclipse.core.resources.IResourceVisitor; import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.SubProgressMonitor; public class CodanBuilder extends IncrementalProjectBuilder implements ICodanBuilder { public static final String BUILDER_ID = "org.eclipse.cdt.codan.core.codanBuilder"; //$NON-NLS-1$ public class CodanDeltaVisitor implements IResourceDeltaVisitor { - /* - * (non-Javadoc) - * - * @see - * org.eclipse.core.resources.IResourceDeltaVisitor#visit(org.eclipse - * .core.resources.IResourceDelta) - */ - /* - * (non-Javadoc) - * - * @see - * org.eclipse.cdt.codan.internal.core.ICodanBuilder#visit(org.eclipse - * .core.resources.IResourceDelta) + private IProgressMonitor monitor; + + /** + * @param monitor */ + public CodanDeltaVisitor(IProgressMonitor monitor) { + this.monitor = monitor; + } + public boolean visit(IResourceDelta delta) throws CoreException { IResource resource = delta.getResource(); switch (delta.getKind()) { case IResourceDelta.ADDED: // handle added resource - processResource(resource, new NullProgressMonitor()); + processResource(resource, monitor); break; case IResourceDelta.REMOVED: // handle removed resource break; case IResourceDelta.CHANGED: // handle changed resource - processResource(resource, new NullProgressMonitor()); + processResource(resource, monitor); break; } // return true to continue visiting children. @@ -69,15 +63,6 @@ public class CodanBuilder extends IncrementalProjectBuilder implements } } - public class CodanResourceVisitor implements IResourceVisitor { - public boolean visit(IResource resource) { - if (!(resource instanceof IProject)) - processResource(resource, new NullProgressMonitor()); - // return true to continue visiting children. - return true; - } - } - /* * (non-Javadoc) * @@ -102,89 +87,94 @@ public class CodanBuilder extends IncrementalProjectBuilder implements } public void processResource(IResource resource, IProgressMonitor monitor) { - // String string = Platform.getPreferencesService().getString( - // CodanCorePlugin.PLUGIN_ID, "problems", "", null); - // System.err.println("set = " + string); - // delete general markers - IProblemReporter problemReporter = CodanRuntime.getInstance() - .getProblemReporter(); - if (problemReporter instanceof CodanMarkerProblemReporter) { - ((CodanMarkerProblemReporter) problemReporter) - .deleteProblems(resource); - } + processResource(resource, monitor, null, false); + } + + protected void processResource(IResource resource, + IProgressMonitor monitor, Object model, boolean inEditor) { CheckersRegisry chegistry = CheckersRegisry.getInstance(); - for (IChecker checker : chegistry) { + int checkers = chegistry.getCheckersSize(); + int memsize = 0; + if (resource instanceof IContainer) { try { - if (monitor.isCanceled()) - return; - if (chegistry.isCheckerEnabled(checker, resource) - && checker.enabledInContext(resource)) { - checker.processResource(resource); - } - } catch (Throwable e) { - CodanCorePlugin.log(e); - } - } - if (resource instanceof IProject) { - try { - resource.accept(getResourceVisitor()); + IResource[] members = ((IContainer) resource).members(); + memsize = members.length; } catch (CoreException e) { CodanCorePlugin.log(e); } } + int tick = 1000; + // System.err.println("processing " + resource); + monitor.beginTask("Code analysis on " + resource, checkers + memsize + * tick); + try { + IProblemReporter problemReporter = CodanRuntime.getInstance() + .getProblemReporter(); + for (IChecker checker : chegistry) { + try { + if (monitor.isCanceled()) + return; + if (checker.enabledInContext(resource)) { + // delete markers if checker can possibly run on this + // resource + // this way if checker is not enabled markers would be + // deleted too + if (problemReporter instanceof IProblemReporterPersistent) { + // delete general markers + ((IProblemReporterPersistent) problemReporter) + .deleteProblems(resource, checker); + } + if (chegistry.isCheckerEnabled(checker, resource)) { + if (inEditor) { + if (checker.runInEditor() + && checker instanceof IRunnableInEditorChecker) { + ((IRunnableInEditorChecker) checker) + .processModel(model); + } + } else { + checker.processResource(resource); + } + } + } + monitor.worked(1); + } catch (Throwable e) { + CodanCorePlugin.log(e); + } + } + if (resource instanceof IContainer) { + try { + IResource[] members = ((IContainer) resource).members(); + for (int i = 0; i < members.length; i++) { + if (monitor.isCanceled()) + return; + IResource member = members[i]; + processResource(member, new SubProgressMonitor(monitor, + tick)); + } + } catch (CoreException e) { + CodanCorePlugin.log(e); + } + } + } finally { + monitor.done(); + } } protected void fullBuild(final IProgressMonitor monitor) throws CoreException { - try { - getProject().accept(new CodanResourceVisitor()); - } catch (CoreException e) { - } + processResource(getProject(), monitor); } protected void incrementalBuild(IResourceDelta delta, IProgressMonitor monitor) throws CoreException { // the visitor does the work. - delta.accept(new CodanDeltaVisitor()); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.codan.core.model.ICodanBuilder#getResourceVisitor() - */ - public CodanResourceVisitor getResourceVisitor() { - return new CodanResourceVisitor(); + delta.accept(new CodanDeltaVisitor(monitor)); } public void runInEditor(Object model, IResource resource, IProgressMonitor monitor) { if (model == null) return; - IProblemReporter problemReporter = CodanRuntime.getInstance() - .getProblemReporter(); - // TODO: this is wrong - should not delete all markers - - // only those that contributed by the checker that we run now - if (problemReporter instanceof IProblemReporterPersistent) { - ((IProblemReporterPersistent) problemReporter) - .deleteProblems(resource); - } - CheckersRegisry chegistry = CheckersRegisry.getInstance(); - for (IChecker checker : chegistry) { - try { - boolean run = false; - if (checker.enabledInContext(resource) - && chegistry.isCheckerEnabled(checker, resource)) { - run = true; - } - if (run && checker.runInEditor() - && checker instanceof IRunnableInEditorChecker) - ((IRunnableInEditorChecker) checker).processModel(model); - if (monitor.isCanceled()) - break; - } catch (Throwable e) { - CodanCorePlugin.log(e); - } - } + processResource(resource, monitor, model, true); } } diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CodanMarkerProblemReporter.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CodanMarkerProblemReporter.java index ff978d77216..32c7910801c 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CodanMarkerProblemReporter.java +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CodanMarkerProblemReporter.java @@ -11,8 +11,13 @@ package org.eclipse.cdt.codan.internal.core.model; import java.text.MessageFormat; +import java.util.Collection; +import java.util.Iterator; +import org.eclipse.cdt.codan.core.CodanCorePlugin; +import org.eclipse.cdt.codan.core.CodanRuntime; import org.eclipse.cdt.codan.core.model.IChecker; +import org.eclipse.cdt.codan.core.model.ICheckersRegistry; import org.eclipse.cdt.codan.core.model.IProblem; import org.eclipse.cdt.codan.core.model.IProblemLocation; import org.eclipse.cdt.codan.core.model.IProblemReporterPersistent; @@ -101,7 +106,7 @@ public class CodanMarkerProblemReporter implements IProblemReporterPersistent { public void deleteProblems(IResource file) { try { - file.deleteMarkers(GENERIC_CODE_ANALYSIS_MARKER_TYPE, false, + file.deleteMarkers(GENERIC_CODE_ANALYSIS_MARKER_TYPE, true, IResource.DEPTH_ZERO); } catch (CoreException ce) { ce.printStackTrace(); @@ -110,13 +115,11 @@ public class CodanMarkerProblemReporter implements IProblemReporterPersistent { public void deleteAllProblems() { try { - // TODO delete contributed markers too ResourcesPlugin.getWorkspace().getRoot().deleteMarkers( - GENERIC_CODE_ANALYSIS_MARKER_TYPE, false, + GENERIC_CODE_ANALYSIS_MARKER_TYPE, true, IResource.DEPTH_INFINITE); } catch (CoreException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + CodanCorePlugin.log(e); } } @@ -129,6 +132,25 @@ public class CodanMarkerProblemReporter implements IProblemReporterPersistent { * org.eclipse.cdt.codan.core.model.IChecker) */ public void deleteProblems(IResource file, IChecker checker) { - deleteProblems(file); + try { + IMarker[] markers = file.findMarkers( + GENERIC_CODE_ANALYSIS_MARKER_TYPE, true, + IResource.DEPTH_INFINITE); + ICheckersRegistry reg = CodanRuntime.getInstance() + .getChechersRegistry(); + for (int i = 0; i < markers.length; i++) { + IMarker m = markers[i]; + String id = m.getAttribute(IMarker.PROBLEM, ""); //$NON-NLS-1$ + Collection problems = reg.getRefProblems(checker); + for (Iterator iterator = problems.iterator(); iterator + .hasNext();) { + IProblem iProblem = iterator.next(); + if (iProblem.getId().equals(id)) + m.delete(); + } + } + } catch (CoreException e) { + CodanCorePlugin.log(e); + } } }