1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-21 16:05:25 +02:00

* Enabled correct API baseline (3.7) and fixed related API-check errors.

* Moved classes that are not part of the API to "internal" packages.
* Removed unnecessary classes.
* Simplified creation of checkers by providing alternative super class
and constructors.
This commit is contained in:
Alex Ruiz 2012-02-23 13:17:23 -08:00 committed by Sergey Prigogin
parent a631e47e43
commit b25c644007
33 changed files with 409 additions and 194 deletions

View file

@ -10,17 +10,18 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.codan.internal.checkers; package org.eclipse.cdt.codan.internal.checkers;
import static java.util.Collections.singletonList;
import java.io.File; import java.io.File;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import org.eclipse.cdt.codan.core.externaltool.AbstractOutputParser;
import org.eclipse.cdt.codan.core.externaltool.ConfigurationSettings; import org.eclipse.cdt.codan.core.externaltool.ConfigurationSettings;
import org.eclipse.cdt.codan.core.externaltool.InvocationParametersProvider; import org.eclipse.cdt.codan.core.externaltool.InvocationParameters;
import org.eclipse.cdt.codan.core.externaltool.SpaceDelimitedArgsSeparator;
import org.eclipse.cdt.codan.core.model.AbstractExternalToolBasedChecker;
import org.eclipse.cdt.codan.core.model.IProblemLocation; import org.eclipse.cdt.codan.core.model.IProblemLocation;
import org.eclipse.cdt.codan.ui.cxx.externaltool.CxxSupportedResourceVerifier; import org.eclipse.cdt.codan.ui.cxx.externaltool.AbstractCxxExternalToolBasedChecker;
import org.eclipse.cdt.codan.ui.externaltool.CommandInvoker;
/** /**
* Checker that invokes <a href="http://cppcheck.sourceforge.net/">Cppcheck</a> when a C/C++ is * Checker that invokes <a href="http://cppcheck.sourceforge.net/">Cppcheck</a> when a C/C++ is
@ -28,7 +29,7 @@ import org.eclipse.cdt.codan.ui.externaltool.CommandInvoker;
* *
* @author alruiz@google.com (Alex Ruiz) * @author alruiz@google.com (Alex Ruiz)
*/ */
public class CppcheckChecker extends AbstractExternalToolBasedChecker { public class CppcheckChecker extends AbstractCxxExternalToolBasedChecker {
private static final String TOOL_NAME = "Cppcheck"; //$NON-NLS-1$ private static final String TOOL_NAME = "Cppcheck"; //$NON-NLS-1$
private static final String EXECUTABLE_NAME = "cppcheck"; //$NON-NLS-1$ private static final String EXECUTABLE_NAME = "cppcheck"; //$NON-NLS-1$
private static final String DEFAULT_ARGS = ""; //$NON-NLS-1$ private static final String DEFAULT_ARGS = ""; //$NON-NLS-1$
@ -51,10 +52,7 @@ public class CppcheckChecker extends AbstractExternalToolBasedChecker {
} }
public CppcheckChecker() { public CppcheckChecker() {
super(new InvocationParametersProvider(), new CxxSupportedResourceVerifier(), super(new ConfigurationSettings(TOOL_NAME, new File(EXECUTABLE_NAME), DEFAULT_ARGS, false));
new SpaceDelimitedArgsSeparator(), new CommandInvoker(),
new CppcheckOutputParserFactory(),
new ConfigurationSettings(TOOL_NAME, new File(EXECUTABLE_NAME), DEFAULT_ARGS));
} }
@Override @Override
@ -70,4 +68,10 @@ public class CppcheckChecker extends AbstractExternalToolBasedChecker {
protected String getReferenceProblemId() { protected String getReferenceProblemId() {
return ERROR_PROBLEM_ID; return ERROR_PROBLEM_ID;
} }
@Override
protected List<AbstractOutputParser> createParsers(InvocationParameters parameters) {
AbstractOutputParser parser = new CppcheckOutputParser(parameters, this);
return singletonList(parser);
}
} }

View file

@ -14,7 +14,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.eclipse.cdt.codan.core.CodanRuntime; import org.eclipse.cdt.codan.core.CodanRuntime;
import org.eclipse.cdt.codan.core.externaltool.IOutputParser; import org.eclipse.cdt.codan.core.externaltool.AbstractOutputParser;
import org.eclipse.cdt.codan.core.externaltool.IProblemDisplay; import org.eclipse.cdt.codan.core.externaltool.IProblemDisplay;
import org.eclipse.cdt.codan.core.externaltool.InvocationParameters; import org.eclipse.cdt.codan.core.externaltool.InvocationParameters;
import org.eclipse.cdt.codan.core.model.IProblemLocation; import org.eclipse.cdt.codan.core.model.IProblemLocation;
@ -26,7 +26,7 @@ import org.eclipse.core.resources.IFile;
* *
* @author alruiz@google.com (Alex Ruiz) * @author alruiz@google.com (Alex Ruiz)
*/ */
class CppcheckOutputParser implements IOutputParser { class CppcheckOutputParser extends AbstractOutputParser {
// the pattern for parsing the message is: // the pattern for parsing the message is:
// //
// [/src/HelloWorld.cpp:19]: (style) The scope of the variable 'i' can be reduced // [/src/HelloWorld.cpp:19]: (style) The scope of the variable 'i' can be reduced

View file

@ -1,32 +0,0 @@
/*******************************************************************************
* Copyright (c) 2012 Google, Inc.
* 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:
* Alex Ruiz - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.codan.internal.checkers;
import static java.util.Collections.singletonList;
import java.util.List;
import org.eclipse.cdt.codan.core.externaltool.IOutputParser;
import org.eclipse.cdt.codan.core.externaltool.IOutputParserFactory;
import org.eclipse.cdt.codan.core.externaltool.IProblemDisplay;
import org.eclipse.cdt.codan.core.externaltool.InvocationParameters;
/**
* @author alruiz@google.com (Alex Ruiz)
*/
class CppcheckOutputParserFactory implements IOutputParserFactory {
@Override
public List<IOutputParser> createParsers(InvocationParameters parameters,
IProblemDisplay problemDisplay) {
IOutputParser parser = new CppcheckOutputParser(parameters, problemDisplay);
return singletonList(parser);
}
}

View file

@ -0,0 +1,127 @@
/*******************************************************************************
* Copyright (c) 2012 Google, Inc.
* 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:
* Alex Ruiz - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.codan.internal.core.externaltool;
import static org.junit.Assert.assertArrayEquals;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.codan.core.externaltool.ConfigurationSettings;
import org.eclipse.cdt.codan.core.externaltool.IArgsSeparator;
import org.eclipse.cdt.codan.core.externaltool.ICommandLauncher;
import org.eclipse.cdt.codan.core.externaltool.AbstractOutputParser;
import org.eclipse.cdt.codan.core.externaltool.InvocationFailure;
import org.eclipse.cdt.codan.core.externaltool.InvocationParameters;
import org.eclipse.cdt.codan.core.externaltool.SpaceDelimitedArgsSeparator;
import org.eclipse.cdt.codan.core.param.BasicProblemPreference;
import org.eclipse.cdt.codan.core.param.MapProblemPreference;
import org.eclipse.cdt.codan.core.test.CodanTestCase;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IPath;
/**
* Tests for <code>{@link ExternalToolInvoker}</code>.
*
* @author alruiz@google.com (Alex Ruiz)
*/
@SuppressWarnings("nls")
public class ExternalToolInvokerTest extends CodanTestCase {
private static final String EXTERNAL_TOOL_NAME = "TestTool";
private ConfigurationSettings configurationSettings;
private IArgsSeparator argsSeparator;
private List<AbstractOutputParser> parsers;
private CommandLauncherStub commandLauncher;
private ExternalToolInvoker externalToolInvoker;
@Override
public void setUp() throws Exception {
super.setUp();
createConfigurationSettings();
argsSeparator = new SpaceDelimitedArgsSeparator();
parsers = new ArrayList<AbstractOutputParser>();
commandLauncher = new CommandLauncherStub();
externalToolInvoker = new ExternalToolInvoker(commandLauncher);
}
private void createConfigurationSettings() {
configurationSettings = new ConfigurationSettings(EXTERNAL_TOOL_NAME, new File("testtool"),
"", false);
// Update current value of ConfigurationSettings from preferences.
MapProblemPreference preferences = createPreferences(new File("usr/local/testtool"),
"--debug=true --include=all", true);
configurationSettings.updateValuesFrom(preferences);
}
private MapProblemPreference createPreferences(File path, String args,
boolean shouldDisplayOutput) {
MapProblemPreference preferences = new MapProblemPreference();
preferences.addChildDescriptor(new BasicProblemPreference("externalToolPath", "Path"));
preferences.addChildDescriptor(new BasicProblemPreference("externalToolArgs", "Args"));
preferences.addChildDescriptor(new BasicProblemPreference("externalToolShouldDisplayOutput",
"Should Display Output"));
preferences.setChildValue("externalToolPath", path);
preferences.setChildValue("externalToolArgs", args);
preferences.setChildValue("externalToolShouldDisplayOutput", shouldDisplayOutput);
return preferences;
}
@Override
public boolean isCpp() {
return true;
}
// class C {
// };
public void testCommandLauncherGetsCalledCorrectly() throws Throwable {
loadcode(getAboveComment());
InvocationParameters parameters = new InvocationParameters(currentIFile, currentIFile,
currentIFile.getLocation().toOSString(), cproject.getProject().getLocation());
externalToolInvoker.invoke(parameters, configurationSettings, argsSeparator, parsers);
assertSame(cproject.getProject(), commandLauncher.project);
assertEquals(EXTERNAL_TOOL_NAME, commandLauncher.externalToolName);
String expectedExecutablePath = configurationSettings.getPath().getValue().toString();
assertEquals(expectedExecutablePath, commandLauncher.executablePath.toOSString());
String[] expectedArgs = { parameters.getActualFilePath(), "--debug=true", "--include=all" };
assertArrayEquals(expectedArgs, commandLauncher.args);
assertEquals(parameters.getWorkingDirectory(), commandLauncher.workingDirectory);
assertEquals(configurationSettings.getShouldDisplayOutput().getValue().booleanValue(),
commandLauncher.shouldDisplayOutput);
assertSame(parsers, commandLauncher.parsers);
}
private static class CommandLauncherStub implements ICommandLauncher {
IProject project;
String externalToolName;
IPath executablePath;
String[] args;
IPath workingDirectory;
boolean shouldDisplayOutput;
List<AbstractOutputParser> parsers;
@Override
public void buildAndLaunchCommand(IProject project, String externalToolName,
IPath executablePath, String[] args, IPath workingDirectory,
boolean shouldDisplayOutput, List<AbstractOutputParser> parsers) throws InvocationFailure,
Throwable {
this.project = project;
this.externalToolName = externalToolName;
this.executablePath = executablePath;
this.args = args;
this.workingDirectory = workingDirectory;
this.shouldDisplayOutput = shouldDisplayOutput;
this.parsers = parsers;
}
}
}

View file

@ -20,4 +20,5 @@ Export-Package: org.eclipse.cdt.codan.core,
org.eclipse.cdt.codan.core.test, org.eclipse.cdt.codan.core.test,
org.eclipse.cdt.codan.ui", org.eclipse.cdt.codan.ui",
org.eclipse.cdt.codan.internal.core.cfg;x-friends:="org.eclipse.cdt.codan.core.cxx", org.eclipse.cdt.codan.internal.core.cfg;x-friends:="org.eclipse.cdt.codan.core.cxx",
org.eclipse.cdt.codan.internal.core.externaltool,
org.eclipse.cdt.codan.internal.core.model;x-friends:="org.eclipse.cdt.codan.core.cxx,org.eclipse.cdt.codan.core.test,org.eclipse.cdt.codan.ui" org.eclipse.cdt.codan.internal.core.model;x-friends:="org.eclipse.cdt.codan.core.cxx,org.eclipse.cdt.codan.core.test,org.eclipse.cdt.codan.ui"

View file

@ -14,8 +14,10 @@ package org.eclipse.cdt.codan.core.externaltool;
* Parses the output of an external tool. * Parses the output of an external tool.
* *
* @author alruiz@google.com (Alex Ruiz) * @author alruiz@google.com (Alex Ruiz)
*
* @since 2.1
*/ */
public interface IOutputParser { public abstract class AbstractOutputParser {
/** /**
* Parses one line of output. Implementations are free to create markers from the information * Parses one line of output. Implementations are free to create markers from the information
* retrieved from the parsed output. * retrieved from the parsed output.
@ -24,11 +26,11 @@ public interface IOutputParser {
* @throws InvocationFailure if the output indicates that the invocation of the external tool * @throws InvocationFailure if the output indicates that the invocation of the external tool
* failed. * failed.
*/ */
boolean parse(String line) throws InvocationFailure; public abstract boolean parse(String line) throws InvocationFailure;
/** /**
* Resets the value of this parser, usually after the execution of the external tool is * Resets the value of this parser, usually after the execution of the external tool is
* finished. * finished.
*/ */
void reset(); public abstract void reset();
} }

View file

@ -10,18 +10,19 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.codan.core.externaltool; package org.eclipse.cdt.codan.core.externaltool;
import static org.eclipse.cdt.codan.core.externaltool.Messages.ConfigurationSettings_args_format;
import static org.eclipse.cdt.codan.core.externaltool.Messages.ConfigurationSettings_path_format;
import static org.eclipse.cdt.codan.core.externaltool.Messages.ConfigurationSettings_should_display_output;
import java.io.File; import java.io.File;
import org.eclipse.cdt.codan.core.param.MapProblemPreference; import org.eclipse.cdt.codan.core.param.MapProblemPreference;
import org.eclipse.cdt.codan.internal.core.externaltool.ArgsSetting;
import org.eclipse.cdt.codan.internal.core.externaltool.PathSetting;
import org.eclipse.cdt.codan.internal.core.externaltool.ShouldDisplayOutputSetting;
/** /**
* User-configurable external tool settings. * User-configurable external tool settings.
* *
* @author alruiz@google.com (Alex Ruiz) * @author alruiz@google.com (Alex Ruiz)
*
* @since 2.1
*/ */
public class ConfigurationSettings { public class ConfigurationSettings {
private final PathSetting path; private final PathSetting path;
@ -31,38 +32,18 @@ public class ConfigurationSettings {
/** /**
* Constructor. * Constructor.
* <p>
* <strong>Note:</strong> this constructor uses {@code false} as the default value of the
* <code>{@link ShouldDisplayOutputSetting}</code> to create.
* </p>
* @param externalToolName the name of the external tool, to be displayed to the user. * @param externalToolName the name of the external tool, to be displayed to the user.
* @param defaultPath the default path of the external tool. * @param defaultPath the default path of the external tool.
* @param defaultArgs the default arguments to pass when invoking the external tool. * @param defaultArgs the default arguments to pass when invoking the external tool.
*/ * @param defaultShouldDisplayOutput indicates whether output of an external tool should be
public ConfigurationSettings(String externalToolName, File defaultPath, String defaultArgs) {
this.externalToolName = externalToolName;
String pathLabel = String.format(ConfigurationSettings_path_format, externalToolName);
this.path = new PathSetting(pathLabel, defaultPath);
String argsLabel = String.format(ConfigurationSettings_args_format, externalToolName);
this.args = new ArgsSetting(argsLabel, defaultArgs);
String shouldDisplayOutputLabel = ConfigurationSettings_should_display_output;
this.shouldDisplayOutput = new ShouldDisplayOutputSetting(shouldDisplayOutputLabel, false);
}
/**
* Constructor.
* @param externalToolName the name of the external tool, to be displayed to the user.
* @param path specifies the path and name of the external tool to invoke.
* @param args specifies the arguments to pass when invoking the external tool.
* @param shouldDisplayOutput specifies whether the output of the external tools should be
* displayed in an Eclipse console. * displayed in an Eclipse console.
*/ */
public ConfigurationSettings(String externalToolName, PathSetting path, ArgsSetting args, public ConfigurationSettings(String externalToolName, File defaultPath, String defaultArgs,
ShouldDisplayOutputSetting shouldDisplayOutput) { boolean defaultShouldDisplayOutput) {
this.externalToolName = externalToolName; this.externalToolName = externalToolName;
this.path = path; this.path = new PathSetting(externalToolName, defaultPath);
this.args = args; this.args = new ArgsSetting(externalToolName, defaultArgs);
this.shouldDisplayOutput = shouldDisplayOutput; this.shouldDisplayOutput = new ShouldDisplayOutputSetting(defaultShouldDisplayOutput);
} }
/** /**
@ -77,7 +58,7 @@ public class ConfigurationSettings {
* Returns the setting that specifies the path and name of the external tool to invoke. * Returns the setting that specifies the path and name of the external tool to invoke.
* @return the setting that specifies the path and name of the external tool to invoke. * @return the setting that specifies the path and name of the external tool to invoke.
*/ */
public PathSetting getPath() { public SingleConfigurationSetting<File> getPath() {
return path; return path;
} }
@ -85,7 +66,7 @@ public class ConfigurationSettings {
* Returns the setting that specifies the arguments to pass when invoking the external tool. * Returns the setting that specifies the arguments to pass when invoking the external tool.
* @return the setting that specifies the arguments to pass when invoking the external tool. * @return the setting that specifies the arguments to pass when invoking the external tool.
*/ */
public ArgsSetting getArgs() { public SingleConfigurationSetting<String> getArgs() {
return args; return args;
} }
@ -95,7 +76,7 @@ public class ConfigurationSettings {
* @return the shouldDisplayOutput the setting that specifies whether the output of the external * @return the shouldDisplayOutput the setting that specifies whether the output of the external
* tools should be displayed in an Eclipse console. * tools should be displayed in an Eclipse console.
*/ */
public ShouldDisplayOutputSetting getShouldDisplayOutput() { public SingleConfigurationSetting<Boolean> getShouldDisplayOutput() {
return shouldDisplayOutput; return shouldDisplayOutput;
} }

View file

@ -11,20 +11,19 @@
package org.eclipse.cdt.codan.core.externaltool; package org.eclipse.cdt.codan.core.externaltool;
/** /**
* Parses and separates the value of an <code>{@link ArgsSetting}</code> into an array of * Parses a given {@code String} containing the arguments to pass to an external tool and separates
* {@code String}s. * them into individual values.
* *
* @author alruiz@google.com (Alex Ruiz) * @author alruiz@google.com (Alex Ruiz)
*
* @since 2.1
*/ */
public interface IArgsSeparator { public interface IArgsSeparator {
/** /**
* Indicates that there are no arguments to pass to the external tool executable. * Parses a given {@code String} containing the arguments to pass to an external tool and
*/ * separates them into individual values.
String[] NO_ARGS = new String[0]; * @param args contains the arguments to pass to the external tool
* executable.
/**
* Parses and separates the given value.
* @param args contains the arguments to pass to the external tool executable.
* @return the separated argument values. * @return the separated argument values.
*/ */
String[] separateArgs(String args); String[] separateArgs(String args);

View file

@ -16,10 +16,13 @@ import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPath;
/** /**
* Builds and launches the command necessary to invoke an external tool.
*
* @author alruiz@google.com (Alex Ruiz) * @author alruiz@google.com (Alex Ruiz)
* *
* @since 2.1
*/ */
public interface ICommandInvoker { public interface ICommandLauncher {
/** /**
* Builds and launches the command necessary to invoke an external tool. * Builds and launches the command necessary to invoke an external tool.
* @param project the current project. * @param project the current project.
@ -35,5 +38,5 @@ public interface ICommandInvoker {
*/ */
void buildAndLaunchCommand(IProject project, String externalToolName, IPath executablePath, void buildAndLaunchCommand(IProject project, String externalToolName, IPath executablePath,
String[] args, IPath workingDirectory, boolean shouldDisplayOutput, String[] args, IPath workingDirectory, boolean shouldDisplayOutput,
List<IOutputParser> parsers) throws InvocationFailure, Throwable; List<AbstractOutputParser> parsers) throws InvocationFailure, Throwable;
} }

View file

@ -16,6 +16,8 @@ import org.eclipse.core.resources.IResource;
* Provides the parameters to pass when invoking an external tool. * Provides the parameters to pass when invoking an external tool.
* *
* @author alruiz@google.com (Alex Ruiz) * @author alruiz@google.com (Alex Ruiz)
*
* @since 2.1
*/ */
public interface IInvocationParametersProvider { public interface IInvocationParametersProvider {
/** /**

View file

@ -1,29 +0,0 @@
/*******************************************************************************
* Copyright (c) 2012 Google, Inc.
* 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:
* Alex Ruiz - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.codan.core.externaltool;
import java.util.List;
/**
* Factory of instances of <code>{@link IOutputParser}</code>.
*
* @author alruiz@google.com (Alex Ruiz)
*/
public interface IOutputParserFactory {
/**
* Creates instances of <code>{@link IOutputParser}</code>.
* @param parameters the parameters to pass when invoking an external tool.
* @param problemDisplay displays problems found by the external tool.
* @return the created parsers.
*/
List<IOutputParser> createParsers(InvocationParameters parameters,
IProblemDisplay problemDisplay);
}

View file

@ -16,6 +16,8 @@ import org.eclipse.cdt.codan.core.model.IProblemLocation;
* Reports problems found in code, reported by an external tool. * Reports problems found in code, reported by an external tool.
* *
* @author alruiz@google.com (Alex Ruiz) * @author alruiz@google.com (Alex Ruiz)
*
* @since 2.1
*/ */
public interface IProblemDisplay { public interface IProblemDisplay {
/** /**

View file

@ -17,22 +17,26 @@ import org.eclipse.core.resources.IResource;
* Verifies that a <code>{@link IResource}</code> can be processed by an external tool. * Verifies that a <code>{@link IResource}</code> can be processed by an external tool.
* *
* @author alruiz@google.com (Alex Ruiz) * @author alruiz@google.com (Alex Ruiz)
*
* @since 2.1
*/ */
public interface ISupportedResourceVerifier { public interface ISupportedResourceVerifier {
/** /**
* Indicates whether the external tool is capable of processing the given * Indicates whether the external tool is capable of processing the given
* <code>{@link IResource}</code>. * <code>{@link IResource}</code>.
* <p> * <p>
* The minimum requirements that the given {@code IResource} should satisfy are: * The minimum requirements that the given {@code IResource} should satisfy
* are:
* <ul> * <ul>
* <li>should be an <code>{@link IFile}</code></li> * <li>should be an <code>{@link IFile}</code></li>
* <li>should be displayed in the current active editor</li> * <li>should be displayed in the current active editor</li>
* <li>should not have any unsaved changes</li> * <li>should not have any unsaved changes</li>
* </ul> * </ul>
* </p> * </p>
*
* @param resource the given {@code IResource}. * @param resource the given {@code IResource}.
* @return {@code true} if the external tool is capable of processing the given file, * @return {@code true} if the external tool is capable of processing the
* {@code false} otherwise. * given file, {@code false} otherwise.
*/ */
boolean isSupported(IResource resource); boolean isSupported(IResource resource);
} }

View file

@ -14,6 +14,8 @@ package org.eclipse.cdt.codan.core.externaltool;
* Indicates that invocation of an external tool failed. * Indicates that invocation of an external tool failed.
* *
* @author alruiz@google.com (Alex Ruiz) * @author alruiz@google.com (Alex Ruiz)
*
* @since 2.1
*/ */
public class InvocationFailure extends Exception { public class InvocationFailure extends Exception {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;

View file

@ -17,6 +17,8 @@ import org.eclipse.core.runtime.IPath;
* Parameters to pass when invoking an external tool. * Parameters to pass when invoking an external tool.
* *
* @author alruiz@google.com (Alex Ruiz) * @author alruiz@google.com (Alex Ruiz)
*
* @since 2.1
*/ */
public class InvocationParameters { public class InvocationParameters {
private final IResource originalFile; private final IResource originalFile;

View file

@ -16,6 +16,8 @@ import org.eclipse.core.resources.IResource;
* Default implementation of <code>{@link InvocationParameters}</code> * Default implementation of <code>{@link InvocationParameters}</code>
* *
* @author alruiz@google.com (Alex Ruiz) * @author alruiz@google.com (Alex Ruiz)
*
* @since 2.1
*/ */
public class InvocationParametersProvider implements IInvocationParametersProvider { public class InvocationParametersProvider implements IInvocationParametersProvider {
/** /**

View file

@ -10,6 +10,7 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.codan.core.externaltool; package org.eclipse.cdt.codan.core.externaltool;
import org.eclipse.cdt.codan.core.param.IProblemPreference;
import org.eclipse.cdt.codan.core.param.IProblemPreferenceDescriptor; import org.eclipse.cdt.codan.core.param.IProblemPreferenceDescriptor;
import org.eclipse.cdt.codan.core.param.MapProblemPreference; import org.eclipse.cdt.codan.core.param.MapProblemPreference;
@ -18,6 +19,8 @@ import org.eclipse.cdt.codan.core.param.MapProblemPreference;
* @param <T> the type of the value this setting stores. * @param <T> the type of the value this setting stores.
* *
* @author alruiz@google.com (Alex Ruiz) * @author alruiz@google.com (Alex Ruiz)
*
* @since 2.1
*/ */
public class SingleConfigurationSetting<T> { public class SingleConfigurationSetting<T> {
private final IProblemPreferenceDescriptor descriptor; private final IProblemPreferenceDescriptor descriptor;
@ -70,7 +73,9 @@ public class SingleConfigurationSetting<T> {
* by this setting. * by this setting.
*/ */
public void updateValue(MapProblemPreference preferences) { public void updateValue(MapProblemPreference preferences) {
Object o = preferences.getChildValue(descriptor.getKey()); IProblemPreference childDescriptor = preferences.getChildDescriptor(descriptor.getKey());
value = valueType.cast(o); if (childDescriptor != null) {
value = valueType.cast(childDescriptor.getValue());
}
} }
} }

View file

@ -13,11 +13,15 @@ package org.eclipse.cdt.codan.core.externaltool;
import java.util.regex.Pattern; import java.util.regex.Pattern;
/** /**
* Separates the value of an <code>{@link ArgsSetting}</code> using an empty space as delimiter. * Default implementation of <code>{@link IArgsSeparator}</code> that uses an empty space as
* the delimiter to separate the arguments to pass to an external tool.
* *
* @author alruiz@google.com (Alex Ruiz) * @author alruiz@google.com (Alex Ruiz)
*
* @since 2.1
*/ */
public class SpaceDelimitedArgsSeparator implements IArgsSeparator { public class SpaceDelimitedArgsSeparator implements IArgsSeparator {
private static final String[] NO_ARGS = new String[0];
private static final Pattern EMPTY_SPACE_PATTERN = Pattern.compile("\\s+"); //$NON-NLS-1$ private static final Pattern EMPTY_SPACE_PATTERN = Pattern.compile("\\s+"); //$NON-NLS-1$
/** /**

View file

@ -5,12 +5,11 @@ package org.eclipse.cdt.codan.core.model;
import java.util.List; import java.util.List;
import org.eclipse.cdt.codan.core.CodanCorePlugin; import org.eclipse.cdt.codan.core.CodanCorePlugin;
import org.eclipse.cdt.codan.core.externaltool.AbstractOutputParser;
import org.eclipse.cdt.codan.core.externaltool.ConfigurationSettings; import org.eclipse.cdt.codan.core.externaltool.ConfigurationSettings;
import org.eclipse.cdt.codan.core.externaltool.IArgsSeparator; import org.eclipse.cdt.codan.core.externaltool.IArgsSeparator;
import org.eclipse.cdt.codan.core.externaltool.ICommandInvoker; import org.eclipse.cdt.codan.core.externaltool.ICommandLauncher;
import org.eclipse.cdt.codan.core.externaltool.IInvocationParametersProvider; import org.eclipse.cdt.codan.core.externaltool.IInvocationParametersProvider;
import org.eclipse.cdt.codan.core.externaltool.IOutputParser;
import org.eclipse.cdt.codan.core.externaltool.IOutputParserFactory;
import org.eclipse.cdt.codan.core.externaltool.IProblemDisplay; import org.eclipse.cdt.codan.core.externaltool.IProblemDisplay;
import org.eclipse.cdt.codan.core.externaltool.ISupportedResourceVerifier; import org.eclipse.cdt.codan.core.externaltool.ISupportedResourceVerifier;
import org.eclipse.cdt.codan.core.externaltool.InvocationFailure; import org.eclipse.cdt.codan.core.externaltool.InvocationFailure;
@ -32,10 +31,12 @@ import org.eclipse.core.resources.IResource;
* <li>not have any unsaved changes</li> * <li>not have any unsaved changes</li>
* </ol> * </ol>
* </p> * </p>
* By default, implementations of this checker are not enable to run while the user types, since * By default, implementations of this checker are not allowed to run while the user types, since
* external tools cannot see unsaved changes. * external tools cannot see unsaved changes.
* *
* @author alruiz@google.com (Alex Ruiz) * @author alruiz@google.com (Alex Ruiz)
*
* @since 2.1
*/ */
public abstract class AbstractExternalToolBasedChecker extends AbstractCheckerWithProblemPreferences public abstract class AbstractExternalToolBasedChecker extends AbstractCheckerWithProblemPreferences
implements IProblemDisplay { implements IProblemDisplay {
@ -44,7 +45,6 @@ public abstract class AbstractExternalToolBasedChecker extends AbstractCheckerWi
private final IInvocationParametersProvider parametersProvider; private final IInvocationParametersProvider parametersProvider;
private final ISupportedResourceVerifier supportedResourceVerifier; private final ISupportedResourceVerifier supportedResourceVerifier;
private final IArgsSeparator argsSeparator; private final IArgsSeparator argsSeparator;
private final IOutputParserFactory outputParserFactory;
private final ConfigurationSettings configurationSettings; private final ConfigurationSettings configurationSettings;
private final ExternalToolInvoker externalToolInvoker; private final ExternalToolInvoker externalToolInvoker;
private final RootProblemPreference preferences; private final RootProblemPreference preferences;
@ -56,20 +56,17 @@ public abstract class AbstractExternalToolBasedChecker extends AbstractCheckerWi
* external tool. * external tool.
* @param argsSeparator separates the arguments to pass to the external tool executable. These * @param argsSeparator separates the arguments to pass to the external tool executable. These
* arguments are stored in a single {@code String}. * arguments are stored in a single {@code String}.
* @param commandInvoker builds and launches the command necessary to invoke the external tool. * @param commandLauncher builds and launches the command necessary to invoke the external tool.
* @param outputParserFactory creates parsers for the output of the external tool.
* @param configurationSettings user-configurable external tool configuration settings. * @param configurationSettings user-configurable external tool configuration settings.
*/ */
public AbstractExternalToolBasedChecker(IInvocationParametersProvider parametersProvider, public AbstractExternalToolBasedChecker(IInvocationParametersProvider parametersProvider,
ISupportedResourceVerifier supportedResourceVerifier, IArgsSeparator argsSeparator, ISupportedResourceVerifier supportedResourceVerifier, IArgsSeparator argsSeparator,
ICommandInvoker commandInvoker, IOutputParserFactory outputParserFactory, ICommandLauncher commandLauncher, ConfigurationSettings configurationSettings) {
ConfigurationSettings configurationSettings) {
this.parametersProvider = parametersProvider; this.parametersProvider = parametersProvider;
this.supportedResourceVerifier = supportedResourceVerifier; this.supportedResourceVerifier = supportedResourceVerifier;
this.argsSeparator = argsSeparator; this.argsSeparator = argsSeparator;
this.outputParserFactory = outputParserFactory;
this.configurationSettings = configurationSettings; this.configurationSettings = configurationSettings;
externalToolInvoker = new ExternalToolInvoker(commandInvoker); externalToolInvoker = new ExternalToolInvoker(commandLauncher);
preferences = new SharedRootProblemPreference(); preferences = new SharedRootProblemPreference();
} }
@ -118,7 +115,7 @@ public abstract class AbstractExternalToolBasedChecker extends AbstractCheckerWi
private void invokeExternalTool(InvocationParameters parameters) throws Throwable { private void invokeExternalTool(InvocationParameters parameters) throws Throwable {
updateConfigurationSettingsFromPreferences(parameters.getActualFile()); updateConfigurationSettingsFromPreferences(parameters.getActualFile());
List<IOutputParser> parsers = outputParserFactory.createParsers(parameters, this); List<AbstractOutputParser> parsers = createParsers(parameters);
try { try {
externalToolInvoker.invoke(parameters, configurationSettings, argsSeparator, parsers); externalToolInvoker.invoke(parameters, configurationSettings, argsSeparator, parsers);
} catch (InvocationFailure error) { } catch (InvocationFailure error) {
@ -132,6 +129,12 @@ public abstract class AbstractExternalToolBasedChecker extends AbstractCheckerWi
configurationSettings.updateValuesFrom(preferences); configurationSettings.updateValuesFrom(preferences);
} }
/**
* Creates instances of <code>{@link AbstractOutputParser}</code>.
* @param parameters the parameters to pass when invoking an external tool.
*/
protected abstract List<AbstractOutputParser> createParsers(InvocationParameters parameters);
/** /**
* Handles a failure reported when invoking the external tool. This implementation simply * Handles a failure reported when invoking the external tool. This implementation simply
* logs the failure. * logs the failure.

View file

@ -10,11 +10,12 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.codan.core.param; package org.eclipse.cdt.codan.core.param;
/** /**
* Preferences that can be shared among several problems. * Preferences that can be shared among several problems.
* *
* @author alruiz@google.com (Alex Ruiz) * @author alruiz@google.com (Alex Ruiz)
*
* @since 2.1
*/ */
public class SharedRootProblemPreference extends RootProblemPreference { public class SharedRootProblemPreference extends RootProblemPreference {
@Override @Override

View file

@ -8,27 +8,37 @@
* Contributors: * Contributors:
* Alex Ruiz - initial API and implementation * Alex Ruiz - initial API and implementation
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.codan.core.externaltool; package org.eclipse.cdt.codan.internal.core.externaltool;
import static org.eclipse.cdt.codan.core.param.IProblemPreferenceDescriptor.PreferenceType.TYPE_STRING; import static org.eclipse.cdt.codan.core.param.IProblemPreferenceDescriptor.PreferenceType.TYPE_STRING;
import static org.eclipse.cdt.codan.internal.core.externaltool.Messages.ConfigurationSettings_args_format;
import org.eclipse.cdt.codan.core.externaltool.SingleConfigurationSetting;
import org.eclipse.cdt.codan.core.param.BasicProblemPreference; import org.eclipse.cdt.codan.core.param.BasicProblemPreference;
import org.eclipse.cdt.codan.core.param.IProblemPreferenceDescriptor;
/** /**
* User-configurable setting that specifies the arguments to pass when invoking the external tool. * User-configurable setting that specifies the arguments to pass when invoking the external tool.
* The arguments are stored in a single {@code String}. * The arguments are stored in a single {@code String}.
* *
* @author alruiz@google.com (Alex Ruiz) * @author alruiz@google.com (Alex Ruiz)
*
* @since 2.1
*/ */
public class ArgsSetting extends SingleConfigurationSetting<String> { public class ArgsSetting extends SingleConfigurationSetting<String> {
private static final String KEY = "externalToolArgs"; //$NON-NLS-1$ private static final String KEY = "externalToolArgs"; //$NON-NLS-1$
/** /**
* Constructor. * Constructor.
* @param label the label to be displayed in the UI. * @param externalToolName the name of the external tool, to be displayed to the user.
* @param defaultValue the default value of the setting. * @param defaultValue the default value of the setting.
*/ */
public ArgsSetting(String label, String defaultValue) { public ArgsSetting(String externalToolName, String defaultValue) {
super(new BasicProblemPreference(KEY, label, TYPE_STRING), defaultValue, String.class); super(newPreferenceDescriptor(externalToolName), defaultValue, String.class);
}
private static IProblemPreferenceDescriptor newPreferenceDescriptor(String externalToolName) {
String label = String.format(ConfigurationSettings_args_format, externalToolName);
return new BasicProblemPreference(KEY, label, TYPE_STRING);
} }
} }

View file

@ -15,8 +15,8 @@ import java.util.List;
import org.eclipse.cdt.codan.core.externaltool.ConfigurationSettings; import org.eclipse.cdt.codan.core.externaltool.ConfigurationSettings;
import org.eclipse.cdt.codan.core.externaltool.IArgsSeparator; import org.eclipse.cdt.codan.core.externaltool.IArgsSeparator;
import org.eclipse.cdt.codan.core.externaltool.ICommandInvoker; import org.eclipse.cdt.codan.core.externaltool.ICommandLauncher;
import org.eclipse.cdt.codan.core.externaltool.IOutputParser; import org.eclipse.cdt.codan.core.externaltool.AbstractOutputParser;
import org.eclipse.cdt.codan.core.externaltool.InvocationFailure; import org.eclipse.cdt.codan.core.externaltool.InvocationFailure;
import org.eclipse.cdt.codan.core.externaltool.InvocationParameters; import org.eclipse.cdt.codan.core.externaltool.InvocationParameters;
import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProject;
@ -27,38 +27,43 @@ import org.eclipse.core.runtime.Path;
* Invokes an external tool to perform checks on a single file. * Invokes an external tool to perform checks on a single file.
* *
* @author alruiz@google.com (Alex Ruiz) * @author alruiz@google.com (Alex Ruiz)
*
* @since 2.1
*/ */
public class ExternalToolInvoker { public class ExternalToolInvoker {
private final ICommandInvoker commandInvoker; private final ICommandLauncher commandLauncher;
/** /**
* Constructor. * Constructor.
* @param commandInvoker builds and launches the command necessary to invoke the external tool. *
* @param commandLauncher builds and launches the command necessary to
* invoke the external tool.
*/ */
public ExternalToolInvoker(ICommandInvoker commandInvoker) { public ExternalToolInvoker(ICommandLauncher commandLauncher) {
this.commandInvoker = commandInvoker; this.commandLauncher = commandLauncher;
} }
/** /**
* Invokes an external tool. * Invokes an external tool.
*
* @param parameters the parameters to pass to the external tool executable. * @param parameters the parameters to pass to the external tool executable.
* @param configurationSettings user-configurable settings. * @param configurationSettings user-configurable settings.
* @param argsSeparator separates the arguments to pass to the external tool executable. These * @param argsSeparator separates the arguments to pass to the external tool
* arguments are stored in a single {@code String}. * executable. These
* arguments are stored in a single {@code String}.
* @param parsers parse the output of the external tool. * @param parsers parse the output of the external tool.
* @throws InvocationFailure if the external tool reports that it cannot be executed. * @throws InvocationFailure if the external tool reports that it cannot be
* executed.
* @throws Throwable if the external tool cannot be launched. * @throws Throwable if the external tool cannot be launched.
*/ */
public void invoke(InvocationParameters parameters, ConfigurationSettings configurationSettings, public void invoke(InvocationParameters parameters, ConfigurationSettings configurationSettings, IArgsSeparator argsSeparator,
IArgsSeparator argsSeparator, List<IOutputParser> parsers) throws InvocationFailure, List<AbstractOutputParser> parsers) throws InvocationFailure, Throwable {
Throwable {
IPath executablePath = executablePath(configurationSettings); IPath executablePath = executablePath(configurationSettings);
String[] args = argsToPass(parameters, configurationSettings, argsSeparator); String[] args = argsToPass(parameters, configurationSettings, argsSeparator);
boolean shouldDisplayOutput = configurationSettings.getShouldDisplayOutput().getValue(); boolean shouldDisplayOutput = configurationSettings.getShouldDisplayOutput().getValue();
IProject project = parameters.getActualFile().getProject(); IProject project = parameters.getActualFile().getProject();
try { try {
commandInvoker.buildAndLaunchCommand(project, commandLauncher.buildAndLaunchCommand(project, configurationSettings.getExternalToolName(), executablePath, args,
configurationSettings.getExternalToolName(), executablePath, args,
parameters.getWorkingDirectory(), shouldDisplayOutput, parsers); parameters.getWorkingDirectory(), shouldDisplayOutput, parsers);
} finally { } finally {
reset(parsers); reset(parsers);
@ -70,21 +75,20 @@ public class ExternalToolInvoker {
return new Path(executablePath.toString()); return new Path(executablePath.toString());
} }
private String[] argsToPass(InvocationParameters parameters, private String[] argsToPass(InvocationParameters parameters, ConfigurationSettings configurationSettings, IArgsSeparator argsSeparator) {
ConfigurationSettings configurationSettings, IArgsSeparator argsSeparator) {
String[] configuredArgs = configuredArgs(configurationSettings, argsSeparator); String[] configuredArgs = configuredArgs(configurationSettings, argsSeparator);
String actualFilePath = parameters.getActualFilePath(); String actualFilePath = parameters.getActualFilePath();
return addFilePathToArgs(actualFilePath, configuredArgs); return addFilePathToArgs(actualFilePath, configuredArgs);
} }
private String[] configuredArgs(ConfigurationSettings configurationSettings, private String[] configuredArgs(ConfigurationSettings configurationSettings, IArgsSeparator argsSeparator) {
IArgsSeparator argsSeparator) {
String args = configurationSettings.getArgs().getValue(); String args = configurationSettings.getArgs().getValue();
return argsSeparator.separateArgs(args); return argsSeparator.separateArgs(args);
} }
private String[] addFilePathToArgs(String actualFilePath, String[] configuredArgs) { private String[] addFilePathToArgs(String actualFilePath, String[] configuredArgs) {
int argCount = configuredArgs.length; int argCount = configuredArgs.length;
// TODO (alruiz) use array copy.
String[] allArgs = new String[argCount + 1]; String[] allArgs = new String[argCount + 1];
// add file to process as the first argument // add file to process as the first argument
allArgs[0] = actualFilePath; allArgs[0] = actualFilePath;
@ -94,8 +98,8 @@ public class ExternalToolInvoker {
return allArgs; return allArgs;
} }
private void reset(List<IOutputParser> parsers) { private void reset(List<AbstractOutputParser> parsers) {
for (IOutputParser parser : parsers) { for (AbstractOutputParser parser : parsers) {
parser.reset(); parser.reset();
} }
} }

View file

@ -8,12 +8,14 @@
* Contributors: * Contributors:
* Alex Ruiz - initial API and implementation * Alex Ruiz - initial API and implementation
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.codan.core.externaltool; package org.eclipse.cdt.codan.internal.core.externaltool;
import org.eclipse.osgi.util.NLS; import org.eclipse.osgi.util.NLS;
/** /**
* @author alruiz@google.com (Alex Ruiz) * @author alruiz@google.com (Alex Ruiz)
*
* @since 2.1
*/ */
@SuppressWarnings("javadoc") @SuppressWarnings("javadoc")
public class Messages extends NLS { public class Messages extends NLS {

View file

@ -8,28 +8,38 @@
* Contributors: * Contributors:
* Alex Ruiz - initial API and implementation * Alex Ruiz - initial API and implementation
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.codan.core.externaltool; package org.eclipse.cdt.codan.internal.core.externaltool;
import static org.eclipse.cdt.codan.core.param.IProblemPreferenceDescriptor.PreferenceType.TYPE_FILE; import static org.eclipse.cdt.codan.core.param.IProblemPreferenceDescriptor.PreferenceType.TYPE_FILE;
import static org.eclipse.cdt.codan.internal.core.externaltool.Messages.ConfigurationSettings_path_format;
import java.io.File; import java.io.File;
import org.eclipse.cdt.codan.core.externaltool.SingleConfigurationSetting;
import org.eclipse.cdt.codan.core.param.BasicProblemPreference; import org.eclipse.cdt.codan.core.param.BasicProblemPreference;
import org.eclipse.cdt.codan.core.param.IProblemPreferenceDescriptor;
/** /**
* User-configurable setting that specifies the path and name of an external tool's executable. * User-configurable setting that specifies the path and name of an external tool's executable.
* *
* @author alruiz@google.com (Alex Ruiz) * @author alruiz@google.com (Alex Ruiz)
*
* @since 2.1
*/ */
public class PathSetting extends SingleConfigurationSetting<File> { public class PathSetting extends SingleConfigurationSetting<File> {
private static final String KEY = "externalToolPath"; //$NON-NLS-1$ private static final String KEY = "externalToolPath"; //$NON-NLS-1$
/** /**
* Constructor. * Constructor.
* @param label the label to be displayed in the UI. * @param externalToolName the name of the external tool, to be displayed to the user.
* @param defaultValue the default value of the setting. * @param defaultValue the default value of the setting.
*/ */
public PathSetting(String label, File defaultValue) { public PathSetting(String externalToolName, File defaultValue) {
super(new BasicProblemPreference(KEY, label, TYPE_FILE), defaultValue, File.class); super(newPreferenceDescriptor(externalToolName), defaultValue, File.class);
}
private static IProblemPreferenceDescriptor newPreferenceDescriptor(String externalToolName) {
String label = String.format(ConfigurationSettings_path_format, externalToolName);
return new BasicProblemPreference(KEY, label, TYPE_FILE);
} }
} }

View file

@ -8,27 +8,36 @@
* Contributors: * Contributors:
* Alex Ruiz - initial API and implementation * Alex Ruiz - initial API and implementation
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.codan.core.externaltool; package org.eclipse.cdt.codan.internal.core.externaltool;
import static org.eclipse.cdt.codan.core.param.IProblemPreferenceDescriptor.PreferenceType.TYPE_BOOLEAN; import static org.eclipse.cdt.codan.core.param.IProblemPreferenceDescriptor.PreferenceType.TYPE_BOOLEAN;
import static org.eclipse.cdt.codan.internal.core.externaltool.Messages.ConfigurationSettings_should_display_output;
import org.eclipse.cdt.codan.core.externaltool.SingleConfigurationSetting;
import org.eclipse.cdt.codan.core.param.BasicProblemPreference; import org.eclipse.cdt.codan.core.param.BasicProblemPreference;
import org.eclipse.cdt.codan.core.param.IProblemPreferenceDescriptor;
/** /**
* User-configurable setting that specifies whether the output of an external tool should be * User-configurable setting that specifies whether the output of an external tool should be
* displayed in an Eclipse console. * displayed in an Eclipse console.
* *
* @author alruiz@google.com (Alex Ruiz) * @author alruiz@google.com (Alex Ruiz)
*
* @since 2.1
*/ */
public class ShouldDisplayOutputSetting extends SingleConfigurationSetting<Boolean> { public class ShouldDisplayOutputSetting extends SingleConfigurationSetting<Boolean> {
private static final String KEY = "externalToolShouldDisplayOutput"; //$NON-NLS-1$ private static final String KEY = "externalToolShouldDisplayOutput"; //$NON-NLS-1$
/** /**
* Constructor. * Constructor.
* @param label the label to be displayed in the UI.
* @param defaultValue the default value of the setting. * @param defaultValue the default value of the setting.
*/ */
public ShouldDisplayOutputSetting(String label, boolean defaultValue) { public ShouldDisplayOutputSetting(boolean defaultValue) {
super(new BasicProblemPreference(KEY, label, TYPE_BOOLEAN), defaultValue, Boolean.class); super(newPreferenceDescriptor(), defaultValue, Boolean.class);
}
private static IProblemPreferenceDescriptor newPreferenceDescriptor() {
String label = ConfigurationSettings_should_display_output;
return new BasicProblemPreference(KEY, label, TYPE_BOOLEAN);
} }
} }

View file

@ -0,0 +1,63 @@
/*******************************************************************************
* Copyright (c) 2012 Google, Inc.
* 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:
* Alex Ruiz - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.codan.ui.cxx.externaltool;
import org.eclipse.cdt.codan.core.externaltool.ConfigurationSettings;
import org.eclipse.cdt.codan.core.externaltool.IArgsSeparator;
import org.eclipse.cdt.codan.core.externaltool.IInvocationParametersProvider;
import org.eclipse.cdt.codan.core.externaltool.ISupportedResourceVerifier;
import org.eclipse.cdt.codan.core.externaltool.InvocationParametersProvider;
import org.eclipse.cdt.codan.core.externaltool.SpaceDelimitedArgsSeparator;
import org.eclipse.cdt.codan.core.model.AbstractExternalToolBasedChecker;
import org.eclipse.cdt.codan.ui.externaltool.CommandLauncher;
/**
* Base class for checkers that invoke external command-line tools to perform code checking
* on C++ files.
* <p>
* A file, to be processed by this type of checker, must:
* <ol>
* <li>a C++ file</li>
* <li>be in the current active editor</li>
* <li>not have any unsaved changes</li>
* </ol>
* </p>
* By default, implementations of this checker are not allowed to run while the user types, since
* external tools cannot see unsaved changes.
*
* @author alruiz@google.com (Alex Ruiz)
*/
public abstract class AbstractCxxExternalToolBasedChecker extends AbstractExternalToolBasedChecker {
/**
* Constructor
* @param configurationSettings user-configurable external tool configuration settings.
*/
public AbstractCxxExternalToolBasedChecker(ConfigurationSettings configurationSettings) {
this(new InvocationParametersProvider(), new CxxSupportedResourceVerifier(),
new SpaceDelimitedArgsSeparator(), configurationSettings);
}
/**
* Constructor.
* @param parametersProvider provides the parameters to pass when invoking the external tool.
* @param supportedResourceVerifier indicates whether a resource can be processed by the
* external tool.
* @param argsSeparator separates the arguments to pass to the external tool executable. These
* arguments are stored in a single {@code String}.
* @param configurationSettings user-configurable external tool configuration settings.
*/
public AbstractCxxExternalToolBasedChecker(IInvocationParametersProvider parametersProvider,
ISupportedResourceVerifier supportedResourceVerifier, IArgsSeparator argsSeparator,
ConfigurationSettings configurationSettings) {
super(parametersProvider, supportedResourceVerifier, argsSeparator, new CommandLauncher(),
configurationSettings);
}
}

View file

@ -24,9 +24,12 @@ import org.eclipse.ui.editors.text.TextEditor;
* @author alruiz@google.com (Alex Ruiz) * @author alruiz@google.com (Alex Ruiz)
*/ */
@SuppressWarnings("restriction") // CEditor is internal API @SuppressWarnings("restriction") // CEditor is internal API
final class CEditors { public final class CEditors {
/**
static TextEditor activeCEditor() { * Finds the current {@code CEditor}.
* @return the current {@code CEditor}, or {@code null} if one cannot be found.
*/
public static TextEditor activeCEditor() {
IWorkbench workbench = PlatformUI.getWorkbench(); IWorkbench workbench = PlatformUI.getWorkbench();
for (IWorkbenchWindow w : workbench.getWorkbenchWindows()) { for (IWorkbenchWindow w : workbench.getWorkbenchWindows()) {
IWorkbenchPage activePage = w.getActivePage(); IWorkbenchPage activePage = w.getActivePage();

View file

@ -20,11 +20,11 @@ import org.eclipse.core.resources.IResource;
import org.eclipse.ui.editors.text.TextEditor; import org.eclipse.ui.editors.text.TextEditor;
/** /**
* Implemenation of <code>{@link ISupportedResourceVerifier}</code> for C/C++ files. * Implementation of <code>{@link ISupportedResourceVerifier}</code> for C/C++ files.
* *
* @author alruiz@google.com (Alex Ruiz) * @author alruiz@google.com (Alex Ruiz)
*/ */
public class CxxSupportedResourceVerifier implements ISupportedResourceVerifier { class CxxSupportedResourceVerifier implements ISupportedResourceVerifier {
/** /**
* Indicates whether the external tool is capable of processing the given * Indicates whether the external tool is capable of processing the given
* <code>{@link IResource}</code>. * <code>{@link IResource}</code>.

View file

@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2 Bundle-ManifestVersion: 2
Bundle-Name: %Bundle-Name Bundle-Name: %Bundle-Name
Bundle-SymbolicName: org.eclipse.cdt.codan.ui; singleton:=true Bundle-SymbolicName: org.eclipse.cdt.codan.ui; singleton:=true
Bundle-Version: 2.0.1.qualifier Bundle-Version: 2.1.0.qualifier
Bundle-Activator: org.eclipse.cdt.codan.internal.ui.CodanUIActivator Bundle-Activator: org.eclipse.cdt.codan.internal.ui.CodanUIActivator
Bundle-Vendor: %Bundle-Vendor Bundle-Vendor: %Bundle-Vendor
Require-Bundle: org.eclipse.ui, Require-Bundle: org.eclipse.ui,

View file

@ -160,6 +160,7 @@ public class CodanEditorUtility {
/** /**
* Returns the active workbench page. * Returns the active workbench page.
* @return the active workbench page, or {@code null} if none can be found. * @return the active workbench page, or {@code null} if none can be found.
* @since 2.1
*/ */
public static IWorkbenchPage getActivePage() { public static IWorkbenchPage getActivePage() {
IWorkbenchWindow activeWorkbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); IWorkbenchWindow activeWorkbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();

View file

@ -17,26 +17,28 @@ import java.io.InputStreamReader;
import java.io.Reader; import java.io.Reader;
import java.util.List; import java.util.List;
import org.eclipse.cdt.codan.core.externaltool.ICommandInvoker; import org.eclipse.cdt.codan.core.externaltool.ICommandLauncher;
import org.eclipse.cdt.codan.core.externaltool.IOutputParser; import org.eclipse.cdt.codan.core.externaltool.AbstractOutputParser;
import org.eclipse.cdt.codan.core.externaltool.InvocationFailure; import org.eclipse.cdt.codan.core.externaltool.InvocationFailure;
import org.eclipse.cdt.codan.internal.ui.CodanUIActivator;
import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPath;
import org.eclipse.ui.PartInitException;
/** /**
* Invokes an external tool command. * Invokes an external tool command.
* *
* @author alruiz@google.com (Alex Ruiz) * @author alruiz@google.com (Alex Ruiz)
*
* @since 2.1
*/ */
public class CommandInvoker implements ICommandInvoker { public class CommandLauncher implements ICommandLauncher {
private static final String[] ENVIRONMENT_VARIABLE_SETTINGS = {}; private static final String[] ENVIRONMENT_VARIABLE_SETTINGS = {};
private ConsolePrinterFactory consolePrinterFactory = new ConsolePrinterFactory();
@Override @Override
public void buildAndLaunchCommand(IProject project, String externalToolName, public void buildAndLaunchCommand(IProject project, String externalToolName,
IPath executablePath, String[] args, IPath workingDirectory, boolean shouldDisplayOutput, IPath executablePath, String[] args, IPath workingDirectory, boolean shouldDisplayOutput,
List<IOutputParser> parsers) throws InvocationFailure, Throwable { List<AbstractOutputParser> parsers) throws InvocationFailure, Throwable {
ConsolePrinter consolePrinter = consolePrinter(externalToolName, shouldDisplayOutput); ConsolePrinter consolePrinter = consolePrinter(externalToolName, shouldDisplayOutput);
String command = buildCommand(executablePath, args); String command = buildCommand(executablePath, args);
Process process = null; Process process = null;
@ -60,14 +62,7 @@ public class CommandInvoker implements ICommandInvoker {
} }
private ConsolePrinter consolePrinter(String externalToolName, boolean shouldDisplayOutput) { private ConsolePrinter consolePrinter(String externalToolName, boolean shouldDisplayOutput) {
if (shouldDisplayOutput) { return consolePrinterFactory.createConsolePrinter(externalToolName, shouldDisplayOutput);
try {
return ConsolePrinterImpl.createOrFindConsole(externalToolName);
} catch (PartInitException e) {
CodanUIActivator.log("Unable to create/find console", e); //$NON-NLS-1$
}
}
return ConsolePrinter.NullImpl;
} }
private String buildCommand(IPath executablePath, String[] args) { private String buildCommand(IPath executablePath, String[] args) {
@ -87,7 +82,7 @@ public class CommandInvoker implements ICommandInvoker {
return runtime.exec(command, ENVIRONMENT_VARIABLE_SETTINGS, workingDirectory.toFile()); return runtime.exec(command, ENVIRONMENT_VARIABLE_SETTINGS, workingDirectory.toFile());
} }
private void processStream(InputStream inputStream, List<IOutputParser> parsers, private void processStream(InputStream inputStream, List<AbstractOutputParser> parsers,
ConsolePrinter consolePrinter) throws IOException, InvocationFailure { ConsolePrinter consolePrinter) throws IOException, InvocationFailure {
Reader reader = null; Reader reader = null;
try { try {
@ -96,7 +91,7 @@ public class CommandInvoker implements ICommandInvoker {
String line = null; String line = null;
while ((line = bufferedReader.readLine()) != null) { while ((line = bufferedReader.readLine()) != null) {
consolePrinter.println(line); consolePrinter.println(line);
for (IOutputParser parser : parsers) { for (AbstractOutputParser parser : parsers) {
if (parser.parse(line)) { if (parser.parse(line)) {
break; break;
} }
@ -110,4 +105,9 @@ public class CommandInvoker implements ICommandInvoker {
} }
} }
} }
// Visible for testing.
void setConsolePrinterFactory(ConsolePrinterFactory newVal) {
this.consolePrinterFactory = newVal;
}
} }

View file

@ -0,0 +1,30 @@
/*******************************************************************************
* Copyright (c) 2012 Google, Inc.
* 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:
* Alex Ruiz - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.codan.ui.externaltool;
import org.eclipse.cdt.codan.internal.ui.CodanUIActivator;
import org.eclipse.ui.PartInitException;
/**
* @author alruiz@google.com (Alex Ruiz)
*/
class ConsolePrinterFactory {
ConsolePrinter createConsolePrinter(String externalToolName, boolean shouldDisplayOutput) {
if (shouldDisplayOutput) {
try {
return ConsolePrinterImpl.createOrFindConsole(externalToolName);
} catch (PartInitException e) {
CodanUIActivator.log("Unable to create/find console", e); //$NON-NLS-1$
}
}
return ConsolePrinter.NullImpl;
}
}