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:
parent
8e71d0d8e8
commit
2b86aeb5b9
5 changed files with 39 additions and 28 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue