mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 14:42:11 +02:00
Bug 244434 - When the target file of "Open Declaration" is reachable via
multiple workspace paths, open it under the path that most closely matches the originating file Change-Id: I616804c6ffb9900e5df2f918a409f46c3cbb7a3a Signed-off-by: Nathan Ridge <zeratul976@hotmail.com>
This commit is contained in:
parent
0d52c4ab82
commit
7eeecab020
2 changed files with 87 additions and 1 deletions
|
@ -496,7 +496,17 @@ class OpenDeclarationsJob extends Job implements ASTRunnable {
|
||||||
|
|
||||||
private ICElementHandle getCElementForName(ICProject project, IIndex index, IName declName) throws CoreException {
|
private ICElementHandle getCElementForName(ICProject project, IIndex index, IName declName) throws CoreException {
|
||||||
if (declName instanceof IIndexName) {
|
if (declName instanceof IIndexName) {
|
||||||
return IndexUI.getCElementForName(project, index, (IIndexName) declName);
|
IIndexName indexName = (IIndexName) declName;
|
||||||
|
ITranslationUnit tu= IndexUI.getTranslationUnit(project, indexName);
|
||||||
|
if (tu != null) {
|
||||||
|
// If the file containing the target name is accessible via multiple
|
||||||
|
// workspace paths, choose the one that most closely matches the
|
||||||
|
// workspace path of the file originating the action.
|
||||||
|
tu = IndexUI.getPreferredTranslationUnit(tu, fTranslationUnit);
|
||||||
|
|
||||||
|
return IndexUI.getCElementForName(tu, index, indexName);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
if (declName instanceof IASTName) {
|
if (declName instanceof IASTName) {
|
||||||
IASTName astName = (IASTName) declName;
|
IASTName astName = (IASTName) declName;
|
||||||
|
|
|
@ -13,7 +13,9 @@
|
||||||
package org.eclipse.cdt.internal.ui.viewsupport;
|
package org.eclipse.cdt.internal.ui.viewsupport;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
@ -92,6 +94,7 @@ import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable;
|
||||||
import org.eclipse.cdt.internal.core.model.ext.CElementHandleFactory;
|
import org.eclipse.cdt.internal.core.model.ext.CElementHandleFactory;
|
||||||
import org.eclipse.cdt.internal.core.model.ext.ICElementHandle;
|
import org.eclipse.cdt.internal.core.model.ext.ICElementHandle;
|
||||||
import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences;
|
import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences;
|
||||||
|
import org.eclipse.cdt.internal.core.resources.ResourceLookup;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.editor.ASTProvider;
|
import org.eclipse.cdt.internal.ui.editor.ASTProvider;
|
||||||
|
|
||||||
|
@ -360,6 +363,79 @@ public class IndexUI {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a 'source' and a 'target' translation unit, return a translation unit
|
||||||
|
* that resolves to the same file as 'target' and has a workspace path that
|
||||||
|
* matches the workspace path of 'source' as closely as possible.
|
||||||
|
*
|
||||||
|
* Most commonly, 'target' will be the only trasnlation unit that resolves to
|
||||||
|
* the file in question, and 'target' is returned. In the presence of linked
|
||||||
|
* folders, however, multiple workspace paths can refer to the same file, and
|
||||||
|
* this function chooses the one that's closest to 'source'.
|
||||||
|
*/
|
||||||
|
public static ITranslationUnit getPreferredTranslationUnit(ITranslationUnit target,
|
||||||
|
ITranslationUnit source) {
|
||||||
|
// Get the files corresponding to the source and target translation units.
|
||||||
|
// These files encode the workspace paths.
|
||||||
|
IFile sourceFile = source.getFile();
|
||||||
|
IFile targetFile = target.getFile();
|
||||||
|
if (sourceFile == null || targetFile == null) {
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resolve the location of the target in the filesystem.
|
||||||
|
IPath targetLocation = targetFile.getLocation();
|
||||||
|
if (targetLocation == null) {
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find all files that resolve to the same location.
|
||||||
|
IFile[] candidates = ResourceLookup.findFilesForLocation(targetLocation);
|
||||||
|
|
||||||
|
// In the common case that there is one only file that resolves to that
|
||||||
|
// location, or if the search found no results, return the original target.
|
||||||
|
if (candidates.length <= 1) {
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the workspace path of the source translation unit's file.
|
||||||
|
final IPath sourcePath = sourceFile.getFullPath();
|
||||||
|
|
||||||
|
// Sort the candidates files by how closely they match 'sourcePath'.
|
||||||
|
Arrays.sort(candidates, new Comparator<IFile>() {
|
||||||
|
@Override
|
||||||
|
public int compare(IFile f1, IFile f2) {
|
||||||
|
// Get the workspace paths of the files being compared.
|
||||||
|
IPath p1 = f1.getFullPath();
|
||||||
|
IPath p2 = f2.getFullPath();
|
||||||
|
|
||||||
|
// Closeness of the match is defined by how many segments of
|
||||||
|
// the candidate's workspace path match 'sourcePath'.
|
||||||
|
int s1 = p1.matchingFirstSegments(sourcePath);
|
||||||
|
int s2 = p2.matchingFirstSegments(sourcePath);
|
||||||
|
if (s1 > s2)
|
||||||
|
return -1;
|
||||||
|
if (s1 < s2)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
// Fall back on alphabetical comparison.
|
||||||
|
return p1.toString().compareTo(p2.toString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Processing in the sorted order, return the first file for which
|
||||||
|
// a translation unit can be found.
|
||||||
|
for (IFile candidate : candidates) {
|
||||||
|
ITranslationUnit tu = CoreModelUtil.findTranslationUnit(candidate);
|
||||||
|
if (tu != null) {
|
||||||
|
return tu;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fall back on returning the original target.
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
public static ICElementHandle getCElementForName(ICProject preferProject, IIndex index, IIndexName declName)
|
public static ICElementHandle getCElementForName(ICProject preferProject, IIndex index, IIndexName declName)
|
||||||
throws CoreException {
|
throws CoreException {
|
||||||
assert !declName.isReference();
|
assert !declName.isReference();
|
||||||
|
|
Loading…
Add table
Reference in a new issue