Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package org.codechecker.eclipse.plugin.codechecker;

import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

import org.codechecker.eclipse.plugin.codechecker.locator.InvalidCodeCheckerException;
import org.codechecker.eclipse.plugin.config.CcConfigurationBase;
import org.codechecker.eclipse.plugin.config.Config.ConfigTypes;
import org.codechecker.eclipse.plugin.runtime.LogI;
import org.codechecker.eclipse.plugin.runtime.SLogger;
import org.codechecker.eclipse.plugin.runtime.ShellExecutorHelper;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.annotation.NonNull;

import com.google.common.base.Optional;

/**
* Internal representation of a CodeChecker package.
*/
public class CodeChecker implements ICodeChecker {

private static final String LOCATION_KEY = "location";
private static final String RESULTS_KEY = "results";
private static final String LOGFILE_KEY = "logFile";
private static final String LOCATION_SUB = "${location}";
private static final String RESULTS_SUB = "${results}";
private static final String LOGFILE_SUB = "${logFile}";

private static final String RESULTS_FOLDER = RESULTS_KEY;

private Path location;
private ShellExecutorHelper she;
private Map<String, File> subMap;

/**
*
* @param path
* Path to the binary itself.
* @param she
* The ShellExecutor to be used.
*
* @throws InvalidCodeCheckerException
* Thrown when no CodeChecker found.
*/
public CodeChecker(Path path, ShellExecutorHelper she) throws InvalidCodeCheckerException {
location = path;
this.she = she;
subMap = new HashMap<String, File>();
subMap.put(LOCATION_KEY, path.toAbsolutePath().toFile());
getVersion();
}

@Override
@NonNull
public String getCheckers() {
String cmd = LOCATION_SUB + " checkers";
Optional<String> ccOutput = she.waitReturnOutput(cmd, subMap, false);
return ccOutput.or("No Checkers found");
}

@Override
@NonNull
public String getVersion() throws InvalidCodeCheckerException {
String cmd = LOCATION_SUB + " version";
Optional<String> ccOutput = she.waitReturnOutput(cmd, subMap, false);
if (!ccOutput.isPresent() || ccOutput.get().isEmpty())
throw new InvalidCodeCheckerException("Couldn't run CodeChecker version!");
return ccOutput.get();
}

@Override
public Path getLocation() {
return location;
}

@Override
public String analyze(Path logFile, boolean logToConsole, IProgressMonitor monitor, int taskCount,
CcConfigurationBase config) {

subMap.put(RESULTS_KEY, logFile.getParent().toAbsolutePath().resolve(Paths.get(RESULTS_FOLDER)).toFile());
subMap.put(LOGFILE_KEY, logFile.toAbsolutePath().toFile());
String cmd = LOCATION_SUB + " analyze " + config.get(ConfigTypes.CHECKER_LIST) + " -j "
+ config.get(ConfigTypes.ANAL_THREADS) + " -n javarunner" + " -o "
+ RESULTS_SUB + " " + LOGFILE_SUB;

SLogger.log(LogI.INFO, "Running analyze Command: " + cmd);
Optional<String> ccOutput = she.progressableWaitReturnOutput(cmd, subMap, logToConsole, monitor, taskCount);

return ccOutput.or("");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.codechecker.eclipse.plugin.codechecker;

import java.nio.file.Path;

import org.codechecker.eclipse.plugin.codechecker.locator.InvalidCodeCheckerException;
import org.codechecker.eclipse.plugin.runtime.ShellExecutorHelper;

/**
* Implementation of the {@link ICodeCheckerFactory} interface.
*/
public class CodeCheckerFactory implements ICodeCheckerFactory {
@Override
public ICodeChecker createCodeChecker(Path pathToBin, ShellExecutorHelper she)
throws InvalidCodeCheckerException {
return new CodeChecker(pathToBin, she);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package org.codechecker.eclipse.plugin.codechecker;

import java.nio.file.Path;

import org.codechecker.eclipse.plugin.codechecker.locator.InvalidCodeCheckerException;
import org.codechecker.eclipse.plugin.config.CcConfigurationBase;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.annotation.NonNull;

/**
* Interface representing a CodeChecker package.
*/
public interface ICodeChecker {
/**
* Returns the unformatted output of the CodeChecker checkers command.
*
* @return The checker list.
*/
@NonNull
public String getCheckers();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say, that getCheckers, getVersion should return an Optional, an analyze could indicate with an exception if something went wrong. Feel free to apply these suggestions liberally, at your discretion.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not completely convinced about the Optional usage in this case, as the version information should not be absent, if there is a valid CodeChecker package at that location. Same situation with the checkers. Maybe I could annotate these methods with @nonnull to be more clear.

Related: I'm still thinking about extracting the package validation section from the getVersion method. I'm just not sure whether to do it on the interface level, or in the implementation. (This getVersion currently not used in the plugin, but could be useful in the future for example to check compatibility).


/**
* Returns the full and complete version string of the CodeChecker package. The
* returned String will never be empty.
*
* @return The version String.
* @throws InvalidCodeCheckerException
* Thrown when no version string can be returned.
*/
@NonNull
public String getVersion() throws InvalidCodeCheckerException;

/**
* To get the location of the CodeChecker binary. The returned String will never
* be empty.
*
* @return The path.
*/
public Path getLocation();

/**
* Executes CodeChecker check command on the build log received in the logFile
* parameter.
*
* @param logFile
* A Path to the build log in the following format:
* http://clang.llvm.org/docs/JSONCompilationDatabase.html .
* @param logToConsole
* Flag for indicating console logging.
* @param monitor
* ProgressMonitor for to be able to increment progress bar.
* @param taskCount
* How many analyze step to be taken.
* @param config
* The configuration being used.
* @return CodeChecker The full analyze command output.
*/
public String analyze(Path logFile, boolean logToConsole, IProgressMonitor monitor, int taskCount,
CcConfigurationBase config);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.codechecker.eclipse.plugin.codechecker;

import java.nio.file.Path;

import org.codechecker.eclipse.plugin.codechecker.locator.InvalidCodeCheckerException;
import org.codechecker.eclipse.plugin.runtime.ShellExecutorHelper;

/**
* Interface for CodeChecker factory.
*/
public interface ICodeCheckerFactory {
/**
* Method for creating CodeChecker instances.
*
* @param pathToBin
* Path to the CodeChecker binary. (Not to root!)
* @param she
* The shell executor helper that will be used.
* @return A newly created {@link ICodeChecker} ICodeChecker instance.
* @throws InvalidCodeCheckerException
* Thrown when a new instance couldn't be created.
*/
public ICodeChecker createCodeChecker(Path pathToBin, ShellExecutorHelper she)
throws InvalidCodeCheckerException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.codechecker.eclipse.plugin.codechecker.locator;

/**
* Class responsible to create {@link CodeCheckerLocatorService} instances.
*/
public class CodeCheckerLocatorFactory {
/**
* Returns a {@link CodeCheckerLocatorService} depending on a the input
* parameter.
*
* @param t
* Any of the {@link ResolutionMethodTypes} enum values.
* @return A {@link CodeCheckerLocatorService} instance.
*/
public CodeCheckerLocatorService create(ResolutionMethodTypes t) {
switch (t) {
case PATH:
return new EnvCodeCheckerLocatorService();
case PRE:
return new PreBuiltCodeCheckerLocatorService();
default:
return null;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.codechecker.eclipse.plugin.codechecker.locator;

import java.nio.file.Path;

import org.codechecker.eclipse.plugin.codechecker.ICodeChecker;
import org.codechecker.eclipse.plugin.codechecker.ICodeCheckerFactory;
import org.codechecker.eclipse.plugin.runtime.IShellExecutorHelperFactory;

/**
* Implementations of this interface should return the location of the
* CodeChecker package.
*/
public abstract class CodeCheckerLocatorService {
/**
* @param pathToBin
* Path to CodeChecker package root.
* @param ccfactory
* An {@link ICodeCheckerFactory} that will create the CodeChecker.
* @param sheFactory
* A {@link IShellExecutorHelperFactory} to be used.
* @return A CodeChecker Instance.
* @throws InvalidCodeCheckerException
* Thrown when the {@link ICodeChecker} instantiation fails.
*/
public abstract ICodeChecker findCodeChecker(Path pathToBin, ICodeCheckerFactory ccfactory, IShellExecutorHelperFactory sheFactory)
throws InvalidCodeCheckerException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.codechecker.eclipse.plugin.codechecker.locator;

import java.nio.file.Path;
import java.nio.file.Paths;

import org.codechecker.eclipse.plugin.codechecker.ICodeChecker;
import org.codechecker.eclipse.plugin.codechecker.ICodeCheckerFactory;
import org.codechecker.eclipse.plugin.runtime.IShellExecutorHelperFactory;
import org.codechecker.eclipse.plugin.runtime.ShellExecutorHelper;

/**
* Provides a CodeChecker instance tied to a CodeChecker package resulting of
* "which CodeChecker".
*/
public class EnvCodeCheckerLocatorService extends CodeCheckerLocatorService {
public static final String CC_NOT_FOUND = "CodeChecker wasn't found in PATH environment variable!";

@Override
public ICodeChecker findCodeChecker(Path path, ICodeCheckerFactory ccFactory,
IShellExecutorHelperFactory sheFactory) throws InvalidCodeCheckerException {

ShellExecutorHelper she = sheFactory.createShellExecutorHelper(System.getenv());
String location = she.quickReturnFirstLine("which CodeChecker", null).or("");
try {
return ccFactory.createCodeChecker(Paths.get(location), she);
} catch (InvalidCodeCheckerException e) {
throw new InvalidCodeCheckerException(CC_NOT_FOUND);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.codechecker.eclipse.plugin.codechecker.locator;

/**
* Custom exception indicating a failed CodeChecker instance creation.
*/
@SuppressWarnings("serial")
public class InvalidCodeCheckerException extends Exception {
/**
* Ctor.
*
* @param errorMessage
* Error message.
*/
public InvalidCodeCheckerException(String errorMessage) {
super(errorMessage);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.codechecker.eclipse.plugin.codechecker.locator;

import java.nio.file.Path;

import org.codechecker.eclipse.plugin.codechecker.ICodeChecker;
import org.codechecker.eclipse.plugin.codechecker.ICodeCheckerFactory;
import org.codechecker.eclipse.plugin.runtime.IShellExecutorHelperFactory;

/**
* Provides a CodeChecker instance which is tied to a pre-built CodeChecker
* package.
*/
public class PreBuiltCodeCheckerLocatorService extends CodeCheckerLocatorService {
public static final String CC_INVALID = "The path to the CodeChecker binary is not valid";
public static final String CC_NOT_FOUND = "Couldn't find CodeChecker at the given destination!";

@Override
public ICodeChecker findCodeChecker(Path pathToBin, ICodeCheckerFactory ccfactory,
IShellExecutorHelperFactory sheFactory) throws InvalidCodeCheckerException {
if (pathToBin == null)
throw new IllegalArgumentException(CC_INVALID);
try {
return ccfactory.createCodeChecker(pathToBin, sheFactory.createShellExecutorHelper(System.getenv()));
} catch (InvalidCodeCheckerException e) {
throw new InvalidCodeCheckerException(CC_NOT_FOUND);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.codechecker.eclipse.plugin.codechecker.locator;

/**
* This enum represents the available types of CodeChecker resolution methods.
*/
public enum ResolutionMethodTypes {
PATH, PRE;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/**
* CodeChecker locator related classes.
*/
package org.codechecker.eclipse.plugin.codechecker.locator;
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/**
* CodeChecker related classes.
*/
package org.codechecker.eclipse.plugin.codechecker;
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.Set;
import java.util.stream.Collectors;

import org.codechecker.eclipse.plugin.codechecker.ICodeChecker;
import org.codechecker.eclipse.plugin.config.Config.ConfigTypes;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;

Expand All @@ -17,6 +18,7 @@ public abstract class CcConfigurationBase {

protected Map<ConfigTypes, String> config;
protected IEclipsePreferences preferences;
protected ICodeChecker codeChecker;

private final Set<ConfigurationChangedListener> listeners = new HashSet<>();

Expand Down Expand Up @@ -49,6 +51,23 @@ public CcConfigurationBase(CcConfigurationBase other) {
*/
protected abstract void validate();

/**
* @return The CodeChecker being used.
*/
public ICodeChecker getCodeChecker() {
return codeChecker;
}

/**
* Sets the currently used CodeChecker.
*
* @param codeChecker
* The CodeChecker that will be stored.
*/
public void setCodeChecker(ICodeChecker codeChecker) {
this.codeChecker = codeChecker;
}

/**
* @return the internal configuration.
*/
Expand Down
Loading