From 11c76639db6d78c985fefb2d216b3d57947ab4f5 Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Mon, 26 Aug 2013 14:25:48 +0200 Subject: [PATCH] Bug 411605: ResourceLookup should honor the PathCanonicalization strategy. --- .../core/resources/FileRelevance.java | 37 +++++++++++++++++-- .../PathCanonicalizationStrategy.java | 15 ++++++++ .../core/resources/ResourceLookup.java | 8 ++-- 3 files changed, 52 insertions(+), 8 deletions(-) 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 8a50029e7d1..48c281ee054 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 @@ -11,12 +11,15 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.resources; +import java.net.URI; + import org.eclipse.cdt.core.model.CoreModel; 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; +import org.eclipse.core.runtime.IPath; /** * This class computes a relevance for files in case we have to select @@ -43,6 +46,22 @@ public class FileRelevance { * @return integer representing file relevance. Larger numbers are more relevant */ public static int getRelevance(IFile f, IProject preferredProject) { + return getRelevance(f, preferredProject, true, null); + } + + /** + * 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 + * - file matches the original location + * @param f the file to compute the relevance for + * @return integer representing file relevance. Larger numbers are more relevant + */ + public static int getRelevance(IFile f, IProject preferredProject, boolean degradeSymLinks, Object originalLocation) { int result= 0; IProject p= f.getProject(); if (p.equals(preferredProject)) @@ -55,14 +74,24 @@ public class FileRelevance { result+= ON_SOURCE_ROOT; } - if (!f.isAccessible()) + if (!f.isAccessible()) { result >>= INACCESSIBLE_SHIFT; - else { + } else if (f.isLinked()) { + result -= LINK_PENALTY; + } else if (degradeSymLinks) { ResourceAttributes ra = f.getResourceAttributes(); - if (f.isLinked() || (ra != null && ra.isSymbolicLink())) + if (ra != null && ra.isSymbolicLink()) result -= LINK_PENALTY; + } else { + // Symbolic links are not degraded, prefer the original location + if (originalLocation instanceof URI) { + if (originalLocation.equals(f.getLocationURI())) + result += LINK_PENALTY; + } else if (originalLocation instanceof IPath) { + if (originalLocation.equals(f.getLocation())) + result+= LINK_PENALTY; + } } - return result; } } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/resources/PathCanonicalizationStrategy.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/resources/PathCanonicalizationStrategy.java index e592fb95ab6..5f1fe6ae686 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/resources/PathCanonicalizationStrategy.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/resources/PathCanonicalizationStrategy.java @@ -29,6 +29,10 @@ public abstract class PathCanonicalizationStrategy { public static String getCanonicalPath(File file) { return instance.getCanonicalPathInternal(file); } + + public static boolean resolvesSymbolicLinks() { + return instance.resolvesSymbolicLinksInternal(); + } /** * Sets path canonicalization strategy. If canonicalize is true, @@ -49,6 +53,11 @@ public abstract class PathCanonicalizationStrategy { return file.getAbsolutePath(); } } + + @Override + protected boolean resolvesSymbolicLinksInternal() { + return true; + } }; } else { instance = new PathCanonicalizationStrategy() { @@ -56,9 +65,15 @@ public abstract class PathCanonicalizationStrategy { protected String getCanonicalPathInternal(File file) { return file.getAbsolutePath(); } + + @Override + protected boolean resolvesSymbolicLinksInternal() { + return false; + } }; } } protected abstract String getCanonicalPathInternal(File file); + protected abstract boolean resolvesSymbolicLinksInternal(); } 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 6598ae9b5bf..803173b65fe 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 @@ -76,7 +76,7 @@ public class ResourceLookup { * NB the returned IFile may not exist */ public static IFile selectFileForLocationURI(URI location, IProject preferredProject) { - return selectFile(findFilesForLocationURI(location), preferredProject); + return selectFile(findFilesForLocationURI(location), preferredProject, location); } /** @@ -89,7 +89,7 @@ public class ResourceLookup { * NB the returned IFile may not exist */ public static IFile selectFileForLocation(IPath location, IProject preferredProject) { - return selectFile(findFilesForLocation(location), preferredProject); + return selectFile(findFilesForLocation(location), preferredProject, location); } /** @@ -102,7 +102,7 @@ public class ResourceLookup { * one that's most relevant, then first try to find it directly - before getting to the more expensive * loop of computing the "relevance scores" for all the files. */ - private static IFile selectFile(IFile[] files, IProject preferredProject) { + private static IFile selectFile(IFile[] files, IProject preferredProject, Object originalLocation) { if (files.length == 0) return null; @@ -134,7 +134,7 @@ public class ResourceLookup { int bestRelevance= -1; for (IFile file : files) { - int relevance= FileRelevance.getRelevance(file, preferredProject); + int relevance= FileRelevance.getRelevance(file, preferredProject, PathCanonicalizationStrategy.resolvesSymbolicLinks(), originalLocation); if (best == null || relevance > bestRelevance || (relevance == bestRelevance && best.getFullPath().toString().compareTo(file.getFullPath().toString()) > 0)) {