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);