diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IndexLocationFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IndexLocationFactory.java
index 3242a9f4463..5cf1c2969cb 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IndexLocationFactory.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IndexLocationFactory.java
@@ -110,7 +110,7 @@ public class IndexLocationFactory {
public static IIndexFileLocation getIFLExpensive(ICProject cproject, String absolutePath) {
final IProject preferredProject= cproject == null ? null : cproject.getProject();
IFile file= ResourceLookup.selectFileForLocation(new Path(absolutePath), preferredProject);
- if (file != null)
+ if (file != null && file.exists())
return getWorkspaceIFL(file);
return getExternalIFL(absolutePath);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGenerator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGenerator.java
index e7523157cad..1f3da625f7c 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGenerator.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGenerator.java
@@ -231,7 +231,7 @@ public class ChangeGenerator extends CPPASTVisitor {
String currentFile = targetLocation.getFileName();
IPath implPath = new Path(currentFile);
IFile relevantFile= ResourceLookup.selectFileForLocation(implPath, null);
- if (relevantFile == null) { // if not in workspace or local file system
+ if (relevantFile == null || !relevantFile.exists()) { // if not in workspace or local file system
throw new UnhandledASTModificationException(modification);
}
MultiTextEdit edit;
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ErrorParserManager.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ErrorParserManager.java
index 3da93073867..36d1c192d8a 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ErrorParserManager.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ErrorParserManager.java
@@ -296,13 +296,16 @@ public class ErrorParserManager extends OutputStream {
* Find exact match in the workspace. If path is not absolute search is done in working directory.
*
* @param path - file path.
- * @return - file in the workspace or {@code null}.
+ * @return - file in the workspace or {@code null} if such a file doesn't exist
*/
protected IFile findFileInWorkspace(IPath path) {
if (!path.isAbsolute()) {
path = getWorkingDirectory().append(path);
}
- return ResourceLookup.selectFileForLocation(path, fProject);
+ IFile f = ResourceLookup.selectFileForLocation(path, fProject);
+ if (f != null && f.isAccessible())
+ return f;
+ return null;
}
/**
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/resources/FileRelevance.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/resources/FileRelevance.java
index a38297e4aa4..adbbb86a3c5 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/resources/FileRelevance.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/resources/FileRelevance.java
@@ -16,6 +16,7 @@ import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.internal.core.model.CModelManager;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourceAttributes;
/**
* This class computes a relevance for files in case we have to select
@@ -26,27 +27,42 @@ public class FileRelevance {
private static final int CDT_PROJECT = 0x20;
private static final int ON_SOURCE_ROOT = 0x10;
+ // Penalty for undesirable attributes
+ private static final int LINK_PENALTY = 1;
+ private static final int INACCESSIBLE_SHIFT = 4;
+
/**
* Compute a relevance for the given file. The higher the score the more relevant the
* file. It is determined by the following criteria:
* - file belongs to preferred project
* - file belongs to a cdt-project
* - file belongs to a source folder of a cdt-project
+ * - file is accessible
+ * - file is not a link
* @param f the file to compute the relevance for
- * @return -1 if f1 is preferable, 1 if f2 is preferable, 0 if there is no difference.
+ * @return integer representing file relevance. Larger numbers are more relevant
*/
public static int getRelevance(IFile f, IProject preferredProject) {
int result= 0;
IProject p= f.getProject();
- if (p.equals(preferredProject))
+ if (p.equals(preferredProject))
result+= PREFERRED_PROJECT;
if (CoreModel.hasCNature(p)) {
result+= CDT_PROJECT;
ICProject cproject= CModelManager.getDefault().create(p);
- if (cproject.isOnSourceRoot(f))
+ if (cproject.isOnSourceRoot(f))
result+= ON_SOURCE_ROOT;
}
+
+ if (!f.isAccessible())
+ result >>= INACCESSIBLE_SHIFT;
+ else {
+ ResourceAttributes ra = f.getResourceAttributes();
+ if (f.isLinked() || (ra != null && ra.isSymbolicLink()))
+ result -= LINK_PENALTY;
+ }
+
return result;
}
}
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/resources/ResourceLookup.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/resources/ResourceLookup.java
index a71a1ee1916..226f631b293 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/resources/ResourceLookup.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/resources/ResourceLookup.java
@@ -72,6 +72,7 @@ public class ResourceLookup {
* @param location an URI for the location of the files to search for.
* @param preferredProject a project to be preferred over others, or null
.
* @return a file for the location in one of the given projects, or null
.
+ * NB the returned IFile may not exist
*/
public static IFile selectFileForLocationURI(URI location, IProject preferredProject) {
return selectFile(findFilesForLocationURI(location), preferredProject);
@@ -84,6 +85,7 @@ public class ResourceLookup {
* @param location a path for the location of the files to search for.
* @param preferredProject a project to be preferred over others, or null
.
* @return a file for the location or null
.
+ * NB the returned IFile may not exist
*/
public static IFile selectFileForLocation(IPath location, IProject preferredProject) {
return selectFile(findFilesForLocation(location), preferredProject);
@@ -92,26 +94,21 @@ public class ResourceLookup {
private static IFile selectFile(IFile[] files, IProject preferredProject) {
if (files.length == 0)
return null;
-
- if (files.length == 1) {
- final IFile file= files[0];
- if (file.isAccessible())
- return file;
- }
-
+
+ if (files.length == 1)
+ return files[0];
+
IFile best= null;
int bestRelevance= -1;
-
+
for (int i = 0; i < files.length; i++) {
IFile file = files[i];
- if (file.isAccessible()) {
- int relevance= FileRelevance.getRelevance(file, preferredProject);
- if (best == null || relevance > bestRelevance ||
- (relevance == bestRelevance &&
- best.getFullPath().toString().compareTo(file.getFullPath().toString()) > 0)) {
- bestRelevance= relevance;
- best= file;
- }
+ int relevance= FileRelevance.getRelevance(file, preferredProject);
+ if (best == null || relevance > bestRelevance ||
+ (relevance == bestRelevance &&
+ best.getFullPath().toString().compareTo(file.getFullPath().toString()) > 0)) {
+ bestRelevance= relevance;
+ best= file;
}
}
return best;
@@ -128,11 +125,6 @@ public class ResourceLookup {
public static void sortFilesByRelevance(IFile[] filesToSort, final IProject preferredProject) {
Collections.sort(Arrays.asList(filesToSort), new Comparator() {
public int compare(IFile f1, IFile f2) {
- boolean a1= f1.isAccessible();
- boolean a2= f2.isAccessible();
- if (a1 != a2)
- return a1 ? -1 : 1;
-
int r1= FileRelevance.getRelevance(f1, preferredProject);
int r2= FileRelevance.getRelevance(f2, preferredProject);