mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 14:42:11 +02:00
bug 404125: Build output parser incorrectly handles compile lines compiling files outside of the workspace
This commit is contained in:
parent
eafce4c179
commit
a7acc2b250
2 changed files with 106 additions and 37 deletions
|
@ -1391,6 +1391,9 @@ public class GCCBuildCommandParserTest extends BaseTestCase {
|
|||
IFolder folder=ResourceHelper.createFolder(project, "Local/BuildDir/Folder");
|
||||
IFolder folder2=ResourceHelper.createFolder(project, "Local/BuildDir/Folder2");
|
||||
IFile file=ResourceHelper.createFile(project, "Local/BuildDir/file.cpp");
|
||||
IFile incFile1=ResourceHelper.createFile(project, "Local/BuildDir/include.file1");
|
||||
IFile incFile2=ResourceHelper.createFile(project, "Local/BuildDir/include.file2");
|
||||
|
||||
ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
|
||||
String languageId = ls.getLanguageId();
|
||||
|
||||
|
@ -1410,6 +1413,10 @@ public class GCCBuildCommandParserTest extends BaseTestCase {
|
|||
+ " -I../BuildDir/Folder2"
|
||||
+ " -I/BuildDir/MissingFolder"
|
||||
+ " -I../BuildDir/MissingFolder2"
|
||||
+ " -include /BuildDir/include.file1"
|
||||
+ " -include ../BuildDir/include.file2"
|
||||
+ " -include /BuildDir/missing.include.file"
|
||||
+ " -include ../BuildDir/missing.include.file"
|
||||
+ " /BuildDir/file.cpp");
|
||||
parser.shutdown();
|
||||
|
||||
|
@ -1420,6 +1427,10 @@ public class GCCBuildCommandParserTest extends BaseTestCase {
|
|||
assertEquals(new CIncludePathEntry(folder2.getFullPath(), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(2));
|
||||
assertEquals(new CIncludePathEntry("/BuildDir/MissingFolder", 0), entries.get(3));
|
||||
assertEquals(new CIncludePathEntry(buildDir.getFullPath().append("MissingFolder2"), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(4));
|
||||
assertEquals(new CIncludeFileEntry(incFile1.getFullPath(), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(5));
|
||||
assertEquals(new CIncludeFileEntry(incFile2.getFullPath(), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(6));
|
||||
assertEquals(new CIncludeFileEntry("/BuildDir/missing.include.file", 0), entries.get(7));
|
||||
assertEquals(new CIncludeFileEntry(buildDir.getFullPath().append("missing.include.file"), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(8));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2070,24 +2081,26 @@ public class GCCBuildCommandParserTest extends BaseTestCase {
|
|||
IFile file=ResourceHelper.createFile(project, "file.cpp");
|
||||
ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
|
||||
ICConfigurationDescription cfgDescription = cfgDescriptions[0];
|
||||
|
||||
|
||||
ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
|
||||
String languageId = ls.getLanguageId();
|
||||
|
||||
|
||||
// create GCCBuildCommandParser
|
||||
GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT, true);
|
||||
parser.setResourceScope(AbstractBuildCommandParser.ResourceScope.PROJECT);
|
||||
|
||||
|
||||
// parse line
|
||||
parser.startup(cfgDescription, null);
|
||||
parser.processLine("gcc "
|
||||
+ "-I/path0 "
|
||||
+ "-IC:/path1 "
|
||||
+ "/absolute/path/file.cpp");
|
||||
parser.shutdown();
|
||||
|
||||
|
||||
// check entries
|
||||
List<ICLanguageSettingEntry> entries = parser.getSettingEntries(cfgDescription, project, languageId);
|
||||
assertEquals(new CIncludePathEntry("/path0", 0), entries.get(0));
|
||||
assertEquals(new CIncludePathEntry("C:/path1", 0), entries.get(1));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2099,17 +2112,56 @@ public class GCCBuildCommandParserTest extends BaseTestCase {
|
|||
GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getRawProvider(wspProvider);
|
||||
parser.setResourceScope(AbstractBuildCommandParser.ResourceScope.PROJECT);
|
||||
parser.clear();
|
||||
|
||||
|
||||
// parse line
|
||||
parser.startup(null, null);
|
||||
parser.processLine("gcc "
|
||||
+ "-I/path0 "
|
||||
+ "/absolute/path/file.cpp");
|
||||
parser.shutdown();
|
||||
|
||||
|
||||
// check entries
|
||||
List<ICLanguageSettingEntry> entries = parser.getSettingEntries(null, null, LANG_CPP);
|
||||
assertEquals(new CIncludePathEntry("/path0", 0), entries.get(0));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parsing of file being compiled outside of workspace saving entries at project scope.
|
||||
*/
|
||||
public void testFileAbsolutePath_ProjectLevel_bug404125() throws Exception {
|
||||
// Create model project and accompanied descriptions
|
||||
String projectName = getName();
|
||||
IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
|
||||
IFile file=ResourceHelper.createFile(project, "file.c");
|
||||
ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
|
||||
ICConfigurationDescription cfgDescription = cfgDescriptions[0];
|
||||
|
||||
ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
|
||||
String languageId = ls.getLanguageId();
|
||||
|
||||
// create GCCBuildCommandParser
|
||||
GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT, true);
|
||||
parser.setResourceScope(AbstractBuildCommandParser.ResourceScope.PROJECT);
|
||||
|
||||
ErrorParserManager epm = new ErrorParserManager(project, null);
|
||||
// Set build directory
|
||||
epm.pushDirectoryURI(project.getLocationURI());
|
||||
|
||||
// parse line
|
||||
parser.startup(cfgDescription, epm);
|
||||
parser.processLine("gcc "
|
||||
// In scenario from bug 404125 drive letter somehow induced path to be appended to project directory
|
||||
+ "-IC:/path "
|
||||
+ "-I.. "
|
||||
+ "/absolute/path/file.c");
|
||||
parser.shutdown();
|
||||
|
||||
// check entries
|
||||
List<ICLanguageSettingEntry> entries = parser.getSettingEntries(cfgDescription, project, languageId);
|
||||
assertEquals(new CIncludePathEntry("C:/path", 0), entries.get(0));
|
||||
assertEquals(new CIncludePathEntry(project.getLocation().removeLastSegments(1), 0), entries.get(1));
|
||||
assertEquals(2, entries.size());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -460,12 +460,12 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
|
|||
if (optionParser.parseOption(option)) {
|
||||
ICLanguageSettingEntry entry = null;
|
||||
if (isResolvingPaths && (optionParser.isForFile() || optionParser.isForFolder())) {
|
||||
URI baseURI = buildDirURI;
|
||||
if (mappedRootURI != null) {
|
||||
if (buildDirURI != null && !new Path(optionParser.parsedName).isAbsolute()) {
|
||||
URI baseURI = mappedRootURI;
|
||||
if (buildDirURI != null && !new Path(optionParser.parsedName).isAbsolute()) {
|
||||
if (mappedRootURI != null) {
|
||||
baseURI = efsProvider.append(mappedRootURI, buildDirURI.getPath());
|
||||
} else {
|
||||
baseURI = mappedRootURI;
|
||||
baseURI = buildDirURI;
|
||||
}
|
||||
}
|
||||
entry = createResolvedPathEntry(optionParser, optionParser.parsedName, 0, baseURI);
|
||||
|
@ -644,21 +644,21 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
|
|||
}
|
||||
|
||||
/**
|
||||
* Find resource in the workspace for a given URI with a preference for the resource
|
||||
* Find file resource in the workspace for a given URI with a preference for the resource
|
||||
* to reside in the given project.
|
||||
*/
|
||||
private static IResource findFileForLocationURI(URI uri, IProject preferredProject) {
|
||||
private static IResource findFileForLocationURI(URI uri, IProject preferredProject, boolean checkExistence) {
|
||||
IResource sourceFile = null;
|
||||
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
|
||||
IResource[] resources = root.findFilesForLocationURI(uri);
|
||||
if (resources.length > 0) {
|
||||
sourceFile = resources[0];
|
||||
if (preferredProject != null) {
|
||||
for (IResource rc : resources) {
|
||||
if (rc.getProject().equals(preferredProject)) {
|
||||
sourceFile = rc;
|
||||
break;
|
||||
}
|
||||
for (IResource rc : resources) {
|
||||
if (!checkExistence || rc.isAccessible()) {
|
||||
if (rc.getProject().equals(preferredProject)) {
|
||||
sourceFile = rc;
|
||||
break;
|
||||
}
|
||||
if (sourceFile == null) {
|
||||
sourceFile = rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -669,11 +669,11 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
|
|||
* Return a resource in workspace corresponding the given folder {@link URI} preferable residing in
|
||||
* the provided project.
|
||||
*/
|
||||
private static IResource findContainerForLocationURI(URI uri, IProject preferredProject) {
|
||||
private static IResource findContainerForLocationURI(URI uri, IProject preferredProject, boolean checkExistence) {
|
||||
IResource resource = null;
|
||||
IResource[] resources = ResourcesPlugin.getWorkspace().getRoot().findContainersForLocationURI(uri);
|
||||
for (IResource rc : resources) {
|
||||
if ((rc instanceof IProject || rc instanceof IFolder)) { // treat IWorkspaceRoot as non-workspace path
|
||||
if ((rc instanceof IProject || rc instanceof IFolder) && (!checkExistence || rc.isAccessible())) { // treat IWorkspaceRoot as non-workspace path
|
||||
if (rc.getProject().equals(preferredProject)) {
|
||||
resource = rc;
|
||||
break;
|
||||
|
@ -704,7 +704,7 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
|
|||
// try to find absolute path in the workspace
|
||||
if (sourceFile == null && new Path(parsedResourceName).isAbsolute()) {
|
||||
URI uri = org.eclipse.core.filesystem.URIUtil.toURI(parsedResourceName);
|
||||
sourceFile = findFileForLocationURI(uri, currentProject);
|
||||
sourceFile = findFileForLocationURI(uri, currentProject, /*checkExistence*/ true);
|
||||
}
|
||||
|
||||
// try last known current working directory from build output
|
||||
|
@ -712,7 +712,7 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
|
|||
URI cwdURI = cwdTracker.getWorkingDirectoryURI();
|
||||
if (cwdURI != null) {
|
||||
URI uri = efsProvider.append(cwdURI, parsedResourceName);
|
||||
sourceFile = findFileForLocationURI(uri, currentProject);
|
||||
sourceFile = findFileForLocationURI(uri, currentProject, /*checkExistence*/ true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -722,7 +722,7 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
|
|||
if (builderCWD!=null) {
|
||||
IPath path = builderCWD.append(parsedResourceName);
|
||||
URI uri = org.eclipse.core.filesystem.URIUtil.toURI(path);
|
||||
sourceFile = findFileForLocationURI(uri, currentProject);
|
||||
sourceFile = findFileForLocationURI(uri, currentProject, /*checkExistence*/ true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1002,12 +1002,12 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
|
|||
URI uri = determineMappedURI(parsedPath, baseURI);
|
||||
IResource rc = null;
|
||||
|
||||
// Try to resolve in the workspace
|
||||
// Try to resolve as existing resource in the workspace
|
||||
if (uri != null && uri.isAbsolute()) {
|
||||
if (optionParser.isForFolder()) {
|
||||
rc = findContainerForLocationURI(uri, currentProject);
|
||||
rc = findContainerForLocationURI(uri, currentProject, /*checkExistence*/ true);
|
||||
} else if (optionParser.isForFile()) {
|
||||
rc = findFileForLocationURI(uri, currentProject);
|
||||
rc = findFileForLocationURI(uri, currentProject, /*checkExistence*/ true);
|
||||
}
|
||||
if (rc != null) {
|
||||
resolvedPath = rc.getFullPath().toString();
|
||||
|
@ -1015,11 +1015,11 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
|
|||
}
|
||||
}
|
||||
|
||||
// Try to resolve on the file-system
|
||||
// Try to resolve as existing file/folder on the file-system
|
||||
IPath fileSystemLocation = getFilesystemLocation(uri);
|
||||
if (resolvedPath == null) {
|
||||
IPath path = getFilesystemLocation(uri);
|
||||
if (path != null && new File(path.toString()).exists()) {
|
||||
resolvedPath = path.toString();
|
||||
if (fileSystemLocation != null && new File(fileSystemLocation.toString()).exists()) {
|
||||
resolvedPath = fileSystemLocation.toString();
|
||||
resolvedFlag = flag;
|
||||
}
|
||||
if (resolvedPath == null) {
|
||||
|
@ -1034,13 +1034,30 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
|
|||
resolvedFlag = flag | ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED;
|
||||
}
|
||||
}
|
||||
if (resolvedPath == null && path != null) {
|
||||
resolvedPath = path.toString();
|
||||
resolvedFlag = flag;
|
||||
}
|
||||
|
||||
// Try to resolve in the workspace as a handle
|
||||
if (resolvedPath == null) {
|
||||
if (uri != null && uri.isAbsolute()) {
|
||||
if (optionParser.isForFolder()) {
|
||||
rc = findContainerForLocationURI(uri, currentProject, /*checkExistence*/ false);
|
||||
} else if (optionParser.isForFile()) {
|
||||
rc = findFileForLocationURI(uri, currentProject, /*checkExistence*/ false);
|
||||
}
|
||||
if (rc != null) {
|
||||
resolvedPath = rc.getFullPath().toString();
|
||||
resolvedFlag = flag | ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if cannot resolve keep parsed path
|
||||
// Try to set to file-system location if available
|
||||
if (resolvedPath == null && fileSystemLocation != null) {
|
||||
resolvedPath = fileSystemLocation.toString();
|
||||
resolvedFlag = flag;
|
||||
}
|
||||
|
||||
// If still cannot resolve keep parsed path
|
||||
if (resolvedPath == null) {
|
||||
resolvedPath = parsedPath;
|
||||
resolvedFlag = flag;
|
||||
|
|
Loading…
Add table
Reference in a new issue