mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-22 22:22:11 +02:00
Initial take on external-tool-based checkers.
This commit is contained in:
parent
ac7ee03d25
commit
3115bb4e22
38 changed files with 1756 additions and 7 deletions
|
@ -8,7 +8,9 @@ Require-Bundle: org.eclipse.core.runtime,
|
||||||
org.eclipse.core.resources;bundle-version="3.5.0",
|
org.eclipse.core.resources;bundle-version="3.5.0",
|
||||||
org.eclipse.cdt.codan.core;bundle-version="1.0.0",
|
org.eclipse.cdt.codan.core;bundle-version="1.0.0",
|
||||||
org.eclipse.cdt.core;bundle-version="5.1.0",
|
org.eclipse.cdt.core;bundle-version="5.1.0",
|
||||||
org.eclipse.cdt.codan.core.cxx;bundle-version="1.0.0"
|
org.eclipse.cdt.codan.core.cxx;bundle-version="1.0.0",
|
||||||
|
org.eclipse.cdt.codan.ui.cxx;bundle-version="3.0.0",
|
||||||
|
org.eclipse.cdt.codan.ui;bundle-version="2.0.1"
|
||||||
Bundle-ActivationPolicy: lazy
|
Bundle-ActivationPolicy: lazy
|
||||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||||
Bundle-Vendor: %Bundle-Vendor
|
Bundle-Vendor: %Bundle-Vendor
|
||||||
|
|
|
@ -398,5 +398,41 @@
|
||||||
name="%problem.name.ClassMembersInitialization">
|
name="%problem.name.ClassMembersInitialization">
|
||||||
</problem>
|
</problem>
|
||||||
</checker>
|
</checker>
|
||||||
|
<category
|
||||||
|
id="org.eclipse.cdt.codan.checkers.cppcheck"
|
||||||
|
name="Cppcheck Errors">
|
||||||
|
</category>
|
||||||
|
<checker
|
||||||
|
class="org.eclipse.cdt.codan.internal.checkers.CppcheckChecker"
|
||||||
|
id="org.eclipse.cdt.codan.checkers.CppcheckChecker"
|
||||||
|
name="Cppcheck">
|
||||||
|
<problem
|
||||||
|
category="org.eclipse.cdt.codan.checkers.cppcheck"
|
||||||
|
defaultEnabled="false"
|
||||||
|
defaultSeverity="Error"
|
||||||
|
description="Errors reported by Cppcheck (http://cppcheck.sourceforge.net/)"
|
||||||
|
id="org.eclipse.cdt.codan.checkers.cppcheck.error"
|
||||||
|
messagePattern="{0}"
|
||||||
|
name="Errors">
|
||||||
|
</problem>
|
||||||
|
<problem
|
||||||
|
category="org.eclipse.cdt.codan.checkers.cppcheck"
|
||||||
|
defaultEnabled="false"
|
||||||
|
defaultSeverity="Warning"
|
||||||
|
description="Warnings reported by Cppcheck (http://cppcheck.sourceforge.net/)"
|
||||||
|
id="org.eclipse.cdt.codan.checkers.cppcheck.warning"
|
||||||
|
messagePattern="{0}"
|
||||||
|
name="Warnings">
|
||||||
|
</problem>
|
||||||
|
<problem
|
||||||
|
category="org.eclipse.cdt.codan.checkers.cppcheck"
|
||||||
|
defaultEnabled="false"
|
||||||
|
defaultSeverity="Warning"
|
||||||
|
description="Style issues reported by Cppcheck (http://cppcheck.sourceforge.net/)"
|
||||||
|
id="org.eclipse.cdt.codan.checkers.cppcheck.style"
|
||||||
|
messagePattern="{0}"
|
||||||
|
name="Style Issues">
|
||||||
|
</problem>
|
||||||
|
</checker>
|
||||||
</extension>
|
</extension>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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 java.io.File;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.codan.core.externaltool.ConfigurationSettings;
|
||||||
|
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.core.model.IProblemLocation;
|
||||||
|
import org.eclipse.cdt.codan.ui.cxx.externaltool.CxxSupportedResourceVerifier;
|
||||||
|
import org.eclipse.cdt.codan.ui.externaltool.CommandInvoker;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checker that invokes <a href="http://cppcheck.sourceforge.net/">Cppcheck</a> when a C/C++ is
|
||||||
|
* saved.
|
||||||
|
*
|
||||||
|
* @author alruiz@google.com (Alex Ruiz)
|
||||||
|
*/
|
||||||
|
public class CppcheckChecker extends AbstractExternalToolBasedChecker {
|
||||||
|
private static final String TOOL_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 DESCRIPTION_FORMAT = "[" + TOOL_NAME + "] %s"; //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
|
||||||
|
private static final String ERROR_PROBLEM_ID;
|
||||||
|
|
||||||
|
// key: severity (error, warning, etc.) - value : problem ID associated to severity
|
||||||
|
private static final Map<String, String> PROBLEM_IDS = new HashMap<String, String>();
|
||||||
|
static {
|
||||||
|
ERROR_PROBLEM_ID = addProblemId("error"); //$NON-NLS-1$
|
||||||
|
addProblemId("warning"); //$NON-NLS-1$
|
||||||
|
addProblemId("style"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
private static String addProblemId(String severity) {
|
||||||
|
String problemId = "org.eclipse.cdt.codan.checkers.cppcheck." + severity; //$NON-NLS-1$
|
||||||
|
PROBLEM_IDS.put(severity, problemId);
|
||||||
|
return problemId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CppcheckChecker() {
|
||||||
|
super(new InvocationParametersProvider(), new CxxSupportedResourceVerifier(),
|
||||||
|
new SpaceDelimitedArgsSeparator(), new CommandInvoker(),
|
||||||
|
new CppcheckOutputParserFactory(),
|
||||||
|
new ConfigurationSettings(TOOL_NAME, new File(EXECUTABLE_NAME), DEFAULT_ARGS));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reportProblem(IProblemLocation location, String description, String severity) {
|
||||||
|
String problemId = PROBLEM_IDS.get(severity);
|
||||||
|
if (problemId == null) {
|
||||||
|
problemId = getReferenceProblemId();
|
||||||
|
}
|
||||||
|
super.reportProblem(problemId, location, String.format(DESCRIPTION_FORMAT, description));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getReferenceProblemId() {
|
||||||
|
return ERROR_PROBLEM_ID;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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 java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.codan.core.CodanRuntime;
|
||||||
|
import org.eclipse.cdt.codan.core.externaltool.IOutputParser;
|
||||||
|
import org.eclipse.cdt.codan.core.externaltool.IProblemDisplay;
|
||||||
|
import org.eclipse.cdt.codan.core.externaltool.InvocationParameters;
|
||||||
|
import org.eclipse.cdt.codan.core.model.IProblemLocation;
|
||||||
|
import org.eclipse.cdt.codan.core.model.IProblemLocationFactory;
|
||||||
|
import org.eclipse.core.resources.IFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the output of Cppcheck.
|
||||||
|
*
|
||||||
|
* @author alruiz@google.com (Alex Ruiz)
|
||||||
|
*/
|
||||||
|
class CppcheckOutputParser implements IOutputParser {
|
||||||
|
// the pattern for parsing the message is:
|
||||||
|
//
|
||||||
|
// [/src/HelloWorld.cpp:19]: (style) The scope of the variable 'i' can be reduced
|
||||||
|
// ----------1--------- -2 --3-- ------------------4-------------------------
|
||||||
|
//
|
||||||
|
// groups:
|
||||||
|
// 1: file path and name
|
||||||
|
// 2: line where problem was found
|
||||||
|
// 3: problem severity
|
||||||
|
// 4: problem description
|
||||||
|
|
||||||
|
private static Pattern pattern = Pattern.compile("\\[(.*):(\\d+)\\]:\\s*\\((.*)\\)\\s*(.*)"); //$NON-NLS-1$
|
||||||
|
|
||||||
|
private final InvocationParameters parameters;
|
||||||
|
private final IProblemDisplay problemDisplay;
|
||||||
|
|
||||||
|
CppcheckOutputParser(InvocationParameters parameters, IProblemDisplay problemDisplay) {
|
||||||
|
this.parameters = parameters;
|
||||||
|
this.problemDisplay = problemDisplay;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean parse(String line) {
|
||||||
|
Matcher matcher = pattern.matcher(line);
|
||||||
|
if (!matcher.matches()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String filePath = matcher.group(1);
|
||||||
|
if (parameters.getActualFilePath().equals(filePath)) {
|
||||||
|
int lineNumber = Integer.parseInt(matcher.group(2));
|
||||||
|
String severity = matcher.group(3);
|
||||||
|
String description = matcher.group(4);
|
||||||
|
IProblemLocation location = createProblemLocation(lineNumber);
|
||||||
|
problemDisplay.reportProblem(location, description, severity);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IProblemLocation createProblemLocation(int lineNumber) {
|
||||||
|
IProblemLocationFactory factory = CodanRuntime.getInstance().getProblemLocationFactory();
|
||||||
|
IFile actualFile = (IFile) parameters.getActualFile();
|
||||||
|
return factory.createProblemLocation(actualFile, -1, -1, lineNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reset() {}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,6 +12,7 @@ Bundle-ActivationPolicy: lazy
|
||||||
Export-Package: org.eclipse.cdt.codan.core.cxx,
|
Export-Package: org.eclipse.cdt.codan.core.cxx,
|
||||||
org.eclipse.cdt.codan.core.cxx.internal.model;x-friends:="org.eclipse.cdt.codan.checkers.ui,org.eclipse.cdt.codan.ui,org.eclipse.cdt.codan.ui.cxx",
|
org.eclipse.cdt.codan.core.cxx.internal.model;x-friends:="org.eclipse.cdt.codan.checkers.ui,org.eclipse.cdt.codan.ui,org.eclipse.cdt.codan.ui.cxx",
|
||||||
org.eclipse.cdt.codan.core.cxx.internal.model.cfg;x-friends:="org.eclipse.cdt.codan.core.test",
|
org.eclipse.cdt.codan.core.cxx.internal.model.cfg;x-friends:="org.eclipse.cdt.codan.core.test",
|
||||||
org.eclipse.cdt.codan.core.cxx.model
|
org.eclipse.cdt.codan.core.cxx.model,
|
||||||
|
org.eclipse.cdt.codan.core.cxx.util
|
||||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||||
Bundle-Vendor: %Bundle-Vendor
|
Bundle-Vendor: %Bundle-Vendor
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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.cxx.util;
|
||||||
|
|
||||||
|
import org.eclipse.core.resources.IFile;
|
||||||
|
import org.eclipse.core.resources.IResource;
|
||||||
|
import org.eclipse.core.runtime.IPath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility methods related to C++ file types.
|
||||||
|
*
|
||||||
|
* @author alruiz@google.com (Alex Ruiz)
|
||||||
|
*/
|
||||||
|
public final class FileTypes {
|
||||||
|
private static final String[] CPP_FILE_EXTENSIONS = {
|
||||||
|
"cc", //$NON-NLS-1$
|
||||||
|
"cpp", //$NON-NLS-1$
|
||||||
|
"cxx" //$NON-NLS-1$
|
||||||
|
};
|
||||||
|
private static final String[] HEADER_FILE_EXTENSIONS = { "h" }; //$NON-NLS-1$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether the given <code>{@link IResource}</code> is a C++ file.
|
||||||
|
* @param resource the {@code IResource} to check.
|
||||||
|
* @return {@code true} if the given {@code IResource} is a C++ file; {@code false} otherwise.
|
||||||
|
*/
|
||||||
|
public static boolean isCppFile(IResource resource) {
|
||||||
|
return isFileWithExtension(resource, CPP_FILE_EXTENSIONS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether the given <code>{@link IResource}</code> is a header file.
|
||||||
|
* @param resource the {@code IResource} to check.
|
||||||
|
* @return {@code true} if the given {@code IResource} is a header file; {@code false}
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
public static boolean isHeaderFile(IResource resource) {
|
||||||
|
return isFileWithExtension(resource, HEADER_FILE_EXTENSIONS);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isFileWithExtension(IResource resource, String[] validExtensions) {
|
||||||
|
if (!(resource instanceof IFile)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
IPath path = resource.getFullPath();
|
||||||
|
return doesPathHaveExtension(path, validExtensions);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean doesPathHaveExtension(IPath path, String[] validExtensions) {
|
||||||
|
String fileExtension = path.getFileExtension();
|
||||||
|
for (String extension : validExtensions) {
|
||||||
|
if (extension.equalsIgnoreCase(fileExtension)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private FileTypes() {}
|
||||||
|
}
|
|
@ -10,6 +10,7 @@ Require-Bundle: org.eclipse.core.runtime,
|
||||||
Bundle-ActivationPolicy: lazy
|
Bundle-ActivationPolicy: lazy
|
||||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||||
Export-Package: org.eclipse.cdt.codan.core,
|
Export-Package: org.eclipse.cdt.codan.core,
|
||||||
|
org.eclipse.cdt.codan.core.externaltool,
|
||||||
org.eclipse.cdt.codan.core.model,
|
org.eclipse.cdt.codan.core.model,
|
||||||
org.eclipse.cdt.codan.core.model.cfg;x-friends:="org.eclipse.cdt.codan.core.cxx,org.eclipse.cdt.codan.checkers",
|
org.eclipse.cdt.codan.core.model.cfg;x-friends:="org.eclipse.cdt.codan.core.cxx,org.eclipse.cdt.codan.checkers",
|
||||||
org.eclipse.cdt.codan.core.param,
|
org.eclipse.cdt.codan.core.param,
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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 static org.eclipse.cdt.codan.core.param.IProblemPreferenceDescriptor.PreferenceType.TYPE_STRING;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.codan.core.param.BasicProblemPreference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User-configurable setting that specifies the arguments to pass when invoking the external tool.
|
||||||
|
* The arguments are stored in a single {@code String}.
|
||||||
|
*
|
||||||
|
* @author alruiz@google.com (Alex Ruiz)
|
||||||
|
*/
|
||||||
|
public class ArgsSetting extends SingleConfigurationSetting<String> {
|
||||||
|
private static final String KEY = "externalToolArgs"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
* @param label the label to be displayed in the UI.
|
||||||
|
* @param defaultValue the default value of the setting.
|
||||||
|
*/
|
||||||
|
public ArgsSetting(String label, String defaultValue) {
|
||||||
|
super(new BasicProblemPreference(KEY, label, TYPE_STRING), defaultValue, String.class);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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 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 org.eclipse.cdt.codan.core.param.MapProblemPreference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User-configurable external tool settings.
|
||||||
|
*
|
||||||
|
* @author alruiz@google.com (Alex Ruiz)
|
||||||
|
*/
|
||||||
|
public class ConfigurationSettings {
|
||||||
|
private final PathSetting path;
|
||||||
|
private final ArgsSetting args;
|
||||||
|
private final ShouldDisplayOutputSetting shouldDisplayOutput;
|
||||||
|
private final String externalToolName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 defaultPath the default path of the external tool.
|
||||||
|
* @param defaultArgs the default arguments to pass when invoking the external tool.
|
||||||
|
*/
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
public ConfigurationSettings(String externalToolName, PathSetting path, ArgsSetting args,
|
||||||
|
ShouldDisplayOutputSetting shouldDisplayOutput) {
|
||||||
|
this.externalToolName = externalToolName;
|
||||||
|
this.path = path;
|
||||||
|
this.args = args;
|
||||||
|
this.shouldDisplayOutput = shouldDisplayOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the external tool, to be displayed to the user.
|
||||||
|
* @return the name of the external tool, to be displayed to the user.
|
||||||
|
*/
|
||||||
|
public String getExternalToolName() {
|
||||||
|
return externalToolName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
public PathSetting getPath() {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
public ArgsSetting getArgs() {
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the setting that specifies whether the output of the external tools should be
|
||||||
|
* displayed in an Eclipse console.
|
||||||
|
* @return the shouldDisplayOutput the setting that specifies whether the output of the external
|
||||||
|
* tools should be displayed in an Eclipse console.
|
||||||
|
*/
|
||||||
|
public ShouldDisplayOutputSetting getShouldDisplayOutput() {
|
||||||
|
return shouldDisplayOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the values of the configuration settings value with the ones stored in the given
|
||||||
|
* preference map.
|
||||||
|
* @param preferences the given preference map that may contain the values to set.
|
||||||
|
* @throws ClassCastException if any of the values to set is not of the same type as the one
|
||||||
|
* supported by a setting.
|
||||||
|
*/
|
||||||
|
public void updateValuesFrom(MapProblemPreference preferences) {
|
||||||
|
path.updateValue(preferences);
|
||||||
|
args.updateValue(preferences);
|
||||||
|
shouldDisplayOutput.updateValue(preferences);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses and separates the value of an <code>{@link ArgsSetting}</code> into an array of
|
||||||
|
* {@code String}s.
|
||||||
|
*
|
||||||
|
* @author alruiz@google.com (Alex Ruiz)
|
||||||
|
*/
|
||||||
|
public interface IArgsSeparator {
|
||||||
|
/**
|
||||||
|
* Indicates that there are no arguments to pass to the external tool executable.
|
||||||
|
*/
|
||||||
|
String[] NO_ARGS = new String[0];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses and separates the given value.
|
||||||
|
* @param args contains the arguments to pass to the external tool executable.
|
||||||
|
* @return the separated argument values.
|
||||||
|
*/
|
||||||
|
String[] separateArgs(String args);
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import org.eclipse.core.resources.IProject;
|
||||||
|
import org.eclipse.core.runtime.IPath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author alruiz@google.com (Alex Ruiz)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface ICommandInvoker {
|
||||||
|
/**
|
||||||
|
* Builds and launches the command necessary to invoke an external tool.
|
||||||
|
* @param project the current project.
|
||||||
|
* @param externalToolName the name of the external tool.
|
||||||
|
* @param executablePath the path and name of the external tool executable.
|
||||||
|
* @param args the arguments to pass to the external tool executable.
|
||||||
|
* @param workingDirectory the directory where the external tool should be executed.
|
||||||
|
* @param shouldDisplayOutput indicates whether the output of the external tools should be
|
||||||
|
* displayed in an Eclipse console.
|
||||||
|
* @param parsers parse the output of the external tool.
|
||||||
|
* @throws InvocationFailure if the external tool reports that it cannot be executed.
|
||||||
|
* @throws Throwable if the external tool cannot be launched.
|
||||||
|
*/
|
||||||
|
void buildAndLaunchCommand(IProject project, String externalToolName, IPath executablePath,
|
||||||
|
String[] args, IPath workingDirectory, boolean shouldDisplayOutput,
|
||||||
|
List<IOutputParser> parsers) throws InvocationFailure, Throwable;
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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 org.eclipse.core.resources.IResource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the parameters to pass when invoking an external tool.
|
||||||
|
*
|
||||||
|
* @author alruiz@google.com (Alex Ruiz)
|
||||||
|
*/
|
||||||
|
public interface IInvocationParametersProvider {
|
||||||
|
/**
|
||||||
|
* Creates the parameters to pass when invoking an external tool.
|
||||||
|
* @param fileToProcess the file to process.
|
||||||
|
* @return the created parameters.
|
||||||
|
* @throws Throwable if something goes wrong.
|
||||||
|
*/
|
||||||
|
InvocationParameters createParameters(IResource fileToProcess) throws Throwable;
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the output of an external tool.
|
||||||
|
*
|
||||||
|
* @author alruiz@google.com (Alex Ruiz)
|
||||||
|
*/
|
||||||
|
public interface IOutputParser {
|
||||||
|
/**
|
||||||
|
* Parses one line of output. Implementations are free to create markers from the information
|
||||||
|
* retrieved from the parsed output.
|
||||||
|
* @param line the line to parse.
|
||||||
|
* @return {@code true} if the line was successfully parsed; {@code false} otherwise.
|
||||||
|
* @throws InvocationFailure if the output indicates that the invocation of the external tool
|
||||||
|
* failed.
|
||||||
|
*/
|
||||||
|
boolean parse(String line) throws InvocationFailure;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the value of this parser, usually after the execution of the external tool is
|
||||||
|
* finished.
|
||||||
|
*/
|
||||||
|
void reset();
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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);
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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 org.eclipse.cdt.codan.core.model.IProblemLocation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reports problems found in code, reported by an external tool.
|
||||||
|
*
|
||||||
|
* @author alruiz@google.com (Alex Ruiz)
|
||||||
|
*/
|
||||||
|
public interface IProblemDisplay {
|
||||||
|
/**
|
||||||
|
* Reports a problem found by an external tool.
|
||||||
|
* @param location the problem's location (e.g. file and line number.)
|
||||||
|
* @param description the description of the problem.
|
||||||
|
*/
|
||||||
|
void reportProblem(IProblemLocation location, String description);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reports a problem found by an external tool.
|
||||||
|
* @param location the problem's location (e.g. file and line number.)
|
||||||
|
* @param description the description of the problem.
|
||||||
|
* @param severity the problem's severity (e.g. "error", "warning", etc.)
|
||||||
|
*/
|
||||||
|
void reportProblem(IProblemLocation location, String description, String severity);
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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 org.eclipse.core.resources.IFile;
|
||||||
|
import org.eclipse.core.resources.IResource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifies that a <code>{@link IResource}</code> can be processed by an external tool.
|
||||||
|
*
|
||||||
|
* @author alruiz@google.com (Alex Ruiz)
|
||||||
|
*/
|
||||||
|
public interface ISupportedResourceVerifier {
|
||||||
|
/**
|
||||||
|
* Indicates whether the external tool is capable of processing the given
|
||||||
|
* <code>{@link IResource}</code>.
|
||||||
|
* <p>
|
||||||
|
* The minimum requirements that the given {@code IResource} should satisfy are:
|
||||||
|
* <ul>
|
||||||
|
* <li>should be an <code>{@link IFile}</code></li>
|
||||||
|
* <li>should be displayed in the current active editor</li>
|
||||||
|
* <li>should not have any unsaved changes</li>
|
||||||
|
* </ul>
|
||||||
|
* </p>
|
||||||
|
* @param resource the given {@code IResource}.
|
||||||
|
* @return {@code true} if the external tool is capable of processing the given file,
|
||||||
|
* {@code false} otherwise.
|
||||||
|
*/
|
||||||
|
boolean isSupported(IResource resource);
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that invocation of an external tool failed.
|
||||||
|
*
|
||||||
|
* @author alruiz@google.com (Alex Ruiz)
|
||||||
|
*/
|
||||||
|
public class InvocationFailure extends Exception {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
* @param message the detail message.
|
||||||
|
*/
|
||||||
|
public InvocationFailure(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
* @param message the detail message.
|
||||||
|
* @param cause the cause (which is saved for later retrieval by the
|
||||||
|
* <code>{@link #getCause()}</code> method.)
|
||||||
|
*/
|
||||||
|
public InvocationFailure(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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 org.eclipse.core.resources.IResource;
|
||||||
|
import org.eclipse.core.runtime.IPath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameters to pass when invoking an external tool.
|
||||||
|
*
|
||||||
|
* @author alruiz@google.com (Alex Ruiz)
|
||||||
|
*/
|
||||||
|
public class InvocationParameters {
|
||||||
|
private final IResource originalFile;
|
||||||
|
private final IResource actualFile;
|
||||||
|
private final String actualFilePath;
|
||||||
|
private final IPath workingDirectory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
* @param originalFile the original file to process.
|
||||||
|
* @param actualFile the actual file to process.
|
||||||
|
* @param actualFilePath the path of {@code actual}, in a format that the external tool can
|
||||||
|
* understand.
|
||||||
|
* @param workingDirectory the directory where the external tool should be executed.
|
||||||
|
* @see #getOriginalFile()
|
||||||
|
* @see #getActualFile()
|
||||||
|
*/
|
||||||
|
public InvocationParameters(IResource originalFile, IResource actualFile, String actualFilePath,
|
||||||
|
IPath workingDirectory) {
|
||||||
|
this.originalFile = originalFile;
|
||||||
|
this.actualFile = actualFile;
|
||||||
|
this.actualFilePath = actualFilePath;
|
||||||
|
this.workingDirectory = workingDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the original file to process. This is the file that triggered execution of a
|
||||||
|
* command-line tool when saved.
|
||||||
|
* @return the original file to process.
|
||||||
|
*/
|
||||||
|
public IResource getOriginalFile() {
|
||||||
|
return originalFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the actual file to process. It may not be the same as
|
||||||
|
* <code>{@link #getActualFile()}</code>, depending on how the external tool works.
|
||||||
|
* <p>
|
||||||
|
* A good example is an external tool that can only process C++ files but header files. If the
|
||||||
|
* <em>original</em> file is a header file, the checker could potentially find a C++ file that
|
||||||
|
* includes such header and use it as the <em>actual</em> file to process.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* We still need to keep a reference to the <em>actual</em> file, in order to add markers to
|
||||||
|
* the editor in case of problems found.
|
||||||
|
* </p>
|
||||||
|
* @return the actual file to process.
|
||||||
|
*/
|
||||||
|
public IResource getActualFile() {
|
||||||
|
return actualFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the path of <code>{@link #getActualFile()}</code>, in a format the external tool can
|
||||||
|
* understand.
|
||||||
|
* @return the path of the <em>actual</em> file to process.
|
||||||
|
*/
|
||||||
|
public String getActualFilePath() {
|
||||||
|
return actualFilePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the directory where the external tool should be executed.
|
||||||
|
* @return the directory where the external tool should be executed.
|
||||||
|
*/
|
||||||
|
public IPath getWorkingDirectory() {
|
||||||
|
return workingDirectory;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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 org.eclipse.core.resources.IResource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default implementation of <code>{@link InvocationParameters}</code>
|
||||||
|
*
|
||||||
|
* @author alruiz@google.com (Alex Ruiz)
|
||||||
|
*/
|
||||||
|
public class InvocationParametersProvider implements IInvocationParametersProvider {
|
||||||
|
/**
|
||||||
|
* Creates the parameters to pass when invoking an external tool.
|
||||||
|
* <p>
|
||||||
|
* In this implementation:
|
||||||
|
* <ul>
|
||||||
|
* <li>the <em>actual</em> file to process is the same as the <em>original</em> file</li>
|
||||||
|
* <li>the path of the actual file is its absolute path in the file system</li>
|
||||||
|
* <li>the working directory is {@code null}</li>
|
||||||
|
* </ul>
|
||||||
|
* @param fileToProcess the file to process.
|
||||||
|
* @return the created parameters.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public InvocationParameters createParameters(IResource fileToProcess) {
|
||||||
|
String path = fileToProcess.getLocation().toOSString();
|
||||||
|
return new InvocationParameters(fileToProcess, fileToProcess, path, null);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.core.externaltool;
|
||||||
|
|
||||||
|
import org.eclipse.osgi.util.NLS;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author alruiz@google.com (Alex Ruiz)
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("javadoc")
|
||||||
|
public class Messages extends NLS {
|
||||||
|
public static String ConfigurationSettings_args_format;
|
||||||
|
public static String ConfigurationSettings_path_format;
|
||||||
|
public static String ConfigurationSettings_should_display_output;
|
||||||
|
|
||||||
|
static {
|
||||||
|
Class<Messages> clazz = Messages.class;
|
||||||
|
NLS.initializeMessages(clazz.getName(), clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Messages() {}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
ConfigurationSettings_args_format=%s Args:
|
||||||
|
ConfigurationSettings_path_format=%s Path:
|
||||||
|
ConfigurationSettings_should_display_output=Display Output in Console
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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 static org.eclipse.cdt.codan.core.param.IProblemPreferenceDescriptor.PreferenceType.TYPE_FILE;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.codan.core.param.BasicProblemPreference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User-configurable setting that specifies the path and name of an external tool's executable.
|
||||||
|
*
|
||||||
|
* @author alruiz@google.com (Alex Ruiz)
|
||||||
|
*/
|
||||||
|
public class PathSetting extends SingleConfigurationSetting<File> {
|
||||||
|
private static final String KEY = "externalToolPath"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
* @param label the label to be displayed in the UI.
|
||||||
|
* @param defaultValue the default value of the setting.
|
||||||
|
*/
|
||||||
|
public PathSetting(String label, File defaultValue) {
|
||||||
|
super(new BasicProblemPreference(KEY, label, TYPE_FILE), defaultValue, File.class);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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 static org.eclipse.cdt.codan.core.param.IProblemPreferenceDescriptor.PreferenceType.TYPE_BOOLEAN;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.codan.core.param.BasicProblemPreference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User-configurable setting that specifies whether the output of an external tool should be
|
||||||
|
* displayed in an Eclipse console.
|
||||||
|
*
|
||||||
|
* @author alruiz@google.com (Alex Ruiz)
|
||||||
|
*/
|
||||||
|
public class ShouldDisplayOutputSetting extends SingleConfigurationSetting<Boolean> {
|
||||||
|
private static final String KEY = "externalToolShouldDisplayOutput"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
* @param label the label to be displayed in the UI.
|
||||||
|
* @param defaultValue the default value of the setting.
|
||||||
|
*/
|
||||||
|
public ShouldDisplayOutputSetting(String label, boolean defaultValue) {
|
||||||
|
super(new BasicProblemPreference(KEY, label, TYPE_BOOLEAN), defaultValue, Boolean.class);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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 org.eclipse.cdt.codan.core.param.IProblemPreferenceDescriptor;
|
||||||
|
import org.eclipse.cdt.codan.core.param.MapProblemPreference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Single external tool configuration setting.
|
||||||
|
* @param <T> the type of the value this setting stores.
|
||||||
|
*
|
||||||
|
* @author alruiz@google.com (Alex Ruiz)
|
||||||
|
*/
|
||||||
|
public class SingleConfigurationSetting<T> {
|
||||||
|
private final IProblemPreferenceDescriptor descriptor;
|
||||||
|
private final T defaultValue;
|
||||||
|
private final Class<T> valueType;
|
||||||
|
|
||||||
|
private T value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
* @param descriptor meta-data that tells the UI how to display this setting.
|
||||||
|
* @param defaultValue the setting's default value.
|
||||||
|
* @param valueType the type of the value to store (used for safe casting.)
|
||||||
|
*/
|
||||||
|
public SingleConfigurationSetting(IProblemPreferenceDescriptor descriptor, T defaultValue,
|
||||||
|
Class<T> valueType) {
|
||||||
|
this.descriptor = descriptor;
|
||||||
|
this.defaultValue = defaultValue;
|
||||||
|
this.valueType = valueType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns this setting's value.
|
||||||
|
* @return this setting's value.
|
||||||
|
*/
|
||||||
|
public T getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the meta-data that tells the UI how to display this setting.
|
||||||
|
* @return the meta-data that tells the UI how to display this setting.
|
||||||
|
*/
|
||||||
|
public IProblemPreferenceDescriptor getDescriptor() {
|
||||||
|
return descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns this setting's default value.
|
||||||
|
* @return this setting's default value.
|
||||||
|
*/
|
||||||
|
public T getDefaultValue() {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates this setting's value with the one stored in the given preference map.
|
||||||
|
* @param preferences the given preference map that may contain the value to set.
|
||||||
|
* @throws ClassCastException if the value to set is not of the same type as the one supported
|
||||||
|
* by this setting.
|
||||||
|
*/
|
||||||
|
public void updateValue(MapProblemPreference preferences) {
|
||||||
|
Object o = preferences.getChildValue(descriptor.getKey());
|
||||||
|
value = valueType.cast(o);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Separates the value of an <code>{@link ArgsSetting}</code> using an empty space as delimiter.
|
||||||
|
*
|
||||||
|
* @author alruiz@google.com (Alex Ruiz)
|
||||||
|
*/
|
||||||
|
public class SpaceDelimitedArgsSeparator implements IArgsSeparator {
|
||||||
|
private static final Pattern EMPTY_SPACE_PATTERN = Pattern.compile("\\s+"); //$NON-NLS-1$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String[] separateArgs(String args) {
|
||||||
|
if (args == null || args.isEmpty()) {
|
||||||
|
return NO_ARGS;
|
||||||
|
}
|
||||||
|
return EMPTY_SPACE_PATTERN.split(args);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,209 @@
|
||||||
|
// Copyright 2012 Google Inc. All Rights Reserved.
|
||||||
|
|
||||||
|
package org.eclipse.cdt.codan.core.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.codan.core.CodanCorePlugin;
|
||||||
|
import org.eclipse.cdt.codan.core.externaltool.ConfigurationSettings;
|
||||||
|
import org.eclipse.cdt.codan.core.externaltool.IArgsSeparator;
|
||||||
|
import org.eclipse.cdt.codan.core.externaltool.ICommandInvoker;
|
||||||
|
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.ISupportedResourceVerifier;
|
||||||
|
import org.eclipse.cdt.codan.core.externaltool.InvocationFailure;
|
||||||
|
import org.eclipse.cdt.codan.core.externaltool.InvocationParameters;
|
||||||
|
import org.eclipse.cdt.codan.core.externaltool.SingleConfigurationSetting;
|
||||||
|
import org.eclipse.cdt.codan.core.param.IProblemPreference;
|
||||||
|
import org.eclipse.cdt.codan.core.param.MapProblemPreference;
|
||||||
|
import org.eclipse.cdt.codan.core.param.RootProblemPreference;
|
||||||
|
import org.eclipse.cdt.codan.core.param.SharedRootProblemPreference;
|
||||||
|
import org.eclipse.cdt.codan.internal.core.externaltool.ExternalToolInvoker;
|
||||||
|
import org.eclipse.core.resources.IResource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for checkers that invoke external command-line tools to perform code checking.
|
||||||
|
* <p>
|
||||||
|
* A file, to be processed by this type of checker, must:
|
||||||
|
* <ol>
|
||||||
|
* <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 enable to run while the user types, since
|
||||||
|
* external tools cannot see unsaved changes.
|
||||||
|
*
|
||||||
|
* @author alruiz@google.com (Alex Ruiz)
|
||||||
|
*/
|
||||||
|
public abstract class AbstractExternalToolBasedChecker extends AbstractCheckerWithProblemPreferences
|
||||||
|
implements IProblemDisplay {
|
||||||
|
private static final boolean DO_NOT_TRAVERSE_CHILDREN = false;
|
||||||
|
|
||||||
|
private final IInvocationParametersProvider parametersProvider;
|
||||||
|
private final ISupportedResourceVerifier supportedResourceVerifier;
|
||||||
|
private final IArgsSeparator argsSeparator;
|
||||||
|
private final IOutputParserFactory outputParserFactory;
|
||||||
|
private final ConfigurationSettings configurationSettings;
|
||||||
|
private final ExternalToolInvoker externalToolInvoker;
|
||||||
|
private final RootProblemPreference preferences;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 commandInvoker 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.
|
||||||
|
*/
|
||||||
|
public AbstractExternalToolBasedChecker(IInvocationParametersProvider parametersProvider,
|
||||||
|
ISupportedResourceVerifier supportedResourceVerifier, IArgsSeparator argsSeparator,
|
||||||
|
ICommandInvoker commandInvoker, IOutputParserFactory outputParserFactory,
|
||||||
|
ConfigurationSettings configurationSettings) {
|
||||||
|
this.parametersProvider = parametersProvider;
|
||||||
|
this.supportedResourceVerifier = supportedResourceVerifier;
|
||||||
|
this.argsSeparator = argsSeparator;
|
||||||
|
this.outputParserFactory = outputParserFactory;
|
||||||
|
this.configurationSettings = configurationSettings;
|
||||||
|
externalToolInvoker = new ExternalToolInvoker(commandInvoker);
|
||||||
|
preferences = new SharedRootProblemPreference();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether this checker can process the given resource. For more details, please
|
||||||
|
* see <code>{@link ISupportedResourceVerifier#isSupported(IResource)}</code>.
|
||||||
|
* @param resource the given resource.
|
||||||
|
* @return {@code true} if this checker can process the given resource, {@code false} otherwise.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean enabledInContext(IResource resource) {
|
||||||
|
return supportedResourceVerifier.isSupported(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether this checker is enabled to run while the user types. By default, this
|
||||||
|
* method returns {@code false}.
|
||||||
|
* <p>
|
||||||
|
* Running command-line based checkers while the user types is unnecessary and wasteful, since
|
||||||
|
* command-line tools are expensive to call (they run in a separate process) and they cannot
|
||||||
|
* see unsaved changes.
|
||||||
|
* </p>
|
||||||
|
* @return {@code false}.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean runInEditor() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean processResource(IResource resource) {
|
||||||
|
process(resource);
|
||||||
|
return DO_NOT_TRAVERSE_CHILDREN;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void process(IResource resource) {
|
||||||
|
try {
|
||||||
|
InvocationParameters parameters = parametersProvider.createParameters(resource);
|
||||||
|
if (parameters != null) {
|
||||||
|
invokeExternalTool(parameters);
|
||||||
|
}
|
||||||
|
} catch (Throwable error) {
|
||||||
|
logResourceProcessingFailure(error, resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void invokeExternalTool(InvocationParameters parameters) throws Throwable {
|
||||||
|
updateConfigurationSettingsFromPreferences(parameters.getActualFile());
|
||||||
|
List<IOutputParser> parsers = outputParserFactory.createParsers(parameters, this);
|
||||||
|
try {
|
||||||
|
externalToolInvoker.invoke(parameters, configurationSettings, argsSeparator, parsers);
|
||||||
|
} catch (InvocationFailure error) {
|
||||||
|
handleInvocationFailure(error, parameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateConfigurationSettingsFromPreferences(IResource fileToProcess) {
|
||||||
|
IProblem problem = getProblemById(getReferenceProblemId(), fileToProcess);
|
||||||
|
MapProblemPreference preferences = (MapProblemPreference) problem.getPreference();
|
||||||
|
configurationSettings.updateValuesFrom(preferences);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles a failure reported when invoking the external tool. This implementation simply
|
||||||
|
* logs the failure.
|
||||||
|
* @param error the reported failure.
|
||||||
|
* @param parameters the parameters passed to the external tool executable.
|
||||||
|
*/
|
||||||
|
protected void handleInvocationFailure(InvocationFailure error, InvocationParameters parameters) {
|
||||||
|
logResourceProcessingFailure(error, parameters.getActualFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logResourceProcessingFailure(Throwable error, IResource resource) {
|
||||||
|
String location = resource.getLocation().toOSString();
|
||||||
|
String msg = String.format("Unable to process resource %s", location); //$NON-NLS-1$
|
||||||
|
CodanCorePlugin.log(msg, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public void reportProblem(IProblemLocation location, String description) {
|
||||||
|
String severity = null;
|
||||||
|
reportProblem(location, description, severity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public void reportProblem(IProblemLocation location, String description, String severity) {
|
||||||
|
super.reportProblem(getReferenceProblemId(), location, description);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the id of the problem used as reference to obtain this checker's preferences. All
|
||||||
|
* preferences in a external-tool-based checker are shared among its defined problems.
|
||||||
|
* @return the id of the problem used as reference to obtain this checker's preferences.
|
||||||
|
*/
|
||||||
|
protected abstract String getReferenceProblemId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the preferences of the given problem. All preferences in a external-tool-based
|
||||||
|
* checker are shared among its defined problems.
|
||||||
|
* @param problem the given problem.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void initPreferences(IProblemWorkingCopy problem) {
|
||||||
|
super.initPreferences(problem);
|
||||||
|
addPreference(problem, configurationSettings.getPath());
|
||||||
|
addPreference(problem, configurationSettings.getArgs());
|
||||||
|
addPreference(problem, configurationSettings.getShouldDisplayOutput());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addPreference(IProblemWorkingCopy problem, SingleConfigurationSetting<?> setting) {
|
||||||
|
IProblemPreference descriptor = (IProblemPreference) setting.getDescriptor();
|
||||||
|
addPreference(problem, descriptor, setting.getDefaultValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
protected void setDefaultPreferenceValue(IProblemWorkingCopy problem, String key,
|
||||||
|
Object defaultValue) {
|
||||||
|
MapProblemPreference map = getTopLevelPreference(problem);
|
||||||
|
map.setChildValue(key, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public RootProblemPreference getTopLevelPreference(IProblem problem) {
|
||||||
|
RootProblemPreference map = (RootProblemPreference) problem.getPreference();
|
||||||
|
if (map == null) {
|
||||||
|
map = preferences;
|
||||||
|
if (problem instanceof IProblemWorkingCopy) {
|
||||||
|
((IProblemWorkingCopy) problem).setPreference(map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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.param;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Preferences that can be shared among several problems.
|
||||||
|
*
|
||||||
|
* @author alruiz@google.com (Alex Ruiz)
|
||||||
|
*/
|
||||||
|
public class SharedRootProblemPreference extends RootProblemPreference {
|
||||||
|
@Override
|
||||||
|
public Object clone() {
|
||||||
|
SharedRootProblemPreference map = (SharedRootProblemPreference) super.clone();
|
||||||
|
// alruiz: sharing the internal hash is the only way I could make this work.
|
||||||
|
map.hash = hash;
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,102 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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 java.io.File;
|
||||||
|
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.ICommandInvoker;
|
||||||
|
import org.eclipse.cdt.codan.core.externaltool.IOutputParser;
|
||||||
|
import org.eclipse.cdt.codan.core.externaltool.InvocationFailure;
|
||||||
|
import org.eclipse.cdt.codan.core.externaltool.InvocationParameters;
|
||||||
|
import org.eclipse.core.resources.IProject;
|
||||||
|
import org.eclipse.core.runtime.IPath;
|
||||||
|
import org.eclipse.core.runtime.Path;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invokes an external tool to perform checks on a single file.
|
||||||
|
*
|
||||||
|
* @author alruiz@google.com (Alex Ruiz)
|
||||||
|
*/
|
||||||
|
public class ExternalToolInvoker {
|
||||||
|
private final ICommandInvoker commandInvoker;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
* @param commandInvoker builds and launches the command necessary to invoke the external tool.
|
||||||
|
*/
|
||||||
|
public ExternalToolInvoker(ICommandInvoker commandInvoker) {
|
||||||
|
this.commandInvoker = commandInvoker;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invokes an external tool.
|
||||||
|
* @param parameters the parameters to pass to the external tool executable.
|
||||||
|
* @param configurationSettings user-configurable settings.
|
||||||
|
* @param argsSeparator separates the arguments to pass to the external tool executable. These
|
||||||
|
* arguments are stored in a single {@code String}.
|
||||||
|
* @param parsers parse the output of the external tool.
|
||||||
|
* @throws InvocationFailure if the external tool reports that it cannot be executed.
|
||||||
|
* @throws Throwable if the external tool cannot be launched.
|
||||||
|
*/
|
||||||
|
public void invoke(InvocationParameters parameters, ConfigurationSettings configurationSettings,
|
||||||
|
IArgsSeparator argsSeparator, List<IOutputParser> parsers) throws InvocationFailure,
|
||||||
|
Throwable {
|
||||||
|
IPath executablePath = executablePath(configurationSettings);
|
||||||
|
String[] args = argsToPass(parameters, configurationSettings, argsSeparator);
|
||||||
|
boolean shouldDisplayOutput = configurationSettings.getShouldDisplayOutput().getValue();
|
||||||
|
IProject project = parameters.getActualFile().getProject();
|
||||||
|
try {
|
||||||
|
commandInvoker.buildAndLaunchCommand(project,
|
||||||
|
configurationSettings.getExternalToolName(), executablePath, args,
|
||||||
|
parameters.getWorkingDirectory(), shouldDisplayOutput, parsers);
|
||||||
|
} finally {
|
||||||
|
reset(parsers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IPath executablePath(ConfigurationSettings configurationSettings) {
|
||||||
|
File executablePath = configurationSettings.getPath().getValue();
|
||||||
|
return new Path(executablePath.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String[] argsToPass(InvocationParameters parameters,
|
||||||
|
ConfigurationSettings configurationSettings, IArgsSeparator argsSeparator) {
|
||||||
|
String[] configuredArgs = configuredArgs(configurationSettings, argsSeparator);
|
||||||
|
String actualFilePath = parameters.getActualFilePath();
|
||||||
|
return addFilePathToArgs(actualFilePath, configuredArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String[] configuredArgs(ConfigurationSettings configurationSettings,
|
||||||
|
IArgsSeparator argsSeparator) {
|
||||||
|
String args = configurationSettings.getArgs().getValue();
|
||||||
|
return argsSeparator.separateArgs(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String[] addFilePathToArgs(String actualFilePath, String[] configuredArgs) {
|
||||||
|
int argCount = configuredArgs.length;
|
||||||
|
String[] allArgs = new String[argCount + 1];
|
||||||
|
// add file to process as the first argument
|
||||||
|
allArgs[0] = actualFilePath;
|
||||||
|
for (int i = 0; i < argCount; i++) {
|
||||||
|
allArgs[i + 1] = configuredArgs[i];
|
||||||
|
}
|
||||||
|
return allArgs;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void reset(List<IOutputParser> parsers) {
|
||||||
|
for (IOutputParser parser : parsers) {
|
||||||
|
parser.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,4 +19,5 @@ Require-Bundle: org.eclipse.ui,
|
||||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||||
Bundle-ActivationPolicy: lazy
|
Bundle-ActivationPolicy: lazy
|
||||||
Export-Package: org.eclipse.cdt.codan.internal.ui.cxx;x-internal:=true,
|
Export-Package: org.eclipse.cdt.codan.internal.ui.cxx;x-internal:=true,
|
||||||
org.eclipse.cdt.codan.ui
|
org.eclipse.cdt.codan.ui,
|
||||||
|
org.eclipse.cdt.codan.ui.cxx.externaltool
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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.internal.ui.editor.CEditor;
|
||||||
|
import org.eclipse.ui.IEditorPart;
|
||||||
|
import org.eclipse.ui.IWorkbench;
|
||||||
|
import org.eclipse.ui.IWorkbenchPage;
|
||||||
|
import org.eclipse.ui.IWorkbenchWindow;
|
||||||
|
import org.eclipse.ui.PlatformUI;
|
||||||
|
import org.eclipse.ui.editors.text.TextEditor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility methods related to <code>{@link CEditor}</code>.
|
||||||
|
*
|
||||||
|
* @author alruiz@google.com (Alex Ruiz)
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("restriction") // CEditor is internal API
|
||||||
|
final class CEditors {
|
||||||
|
|
||||||
|
static TextEditor activeCEditor() {
|
||||||
|
IWorkbench workbench = PlatformUI.getWorkbench();
|
||||||
|
for (IWorkbenchWindow w : workbench.getWorkbenchWindows()) {
|
||||||
|
IWorkbenchPage activePage = w.getActivePage();
|
||||||
|
IEditorPart editor = activePage.getActiveEditor();
|
||||||
|
if (editor instanceof CEditor) {
|
||||||
|
return (CEditor) editor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CEditors() {}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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 static org.eclipse.cdt.codan.core.cxx.util.FileTypes.isCppFile;
|
||||||
|
import static org.eclipse.cdt.codan.core.cxx.util.FileTypes.isHeaderFile;
|
||||||
|
import static org.eclipse.cdt.codan.ui.CodanEditorUtility.isResourceOpenInEditor;
|
||||||
|
import static org.eclipse.cdt.codan.ui.cxx.externaltool.CEditors.activeCEditor;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.codan.core.externaltool.ISupportedResourceVerifier;
|
||||||
|
import org.eclipse.core.resources.IResource;
|
||||||
|
import org.eclipse.ui.editors.text.TextEditor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implemenation of <code>{@link ISupportedResourceVerifier}</code> for C/C++ files.
|
||||||
|
*
|
||||||
|
* @author alruiz@google.com (Alex Ruiz)
|
||||||
|
*/
|
||||||
|
public class CxxSupportedResourceVerifier implements ISupportedResourceVerifier {
|
||||||
|
/**
|
||||||
|
* Indicates whether the external tool is capable of processing the given
|
||||||
|
* <code>{@link IResource}</code>.
|
||||||
|
* <p>
|
||||||
|
* The minimum requirements that the given {@code IResource} should satisfy are:
|
||||||
|
* <ul>
|
||||||
|
* <li>should be C/C++ file</li>
|
||||||
|
* <li>should be displayed in the current active {@code CEditor}</li>
|
||||||
|
* <li>should not have any unsaved changes</li>
|
||||||
|
* </ul>
|
||||||
|
* </p>
|
||||||
|
* @param resource the given {@code IResource}.
|
||||||
|
* @return {@code true} if the external tool is capable of processing the given file,
|
||||||
|
* {@code false} otherwise.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isSupported(IResource resource) {
|
||||||
|
return isFileOfSupportedType(resource) && isOpenInActiveCEditor(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isFileOfSupportedType(IResource resource) {
|
||||||
|
return isCppFile(resource) || isHeaderFile(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isOpenInActiveCEditor(IResource resource) {
|
||||||
|
TextEditor activeCEditor = activeCEditor();
|
||||||
|
if (activeCEditor == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return !activeCEditor.isDirty() && isResourceOpenInEditor(resource, activeCEditor);
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,7 +13,8 @@ Require-Bundle: org.eclipse.ui,
|
||||||
org.eclipse.jface.text,
|
org.eclipse.jface.text,
|
||||||
org.eclipse.ui.ide,
|
org.eclipse.ui.ide,
|
||||||
org.eclipse.cdt.ui,
|
org.eclipse.cdt.ui,
|
||||||
org.eclipse.core.filesystem
|
org.eclipse.core.filesystem,
|
||||||
|
org.eclipse.ui.console;bundle-version="3.5.100"
|
||||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||||
Bundle-ActivationPolicy: lazy
|
Bundle-ActivationPolicy: lazy
|
||||||
Export-Package: org.eclipse.cdt.codan.internal.ui;x-friends:="org.eclipse.cdt.codan.ui.cxx",
|
Export-Package: org.eclipse.cdt.codan.internal.ui;x-friends:="org.eclipse.cdt.codan.ui.cxx",
|
||||||
|
@ -23,5 +24,6 @@ Export-Package: org.eclipse.cdt.codan.internal.ui;x-friends:="org.eclipse.cdt.co
|
||||||
org.eclipse.cdt.codan.internal.ui.views;x-internal:=true,
|
org.eclipse.cdt.codan.internal.ui.views;x-internal:=true,
|
||||||
org.eclipse.cdt.codan.internal.ui.widgets;x-internal:=true,
|
org.eclipse.cdt.codan.internal.ui.widgets;x-internal:=true,
|
||||||
org.eclipse.cdt.codan.ui,
|
org.eclipse.cdt.codan.ui,
|
||||||
|
org.eclipse.cdt.codan.ui.externaltool,
|
||||||
org.eclipse.cdt.codan.ui.handlers
|
org.eclipse.cdt.codan.ui.handlers
|
||||||
|
|
||||||
|
|
|
@ -83,7 +83,7 @@ public class CodanUIActivator extends AbstractUIPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs an internal error with the specified throwable
|
* Logs an internal error with the specified {@code Throwable}.
|
||||||
*
|
*
|
||||||
* @param e
|
* @param e
|
||||||
* the exception to be logged
|
* the exception to be logged
|
||||||
|
@ -102,6 +102,18 @@ public class CodanUIActivator extends AbstractUIPlugin {
|
||||||
log(new Status(IStatus.ERROR, PLUGIN_ID, 1, message, null));
|
log(new Status(IStatus.ERROR, PLUGIN_ID, 1, message, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs an internal error with the specified message and {@code Throwable}.
|
||||||
|
*
|
||||||
|
* @param message
|
||||||
|
* the error message to log
|
||||||
|
* @param e
|
||||||
|
* the exception to be logged
|
||||||
|
*/
|
||||||
|
public static void log(String message, Throwable e) {
|
||||||
|
log(new Status(IStatus.ERROR, PLUGIN_ID, 1, message, e));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -158,9 +158,10 @@ public class CodanEditorUtility {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return
|
* Returns the active workbench page.
|
||||||
|
* @return the active workbench page, or {@code null} if none can be found.
|
||||||
*/
|
*/
|
||||||
private static IWorkbenchPage getActivePage() {
|
public static IWorkbenchPage getActivePage() {
|
||||||
IWorkbenchWindow activeWorkbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
|
IWorkbenchWindow activeWorkbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
|
||||||
if (activeWorkbenchWindow == null)
|
if (activeWorkbenchWindow == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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 java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.codan.core.externaltool.ICommandInvoker;
|
||||||
|
import org.eclipse.cdt.codan.core.externaltool.IOutputParser;
|
||||||
|
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.runtime.IPath;
|
||||||
|
import org.eclipse.ui.PartInitException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invokes an external tool command.
|
||||||
|
*
|
||||||
|
* @author alruiz@google.com (Alex Ruiz)
|
||||||
|
*/
|
||||||
|
public class CommandInvoker implements ICommandInvoker {
|
||||||
|
private static final String[] ENVIRONMENT_VARIABLE_SETTINGS = {};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void buildAndLaunchCommand(IProject project, String externalToolName,
|
||||||
|
IPath executablePath, String[] args, IPath workingDirectory, boolean shouldDisplayOutput,
|
||||||
|
List<IOutputParser> parsers) throws InvocationFailure, Throwable {
|
||||||
|
ConsolePrinter consolePrinter = consolePrinter(externalToolName, shouldDisplayOutput);
|
||||||
|
String command = buildCommand(executablePath, args);
|
||||||
|
Process process = null;
|
||||||
|
try {
|
||||||
|
consolePrinter.clear();
|
||||||
|
consolePrinter.println(command);
|
||||||
|
consolePrinter.println();
|
||||||
|
try {
|
||||||
|
process = invoke(command, workingDirectory);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new InvocationFailure("Unable to start " + externalToolName, e); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
processStream(process.getInputStream(), parsers, consolePrinter);
|
||||||
|
processStream(process.getErrorStream(), parsers, consolePrinter);
|
||||||
|
} finally {
|
||||||
|
if (process != null) {
|
||||||
|
process.destroy();
|
||||||
|
}
|
||||||
|
consolePrinter.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConsolePrinter consolePrinter(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildCommand(IPath executablePath, String[] args) {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append(executablePath.toOSString());
|
||||||
|
for (String arg : args) {
|
||||||
|
builder.append(" ").append(arg); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Process invoke(String command, IPath workingDirectory) throws IOException {
|
||||||
|
Runtime runtime = Runtime.getRuntime();
|
||||||
|
if (workingDirectory == null) {
|
||||||
|
return runtime.exec(command);
|
||||||
|
}
|
||||||
|
return runtime.exec(command, ENVIRONMENT_VARIABLE_SETTINGS, workingDirectory.toFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processStream(InputStream inputStream, List<IOutputParser> parsers,
|
||||||
|
ConsolePrinter consolePrinter) throws IOException, InvocationFailure {
|
||||||
|
Reader reader = null;
|
||||||
|
try {
|
||||||
|
reader = new InputStreamReader(inputStream);
|
||||||
|
BufferedReader bufferedReader = new BufferedReader(reader);
|
||||||
|
String line = null;
|
||||||
|
while ((line = bufferedReader.readLine()) != null) {
|
||||||
|
consolePrinter.println(line);
|
||||||
|
for (IOutputParser parser : parsers) {
|
||||||
|
if (parser.parse(line)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (reader != null) {
|
||||||
|
try {
|
||||||
|
reader.close();
|
||||||
|
} catch (IOException ignored) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints the output of an external tool to an Eclipse console. It uses the name of the external
|
||||||
|
* tool as the console ID.
|
||||||
|
*
|
||||||
|
* @author alruiz@google.com (Alex Ruiz)
|
||||||
|
*/
|
||||||
|
interface ConsolePrinter {
|
||||||
|
ConsolePrinter NullImpl = new ConsolePrinter() {
|
||||||
|
@Override
|
||||||
|
public void clear() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void println(String message) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void println() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the contents of the console.
|
||||||
|
*/
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints the specified message to the console, followed by a line separator string.
|
||||||
|
* @param message the message to print.
|
||||||
|
*/
|
||||||
|
void println(String message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints a line separator to the console.
|
||||||
|
*/
|
||||||
|
void println();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the output stream of the console.
|
||||||
|
*/
|
||||||
|
void close();
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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 static org.eclipse.ui.console.IConsoleConstants.ID_CONSOLE_VIEW;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.codan.ui.CodanEditorUtility;
|
||||||
|
import org.eclipse.ui.IWorkbenchPage;
|
||||||
|
import org.eclipse.ui.PartInitException;
|
||||||
|
import org.eclipse.ui.console.ConsolePlugin;
|
||||||
|
import org.eclipse.ui.console.IConsole;
|
||||||
|
import org.eclipse.ui.console.IConsoleManager;
|
||||||
|
import org.eclipse.ui.console.IConsoleView;
|
||||||
|
import org.eclipse.ui.console.MessageConsole;
|
||||||
|
import org.eclipse.ui.console.MessageConsoleStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default implementation of <code>{@link ConsolePrinter}</code>.
|
||||||
|
*
|
||||||
|
* @author alruiz@google.com (Alex Ruiz)
|
||||||
|
*/
|
||||||
|
class ConsolePrinterImpl implements ConsolePrinter {
|
||||||
|
private final MessageConsole console;
|
||||||
|
private final MessageConsoleStream out;
|
||||||
|
|
||||||
|
static ConsolePrinter createOrFindConsole(String externalToolName)
|
||||||
|
throws PartInitException {
|
||||||
|
MessageConsole console = findConsole(externalToolName);
|
||||||
|
IWorkbenchPage page = CodanEditorUtility.getActivePage();
|
||||||
|
if (page != null) {
|
||||||
|
IConsoleView view = (IConsoleView) page.showView(ID_CONSOLE_VIEW);
|
||||||
|
view.display(console);
|
||||||
|
}
|
||||||
|
return new ConsolePrinterImpl(console);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MessageConsole findConsole(String externalToolName) {
|
||||||
|
IConsoleManager consoleManager = ConsolePlugin.getDefault().getConsoleManager();
|
||||||
|
for (IConsole console : consoleManager.getConsoles()) {
|
||||||
|
if (externalToolName.equals(console.getName()) && console instanceof MessageConsole) {
|
||||||
|
return (MessageConsole) console;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MessageConsole console = new MessageConsole(externalToolName, null);
|
||||||
|
consoleManager.addConsoles(new IConsole[] { console });
|
||||||
|
return console;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConsolePrinterImpl(MessageConsole console) {
|
||||||
|
this.console = console;
|
||||||
|
out = console.newMessageStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
console.clearConsole();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void println(String s) {
|
||||||
|
out.println(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void println() {
|
||||||
|
out.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() {
|
||||||
|
try {
|
||||||
|
out.close();
|
||||||
|
} catch (IOException ignored) {}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue