mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-08 02:06:01 +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) {
|
public static IIndexFileLocation getIFLExpensive(ICProject cproject, String absolutePath) {
|
||||||
final IProject preferredProject= cproject == null ? null : cproject.getProject();
|
final IProject preferredProject= cproject == null ? null : cproject.getProject();
|
||||||
IFile file= ResourceLookup.selectFileForLocation(new Path(absolutePath), preferredProject);
|
IFile file= ResourceLookup.selectFileForLocation(new Path(absolutePath), preferredProject);
|
||||||
if (file != null)
|
if (file != null && file.exists())
|
||||||
return getWorkspaceIFL(file);
|
return getWorkspaceIFL(file);
|
||||||
|
|
||||||
return getExternalIFL(absolutePath);
|
return getExternalIFL(absolutePath);
|
||||||
|
|
|
@ -231,7 +231,7 @@ public class ChangeGenerator extends CPPASTVisitor {
|
||||||
String currentFile = targetLocation.getFileName();
|
String currentFile = targetLocation.getFileName();
|
||||||
IPath implPath = new Path(currentFile);
|
IPath implPath = new Path(currentFile);
|
||||||
IFile relevantFile= ResourceLookup.selectFileForLocation(implPath, null);
|
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);
|
throw new UnhandledASTModificationException(modification);
|
||||||
}
|
}
|
||||||
MultiTextEdit edit;
|
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.
|
* Find exact match in the workspace. If path is not absolute search is done in working directory.
|
||||||
*
|
*
|
||||||
* @param path - file path.
|
* @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) {
|
protected IFile findFileInWorkspace(IPath path) {
|
||||||
if (!path.isAbsolute()) {
|
if (!path.isAbsolute()) {
|
||||||
path = getWorkingDirectory().append(path);
|
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.cdt.internal.core.model.CModelManager;
|
||||||
import org.eclipse.core.resources.IFile;
|
import org.eclipse.core.resources.IFile;
|
||||||
import org.eclipse.core.resources.IProject;
|
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
|
* This class computes a relevance for files in case we have to select
|
||||||
|
@ -26,14 +27,20 @@ public class FileRelevance {
|
||||||
private static final int CDT_PROJECT = 0x20;
|
private static final int CDT_PROJECT = 0x20;
|
||||||
private static final int ON_SOURCE_ROOT = 0x10;
|
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
|
* 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. It is determined by the following criteria: <br>
|
||||||
* - file belongs to preferred project <br>
|
* - file belongs to preferred project <br>
|
||||||
* - file belongs to a cdt-project <br>
|
* - file belongs to a cdt-project <br>
|
||||||
* - file belongs to a source folder of 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
|
* @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) {
|
public static int getRelevance(IFile f, IProject preferredProject) {
|
||||||
int result= 0;
|
int result= 0;
|
||||||
|
@ -47,6 +54,15 @@ public class FileRelevance {
|
||||||
if (cproject.isOnSourceRoot(f))
|
if (cproject.isOnSourceRoot(f))
|
||||||
result+= ON_SOURCE_ROOT;
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,6 +72,7 @@ public class ResourceLookup {
|
||||||
* @param location an URI for the location of the files to search for.
|
* @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>.
|
* @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>.
|
* @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) {
|
public static IFile selectFileForLocationURI(URI location, IProject preferredProject) {
|
||||||
return selectFile(findFilesForLocationURI(location), 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 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>.
|
* @param preferredProject a project to be preferred over others, or <code>null</code>.
|
||||||
* @return a file for the location 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) {
|
public static IFile selectFileForLocation(IPath location, IProject preferredProject) {
|
||||||
return selectFile(findFilesForLocation(location), preferredProject);
|
return selectFile(findFilesForLocation(location), preferredProject);
|
||||||
|
@ -93,25 +95,20 @@ public class ResourceLookup {
|
||||||
if (files.length == 0)
|
if (files.length == 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (files.length == 1) {
|
if (files.length == 1)
|
||||||
final IFile file= files[0];
|
return files[0];
|
||||||
if (file.isAccessible())
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
IFile best= null;
|
IFile best= null;
|
||||||
int bestRelevance= -1;
|
int bestRelevance= -1;
|
||||||
|
|
||||||
for (int i = 0; i < files.length; i++) {
|
for (int i = 0; i < files.length; i++) {
|
||||||
IFile file = files[i];
|
IFile file = files[i];
|
||||||
if (file.isAccessible()) {
|
int relevance= FileRelevance.getRelevance(file, preferredProject);
|
||||||
int relevance= FileRelevance.getRelevance(file, preferredProject);
|
if (best == null || relevance > bestRelevance ||
|
||||||
if (best == null || relevance > bestRelevance ||
|
(relevance == bestRelevance &&
|
||||||
(relevance == bestRelevance &&
|
best.getFullPath().toString().compareTo(file.getFullPath().toString()) > 0)) {
|
||||||
best.getFullPath().toString().compareTo(file.getFullPath().toString()) > 0)) {
|
bestRelevance= relevance;
|
||||||
bestRelevance= relevance;
|
best= file;
|
||||||
best= file;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return best;
|
return best;
|
||||||
|
@ -128,11 +125,6 @@ public class ResourceLookup {
|
||||||
public static void sortFilesByRelevance(IFile[] filesToSort, final IProject preferredProject) {
|
public static void sortFilesByRelevance(IFile[] filesToSort, final IProject preferredProject) {
|
||||||
Collections.sort(Arrays.asList(filesToSort), new Comparator<IFile>() {
|
Collections.sort(Arrays.asList(filesToSort), new Comparator<IFile>() {
|
||||||
public int compare(IFile f1, IFile f2) {
|
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 r1= FileRelevance.getRelevance(f1, preferredProject);
|
||||||
int r2= FileRelevance.getRelevance(f2, preferredProject);
|
int r2= FileRelevance.getRelevance(f2, preferredProject);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue