diff --git a/codan/org.eclipse.cdt.codan.core/META-INF/MANIFEST.MF b/codan/org.eclipse.cdt.codan.core/META-INF/MANIFEST.MF index ba450f62d85..40d3d8147fe 100644 --- a/codan/org.eclipse.cdt.codan.core/META-INF/MANIFEST.MF +++ b/codan/org.eclipse.cdt.codan.core/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: org.eclipse.cdt.codan.core;singleton:=true -Bundle-Version: 1.1.0.qualifier +Bundle-Version: 2.0.0.qualifier Bundle-Activator: org.eclipse.cdt.codan.core.CodanCorePlugin Bundle-Vendor: %Bundle-Vendor Require-Bundle: org.eclipse.core.runtime, diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractChecker.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractChecker.java index 411ba671246..cafdb0455bf 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractChecker.java +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractChecker.java @@ -11,6 +11,7 @@ package org.eclipse.cdt.codan.core.model; import org.eclipse.cdt.codan.core.CodanRuntime; +import org.eclipse.cdt.codan.internal.core.CheckerInvocationContext; import org.eclipse.cdt.codan.internal.core.CheckersRegistry; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; @@ -22,6 +23,10 @@ import org.eclipse.core.resources.IResource; */ public abstract class AbstractChecker implements IChecker { protected String name; + /** + * @since 2.0 + */ + protected ICheckerInvocationContext context; /** * Default constructor @@ -34,7 +39,7 @@ public abstract class AbstractChecker implements IChecker { * false checker's "processResource" method won't be called */ public boolean enabledInContext(IResource res) { - return true; + return res instanceof IFile; } /** @@ -93,9 +98,14 @@ public abstract class AbstractChecker implements IChecker { /** * @return problem reporter for given checker + * @since 2.0 */ - protected IProblemReporter getProblemReporter() { - return CodanRuntime.getInstance().getProblemReporter(); + public IProblemReporter getProblemReporter() { + try { + return getContext().getProblemReporter(); + } catch (Exception e) { + return CodanRuntime.getInstance().getProblemReporter(); + } } /** @@ -158,4 +168,63 @@ public abstract class AbstractChecker implements IChecker { Object... args) { getProblemReporter().reportProblem(problemId, loc, args); } + + /** + * Get invocation context. + * + * @return checker invocation context + * + * @since 2.0 + */ + public ICheckerInvocationContext getContext() { + return context; + } + + /** + * Set the invocation context. Usually called by codan builder. + * Object that calls this should also synchronize of checker object + * to prevent multi-thread access to a running context + * + * @since 2.0 + */ + public void setContext(ICheckerInvocationContext context) { + this.context = context; + } + + /** + * @since 2.0 + */ + public boolean before(IResource resource) { + IChecker checker = this; + IProblemReporter problemReporter = CodanRuntime.getInstance() + .getProblemReporter(); + IProblemReporter sessionReporter = problemReporter; + if (problemReporter instanceof IProblemReporterSessionPersistent) { + // create session problem reporter + sessionReporter = ((IProblemReporterSessionPersistent) problemReporter) + .createReporter(resource, checker); + ((IProblemReporterSessionPersistent) sessionReporter).start(); + } else if (problemReporter instanceof IProblemReporterPersistent) { + // delete markers if checker can possibly run on this + // resource this way if checker is not enabled markers would be + // deleted too + ((IProblemReporterPersistent) problemReporter).deleteProblems( + resource, checker); + } + ((AbstractChecker) checker).setContext(new CheckerInvocationContext( + resource, sessionReporter)); + return true; + } + + /** + * @since 2.0 + */ + public boolean after(IResource resource) { + if (getContext().getProblemReporter() instanceof IProblemReporterSessionPersistent) { + // delete general markers + ((IProblemReporterSessionPersistent) getContext() + .getProblemReporter()).done(); + } + return true; + } } diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractProblemLocation.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractProblemLocation.java index 7ce453f8dc0..0f210795c93 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractProblemLocation.java +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractProblemLocation.java @@ -35,7 +35,7 @@ public abstract class AbstractProblemLocation implements IProblemLocation { } /** - * @since 1.1 + * @since 2.0 */ protected AbstractProblemLocation(IResource file, int line) { this.file = file; @@ -49,7 +49,7 @@ public abstract class AbstractProblemLocation implements IProblemLocation { } /** - * @since 1.1 + * @since 2.0 */ protected AbstractProblemLocation(IResource file, int startChar, int endChar) { this.file = file; @@ -87,7 +87,7 @@ public abstract class AbstractProblemLocation implements IProblemLocation { /** * @return resource for which marker is created - * @since 1.1 + * @since 2.0 */ public IResource getResource() { return file; @@ -124,4 +124,42 @@ public abstract class AbstractProblemLocation implements IProblemLocation { public int getEndingChar() { return posEnd; } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((extra == null) ? 0 : extra.hashCode()); + result = prime * result + ((file == null) ? 0 : file.hashCode()); + result = prime * result + line; + result = prime * result + posEnd; + result = prime * result + posStart; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!(obj instanceof AbstractProblemLocation)) + return false; + AbstractProblemLocation other = (AbstractProblemLocation) obj; + if (line != other.line) + return false; + if (posEnd != other.posEnd) + return false; + if (posStart != other.posStart) + return false; + if (extra == null) { + if (other.extra != null) + return false; + } else if (!extra.equals(other.extra)) + return false; + if (file == null) { + if (other.file != null) + return false; + } else if (!file.equals(other.file)) + return false; + return true; + } } diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractProblemReporter.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractProblemReporter.java index fe1a93e9039..1dc13b027e2 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractProblemReporter.java +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractProblemReporter.java @@ -17,7 +17,7 @@ import org.eclipse.core.resources.IResource; /** * Abstract implementation of a IProblemReporter * - * @since 1.1 + * @since 2.0 */ public abstract class AbstractProblemReporter implements IProblemReporter { public void reportProblem(String id, IProblemLocation loc, Object... args) { diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/CodanSeverity.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/CodanSeverity.java index 6f340dc8493..c75d9985cae 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/CodanSeverity.java +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/CodanSeverity.java @@ -60,7 +60,7 @@ public enum CodanSeverity { /** * @param intValue * @return value of severity by its integer value - * @since 1.1 + * @since 2.0 */ public static CodanSeverity valueOf(int intValue) { if (intValue == IMarker.SEVERITY_INFO) diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IChecker.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IChecker.java index f00fea0494b..af32d6eb6af 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IChecker.java +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IChecker.java @@ -37,6 +37,21 @@ public interface IChecker { */ boolean processResource(IResource resource); + /** + * @since 2.0 + */ + boolean before(IResource resource); + + /** + * @since 2.0 + */ + boolean after(IResource resource); + + /** + * @since 2.0 + */ + IProblemReporter getProblemReporter(); + /** * Implement this method to trim down type of resource you are interested * in, usually it will be c/c++ files only. This method should be diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ICheckerInvocationContext.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ICheckerInvocationContext.java new file mode 100644 index 00000000000..057ee6abb88 --- /dev/null +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ICheckerInvocationContext.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2009,2010 QNX Software Systems + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems (Alena Laskavaia) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.model; + +import org.eclipse.core.resources.IResource; + +/** + * Since there is only one instance of checker available this object keeps + * track of invocation context - which would usually contain resource and some + * other object that checker require + *
+ * EXPERIMENTAL. This class or interface has been added as part + * of a work in progress. There is no guarantee that this API will work or that + * it will remain the same. + *
+ * + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + * + * @since 2.0 + */ +public interface ICheckerInvocationContext { + IResource getResource(); + + IProblemReporter getProblemReporter(); +} diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ICodanProblemMarker.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ICodanProblemMarker.java index c19cdf9de72..d8021e52805 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ICodanProblemMarker.java +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ICodanProblemMarker.java @@ -18,7 +18,7 @@ import org.eclipse.core.runtime.CoreException; * Instance of a problem. Intermediate representation before problem become a * marker. * - * @since 1.1 + * @since 2.0 */ public interface ICodanProblemMarker { /** @@ -56,4 +56,9 @@ public interface ICodanProblemMarker { * @return message */ public String createMessage(); + + /** + * @return problem arguments + */ + public Object[] getArgs(); } \ No newline at end of file diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemReporterSessionPersistent.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemReporterSessionPersistent.java new file mode 100644 index 00000000000..edf7a63bab0 --- /dev/null +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemReporterSessionPersistent.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Alena Laskavaia + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.model; + +import org.eclipse.core.resources.IResource; + +/** + * IProblemReporterPersistent - interface to report problems, which are + * persistent, ex. markers. Also this object has context of checker and + * current resource, which allows to manage markers better - i.e. instead of + * deleting replace them when needed, and queue markers for insertion instead + * of add right away. + * + *+ * EXPERIMENTAL. This class or interface has been added as part + * of a work in progress. There is no guarantee that this API will work or that + * it will remain the same. + *
+ * + * @since 2.0 + */ +public interface IProblemReporterSessionPersistent extends IProblemReporter { + /** + * Delete all problems associated with session resource and session checker. + * If "all" is true also delete all problems associated with workspace (and + * session checker) + * + */ + public void deleteProblems(boolean all); + + /** + * Notify that session is started + */ + public void start(); + + /** + * Notify that session is + * ended + */ + public void done(); + + IChecker getChecker(); + + IResource getResource(); + + /** + * Create an instance of the object.This is a bit ugly since implemented has + * to combine + * object itself and factory to this object. + * + * @param resource + * @param checker + * @return + * @since 2.0 + */ + public IProblemReporterSessionPersistent createReporter(IResource resource, + IChecker checker); +} \ No newline at end of file diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CheckerInvocationContext.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CheckerInvocationContext.java new file mode 100644 index 00000000000..69b75bb4056 --- /dev/null +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CheckerInvocationContext.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2009,2010 QNX Software Systems + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems (Alena Laskavaia) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.internal.core; + +import org.eclipse.cdt.codan.core.model.ICheckerInvocationContext; +import org.eclipse.cdt.codan.core.model.IProblemReporter; +import org.eclipse.core.resources.IResource; + +/** + * Implementation of ICheckerInvocationContext + */ +public class CheckerInvocationContext implements ICheckerInvocationContext { + private IResource resource; + private IProblemReporter sessionReporter; + + /** + * @param resource + * @param sessionReporter + */ + public CheckerInvocationContext(IResource resource, + IProblemReporter sessionReporter) { + this.resource = resource; + this.sessionReporter = sessionReporter; + } + + public IResource getResource() { + return resource; + } + + public IProblemReporter getProblemReporter() { + return sessionReporter; + } +} 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 6685b98f4da..bd3cb6721f1 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 @@ -13,12 +13,9 @@ package org.eclipse.cdt.codan.internal.core; import java.util.Map; import org.eclipse.cdt.codan.core.CodanCorePlugin; -import org.eclipse.cdt.codan.core.CodanRuntime; import org.eclipse.cdt.codan.core.Messages; import org.eclipse.cdt.codan.core.model.IChecker; 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.core.resources.IContainer; import org.eclipse.core.resources.IProject; @@ -115,31 +112,35 @@ public class CodanBuilder extends IncrementalProjectBuilder implements monitor.beginTask(Messages.CodanBuilder_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); + synchronized (checker) { + try { + checker.before(resource); + if (chegistry.isCheckerEnabled(checker, + resource)) { + //long time = System.currentTimeMillis(); + if (inEditor) { + if (checker.runInEditor() + && checker instanceof IRunnableInEditorChecker) { + ((IRunnableInEditorChecker) checker) + .processModel(model); + } + } else { + checker.processResource(resource); + } + // System.err + // .println("Checker " + // + checker.getClass() + // + " worked " + // + (System + // .currentTimeMillis() - time)); } - } else { - checker.processResource(resource); + } finally { + checker.after(resource); } } } 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 91f8bbccc6d..eda96e061fc 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 @@ -10,6 +10,8 @@ *******************************************************************************/ package org.eclipse.cdt.codan.internal.core.model; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Iterator; @@ -20,7 +22,9 @@ import org.eclipse.cdt.codan.core.model.IChecker; import org.eclipse.cdt.codan.core.model.ICheckersRegistry; import org.eclipse.cdt.codan.core.model.ICodanProblemMarker; import org.eclipse.cdt.codan.core.model.IProblem; +import org.eclipse.cdt.codan.core.model.IProblemLocation; import org.eclipse.cdt.codan.core.model.IProblemReporterPersistent; +import org.eclipse.cdt.codan.core.model.IProblemReporterSessionPersistent; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; @@ -33,10 +37,45 @@ import org.eclipse.core.runtime.IProgressMonitor; * Problem reported that created eclipse markers */ public class CodanMarkerProblemReporter extends AbstractProblemReporter - implements IProblemReporterPersistent { + implements IProblemReporterPersistent, + IProblemReporterSessionPersistent { + private IResource resource; + private IChecker checker; + private ArrayList