Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trim the filepaths in FindRefs to avoid displaying so much redundant information. #1459

Merged
merged 2 commits into from
Mar 23, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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