1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 14:42:11 +02:00

Bug 269980 ResourceLookup#selectFileForLocation(...) may now return non-existant IFiles (as the equivalent platform methods do).

- FileRelevance consider IFIle#isAccessible() & link state when computing IFile relevance
  - Tweak consumers who assume that ResourceLookup returns null for inaccessible IFiles
This commit is contained in:
James Blackburn 2009-04-28 20:41:49 +00:00
parent 8e71d0d8e8
commit 2b86aeb5b9
5 changed files with 39 additions and 28 deletions

View file

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

View file

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

View file

@ -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;
}
/**

View file

@ -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: <br>
* - file belongs to preferred project <br>
* - file belongs to a cdt-project <br>
* - file belongs to a source folder of a cdt-project <br>
* - 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;
}
}

View file

@ -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 <code>null</code>.
* @return a file for the location in one of the given projects, or <code>null</code>.
* 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 <code>null</code>.
* @return a file for the location or <code>null</code>.
* 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<IFile>() {
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);