提交 840b1567 编写于 作者: C CyrusNajmabadi

Initial work to move the existing FAR presented over to using hte new object model.

上级 a2ace5b6
...@@ -13,7 +13,7 @@ internal class CSharpFindReferencesService : AbstractFindReferencesService ...@@ -13,7 +13,7 @@ internal class CSharpFindReferencesService : AbstractFindReferencesService
{ {
[ImportingConstructor] [ImportingConstructor]
public CSharpFindReferencesService( public CSharpFindReferencesService(
[ImportMany] IEnumerable<IReferencedSymbolsPresenter> referencedSymbolsPresenters, [ImportMany] IEnumerable<IFindReferencesPresenter> referencedSymbolsPresenters,
[ImportMany] IEnumerable<INavigableItemsPresenter> navigableItemsPresenters, [ImportMany] IEnumerable<INavigableItemsPresenter> navigableItemsPresenters,
[ImportMany] IEnumerable<IFindReferencesResultProvider> externalReferencesProviders) [ImportMany] IEnumerable<IFindReferencesResultProvider> externalReferencesProviders)
: base(referencedSymbolsPresenters, navigableItemsPresenters, externalReferencesProviders) : base(referencedSymbolsPresenters, navigableItemsPresenters, externalReferencesProviders)
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // 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.Collections.Generic;
using Microsoft.CodeAnalysis.Editor.Implementation.FindReferences;
using Microsoft.CodeAnalysis.FindSymbols; using Microsoft.CodeAnalysis.FindSymbols;
namespace Microsoft.CodeAnalysis.Editor.Host namespace Microsoft.CodeAnalysis.Editor.Host
{ {
internal interface IReferencedSymbolsPresenter internal interface IFindReferencesPresenter
{ {
void DisplayResult(Solution solution, IEnumerable<ReferencedSymbol> result); void DisplayResult(DefinitionsAndReferences definitionsAndReferences);
} }
} }
\ No newline at end of file
...@@ -16,12 +16,12 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.FindReferences ...@@ -16,12 +16,12 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.FindReferences
{ {
internal abstract partial class AbstractFindReferencesService : IFindReferencesService internal abstract partial class AbstractFindReferencesService : IFindReferencesService
{ {
private readonly IEnumerable<IReferencedSymbolsPresenter> _referenceSymbolPresenters; private readonly IEnumerable<IFindReferencesPresenter> _referenceSymbolPresenters;
private readonly IEnumerable<INavigableItemsPresenter> _navigableItemPresenters; private readonly IEnumerable<INavigableItemsPresenter> _navigableItemPresenters;
private readonly IEnumerable<IFindReferencesResultProvider> _externalReferencesProviders; private readonly IEnumerable<IFindReferencesResultProvider> _externalReferencesProviders;
protected AbstractFindReferencesService( protected AbstractFindReferencesService(
IEnumerable<IReferencedSymbolsPresenter> referenceSymbolPresenters, IEnumerable<IFindReferencesPresenter> referenceSymbolPresenters,
IEnumerable<INavigableItemsPresenter> navigableItemPresenters, IEnumerable<INavigableItemsPresenter> navigableItemPresenters,
IEnumerable<IFindReferencesResultProvider> externalReferencesProviders) IEnumerable<IFindReferencesResultProvider> externalReferencesProviders)
{ {
...@@ -156,10 +156,14 @@ private bool TryDisplayReferences(Tuple<IEnumerable<ReferencedSymbol>, Solution> ...@@ -156,10 +156,14 @@ private bool TryDisplayReferences(Tuple<IEnumerable<ReferencedSymbol>, Solution>
{ {
if (result != null && result.Item1 != null) if (result != null && result.Item1 != null)
{ {
var searchSolution = result.Item2; var solution = result.Item2;
var factory = solution.Workspace.Services.GetService<IDefinitionsAndReferencesFactory>();
var definitionsAndReferences = factory.CreateDefinitionsAndReferences(
solution, result.Item1);
foreach (var presenter in _referenceSymbolPresenters) foreach (var presenter in _referenceSymbolPresenters)
{ {
presenter.DisplayResult(searchSolution, result.Item1); presenter.DisplayResult(definitionsAndReferences);
return true; return true;
} }
} }
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable;
using System.ComponentModel.Composition; using System.ComponentModel.Composition;
using Microsoft.CodeAnalysis.Editor.Commands; using Microsoft.CodeAnalysis.Editor.Commands;
using Microsoft.CodeAnalysis.Editor.Host; using Microsoft.CodeAnalysis.Editor.Host;
...@@ -19,13 +20,13 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.FindReferences ...@@ -19,13 +20,13 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.FindReferences
internal class FindReferencesCommandHandler : internal class FindReferencesCommandHandler :
ICommandHandler<FindReferencesCommandArgs> ICommandHandler<FindReferencesCommandArgs>
{ {
private readonly IEnumerable<IReferencedSymbolsPresenter> _presenters; private readonly IEnumerable<IFindReferencesPresenter> _presenters;
private readonly IWaitIndicator _waitIndicator; private readonly IWaitIndicator _waitIndicator;
[ImportingConstructor] [ImportingConstructor]
internal FindReferencesCommandHandler( internal FindReferencesCommandHandler(
IWaitIndicator waitIndicator, IWaitIndicator waitIndicator,
[ImportMany] IEnumerable<IReferencedSymbolsPresenter> presenters) [ImportMany] IEnumerable<IFindReferencesPresenter> presenters)
{ {
Contract.ThrowIfNull(waitIndicator); Contract.ThrowIfNull(waitIndicator);
Contract.ThrowIfNull(presenters); Contract.ThrowIfNull(presenters);
...@@ -53,7 +54,7 @@ internal void FindReferences(ITextSnapshot snapshot, int caretPosition) ...@@ -53,7 +54,7 @@ internal void FindReferences(ITextSnapshot snapshot, int caretPosition)
{ {
foreach (var presenter in _presenters) foreach (var presenter in _presenters)
{ {
presenter.DisplayResult(document.Project.Solution, SpecializedCollections.EmptyEnumerable<ReferencedSymbol>()); presenter.DisplayResult(DefinitionsAndReferences.Empty);
return; return;
} }
} }
......
...@@ -242,6 +242,9 @@ public int CompareTo(SourceReferenceItem other) ...@@ -242,6 +242,9 @@ public int CompareTo(SourceReferenceItem other)
internal struct DefinitionsAndReferences internal struct DefinitionsAndReferences
{ {
public static readonly DefinitionsAndReferences Empty =
new DefinitionsAndReferences(ImmutableArray<DefinitionItem>.Empty, ImmutableArray<SourceReferenceItem>.Empty);
/// <summary> /// <summary>
/// All the definitions to show. Note: not all definitions may have references. /// All the definitions to show. Note: not all definitions may have references.
/// </summary> /// </summary>
......
...@@ -36,6 +36,15 @@ internal class DefaultDefinitionsAndReferencesFactory : IDefinitionsAndReference ...@@ -36,6 +36,15 @@ internal class DefaultDefinitionsAndReferencesFactory : IDefinitionsAndReference
return new DefinitionsAndReferences(definitions.ToImmutable(), references.ToImmutable()); return new DefinitionsAndReferences(definitions.ToImmutable(), references.ToImmutable());
} }
/// <summary>
/// Reference locations are deduplicated across the entire find references result set
/// Order the definitions so that references to multiple definitions appear under the
/// desired definition (e.g. constructor references should prefer the constructor method
/// over the type definition). Note that this does not change the order in which
/// definitions are displayed in Find Symbol Results, it only changes which definition
/// a given reference should appear under when its location is a reference to multiple
/// definitions.
/// </summary>
private static int GetPrecedence(ReferencedSymbol referencedSymbol) private static int GetPrecedence(ReferencedSymbol referencedSymbol)
{ {
switch (referencedSymbol.Definition.Kind) switch (referencedSymbol.Definition.Kind)
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // 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.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Editor.Commands; using Microsoft.CodeAnalysis.Editor.Commands;
using Microsoft.CodeAnalysis.Editor.Implementation.FindReferences; using Microsoft.CodeAnalysis.Editor.Implementation.FindReferences;
using Microsoft.CodeAnalysis.Editor.Navigation;
using Microsoft.CodeAnalysis.Editor.UnitTests.Utilities; using Microsoft.CodeAnalysis.Editor.UnitTests.Utilities;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Microsoft.CodeAnalysis.FindSymbols;
using Microsoft.VisualStudio.Language.Intellisense;
using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text;
using Moq;
using Roslyn.Test.Utilities; using Roslyn.Test.Utilities;
using Roslyn.Utilities; using Roslyn.Utilities;
using Xunit; using Xunit;
...@@ -37,13 +32,16 @@ public async Task TestFindReferencesSynchronousCall() ...@@ -37,13 +32,16 @@ public async Task TestFindReferencesSynchronousCall()
textView, textView,
textView.TextBuffer), () => { }); textView.TextBuffer), () => { });
AssertResult(findReferencesPresenter.Result, "C", ".ctor"); AssertResult(findReferencesPresenter.DefinitionsAndReferences, "C", ".ctor");
} }
} }
private bool AssertResult(IEnumerable<ReferencedSymbol> result, params string[] definitions) private bool AssertResult(
DefinitionsAndReferences definitionsAndReferences,
params string[] definitions)
{ {
return result.Select(r => r.Definition.Name).SetEquals(definitions); return definitionsAndReferences.Definitions.Select(r => r.DisplayParts.JoinText())
.SetEquals(definitions);
} }
} }
} }
\ No newline at end of file
...@@ -3,19 +3,18 @@ ...@@ -3,19 +3,18 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.CodeAnalysis.Editor.Host; using Microsoft.CodeAnalysis.Editor.Host;
using Microsoft.CodeAnalysis.Editor.Implementation.FindReferences;
using Microsoft.CodeAnalysis.FindSymbols; using Microsoft.CodeAnalysis.FindSymbols;
namespace Microsoft.CodeAnalysis.Editor.UnitTests.FindReferences namespace Microsoft.CodeAnalysis.Editor.UnitTests.FindReferences
{ {
internal class MockReferencedSymbolsPresenter : IReferencedSymbolsPresenter internal class MockReferencedSymbolsPresenter : IFindReferencesPresenter
{ {
public Solution Solution { get; private set; } public DefinitionsAndReferences DefinitionsAndReferences;
public IEnumerable<ReferencedSymbol> Result { get; private set; }
public void DisplayResult(Solution solution, IEnumerable<ReferencedSymbol> result) public void DisplayResult(DefinitionsAndReferences definitionsAndReferences)
{ {
this.Solution = solution; DefinitionsAndReferences = definitionsAndReferences;
this.Result = result;
} }
} }
} }
\ No newline at end of file
...@@ -11,7 +11,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.FindReferences ...@@ -11,7 +11,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.FindReferences
Inherits AbstractFindReferencesService Inherits AbstractFindReferencesService
<ImportingConstructor> <ImportingConstructor>
Protected Sub New(<ImportMany> referencedSymbolsPresenters As IEnumerable(Of IReferencedSymbolsPresenter), Protected Sub New(<ImportMany> referencedSymbolsPresenters As IEnumerable(Of IFindReferencesPresenter),
<ImportMany> navigableItemsPresenters As IEnumerable(Of INavigableItemsPresenter), <ImportMany> navigableItemsPresenters As IEnumerable(Of INavigableItemsPresenter),
<ImportMany> externalReferencesProviders As IEnumerable(Of IFindReferencesResultProvider)) <ImportMany> externalReferencesProviders As IEnumerable(Of IFindReferencesResultProvider))
MyBase.New(referencedSymbolsPresenters, navigableItemsPresenters, externalReferencesProviders) MyBase.New(referencedSymbolsPresenters, navigableItemsPresenters, externalReferencesProviders)
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // 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;
using System.Collections.Generic;
using System.ComponentModel.Composition; using System.ComponentModel.Composition;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Editor.Host; using Microsoft.CodeAnalysis.Editor.Host;
using Microsoft.CodeAnalysis.Editor.Implementation.FindReferences;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.FindSymbols;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.VisualStudio.LanguageServices.Implementation.Library.FindResults; using Microsoft.VisualStudio.LanguageServices.Implementation.Library.FindResults;
using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.FindReferences namespace Microsoft.VisualStudio.LanguageServices.Implementation.FindReferences
{ {
[Export(typeof(IReferencedSymbolsPresenter))] [Export(typeof(IFindReferencesPresenter))]
internal sealed class ReferencedSymbolsPresenter : ForegroundThreadAffinitizedObject, IReferencedSymbolsPresenter internal sealed class FindReferencesPresenter : ForegroundThreadAffinitizedObject, IFindReferencesPresenter
{ {
private readonly IServiceProvider _serviceProvider; private readonly IServiceProvider _serviceProvider;
private readonly LibraryManager _manager; private readonly LibraryManager _manager;
[ImportingConstructor] [ImportingConstructor]
private ReferencedSymbolsPresenter(SVsServiceProvider serviceProvider) : private FindReferencesPresenter(SVsServiceProvider serviceProvider) :
base(assertIsForeground: true) base(assertIsForeground: true)
{ {
_serviceProvider = serviceProvider; _serviceProvider = serviceProvider;
...@@ -30,26 +26,9 @@ internal sealed class ReferencedSymbolsPresenter : ForegroundThreadAffinitizedOb ...@@ -30,26 +26,9 @@ internal sealed class ReferencedSymbolsPresenter : ForegroundThreadAffinitizedOb
_manager = (LibraryManager)serviceProvider.GetService(typeof(LibraryManager)); _manager = (LibraryManager)serviceProvider.GetService(typeof(LibraryManager));
} }
public void DisplayResult(Solution solution, IEnumerable<ReferencedSymbol> symbols) public void DisplayResult(DefinitionsAndReferences definitionsAndReferences)
{ {
var firstResult = symbols.FirstOrDefault(); _manager.PresentDefinitionsAndReferences(definitionsAndReferences);
string title;
if (firstResult != null)
{
title = firstResult.Definition.Name;
if (title == string.Empty)
{
// Anonymous types have no name.
title = firstResult.Definition.ToDisplayString();
}
}
else
{
// PresentFindReferencesResult ignores the title for an empty result, but "VS library" system throws if it is an empty string.
title = "None";
}
_manager.PresentReferencedSymbols(title, solution, symbols);
} }
} }
} }
\ No newline at end of file
...@@ -66,6 +66,11 @@ protected override uint GetUpdateCounter() ...@@ -66,6 +66,11 @@ protected override uint GetUpdateCounter()
private void PresentObjectList(string title, ObjectList objectList) private void PresentObjectList(string title, ObjectList objectList)
{ {
if (string.IsNullOrWhiteSpace(title))
{
title = "None";
}
var navInfo = new NavInfo(objectList); var navInfo = new NavInfo(objectList);
var findSymbol = (IVsFindSymbol)this.ServiceProvider.GetService(typeof(SVsObjectSearch)); var findSymbol = (IVsFindSymbol)this.ServiceProvider.GetService(typeof(SVsObjectSearch));
var searchCriteria = new VSOBSEARCHCRITERIA2() var searchCriteria = new VSOBSEARCHCRITERIA2()
......
...@@ -2,8 +2,10 @@ ...@@ -2,8 +2,10 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq; using System.Linq;
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Editor.Implementation.FindReferences;
using Microsoft.CodeAnalysis.FindSymbols; using Microsoft.CodeAnalysis.FindSymbols;
using Microsoft.CodeAnalysis.Navigation; using Microsoft.CodeAnalysis.Navigation;
using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.Extensions;
...@@ -15,158 +17,109 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.Library.FindRes ...@@ -15,158 +17,109 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.Library.FindRes
{ {
internal partial class LibraryManager internal partial class LibraryManager
{ {
public void PresentReferencedSymbols(string title, Solution solution, IEnumerable<ReferencedSymbol> items) public void PresentDefinitionsAndReferences(DefinitionsAndReferences definitionsAndReferences)
{ {
PresentObjectList(title, new ObjectList(CreateFindReferencesItems(solution, items), this)); var firstDefinition = definitionsAndReferences.Definitions.FirstOrDefault();
var title = firstDefinition?.DisplayParts.JoinText();
PresentObjectList(title, new ObjectList(CreateFindReferencesItems(definitionsAndReferences), this));
} }
// internal for test purposes // internal for test purposes
internal IList<AbstractTreeItem> CreateFindReferencesItems(Solution solution, IEnumerable<ReferencedSymbol> referencedSymbols) internal IList<AbstractTreeItem> CreateFindReferencesItems(
DefinitionsAndReferences definitionsAndReferences)
{ {
var definitions = new List<AbstractTreeItem>(); var definitionItems = definitionsAndReferences.Definitions;
var uniqueLocations = new HashSet<ValueTuple<Document, TextSpan>>(); return definitionItems.SelectMany(d => CreateDefinitionItems(d, definitionsAndReferences))
var symbolNavigationService = solution.Workspace.Services.GetService<ISymbolNavigationService>(); .ToList();
referencedSymbols = referencedSymbols.FilterToItemsToShow().ToList();
foreach (var referencedSymbol in referencedSymbols.OrderBy(GetDefinitionPrecedence))
{
var definition = referencedSymbol.Definition;
var locations = definition.Locations;
// When finding references of a namespace, the data provided by the ReferenceFinder
// will include one definition location for each of its exact namespace
// declarations and each declaration of its children namespaces that mention
// its name (e.g. definitions of A.B will include "namespace A.B.C"). The list of
// reference locations includes both these namespace declarations and their
// references in usings or fully qualified names. Instead of showing many top-level
// declaration nodes (one of which will contain the full list of references
// including declarations, the rest of which will say "0 references" due to
// reference deduplication and there being no meaningful way to partition them),
// we pick a single declaration to use as the top-level definition and nest all of
// the declarations & references underneath.
var definitionLocations = definition.IsKind(SymbolKind.Namespace)
? SpecializedCollections.SingletonEnumerable(definition.Locations.First())
: definition.Locations;
foreach (var definitionLocation in definitionLocations)
{
var definitionItem = ConvertToDefinitionItem(solution, referencedSymbol, definitionLocation, definition.GetGlyph());
if (definitionItem != null)
{
definitions.Add(definitionItem);
var referenceItems = CreateReferenceItems(solution, uniqueLocations, referencedSymbol.Locations.Select(loc => loc.Location));
definitionItem.Children.AddRange(referenceItems);
definitionItem.SetReferenceCount(referenceItems.Count);
}
}
// Add on any definition locations from third party language services
string filePath;
int lineNumber, charOffset;
if (symbolNavigationService.WouldNavigateToSymbol(definition, solution, out filePath, out lineNumber, out charOffset))
{
definitions.Add(new ExternalLanguageDefinitionTreeItem(filePath, lineNumber, charOffset, definition.Name, definition.GetGlyph().GetGlyphIndex(), this.ServiceProvider));
}
}
return definitions;
} }
/// <summary> private IEnumerable<AbstractTreeItem> CreateDefinitionItems(
/// Reference locations are deduplicated across the entire find references result set DefinitionItem definitionItem,
/// Order the definitions so that references to multiple definitions appear under the DefinitionsAndReferences definitionsAndReferences)
/// desired definition (e.g. constructor references should prefer the constructor method
/// over the type definition). Note that this does not change the order in which
/// definitions are displayed in Find Symbol Results, it only changes which definition
/// a given reference should appear under when its location is a reference to multiple
/// definitions.
/// </summary>
private int GetDefinitionPrecedence(ReferencedSymbol referencedSymbol)
{ {
switch (referencedSymbol.Definition.Kind) // Each definition item may end up as several top nodes (because of partials).
// Add the references to the last item actually in the list.
var definitionTreeItems = ConvertToDefinitionTreeItems(definitionItem);
if (!definitionTreeItems.IsEmpty)
{ {
case SymbolKind.Event: var lastTreeItem = definitionTreeItems.Last();
case SymbolKind.Field: var referenceItems = CreateReferenceItems(definitionItem, definitionsAndReferences);
case SymbolKind.Label:
case SymbolKind.Local: lastTreeItem.Children.AddRange(referenceItems);
case SymbolKind.Method: lastTreeItem.SetReferenceCount(referenceItems.Count);
case SymbolKind.Parameter:
case SymbolKind.Property:
case SymbolKind.RangeVariable:
return 0;
case SymbolKind.ArrayType:
case SymbolKind.DynamicType:
case SymbolKind.ErrorType:
case SymbolKind.NamedType:
case SymbolKind.PointerType:
return 1;
default:
return 2;
} }
return definitionTreeItems;
// // Add on any definition locations from third party language services
// string filePath;
// int lineNumber, charOffset;
// if (symbolNavigationService.WouldNavigateToSymbol(definition, solution, out filePath, out lineNumber, out charOffset))
// {
// definitions.Add(new ExternalLanguageDefinitionTreeItem(filePath, lineNumber, charOffset, definition.Name, definition.GetGlyph().GetGlyphIndex(), this.ServiceProvider));
// }
//}
//return definitions;
} }
private AbstractTreeItem ConvertToDefinitionItem( private ImmutableArray<AbstractTreeItem> ConvertToDefinitionTreeItems(
Solution solution, DefinitionItem definitionItem)
ReferencedSymbol referencedSymbol,
Location location,
Glyph glyph)
{ {
if (!location.IsInSource) var result = ImmutableArray.CreateBuilder<AbstractTreeItem>();
{
return referencedSymbol.Locations.Any()
? new MetadataDefinitionTreeItem(
solution.Workspace,
referencedSymbol.Definition,
referencedSymbol.Locations.First().Document.Project.Id,
glyph.GetGlyphIndex())
: null;
}
var document = solution.GetDocument(location.SourceTree); foreach (var location in definitionItem.Locations)
var sourceSpan = location.SourceSpan;
if (!IsValidSourceLocation(document, sourceSpan))
{ {
return null; result.Add(new DefinitionTreeItem(definitionItem, location));
} }
return new SourceDefinitionTreeItem(document, sourceSpan, referencedSymbol.Definition, glyph.GetGlyphIndex()); return result.ToImmutable();
//if (!location.IsInSource)
//{
// return referencedSymbol.Locations.Any()
// ? new MetadataDefinitionTreeItem(
// solution.Workspace,
// referencedSymbol.Definition,
// referencedSymbol.Locations.First().Document.Project.Id,
// glyph.GetGlyphIndex())
// : null;
//}
//var document = solution.GetDocument(location.SourceTree);
//var sourceSpan = location.SourceSpan;
//if (!IsValidSourceLocation(document, sourceSpan))
//{
// return null;
//}
//return new SourceDefinitionTreeItem(document, sourceSpan, referencedSymbol.Definition, glyph.GetGlyphIndex());
} }
private IList<SourceReferenceTreeItem> CreateReferenceItems(Solution solution, HashSet<ValueTuple<Document, TextSpan>> uniqueLocations, IEnumerable<Location> locations) private IList<SourceReferenceTreeItem> CreateReferenceItems(
DefinitionItem definitionItem,
DefinitionsAndReferences definitionsAndReferences)
{ {
var referenceItems = new List<SourceReferenceTreeItem>(); var result = new List<SourceReferenceTreeItem>();
foreach (var location in locations)
{
if (!location.IsInSource)
{
continue;
}
var document = solution.GetDocument(location.SourceTree);
var sourceSpan = location.SourceSpan;
if (!IsValidSourceLocation(document, sourceSpan))
{
continue;
}
if (uniqueLocations.Add(new ValueTuple<Document, TextSpan>(document, sourceSpan)))
{
referenceItems.Add(new SourceReferenceTreeItem(document, sourceSpan, Glyph.Reference.GetGlyphIndex()));
}
}
var linkedReferences = referenceItems.GroupBy(r => r.DisplayText.ToLowerInvariant()).Where(g => g.Count() > 1).SelectMany(g => g); var referenceItems = definitionsAndReferences.References.Where(r => r.Definition == definitionItem);
foreach (var linkedReference in linkedReferences) foreach (var referenceItem in referenceItems)
{ {
linkedReference.AddProjectNameDisambiguator(); var documentLocation = referenceItem.Location;
result.Add(new SourceReferenceTreeItem(
documentLocation.Document,
documentLocation.SourceSpan,
Glyph.Reference.GetGlyphIndex()));
} }
referenceItems.Sort(); //var linkedReferences = referenceItems.GroupBy(r => r.DisplayText.ToLowerInvariant()).Where(g => g.Count() > 1).SelectMany(g => g);
return referenceItems; //foreach (var linkedReference in linkedReferences)
//{
// linkedReference.AddProjectNameDisambiguator();
//}
result.Sort();
return result;
} }
} }
} }
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#if false
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem; using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem;
...@@ -125,3 +126,4 @@ private bool TryNavigateToPosition() ...@@ -125,3 +126,4 @@ private bool TryNavigateToPosition()
} }
} }
} }
#endif
\ No newline at end of file
// 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.Threading;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Editor;
using Microsoft.CodeAnalysis.Editor.Implementation.FindReferences;
using Microsoft.CodeAnalysis.Navigation;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.Library.FindResults
{
internal class MetadataDefinitionTreeItem : AbstractTreeItem
{
private readonly string _assemblyName;
private readonly string _symbolDefinition;
private readonly SymbolKey _symbolKey;
private readonly bool _canGoToDefinition;
private readonly Workspace _workspace;
private readonly ProjectId _referencingProjectId;
public MetadataDefinitionTreeItem(Workspace workspace, ISymbol definition, ProjectId referencingProjectId, ushort glyphIndex)
: base(glyphIndex)
{
_workspace = workspace;
_referencingProjectId = referencingProjectId;
_symbolKey = definition.GetSymbolKey();
_assemblyName = definition.ContainingAssembly?.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat);
_symbolDefinition = definition.ToDisplayString(FindReferencesUtilities.DefinitionDisplayFormat);
_canGoToDefinition = definition.Kind != SymbolKind.Namespace;
this.DisplayText = $"{GetAssemblyNameString()}{_symbolDefinition}";
}
public override bool CanGoToDefinition()
{
return _canGoToDefinition;
}
public override int GoToSource()
{
var symbol = ResolveSymbolInCurrentSolution();
var referencingProject = _workspace.CurrentSolution.GetProject(_referencingProjectId);
if (symbol != null && referencingProject != null)
{
var navigationService = _workspace.Services.GetService<ISymbolNavigationService>();
return navigationService.TryNavigateToSymbol(symbol, referencingProject, cancellationToken: CancellationToken.None)
? VSConstants.S_OK
: VSConstants.E_FAIL;
}
return VSConstants.E_FAIL;
}
private ISymbol ResolveSymbolInCurrentSolution()
{
return _symbolKey.Resolve(_workspace.CurrentSolution.GetProject(_referencingProjectId).GetCompilationAsync(CancellationToken.None).Result).Symbol;
}
internal override void SetReferenceCount(int referenceCount)
{
var referenceCountDisplay = referenceCount == 1
? ServicesVSResources._1_reference
: string.Format(ServicesVSResources._0_references, referenceCount);
this.DisplayText = $"{GetAssemblyNameString()}{_symbolDefinition} ({referenceCountDisplay})";
}
private string GetAssemblyNameString()
{
return (_assemblyName != null && _canGoToDefinition) ? $"[{_assemblyName}] " : string.Empty;
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // 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 Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Completion;
using Microsoft.CodeAnalysis.Editor.Implementation.FindReferences; using Microsoft.CodeAnalysis.Editor.Implementation.FindReferences;
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
using Microsoft.CodeAnalysis.Text; using Microsoft.CodeAnalysis.Text;
using Microsoft.VisualStudio.LanguageServices.Implementation.Utilities;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.Library.FindResults namespace Microsoft.VisualStudio.LanguageServices.Implementation.Library.FindResults
{ {
internal class SourceDefinitionTreeItem : AbstractSourceTreeItem internal class DefinitionTreeItem : AbstractTreeItem
{ {
private readonly bool _canGoToDefinition; private readonly DefinitionItem _definitionItem;
private readonly string _symbolDisplay; private readonly DefinitionLocation _definitionLocation;
public SourceDefinitionTreeItem(Document document, TextSpan sourceSpan, ISymbol symbol, ushort glyphIndex) public DefinitionTreeItem(DefinitionItem definitionItem, DefinitionLocation definitionLocation)
: base(document, sourceSpan, glyphIndex) : base(definitionItem.Tags.GetGlyph().GetGlyphIndex())
{ {
_symbolDisplay = symbol.ToDisplayString(FindReferencesUtilities.DefinitionDisplayFormat); _definitionItem = definitionItem;
_definitionLocation = definitionLocation;
#if false // source base constructor
// We store the document ID, line and offset for navigation so that we
// still provide reasonable navigation if the user makes changes elsewhere
// in the document other than inserting or removing lines.
_workspace = document.Project.Solution.Workspace;
_documentId = document.Id;
_projectName = document.Project.Name;
_filePath = GetFilePath(document, commonPathElements);
_sourceSpan = sourceSpan;
var text = document.GetTextAsync(CancellationToken.None).WaitAndGetResult(CancellationToken.None);
var textLine = text.Lines.GetLineFromPosition(_sourceSpan.Start);
_textLineString = textLine.ToString();
_lineNumber = textLine.LineNumber;
_offset = sourceSpan.Start - textLine.Start;
var spanInSecondaryBuffer = text.GetVsTextSpanForLineOffset(_lineNumber, _offset);
VsTextSpan spanInPrimaryBuffer;
var succeeded = spanInSecondaryBuffer.TryMapSpanFromSecondaryBufferToPrimaryBuffer(_workspace, _documentId, out spanInPrimaryBuffer);
_mappedLineNumber = succeeded ? spanInPrimaryBuffer.iStartLine : _lineNumber;
_mappedOffset = succeeded ? spanInPrimaryBuffer.iStartIndex : _offset;
#endif
#if false // source contructor
_symbolDisplay = symbol.ToDisplayString(FindReferencesUtilities.DefinitionDisplayFormat);
this.DisplayText = $"{GetProjectNameString()}{_symbolDisplay}"; this.DisplayText = $"{GetProjectNameString()}{_symbolDisplay}";
_canGoToDefinition = symbol.Kind != SymbolKind.Namespace; _canGoToDefinition = symbol.Kind != SymbolKind.Namespace;
#endif
#if false // metadata constructor
_workspace = workspace;
_referencingProjectId = referencingProjectId;
_symbolKey = definition.GetSymbolKey();
_assemblyName = definition.ContainingAssembly?.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat);
_symbolDefinition = definition.ToDisplayString(FindReferencesUtilities.DefinitionDisplayFormat);
_canGoToDefinition = definition.Kind != SymbolKind.Namespace;
this.DisplayText = $"{GetAssemblyNameString()}{_symbolDefinition}";
#endif
}
public override int GoToSource()
{
return _definitionLocation.TryNavigateTo()
? VSConstants.S_OK
: VSConstants.E_FAIL;
} }
public override bool CanGoToDefinition() public override bool CanGoToDefinition()
{ {
return _canGoToDefinition; return _definitionLocation.CanNavigateTo();
} }
internal override void SetReferenceCount(int referenceCount) internal override void SetReferenceCount(int referenceCount)
{ {
// source case.
var referenceCountDisplay = referenceCount == 1 var referenceCountDisplay = referenceCount == 1
? ServicesVSResources._1_reference ? ServicesVSResources._1_reference
: string.Format(ServicesVSResources._0_references, referenceCount); : string.Format(ServicesVSResources._0_references, referenceCount);
#if false // source case
this.DisplayText = $"{GetProjectNameString()}{_symbolDisplay} ({referenceCountDisplay})"; this.DisplayText = $"{GetProjectNameString()}{_symbolDisplay} ({referenceCountDisplay})";
#endif
#if false // metadata case
var referenceCountDisplay = referenceCount == 1
? ServicesVSResources._1_reference
: string.Format(ServicesVSResources._0_references, referenceCount);
this.DisplayText = $"{GetAssemblyNameString()}{_symbolDefinition} ({referenceCountDisplay})";
#endif
}
#if false
private string GetAssemblyNameString()
{
return (_assemblyName != null && _canGoToDefinition) ? $"[{_assemblyName}] " : string.Empty;
} }
#endif
private string GetProjectNameString() private string GetProjectNameString()
{ {
return "";
#if false
return (_projectName != null && _canGoToDefinition) ? $"[{_projectName}] " : string.Empty; return (_projectName != null && _canGoToDefinition) ? $"[{_projectName}] " : string.Empty;
#endif
} }
} }
} }
\ No newline at end of file
...@@ -30,18 +30,9 @@ public SourceReferenceTreeItem(Document document, TextSpan sourceSpan, ushort gl ...@@ -30,18 +30,9 @@ public SourceReferenceTreeItem(Document document, TextSpan sourceSpan, ushort gl
} }
} }
public override bool CanGoToReference() public override bool CanGoToReference() => true;
{
return true;
}
public override bool UseGrayText public override bool UseGrayText => false;
{
get
{
return false;
}
}
public void AddProjectNameDisambiguator() public void AddProjectNameDisambiguator()
{ {
...@@ -70,4 +61,4 @@ int IComparable<SourceReferenceTreeItem>.CompareTo(SourceReferenceTreeItem other ...@@ -70,4 +61,4 @@ int IComparable<SourceReferenceTreeItem>.CompareTo(SourceReferenceTreeItem other
return compare; return compare;
} }
} }
} }
\ No newline at end of file
...@@ -125,7 +125,7 @@ protected override void LoadComponentsInUIContext() ...@@ -125,7 +125,7 @@ protected override void LoadComponentsInUIContext()
this.ComponentModel.GetService<VisualStudioDiagnosticListTableCommandHandler>().Initialize(this); this.ComponentModel.GetService<VisualStudioDiagnosticListTableCommandHandler>().Initialize(this);
this.ComponentModel.GetService<HACK_ThemeColorFixer>(); this.ComponentModel.GetService<HACK_ThemeColorFixer>();
this.ComponentModel.GetExtensions<IReferencedSymbolsPresenter>(); this.ComponentModel.GetExtensions<IFindReferencesPresenter>();
this.ComponentModel.GetExtensions<INavigableItemsPresenter>(); this.ComponentModel.GetExtensions<INavigableItemsPresenter>();
this.ComponentModel.GetService<VisualStudioMetadataAsSourceFileSupportService>(); this.ComponentModel.GetService<VisualStudioMetadataAsSourceFileSupportService>();
this.ComponentModel.GetService<VirtualMemoryNotificationListener>(); this.ComponentModel.GetService<VirtualMemoryNotificationListener>();
......
...@@ -75,7 +75,6 @@ ...@@ -75,7 +75,6 @@
<Compile Include="Implementation\Library\AbstractLibraryService.cs" /> <Compile Include="Implementation\Library\AbstractLibraryService.cs" />
<Compile Include="Implementation\Library\ClassView\AbstractSyncClassViewCommandHandler.cs" /> <Compile Include="Implementation\Library\ClassView\AbstractSyncClassViewCommandHandler.cs" />
<Compile Include="Implementation\Library\FindResults\TreeItems\AbstractSourceTreeItem.cs" /> <Compile Include="Implementation\Library\FindResults\TreeItems\AbstractSourceTreeItem.cs" />
<Compile Include="Implementation\Library\FindResults\TreeItems\MetadataDefinitionTreeItem.cs" />
<Compile Include="Implementation\Library\FindResults\TreeItems\SourceDefinitionTreeItem.cs" /> <Compile Include="Implementation\Library\FindResults\TreeItems\SourceDefinitionTreeItem.cs" />
<Compile Include="Implementation\Library\ILibraryService.cs" /> <Compile Include="Implementation\Library\ILibraryService.cs" />
<Compile Include="Implementation\Library\ObjectBrowser\ObjectBrowserTaskExtensions.cs" /> <Compile Include="Implementation\Library\ObjectBrowser\ObjectBrowserTaskExtensions.cs" />
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Editor; using Microsoft.CodeAnalysis.Editor;
using Microsoft.CodeAnalysis.Editor.Host; using Microsoft.CodeAnalysis.Editor.Host;
using Microsoft.CodeAnalysis.Editor.Implementation.FindReferences;
using Microsoft.CodeAnalysis.Editor.Implementation.GoToDefinition; using Microsoft.CodeAnalysis.Editor.Implementation.GoToDefinition;
using Microsoft.CodeAnalysis.Editor.Undo; using Microsoft.CodeAnalysis.Editor.Undo;
using Microsoft.CodeAnalysis.FindSymbols; using Microsoft.CodeAnalysis.FindSymbols;
...@@ -27,7 +28,7 @@ namespace Microsoft.VisualStudio.LanguageServices ...@@ -27,7 +28,7 @@ namespace Microsoft.VisualStudio.LanguageServices
internal class RoslynVisualStudioWorkspace : VisualStudioWorkspaceImpl internal class RoslynVisualStudioWorkspace : VisualStudioWorkspaceImpl
{ {
private readonly IEnumerable<Lazy<INavigableItemsPresenter>> _navigableItemsPresenters; private readonly IEnumerable<Lazy<INavigableItemsPresenter>> _navigableItemsPresenters;
private readonly IEnumerable<Lazy<IReferencedSymbolsPresenter>> _referencedSymbolsPresenters; private readonly IEnumerable<Lazy<IFindReferencesPresenter>> _referencedSymbolsPresenters;
private readonly IEnumerable<Lazy<INavigableDefinitionProvider>> _externalDefinitionProviders; private readonly IEnumerable<Lazy<INavigableDefinitionProvider>> _externalDefinitionProviders;
[ImportingConstructor] [ImportingConstructor]
...@@ -35,7 +36,7 @@ internal class RoslynVisualStudioWorkspace : VisualStudioWorkspaceImpl ...@@ -35,7 +36,7 @@ internal class RoslynVisualStudioWorkspace : VisualStudioWorkspaceImpl
SVsServiceProvider serviceProvider, SVsServiceProvider serviceProvider,
SaveEventsService saveEventsService, SaveEventsService saveEventsService,
[ImportMany] IEnumerable<Lazy<INavigableItemsPresenter>> navigableItemsPresenters, [ImportMany] IEnumerable<Lazy<INavigableItemsPresenter>> navigableItemsPresenters,
[ImportMany] IEnumerable<Lazy<IReferencedSymbolsPresenter>> referencedSymbolsPresenters, [ImportMany] IEnumerable<Lazy<IFindReferencesPresenter>> referencedSymbolsPresenters,
[ImportMany] IEnumerable<Lazy<INavigableDefinitionProvider>> externalDefinitionProviders) [ImportMany] IEnumerable<Lazy<INavigableDefinitionProvider>> externalDefinitionProviders)
: base( : base(
serviceProvider, serviceProvider,
...@@ -222,11 +223,16 @@ public override bool TryFindAllReferences(ISymbol symbol, Project project, Cance ...@@ -222,11 +223,16 @@ public override bool TryFindAllReferences(ISymbol symbol, Project project, Cance
return false; return false;
} }
public override void DisplayReferencedSymbols(Solution solution, IEnumerable<ReferencedSymbol> referencedSymbols) public override void DisplayReferencedSymbols(
Solution solution, IEnumerable<ReferencedSymbol> referencedSymbols)
{ {
var service = this.Services.GetService<IDefinitionsAndReferencesFactory>();
var definitionsAndReferences = service.CreateDefinitionsAndReferences(solution, referencedSymbols);
foreach (var presenter in _referencedSymbolsPresenters) foreach (var presenter in _referencedSymbolsPresenters)
{ {
presenter.Value.DisplayResult(solution, referencedSymbols); presenter.Value.DisplayResult(definitionsAndReferences);
return;
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册