Skip to content

Commit

Permalink
Merge pull request #1459 from CyrusNajmabadi/trimmedFindRefs
Browse files Browse the repository at this point in the history
Trim the filepaths in FindRefs to avoid displaying so much redundant information.
  • Loading branch information
CyrusNajmabadi committed Mar 23, 2015
2 parents adc6657 + 56692d9 commit 4b56f40
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Editor.Navigation;
using Microsoft.VisualStudio.LanguageServices.Implementation.Utilities;
using Roslyn.Utilities;
Expand All @@ -10,24 +13,93 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.Library.FindRes
{
internal partial class LibraryManager
{
private IList<AbstractTreeItem> CreateGoToDefinitionItems(IEnumerable<INavigableItem> items)
private IList<AbstractTreeItem> CreateNavigableItemTreeItems(IEnumerable<INavigableItem> items)
{
var itemsList = items.ToList();
if (itemsList.Count == 0)
{
return new List<AbstractTreeItem>();
}

// Collect all the documents in the list of items we're presenting. Then determine
// what number of common path elements they have in common. We can avoid showing
// these common locations, thus presenting a much cleaner result view to the user.
var documents = new HashSet<Document>();
CollectDocuments(itemsList, documents);

var commonPathElements = CountCommonPathElements(documents);

return CreateNavigableItemTreeItems(itemsList, commonPathElements);
}

private int CountCommonPathElements(HashSet<Document> documents)
{
Debug.Assert(documents.Count > 0);
var commonPathElements = 0;
for (var index = 0; ; index++)
{
var pathPortion = GetPathPortion(documents.First(), index);
if (pathPortion == null)
{
return commonPathElements;
}

foreach (var document in documents)
{
if (GetPathPortion(document, index) != pathPortion)
{
return commonPathElements;
}
}

commonPathElements++;
}
}

private string GetPathPortion(Document document, int index)
{
if (index == 0)
{
return document.Project.Name;
}

index--;
if (index < document.Folders.Count)
{
return document.Folders[index];
}

return null;
}

private void CollectDocuments(IEnumerable<INavigableItem> items, HashSet<Document> documents)
{
foreach (var item in items)
{
documents.Add(item.Document);

CollectDocuments(item.ChildItems, documents);
}
}

private IList<AbstractTreeItem> CreateNavigableItemTreeItems(IEnumerable<INavigableItem> items, int commonPathElements)
{
var sourceListItems =
from item in items
where IsValidSourceLocation(item.Document, item.SourceSpan)
select CreateTreeItem(item);
select CreateTreeItem(item, commonPathElements);

return sourceListItems.ToList();
}

private AbstractTreeItem CreateTreeItem(INavigableItem item)
private AbstractTreeItem CreateTreeItem(INavigableItem item, int commonPathElements)
{
var displayText = !item.ChildItems.IsEmpty ? item.DisplayName : null;
var result = new SourceReferenceTreeItem(item.Document, item.SourceSpan, item.Glyph.GetGlyphIndex(), displayText);
var result = new SourceReferenceTreeItem(item.Document, item.SourceSpan, item.Glyph.GetGlyphIndex(), commonPathElements, displayText);

if (!item.ChildItems.IsEmpty)
{
var childItems = CreateGoToDefinitionItems(item.ChildItems);
var childItems = CreateNavigableItemTreeItems(item.ChildItems, commonPathElements);
result.Children.AddRange(childItems);
result.SetReferenceCount(childItems.Count);
}
Expand All @@ -37,7 +109,7 @@ private AbstractTreeItem CreateTreeItem(INavigableItem item)

public void PresentNavigableItems(string title, IEnumerable<INavigableItem> items)
{
PresentObjectList(title, new ObjectList(CreateGoToDefinitionItems(items), this));
PresentObjectList(title, new ObjectList(CreateNavigableItemTreeItems(items), this));
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
Expand Down Expand Up @@ -27,7 +28,7 @@ internal abstract class AbstractSourceTreeItem : AbstractTreeItem

private static readonly ObjectPool<StringBuilder> s_filePathBuilderPool = new ObjectPool<StringBuilder>(() => new StringBuilder());

public AbstractSourceTreeItem(Document document, TextSpan sourceSpan, ushort glyphIndex)
public AbstractSourceTreeItem(Document document, TextSpan sourceSpan, ushort glyphIndex, int commonPathElements = 0)
: base(glyphIndex)
{
// We store the document ID, line and offset for navigation so that we
Expand All @@ -37,7 +38,7 @@ public AbstractSourceTreeItem(Document document, TextSpan sourceSpan, ushort gly
_workspace = document.Project.Solution.Workspace;
_documentId = document.Id;
_projectName = document.Project.Name;
_filePath = GetFilePath(document);
_filePath = GetFilePath(document, commonPathElements);
_sourceSpan = sourceSpan;

var text = document.GetTextAsync(CancellationToken.None).WaitAndGetResult(CancellationToken.None);
Expand All @@ -64,18 +65,27 @@ public override int GoToSource()
return VSConstants.S_OK;
}

private static string GetFilePath(Document document)
private static string GetFilePath(Document document, int commonPathElements)
{
var builder = s_filePathBuilderPool.Allocate();
try
{
builder.Append(document.Project.Name);
builder.Append('\\');
if (commonPathElements <= 0)
{
builder.Append(document.Project.Name);
builder.Append('\\');
}

commonPathElements--;
foreach (var folder in document.Folders)
{
builder.Append(folder);
builder.Append('\\');
if (commonPathElements <= 0)
{
builder.Append(folder);
builder.Append('\\');
}

commonPathElements--;
}

builder.Append(Path.GetFileName(document.FilePath));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;

namespace Microsoft.VisualStudio.LanguageServices.Implementation.Library.FindResults
{
internal class SourceReferenceTreeItem : AbstractSourceTreeItem, IComparable<SourceReferenceTreeItem>
{
public SourceReferenceTreeItem(Document document, TextSpan sourceSpan, ushort glyphIndex, string displayText = null)
: base(document, sourceSpan, glyphIndex)
public SourceReferenceTreeItem(Document document, TextSpan sourceSpan, ushort glyphIndex, int commonPathElements = 0, string displayText = null)
: base(document, sourceSpan, glyphIndex, commonPathElements)
{
if (displayText != null)
{
Expand Down

0 comments on commit 4b56f40

Please # to comment.