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:
parent
de80240232
commit
4d40c5b68f
5 changed files with 58 additions and 76 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue