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

bug 404125: Build output parser incorrectly handles compile lines compiling files outside of the workspace

This commit is contained in:
Andrew Gvozdev 2013-03-29 15:43:44 -04:00
parent eafce4c179
commit a7acc2b250
2 changed files with 106 additions and 37 deletions

View file

@ -1391,6 +1391,9 @@ public class GCCBuildCommandParserTest extends BaseTestCase {
IFolder folder=ResourceHelper.createFolder(project, "Local/BuildDir/Folder"); IFolder folder=ResourceHelper.createFolder(project, "Local/BuildDir/Folder");
IFolder folder2=ResourceHelper.createFolder(project, "Local/BuildDir/Folder2"); IFolder folder2=ResourceHelper.createFolder(project, "Local/BuildDir/Folder2");
IFile file=ResourceHelper.createFile(project, "Local/BuildDir/file.cpp"); 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); ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
String languageId = ls.getLanguageId(); String languageId = ls.getLanguageId();
@ -1410,6 +1413,10 @@ public class GCCBuildCommandParserTest extends BaseTestCase {
+ " -I../BuildDir/Folder2" + " -I../BuildDir/Folder2"
+ " -I/BuildDir/MissingFolder" + " -I/BuildDir/MissingFolder"
+ " -I../BuildDir/MissingFolder2" + " -I../BuildDir/MissingFolder2"
+ " -include /BuildDir/include.file1"
+ " -include ../BuildDir/include.file2"
+ " -include /BuildDir/missing.include.file"
+ " -include ../BuildDir/missing.include.file"
+ " /BuildDir/file.cpp"); + " /BuildDir/file.cpp");
parser.shutdown(); 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(folder2.getFullPath(), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(2));
assertEquals(new CIncludePathEntry("/BuildDir/MissingFolder", 0), entries.get(3)); 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 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"); IFile file=ResourceHelper.createFile(project, "file.cpp");
ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project); ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
ICConfigurationDescription cfgDescription = cfgDescriptions[0]; ICConfigurationDescription cfgDescription = cfgDescriptions[0];
ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true); ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
String languageId = ls.getLanguageId(); String languageId = ls.getLanguageId();
// create GCCBuildCommandParser // create GCCBuildCommandParser
GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT, true); GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT, true);
parser.setResourceScope(AbstractBuildCommandParser.ResourceScope.PROJECT); parser.setResourceScope(AbstractBuildCommandParser.ResourceScope.PROJECT);
// parse line // parse line
parser.startup(cfgDescription, null); parser.startup(cfgDescription, null);
parser.processLine("gcc " parser.processLine("gcc "
+ "-I/path0 " + "-I/path0 "
+ "-IC:/path1 "
+ "/absolute/path/file.cpp"); + "/absolute/path/file.cpp");
parser.shutdown(); parser.shutdown();
// check entries // check entries
List<ICLanguageSettingEntry> entries = parser.getSettingEntries(cfgDescription, project, languageId); List<ICLanguageSettingEntry> entries = parser.getSettingEntries(cfgDescription, project, languageId);
assertEquals(new CIncludePathEntry("/path0", 0), entries.get(0)); 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); GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getRawProvider(wspProvider);
parser.setResourceScope(AbstractBuildCommandParser.ResourceScope.PROJECT); parser.setResourceScope(AbstractBuildCommandParser.ResourceScope.PROJECT);
parser.clear(); parser.clear();
// parse line // parse line
parser.startup(null, null); parser.startup(null, null);
parser.processLine("gcc " parser.processLine("gcc "
+ "-I/path0 " + "-I/path0 "
+ "/absolute/path/file.cpp"); + "/absolute/path/file.cpp");
parser.shutdown(); parser.shutdown();
// check entries // check entries
List<ICLanguageSettingEntry> entries = parser.getSettingEntries(null, null, LANG_CPP); List<ICLanguageSettingEntry> entries = parser.getSettingEntries(null, null, LANG_CPP);
assertEquals(new CIncludePathEntry("/path0", 0), entries.get(0)); 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());
}
} }

View file

@ -460,12 +460,12 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
if (optionParser.parseOption(option)) { if (optionParser.parseOption(option)) {
ICLanguageSettingEntry entry = null; ICLanguageSettingEntry entry = null;
if (isResolvingPaths && (optionParser.isForFile() || optionParser.isForFolder())) { if (isResolvingPaths && (optionParser.isForFile() || optionParser.isForFolder())) {
URI baseURI = buildDirURI; URI baseURI = mappedRootURI;
if (mappedRootURI != null) { if (buildDirURI != null && !new Path(optionParser.parsedName).isAbsolute()) {
if (buildDirURI != null && !new Path(optionParser.parsedName).isAbsolute()) { if (mappedRootURI != null) {
baseURI = efsProvider.append(mappedRootURI, buildDirURI.getPath()); baseURI = efsProvider.append(mappedRootURI, buildDirURI.getPath());
} else { } else {
baseURI = mappedRootURI; baseURI = buildDirURI;
} }
} }
entry = createResolvedPathEntry(optionParser, optionParser.parsedName, 0, baseURI); 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. * 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; IResource sourceFile = null;
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
IResource[] resources = root.findFilesForLocationURI(uri); IResource[] resources = root.findFilesForLocationURI(uri);
if (resources.length > 0) { for (IResource rc : resources) {
sourceFile = resources[0]; if (!checkExistence || rc.isAccessible()) {
if (preferredProject != null) { if (rc.getProject().equals(preferredProject)) {
for (IResource rc : resources) { sourceFile = rc;
if (rc.getProject().equals(preferredProject)) { break;
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 * Return a resource in workspace corresponding the given folder {@link URI} preferable residing in
* the provided project. * 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 resource = null;
IResource[] resources = ResourcesPlugin.getWorkspace().getRoot().findContainersForLocationURI(uri); IResource[] resources = ResourcesPlugin.getWorkspace().getRoot().findContainersForLocationURI(uri);
for (IResource rc : resources) { 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)) { if (rc.getProject().equals(preferredProject)) {
resource = rc; resource = rc;
break; break;
@ -704,7 +704,7 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
// try to find absolute path in the workspace // try to find absolute path in the workspace
if (sourceFile == null && new Path(parsedResourceName).isAbsolute()) { if (sourceFile == null && new Path(parsedResourceName).isAbsolute()) {
URI uri = org.eclipse.core.filesystem.URIUtil.toURI(parsedResourceName); 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 // try last known current working directory from build output
@ -712,7 +712,7 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
URI cwdURI = cwdTracker.getWorkingDirectoryURI(); URI cwdURI = cwdTracker.getWorkingDirectoryURI();
if (cwdURI != null) { if (cwdURI != null) {
URI uri = efsProvider.append(cwdURI, parsedResourceName); 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) { if (builderCWD!=null) {
IPath path = builderCWD.append(parsedResourceName); IPath path = builderCWD.append(parsedResourceName);
URI uri = org.eclipse.core.filesystem.URIUtil.toURI(path); 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); URI uri = determineMappedURI(parsedPath, baseURI);
IResource rc = null; IResource rc = null;
// Try to resolve in the workspace // Try to resolve as existing resource in the workspace
if (uri != null && uri.isAbsolute()) { if (uri != null && uri.isAbsolute()) {
if (optionParser.isForFolder()) { if (optionParser.isForFolder()) {
rc = findContainerForLocationURI(uri, currentProject); rc = findContainerForLocationURI(uri, currentProject, /*checkExistence*/ true);
} else if (optionParser.isForFile()) { } else if (optionParser.isForFile()) {
rc = findFileForLocationURI(uri, currentProject); rc = findFileForLocationURI(uri, currentProject, /*checkExistence*/ true);
} }
if (rc != null) { if (rc != null) {
resolvedPath = rc.getFullPath().toString(); 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) { if (resolvedPath == null) {
IPath path = getFilesystemLocation(uri); if (fileSystemLocation != null && new File(fileSystemLocation.toString()).exists()) {
if (path != null && new File(path.toString()).exists()) { resolvedPath = fileSystemLocation.toString();
resolvedPath = path.toString();
resolvedFlag = flag; resolvedFlag = flag;
} }
if (resolvedPath == null) { if (resolvedPath == null) {
@ -1034,13 +1034,30 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
resolvedFlag = flag | ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED; 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) { if (resolvedPath == null) {
resolvedPath = parsedPath; resolvedPath = parsedPath;
resolvedFlag = flag; resolvedFlag = flag;