/*******************************************************************************
* Copyright (c) 2009, 2015 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
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.codan.internal.core;
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.IRunnableInEditorChecker;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.osgi.util.NLS;
/**
* Collection of methods for running checkers.
*
* Clients: this should not be called directly, use ICodanBuilder interface instead
*
* CodanRuntime.getInstance().getBuilder()
*/
public class CodanRunner {
/** Do not instantiate. All methods are static */
private CodanRunner() {}
/**
* Runs all checkers that support "run as you type" mode.
*
* @param model - the model of given resource such as AST
* @param resource - the resource to process
* @param monitor - the progress monitor
*/
public static void runInEditor(Object model, IResource resource, IProgressMonitor monitor) {
processResource(resource, model, CheckerLaunchMode.RUN_AS_YOU_TYPE, monitor);
}
/**
* Runs all checkers on a given resource.
*
* @param resource - the resource to run the checkers on, either IFile or IContainer
* @param checkerLaunchMode - the checker launch mode.
* @param monitor - the progress monitor
*/
public static void processResource(IResource resource, CheckerLaunchMode checkerLaunchMode,
IProgressMonitor monitor) {
processResource(resource, null, checkerLaunchMode, monitor);
}
private static void processResource(IResource resource, Object model,
CheckerLaunchMode checkerLaunchMode, IProgressMonitor monitor) {
CheckersRegistry chegistry = CheckersRegistry.getInstance();
int checkers = chegistry.getCheckersSize();
IResource[] children = null;
if (resource instanceof IContainer) {
try {
children = ((IContainer) resource).members();
} catch (CoreException e) {
CodanCorePlugin.log(e);
}
}
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 * (1 + numChildren * childWeight));
try {
CheckersTimeStats.getInstance().checkerStart(CheckersTimeStats.ALL);
ICheckerInvocationContext context = new CheckerInvocationContext(resource);
try {
for (IChecker checker : chegistry) {
if (monitor.isCanceled())
return;
if (chegistry.isCheckerEnabled(checker, resource, checkerLaunchMode)) {
synchronized (checker) {
try {
checker.before(resource);
CheckersTimeStats.getInstance().checkerStart(checker.getClass().getName());
if (checkerLaunchMode == CheckerLaunchMode.RUN_AS_YOU_TYPE) {
((IRunnableInEditorChecker) checker).processModel(model, context);
} else {
checker.processResource(resource, context);
}
} catch (OperationCanceledException e) {
return;
} catch (Throwable e) {
CodanCorePlugin.log(e);
} finally {
CheckersTimeStats.getInstance().checkerStop(checker.getClass().getName());
checker.after(resource);
}
}
}
monitor.worked(1);
}
} finally {
context.dispose();
CheckersTimeStats.getInstance().checkerStop(CheckersTimeStats.ALL);
//CheckersTimeStats.getInstance().printStats();
}
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();
}
}
}