mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
- optimized building
This commit is contained in:
parent
e750d3bff2
commit
404c5aba3c
6 changed files with 185 additions and 127 deletions
|
@ -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
|
||||
|
|
|
@ -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<IChecker> {
|
||||
/**
|
||||
* Iterator for registered checkers
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public abstract Iterator<IChecker> 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<IProblem> 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);
|
||||
}
|
|
@ -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<IChecker>, ICheckersRegistry {
|
|||
// no problem is enabled for this checker, skip the checker
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public int getCheckersSize() {
|
||||
return checkers.size();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<IProblem> problems = reg.getRefProblems(checker);
|
||||
for (Iterator<IProblem> iterator = problems.iterator(); iterator
|
||||
.hasNext();) {
|
||||
IProblem iProblem = iterator.next();
|
||||
if (iProblem.getId().equals(id))
|
||||
m.delete();
|
||||
}
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
CodanCorePlugin.log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue