1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-06 17:26:01 +02:00

generalize indexer-support API

Use IFile to specify the file to parse instead of a file-name implicitly
calculated from CBuildConfiguration.

Change-Id: If9d66a0b7533e9e403bc22fa21bf8e6e8fa80436
Signed-off-by: Martin Weber <fifteenknots505@gmail.com>
This commit is contained in:
Martin Weber 2020-11-10 20:58:33 +01:00
parent de80240232
commit 4d40c5b68f
5 changed files with 58 additions and 76 deletions

View file

@ -144,7 +144,7 @@ public class CMakeBuildConfiguration extends CBuildConfiguration {
runCMake = true;
}
ICMakeProperties cmakeProperties = pc.load();
ICMakeProperties cmakeProperties = getPropertiesController().load();
runCMake |= !Files.exists(buildDir.resolve("CMakeCache.txt")); //$NON-NLS-1$
IOsOverrides overrides = extractCMakeOsOverrides(cmakeProperties);
@ -263,7 +263,7 @@ public class CMakeBuildConfiguration extends CBuildConfiguration {
project.deleteMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
ICMakeProperties cmakeProperties = pc.load();
ICMakeProperties cmakeProperties = getPropertiesController().load();
IOsOverrides overrides = extractCMakeOsOverrides(cmakeProperties);
List<String> command = makeCMakeBuildCommandline(cmakeProperties, overrides, "clean"); //$NON-NLS-1$
ConsoleOutputStream outStream = console.getOutputStream();
@ -430,8 +430,9 @@ public class CMakeBuildConfiguration extends CBuildConfiguration {
* @param monitor the job's progress monitor
*/
private void processCompileCommandsFile(IConsole console, IProgressMonitor monitor) throws CoreException {
IFile file = getBuildContainer().getFile(new org.eclipse.core.runtime.Path("compile_commands.json")); //$NON-NLS-1$
CompileCommandsJsonParser parser = new CompileCommandsJsonParser(
new ParseRequest(this, new CMakeIndexerInfoConsumer(this::setScannerInformation),
new ParseRequest(file, new CMakeIndexerInfoConsumer(this::setScannerInformation),
CommandLauncherManager.getInstance().getCommandLauncher(this), console));
parser.parse(monitor);
}
@ -464,7 +465,7 @@ public class CMakeBuildConfiguration extends CBuildConfiguration {
*/
private CMakePropertiesController getPropertiesController() {
if (pc == null) {
Path filePath = Path.of(getProject().getFile(".settings/CDT-cmake.yaml").getLocationURI()); //$NON-NLS-1$
final Path filePath = Path.of(getProject().getFile(".settings/CDT-cmake.yaml").getLocationURI()); //$NON-NLS-1$
pc = new CMakePropertiesController(filePath, () -> {
deleteCMakeCache = true;
// TODO delete cache file here for the case a user restarts the workbench

View file

@ -13,7 +13,6 @@ import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@ -39,7 +38,6 @@ import org.eclipse.cdt.cmake.is.core.participant.IToolCommandlineParser;
import org.eclipse.cdt.cmake.is.core.participant.IToolCommandlineParser.IResult;
import org.eclipse.cdt.cmake.is.core.participant.IToolDetectionParticipant;
import org.eclipse.cdt.cmake.is.core.participant.builtins.IBuiltinsDetectionBehavior;
import org.eclipse.cdt.core.build.CBuildConfiguration;
import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
@ -142,15 +140,14 @@ public class CompileCommandsJsonParser {
* @throws CoreException
*/
private boolean processJsonFile(IProgressMonitor monitor) throws CoreException {
final CBuildConfiguration configuration = parseRequest.getBuildConfiguration();
final IProject project = configuration.getBuildConfiguration().getProject();
java.nio.file.Path buildRoot = Paths.get(configuration.getBuildDirectoryURI());
final IFile jsonFile = parseRequest.getFile();
final IProject project = jsonFile.getProject();
project.deleteMarkers(MARKER_ID, false, IResource.DEPTH_INFINITE);
final java.nio.file.Path jsonFile = buildRoot.resolve("compile_commands.json"); //$NON-NLS-1$
if (!Files.exists(jsonFile)) {
final java.nio.file.Path jsonDiskFile = java.nio.file.Path.of(jsonFile.getLocationURI());
if (!Files.exists(jsonDiskFile)) {
// no json file was produced in the build
final String msg = String.format(Messages.CompileCommandsJsonParser_errmsg_file_not_found, jsonFile,
final String msg = String.format(Messages.CompileCommandsJsonParser_errmsg_file_not_found, jsonDiskFile,
WORKBENCH_WILL_NOT_KNOW_ALL_MSG);
createMarker(project, msg);
return false;
@ -158,42 +155,41 @@ public class CompileCommandsJsonParser {
// file exists on disk...
long tsJsonModified = 0;
try {
tsJsonModified = Files.getLastModifiedTime(jsonFile).toMillis();
tsJsonModified = Files.getLastModifiedTime(jsonDiskFile).toMillis();
} catch (IOException e) {
// treat as 'file is not modified'
return false;
}
IContainer buildContainer = configuration.getBuildContainer();
final IFile jsonFileRc = buildContainer.getFile(new Path("compile_commands.json")); //$NON-NLS-1$
Long sessionLastModified = (Long) buildContainer.getSessionProperty(TIMESTAMP_COMPILE_COMMANDS_PROPERTY);
IContainer buildRootFolder = jsonFile.getParent();
Long sessionLastModified = (Long) buildRootFolder.getSessionProperty(TIMESTAMP_COMPILE_COMMANDS_PROPERTY);
if (sessionLastModified == null || sessionLastModified.longValue() < tsJsonModified) {
// must parse json file...
monitor.setTaskName(Messages.CompileCommandsJsonParser_msg_processing);
try (Reader in = new FileReader(jsonFile.toFile())) {
try (Reader in = new FileReader(jsonDiskFile.toFile())) {
// parse file...
Gson gson = new Gson();
CommandEntry[] sourceFileInfos = gson.fromJson(in, CommandEntry[].class);
for (CommandEntry sourceFileInfo : sourceFileInfos) {
processCommandEntry(sourceFileInfo, jsonFileRc);
processCommandEntry(sourceFileInfo, jsonFile);
}
} catch (JsonSyntaxException | JsonIOException ex) {
// file format error
final String msg = String.format(Messages.CompileCommandsJsonParser_errmsg_not_json, jsonFile,
final String msg = String.format(Messages.CompileCommandsJsonParser_errmsg_not_json, jsonDiskFile,
WORKBENCH_WILL_NOT_KNOW_ALL_MSG);
createMarker(jsonFileRc, msg);
createMarker(jsonFile, msg);
return false;
} catch (IOException ex) {
final String msg = String.format(Messages.CompileCommandsJsonParser_errmsg_read_error, jsonFile,
final String msg = String.format(Messages.CompileCommandsJsonParser_errmsg_read_error, jsonDiskFile,
WORKBENCH_WILL_NOT_KNOW_ALL_MSG);
createMarker(jsonFileRc, msg);
createMarker(jsonFile, msg);
return false;
}
detectBuiltins(monitor);
// store time-stamp
buildContainer.setSessionProperty(TIMESTAMP_COMPILE_COMMANDS_PROPERTY, tsJsonModified);
buildRootFolder.setSessionProperty(TIMESTAMP_COMPILE_COMMANDS_PROPERTY, tsJsonModified);
return true;
}
return false;
@ -266,13 +262,15 @@ public class CompileCommandsJsonParser {
return;
monitor.setTaskName(Messages.CompileCommandsJsonParser_msg_detecting_builtins);
java.nio.file.Path buildDir = parseRequest.getBuildConfiguration().getBuildDirectory();
final IFile jsonFile = parseRequest.getFile();
final IContainer buildRootFolder = jsonFile.getParent();
java.nio.file.Path buildDir = java.nio.file.Path.of(buildRootFolder.getLocationURI());
// run each built-in detector and collect the results..
Map<String, IRawIndexerInfo> builtinDetectorsResults = new HashMap<>();
for (Entry<String, CompilerBuiltinsDetector> entry : builtinDetectorsToRun.entrySet()) {
IRawIndexerInfo result = entry.getValue().detectBuiltins(
parseRequest.getBuildConfiguration().getBuildConfiguration(), buildDir, parseRequest.getLauncher(),
parseRequest.getConsole(), monitor);
IRawIndexerInfo result = entry.getValue().detectBuiltins(jsonFile.getProject(), buildDir,
parseRequest.getLauncher(), parseRequest.getConsole(), monitor);
// store detector key with result
builtinDetectorsResults.put(entry.getKey(), result);
}
@ -431,8 +429,8 @@ public class CompileCommandsJsonParser {
try {
if (DEBUG_TIME) {
System.out.printf("Project %s parsing compile_commands.json ...%n", //$NON-NLS-1$
parseRequest.getBuildConfiguration().getProject().getName());
System.out.printf("Parsing file '%s' ...%n", //$NON-NLS-1$
parseRequest.getFile().getLocationURI().getPath());
start = System.currentTimeMillis();
}
return processJsonFile(monitor);
@ -440,8 +438,8 @@ public class CompileCommandsJsonParser {
parseRequest.getIndexerInfoConsumer().shutdown();
if (DEBUG_TIME) {
long end = System.currentTimeMillis();
System.out.printf("Project %s parsed compile_commands.json file in %dms%n", //$NON-NLS-1$
parseRequest.getBuildConfiguration().getProject().getName(), end - start);
System.out.printf("Parsed file '%s' in %dms%n", //$NON-NLS-1$
parseRequest.getFile().getLocationURI().getPath(), end - start);
}
// clean up
builtinDetectorsToRun = null;

View file

@ -14,22 +14,22 @@ package org.eclipse.cdt.cmake.is.core;
import java.util.Objects;
import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.cdt.core.build.CBuildConfiguration;
import org.eclipse.cdt.core.resources.IConsole;
import org.eclipse.core.resources.IFile;
/** Holds the arguments used to create a {@link CompileCommandsJsonParser}.
*
* @author weber
*/
public final class ParseRequest {
private final CBuildConfiguration buildConfiguration;
private final IFile compileCommandsJson;
private final IIndexerInfoConsumer indexerInfoConsumer;
private final ICommandLauncher launcher;
private final IConsole console;
/** Creates a new ParseRequest object.
*
* @param buildConfiguration the build configuration of the project
* @param compileCommandsJsonFile the file to parse
* @param indexerInfoConsumer the object that receives the indexer relevant
* information for each source file
* @param launcher the launcher to run the compiler for built-ins detection.
@ -39,18 +39,18 @@ public final class ParseRequest {
* detection to or <code>null</code> if no console output is requested.
* Ignored if workspace preferences indicate that no console output is wanted.
*/
public ParseRequest(CBuildConfiguration buildConfiguration, IIndexerInfoConsumer indexerInfoConsumer,
public ParseRequest(IFile compileCommandsJsonFile, IIndexerInfoConsumer indexerInfoConsumer,
ICommandLauncher launcher, IConsole console) {
this.buildConfiguration = Objects.requireNonNull(buildConfiguration, "buildConfiguration"); //$NON-NLS-1$
this.compileCommandsJson = Objects.requireNonNull(compileCommandsJsonFile, "compileCommandsJsonFile"); //$NON-NLS-1$
this.indexerInfoConsumer = Objects.requireNonNull(indexerInfoConsumer, "indexerInfoConsumer"); //$NON-NLS-1$
this.launcher = Objects.requireNonNull(launcher, "launcher"); //$NON-NLS-1$
this.console = console;
}
/** Gets the build configuration of the project.
/** Gets the 'compile_commands.json' file to parse.
*/
public CBuildConfiguration getBuildConfiguration() {
return buildConfiguration;
public IFile getFile() {
return compileCommandsJson;
}
/** Gets the object that receives the indexer relevant

View file

@ -14,10 +14,8 @@ import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import org.eclipse.cdt.cmake.is.core.IParserPreferences;
import org.eclipse.cdt.cmake.is.core.IParserPreferencesAccess;
@ -26,13 +24,9 @@ import org.eclipse.cdt.cmake.is.core.participant.IRawIndexerInfo;
import org.eclipse.cdt.cmake.is.core.participant.builtins.IBuiltinsDetectionBehavior;
import org.eclipse.cdt.cmake.is.core.participant.builtins.IBuiltinsOutputProcessor;
import org.eclipse.cdt.cmake.is.core.participant.builtins.OutputSniffer;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.ConsoleOutputStream;
import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
import org.eclipse.cdt.core.envvar.IEnvironmentVariableManager;
import org.eclipse.cdt.core.resources.IConsole;
import org.eclipse.core.resources.IBuildConfiguration;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
@ -59,7 +53,7 @@ public class CompilerBuiltinsDetector {
private final List<String> builtinsDetectionArgs;
private final IBuiltinsDetectionBehavior builtinsDetectionBehavior;
private IBuildConfiguration buildConfiguration;
private IProject project;
private java.nio.file.Path buildDirectory;
/**
@ -84,18 +78,18 @@ public class CompilerBuiltinsDetector {
/**
* Runs built-in detection.
*
* @param buildConfiguration the project build configuration to use
* @param theBuildDirectory the build directory of the build configuration
* @param launcher the launcher that can run in docker container, if
* any
* @param project the project
* @param buildDirectory the build root directory. This is the working directory of the compiler process. Temporary,
* but cacheable input files for the compiler are generated her also
* @param launcher the launcher for the compiler process
* @param console the console to print the compiler output to or
* <code>null</code> if no console output is requested.
* @throws CoreException
*/
public IRawIndexerInfo detectBuiltins(IBuildConfiguration buildConfiguration, java.nio.file.Path theBuildDirectory,
public IRawIndexerInfo detectBuiltins(IProject project, java.nio.file.Path buildDirectory,
ICommandLauncher launcher, IConsole console, IProgressMonitor monitor) throws CoreException {
this.buildConfiguration = Objects.requireNonNull(buildConfiguration, "buildConfiguration"); //$NON-NLS-1$
this.buildDirectory = Objects.requireNonNull(theBuildDirectory, "buildDirectory"); //$NON-NLS-1$
this.project = Objects.requireNonNull(project, "project"); //$NON-NLS-1$
this.buildDirectory = Objects.requireNonNull(buildDirectory, "buildDirectory"); //$NON-NLS-1$
if (monitor == null) {
monitor = new NullProgressMonitor();
@ -108,7 +102,7 @@ public class CompilerBuiltinsDetector {
console = startOutputConsole(console);
launcher.setProject(buildConfiguration.getProject());
launcher.setProject(project);
launcher.showCommand(console != null);
final Process proc = launcher.execute(new Path(command), argList.toArray(new String[argList.size()]), getEnvp(),
new Path(this.buildDirectory.toString()), monitor);
@ -166,33 +160,25 @@ public class CompilerBuiltinsDetector {
}
/**
* Get environment variables from configuration as array of "var=value" suitable
* for using as "envp" with Runtime.exec(String[] cmdarray, String[] envp, File
* dir)
* Get environment variables from configuration as array of "var=value".
*
* @return String array of environment variables in format "var=value". Does not
* return {@code null}.
*/
private String[] getEnvp() {
IEnvironmentVariableManager mngr = CCorePlugin.getDefault().getBuildEnvironmentManager();
IEnvironmentVariable[] vars = mngr.getVariables(buildConfiguration, true);
// Convert into envp strings
Set<String> strings = new HashSet<>(vars.length);
for (IEnvironmentVariable var : vars) {
if (var.getName().startsWith("LANGUAGE" + '=') || var.getName().startsWith("LC_ALL" + '=')) //$NON-NLS-1$ //$NON-NLS-2$
continue;
strings.add(var.getName() + '=' + var.getValue());
}
// On POSIX (Linux, UNIX) systems reset language variables to default (English)
// with UTF-8 encoding since GNU compilers can handle only UTF-8 characters.
// Include paths with locale characters will be handled properly regardless
// of the language as long as the encoding is set to UTF-8.
// English language is set for parser because it relies on English messages
// in the output of the 'gcc -v' builtinsDetectionArgs.
strings.add("LANGUAGE" + "=en"); // override for GNU gettext //$NON-NLS-1$ //$NON-NLS-2$
strings.add("LC_ALL" + "=C.UTF-8"); // for other parts of the system libraries //$NON-NLS-1$ //$NON-NLS-2$
// in the output of the 'gcc -v'.
String[] strings = {
// override for GNU gettext
"LANGUAGE" + "=en", //$NON-NLS-1$//$NON-NLS-2$
// for other parts of the system libraries
"LC_ALL" + "=C.UTF-8" }; //$NON-NLS-1$ //$NON-NLS-2$
return strings.toArray(new String[strings.size()]);
return strings;
}
/**
@ -218,7 +204,7 @@ public class CompilerBuiltinsDetector {
}
private void createMarker(String message) throws CoreException {
IMarker marker = buildConfiguration.getProject().createMarker(MARKER_ID);
IMarker marker = project.createMarker(MARKER_ID);
marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_INFO);
marker.setAttribute(IMarker.MESSAGE, message);
}
@ -235,15 +221,12 @@ public class CompilerBuiltinsDetector {
.getServiceContext(FrameworkUtil.getBundle(getClass()).getBundleContext())
.get(IParserPreferencesAccess.class).getWorkspacePreferences();
if (console != null && prefs.getAllocateConsole()) {
IProject project = buildConfiguration.getProject();
console.start(project);
try {
final ConsoleOutputStream cis = console.getInfoStream();
String msg;
msg = String.format(Messages.CompilerBuiltinsDetector_msg_detection_start,
SimpleDateFormat.getTimeInstance().format(new Date()), project.getName(),
buildConfiguration.getName().isEmpty() ? "?" : buildConfiguration.getName(), //$NON-NLS-1$
String.join(" ", builtinsDetectionArgs)); //$NON-NLS-1$
SimpleDateFormat.getTimeInstance().format(new Date()), project.getName());
cis.write(msg.getBytes());
cis.write("\n".getBytes()); //$NON-NLS-1$
} catch (IOException ignore) {

View file

@ -13,5 +13,5 @@
###############################################################################
CompilerBuiltinsDetector_errmsg_command_failed=%1$s exited with status %2$d.
CompilerBuiltinsDetector_msg_detection_finished=Detecting compiler built-ins took %d ms.
CompilerBuiltinsDetector_msg_detection_start=%1$s Detecting compiler built-ins: %2$s::%3$s for '%4$s'
CompilerBuiltinsDetector_msg_detection_start=%1$s Detecting compiler built-ins for project '%2$s'
DetectorConsole_title=Compiler Built-ins Detection Console