提交 d855c686 编写于 作者: D David Poeschl

Hierarchical Find References

In this initial implementation, find references results are now grouped by the definition that they directly reference.

For symbols defined in metadata, we previously showed the references without showing the definition itself. We now show the metadata definition as well.
上级 6c617af2
// 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;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.Library.FindResults
{
internal abstract class AbstractListItem
{
public ushort GlyphIndex { get; private set; }
public string DisplayText { get; private set; }
public ushort DisplaySelectionStart { get; private set; }
public ushort DisplaySelectionLength { get; private set; }
protected AbstractListItem(ushort glyphIndex)
{
this.GlyphIndex = glyphIndex;
}
protected void SetDisplayProperties(string filePath, int mappedLineNumber, int mappedOffset, int lineNumber, int offset, string lineText, int spanLength)
{
// TODO: Old C# code base has a helper, GetLineTextWithUnicodeDirectionMarkersIfNeeded, which we will need at some point.
var sourceSnippet = lineText.Replace('\t', ' ').TrimStart(' ');
var displayText = GetDisplayText(filePath, mappedLineNumber + 1, mappedOffset + 1, sourceSnippet);
var selectionStart = offset + displayText.Length - lineText.Length;
displayText = displayText.TrimEnd();
if (displayText.Length > ushort.MaxValue)
{
displayText = displayText.Substring(0, ushort.MaxValue);
}
this.DisplayText = displayText;
this.DisplaySelectionStart = checked((ushort)Math.Min(ushort.MaxValue, selectionStart));
this.DisplaySelectionLength = checked((ushort)Math.Min(spanLength, DisplayText.Length - DisplaySelectionStart));
}
private static string GetDisplayText(string fileName, int lineNumber, int offset, string sourceText)
{
if (string.IsNullOrWhiteSpace(fileName))
{
return string.Format("({0}, {1}) : {2}", lineNumber, offset, sourceText);
}
else
{
return string.Format("{0} - ({1}, {2}) : {3}", fileName, lineNumber, offset, sourceText);
}
}
public abstract int GoToSource();
}
}
......@@ -4,7 +4,6 @@
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.FindSymbols;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Navigation;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Text;
......@@ -35,12 +34,14 @@ public void PresentReferencedSymbols(string title, Solution solution, IEnumerabl
PresentObjectList(title, new ObjectList(CreateFindReferencesItems(solution, items), this));
}
private IList<AbstractListItem> CreateFindReferencesItems(Solution solution, IEnumerable<ReferencedSymbol> referencedSymbols)
private IList<AbstractTreeItem> CreateFindReferencesItems(Solution solution, IEnumerable<ReferencedSymbol> referencedSymbols)
{
var list = new List<AbstractListItem>();
HashSet<ValueTuple<Document, TextSpan>> uniqueLocations = null;
var definitions = new List<AbstractTreeItem>();
var uniqueLocations = new HashSet<ValueTuple<Document, TextSpan>>();
var symbolNavigationService = solution.Workspace.Services.GetService<ISymbolNavigationService>();
referencedSymbols = referencedSymbols.FilterUnreferencedSyntheticDefinitions().ToList();
foreach (var referencedSymbol in referencedSymbols)
{
if (!IncludeDefinition(referencedSymbol))
......@@ -50,30 +51,60 @@ private IList<AbstractListItem> CreateFindReferencesItems(Solution solution, IEn
var definition = referencedSymbol.Definition;
var locations = definition.Locations;
uniqueLocations = AddLocations(solution, list, uniqueLocations, locations, definition.GetGlyph());
uniqueLocations = AddLocations(solution, list, uniqueLocations, referencedSymbol.Locations.Select(loc => loc.Location), Glyph.Reference);
string filePath;
int lineNumber, charOffset;
var symbolNavigationService = solution.Workspace.Services.GetService<ISymbolNavigationService>();
foreach (var definitionLocation in definition.Locations)
{
var definitionItem = ConvertToDefinitionItem(solution, referencedSymbol, uniqueLocations, definitionLocation, definition.GetGlyph());
if (definitionItem != null)
{
definitions.Add(definitionItem);
var referenceItems = CreateReferenceItems(solution, uniqueLocations, referencedSymbol.Locations.Select(loc => loc.Location), Glyph.Reference);
definitionItem.Children.AddRange(referenceItems);
(definitionItem as ITreeItemWithReferenceCount)?.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))
{
list.Add(new ExternalListItem(filePath, lineNumber, charOffset, definition.Name, definition.GetGlyph().GetGlyphIndex(), this.ServiceProvider));
definitions.Add(new ExternalLanguageDefinitionTreeItem(filePath, lineNumber, charOffset, definition.Name, definition.GetGlyph().GetGlyphIndex(), this.ServiceProvider));
}
}
return list;
return definitions;
}
private HashSet<ValueTuple<Document, TextSpan>> AddLocations(
private AbstractTreeItem ConvertToDefinitionItem(
Solution solution,
List<AbstractListItem> list,
ReferencedSymbol referencedSymbol,
HashSet<ValueTuple<Document, TextSpan>> uniqueLocations,
IEnumerable<Location> locations,
Location location,
Glyph glyph)
{
if (!location.IsInSource)
{
return referencedSymbol.Locations.Any()
? new MetadataDefinitionTreeItem(referencedSymbol.Definition, glyph.GetGlyphIndex())
: null;
}
var document = solution.GetDocument(location.SourceTree);
var sourceSpan = location.SourceSpan;
if (!IsValidSourceLocation(document, sourceSpan) ||
!uniqueLocations.Add(new ValueTuple<Document, TextSpan>(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, Glyph glyph)
{
var referenceItems = new List<SourceReferenceTreeItem>();
foreach (var location in locations)
{
if (!location.IsInSource)
......@@ -88,15 +119,20 @@ private IList<AbstractListItem> CreateFindReferencesItems(Solution solution, IEn
continue;
}
uniqueLocations = uniqueLocations ?? new HashSet<ValueTuple<Document, TextSpan>>();
if (uniqueLocations.Add(new ValueTuple<Document, TextSpan>(document, sourceSpan)))
{
list.Add(new SourceListItem(document, sourceSpan, glyph.GetGlyphIndex()));
referenceItems.Add(new SourceReferenceTreeItem(document, sourceSpan, glyph.GetGlyphIndex()));
}
}
return uniqueLocations;
var linkedReferences = referenceItems.GroupBy(r => r.DisplayText.ToLowerInvariant()).Where(g => g.Count() > 1).SelectMany(g => g);
foreach (var linkedReference in linkedReferences)
{
linkedReference.AddProjectNameDisambiguator();
}
referenceItems.Sort();
return referenceItems;
}
}
}
......@@ -11,12 +11,12 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.Library.FindRes
{
internal partial class LibraryManager
{
private IList<AbstractListItem> CreateGoToDefinitionItems(IEnumerable<INavigableItem> items)
private IList<AbstractTreeItem> CreateGoToDefinitionItems(IEnumerable<INavigableItem> items)
{
var sourceListItems =
from item in items
where IsValidSourceLocation(item.Document, item.SourceSpan)
select (AbstractListItem)new SourceListItem(item.Document, item.SourceSpan, item.Glyph.GetGlyphIndex());
select (AbstractTreeItem)new SourceReferenceTreeItem(item.Document, item.SourceSpan, item.Glyph.GetGlyphIndex());
return sourceListItems.ToList();
}
......
......@@ -4,14 +4,15 @@
using Microsoft.CodeAnalysis;
using Microsoft.VisualStudio.LanguageServices.Implementation.Utilities;
using Microsoft.VisualStudio.Shell.Interop;
using System.Linq;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.Library.FindResults
{
internal class ObjectList : AbstractObjectList<LibraryManager>
{
private readonly IList<AbstractListItem> _items;
private readonly IList<AbstractTreeItem> _items;
public ObjectList(IList<AbstractListItem> items, LibraryManager manager)
public ObjectList(IList<AbstractTreeItem> items, LibraryManager manager)
: base(manager)
{
_items = items;
......@@ -27,10 +28,10 @@ protected override bool CanGoToSource(uint index, VSOBJGOTOSRCTYPE srcType)
return true;
case VSOBJGOTOSRCTYPE.GS_DEFINITION:
return item.GlyphIndex != Glyph.Reference.GetGlyphIndex();
return item.GlyphIndex != Glyph.Reference.GetGlyphIndex() && item.CanGoToSource;
case VSOBJGOTOSRCTYPE.GS_REFERENCE:
return item.GlyphIndex == Glyph.Reference.GetGlyphIndex();
return item.GlyphIndex == Glyph.Reference.GetGlyphIndex() && item.CanGoToSource;
}
return false;
......@@ -56,13 +57,20 @@ protected override void GetDisplayData(uint index, ref VSTREEDISPLAYDATA data)
data.Image = item.GlyphIndex;
data.SelectedImage = item.GlyphIndex;
data.State |= (uint)_VSTREEDISPLAYSTATE.TDS_FORCESELECT;
if (item.UseGrayText)
{
data.State |= (uint)_VSTREEDISPLAYSTATE.TDS_GRAYTEXT;
}
data.ForceSelectStart = item.DisplaySelectionStart;
data.ForceSelectLength = item.DisplaySelectionLength;
}
protected override bool GetExpandable(uint index, uint listTypeExcluded)
{
return false;
var item = _items[(int)index];
return (item?.Children?.Any() == true);
}
protected override uint GetItemCount()
......@@ -72,7 +80,8 @@ protected override uint GetItemCount()
protected override IVsSimpleObjectList2 GetList(uint index, uint listType, uint flags, VSOBSEARCHCRITERIA2[] pobSrch)
{
return null;
var item = _items[(int)index];
return (item?.Children?.Any() == true) ? new ObjectList(item.Children, LibraryManager) : null;
}
protected override string GetText(uint index, VSTREETEXTOPTIONS tto)
......
......@@ -2,7 +2,6 @@
using System.Threading;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Navigation;
using Microsoft.CodeAnalysis.Text;
using Microsoft.VisualStudio.LanguageServices.Implementation.Extensions;
......@@ -11,32 +10,35 @@
namespace Microsoft.VisualStudio.LanguageServices.Implementation.Library.FindResults
{
internal class SourceListItem : AbstractListItem
internal abstract class AbstractSourceTreeItem : AbstractTreeItem
{
private readonly Workspace _workspace;
private readonly DocumentId _documentId;
private readonly int _lineNumber;
private readonly int _offset;
protected readonly Workspace _workspace;
protected readonly DocumentId _documentId;
protected readonly string _projectName;
protected readonly string _filePath;
protected readonly TextSpan _sourceSpan;
protected readonly string _textLineString;
protected readonly int _lineNumber;
protected readonly int _offset;
protected readonly int _mappedLineNumber;
protected readonly int _mappedOffset;
public SourceListItem(Location location, Solution solution, ushort glyphIndex)
: this(solution.GetDocument(location.SourceTree), location.SourceSpan, glyphIndex)
public AbstractSourceTreeItem(Document document, TextSpan sourceSpan, ushort glyphIndex)
: base (glyphIndex)
{
}
public SourceListItem(Document document, TextSpan sourceSpan, ushort glyphIndex)
: base(glyphIndex)
{
_workspace = document.Project.Solution.Workspace;
// 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.
_documentId = document.Id;
var filePath = document.FilePath;
_workspace = document.Project.Solution.Workspace;
_documentId = document.Id;
_projectName = document.Project.Name;
_filePath = document.FilePath;
_sourceSpan = sourceSpan;
var text = document.GetTextAsync(CancellationToken.None).WaitAndGetResult(CancellationToken.None);
var textLine = text.Lines.GetLineFromPosition(sourceSpan.Start);
var textLine = text.Lines.GetLineFromPosition(_sourceSpan.Start);
_textLineString = textLine.ToString();
_lineNumber = textLine.LineNumber;
_offset = sourceSpan.Start - textLine.Start;
......@@ -44,12 +46,11 @@ public SourceListItem(Document document, TextSpan sourceSpan, ushort glyphIndex)
var spanInSecondaryBuffer = text.GetVsTextSpanForLineOffset(_lineNumber, _offset);
VsTextSpan spanInPrimaryBuffer;
var succeeded = spanInSecondaryBuffer.TryMapSpanFromSecondaryBufferToPrimaryBuffer(_workspace, document.Id, out spanInPrimaryBuffer);
var succeeded = spanInSecondaryBuffer.TryMapSpanFromSecondaryBufferToPrimaryBuffer(_workspace, _documentId, out spanInPrimaryBuffer);
var mappedLineNumber = succeeded ? spanInPrimaryBuffer.iStartLine : _lineNumber;
var mappedOffset = succeeded ? spanInPrimaryBuffer.iStartIndex : _offset;
_mappedLineNumber = succeeded ? spanInPrimaryBuffer.iStartLine : _lineNumber;
_mappedOffset = succeeded ? spanInPrimaryBuffer.iStartIndex : _offset;
SetDisplayProperties(filePath, mappedLineNumber, mappedOffset, _lineNumber, _offset, textLine.ToString(), sourceSpan.Length);
}
public override int GoToSource()
......
// 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;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.Library.FindResults
{
internal abstract class AbstractTreeItem
{
public IList<AbstractTreeItem> Children { get; protected set; }
public ushort GlyphIndex { get; protected set; }
// TODO: Old C# code base has a helper, GetLineTextWithUnicodeDirectionMarkersIfNeeded, which we will need at some point.
public string DisplayText { get; protected set; }
public ushort DisplaySelectionStart { get; protected set; }
public ushort DisplaySelectionLength { get; protected set; }
public virtual bool UseGrayText
{
get
{
return false;
}
}
public virtual bool CanGoToSource
{
get
{
return true;
}
}
protected static readonly SymbolDisplayFormat definitionDisplayFormat =
new SymbolDisplayFormat(
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces,
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters,
parameterOptions: SymbolDisplayParameterOptions.IncludeType,
propertyStyle: SymbolDisplayPropertyStyle.ShowReadWriteDescriptor,
delegateStyle: SymbolDisplayDelegateStyle.NameAndSignature,
kindOptions: SymbolDisplayKindOptions.IncludeMemberKeyword | SymbolDisplayKindOptions.IncludeNamespaceKeyword | SymbolDisplayKindOptions.IncludeTypeKeyword,
localOptions: SymbolDisplayLocalOptions.IncludeType,
memberOptions:
SymbolDisplayMemberOptions.IncludeAccessibility |
SymbolDisplayMemberOptions.IncludeContainingType |
SymbolDisplayMemberOptions.IncludeExplicitInterface |
SymbolDisplayMemberOptions.IncludeModifiers |
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeType,
miscellaneousOptions:
SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers |
SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
protected AbstractTreeItem(ushort glyphIndex)
{
this.Children = new List<AbstractTreeItem>();
this.GlyphIndex = glyphIndex;
}
public abstract int GoToSource();
protected void SetDisplayProperties(string filePath, int mappedLineNumber, int mappedOffset, int offset, string lineText, int spanLength, string projectNameDisambiguator)
{
var sourceSnippet = lineText.Replace('\t', ' ').TrimStart(' ');
var displayText = GetDisplayText(filePath, projectNameDisambiguator, mappedLineNumber + 1, mappedOffset + 1, sourceSnippet);
var selectionStart = offset + displayText.Length - lineText.Length;
displayText = displayText.TrimEnd();
if (displayText.Length > ushort.MaxValue)
{
displayText = displayText.Substring(0, ushort.MaxValue);
}
this.DisplayText = displayText;
this.DisplaySelectionStart = checked((ushort)Math.Min(ushort.MaxValue, selectionStart));
this.DisplaySelectionLength = checked((ushort)Math.Min(spanLength, DisplayText.Length - DisplaySelectionStart));
}
private static string GetDisplayText(string fileName, string projectNameDisambiguator, int lineNumber, int offset, string sourceText)
{
var fileLocationDescription = GetFileLocationsText(fileName, projectNameDisambiguator);
return string.IsNullOrWhiteSpace(fileLocationDescription)
? $"({lineNumber}, {offset}) : {sourceText}"
: $"{fileLocationDescription} - ({lineNumber}, {offset}) : {sourceText}";
}
private static string GetFileLocationsText(string fileName, string projectNameDisambiguator)
{
if (!string.IsNullOrWhiteSpace(fileName) && !string.IsNullOrWhiteSpace(projectNameDisambiguator))
{
return $"{fileName} [{projectNameDisambiguator}]";
}
if (!string.IsNullOrWhiteSpace(fileName))
{
return fileName;
}
if (!string.IsNullOrWhiteSpace(projectNameDisambiguator))
{
return $"[{projectNameDisambiguator}]";
}
return string.Empty;
}
}
}
......@@ -9,14 +9,17 @@
namespace Microsoft.VisualStudio.LanguageServices.Implementation.Library.FindResults
{
internal class ExternalListItem : AbstractListItem
internal class ExternalLanguageDefinitionTreeItem : AbstractTreeItem
{
private readonly IServiceProvider _serviceProvider;
private readonly string _filePath;
private readonly int _lineNumber;
private readonly int _charOffset;
public ExternalListItem(string filePath, int lineNumber, int offset, string symbolName, ushort glyphIndex, IServiceProvider serviceProvider)
/// <summary>
/// A definition from an external language service (e.g. xaml).
/// </summary>
public ExternalLanguageDefinitionTreeItem(string filePath, int lineNumber, int offset, string symbolName, ushort glyphIndex, IServiceProvider serviceProvider)
: base(glyphIndex)
{
_filePath = filePath;
......@@ -24,7 +27,14 @@ public ExternalListItem(string filePath, int lineNumber, int offset, string symb
_charOffset = offset;
_serviceProvider = serviceProvider;
SetDisplayProperties(filePath, lineNumber, offset, lineNumber, offset, GetSourceLine(filePath, lineNumber, serviceProvider), symbolName.Length);
SetDisplayProperties(
filePath,
lineNumber,
offset,
offset,
GetSourceLine(filePath, lineNumber, serviceProvider),
symbolName.Length,
projectNameDisambiguator: string.Empty);
}
private static string GetSourceLine(string filePath, int lineNumber, IServiceProvider serviceProvider)
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.VisualStudio.LanguageServices.Implementation.Library.FindResults
{
internal interface ITreeItemWithReferenceCount
{
void SetReferenceCount(int referenceCount);
}
}
// 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;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.Library.FindResults
{
internal class MetadataDefinitionTreeItem : AbstractTreeItem, ITreeItemWithReferenceCount
{
private readonly string _assemblyName;
private readonly string _symbolDefinition;
public override bool CanGoToSource
{
get
{
return false;
}
}
public override bool UseGrayText
{
get
{
return true;
}
}
public MetadataDefinitionTreeItem(ISymbol definition, ushort glyphIndex)
: base(glyphIndex)
{
_assemblyName = definition.ContainingAssembly.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat);
_symbolDefinition = definition.ToDisplayString(definitionDisplayFormat);
this.DisplayText = $"[{_assemblyName}] {_symbolDefinition}";
}
public override int GoToSource()
{
return VSConstants.E_NOTIMPL;
}
public void SetReferenceCount(int referenceCount)
{
if (referenceCount > 0)
{
var referenceCountDisplay = referenceCount == 1
? string.Format(ServicesVSResources.ReferenceCountSingular, referenceCount)
: string.Format(ServicesVSResources.ReferenceCountPlural, referenceCount);
this.DisplayText = $"[{_assemblyName}] {_symbolDefinition} ({referenceCountDisplay})";
}
}
}
}
// 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.Text;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.Library.FindResults
{
internal class SourceDefinitionTreeItem : AbstractSourceTreeItem, ITreeItemWithReferenceCount
{
private readonly string _symbolDisplay;
public SourceDefinitionTreeItem(Document document, TextSpan sourceSpan, ISymbol symbol, ushort glyphIndex)
: base(document, sourceSpan, glyphIndex)
{
_symbolDisplay = symbol.ToDisplayString(definitionDisplayFormat);
this.DisplayText = $"[{document.Project.Name}] {_symbolDisplay}";
}
public void SetReferenceCount(int referenceCount)
{
if (referenceCount > 0)
{
var referenceCountDisplay = referenceCount == 1
? string.Format(ServicesVSResources.ReferenceCountSingular, referenceCount)
: string.Format(ServicesVSResources.ReferenceCountPlural, referenceCount);
this.DisplayText = $"[{_projectName}] {_symbolDisplay} ({referenceCountDisplay})";
}
}
}
}
// 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.Text;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.Library.FindResults
{
internal class SourceReferenceTreeItem : AbstractSourceTreeItem, IComparable<SourceReferenceTreeItem>
{
public SourceReferenceTreeItem(Location location, Solution solution, ushort glyphIndex)
: this(solution.GetDocument(location.SourceTree), location.SourceSpan, glyphIndex)
{
}
public SourceReferenceTreeItem(Document document, TextSpan sourceSpan, ushort glyphIndex)
: this (document, sourceSpan, glyphIndex, includeProjectNameDisambiguator: false)
{
}
public SourceReferenceTreeItem(Document document, TextSpan sourceSpan, ushort glyphIndex, bool includeProjectNameDisambiguator)
: base(document, sourceSpan, glyphIndex)
{
SetDisplayProperties(
_filePath,
_mappedLineNumber,
_mappedOffset,
_offset,
_textLineString,
sourceSpan.Length,
projectNameDisambiguator: string.Empty);
}
public void AddProjectNameDisambiguator()
{
SetDisplayProperties(
_filePath,
_mappedLineNumber,
_mappedOffset,
_offset,
_textLineString,
_sourceSpan.Length,
projectNameDisambiguator: _projectName);
}
int IComparable<SourceReferenceTreeItem>.CompareTo(SourceReferenceTreeItem other)
{
if (other == null)
{
return 1;
}
int compare = _filePath.CompareTo(other._filePath);
compare = compare != 0 ? compare : _lineNumber.CompareTo(other._lineNumber);
compare = compare != 0 ? compare : _offset.CompareTo(other._offset);
compare = compare != 0 ? compare : _projectName.CompareTo(other._projectName);
return compare;
}
}
}
......@@ -840,6 +840,24 @@ internal class ServicesVSResources {
}
}
/// <summary>
/// Looks up a localized string similar to {0} references.
/// </summary>
internal static string ReferenceCountPlural {
get {
return ResourceManager.GetString("ReferenceCountPlural", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to {0} reference.
/// </summary>
internal static string ReferenceCountSingular {
get {
return ResourceManager.GetString("ReferenceCountSingular", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The following references were not found. {0}Please locate and add them manually..
/// </summary>
......
......@@ -447,4 +447,10 @@ Use the dropdown to view and switch to other projects this file may belong to.</
<data name="WRN_AnalyzerDependencyConflictMessage" xml:space="preserve">
<value>Assembly '{0}' used by analyzer '{1}' and assembly '{2}' used by analyzer '{3}' have the same identity but different contents. These analyzers may not run correctly.</value>
</data>
<data name="ReferenceCountPlural" xml:space="preserve">
<value>{0} references</value>
</data>
<data name="ReferenceCountSingular" xml:space="preserve">
<value>{0} reference</value>
</data>
</root>
\ No newline at end of file
......@@ -23,6 +23,10 @@
<Compile Include="Implementation\AnalyzerDependencyConflict.cs" />
<Compile Include="Implementation\CompilationErrorTelemetry\CompilationErrorTelemetryIncrementalAnalyzer.cs" />
<Compile Include="Implementation\Diagnostics\VisualStudioVenusSpanMappingService.cs" />
<Compile Include="Implementation\Library\FindResults\TreeItems\AbstractSourceTreeItem.cs" />
<Compile Include="Implementation\Library\FindResults\TreeItems\ITreeItemWithReferenceCount.cs" />
<Compile Include="Implementation\Library\FindResults\TreeItems\MetadataDefinitionTreeItem.cs" />
<Compile Include="Implementation\Library\FindResults\TreeItems\SourceDefinitionTreeItem.cs" />
<Compile Include="Implementation\Preview\ReferenceChange.MetadataReferenceChange.cs" />
<Compile Include="Implementation\Preview\ReferenceChange.AnalyzerReferenceChange.cs" />
<Compile Include="Implementation\Preview\ReferenceChange.ProjectReferenceChange.cs" />
......@@ -418,14 +422,14 @@
<Compile Include="Implementation\Library\AbstractLibraryManager_IVsLibraryMgr.cs" />
<Compile Include="Implementation\Library\AbstractLibraryManager_IVsSimpleLibrary2.cs" />
<Compile Include="Implementation\Library\AbstractObjectList.cs" />
<Compile Include="Implementation\Library\FindResults\AbstractListItem.cs" />
<Compile Include="Implementation\Library\FindResults\ExternalListItem.cs" />
<Compile Include="Implementation\Library\FindResults\TreeItems\AbstractTreeItem.cs" />
<Compile Include="Implementation\Library\FindResults\TreeItems\ExternalLanguageDefinitionTreeItem.cs" />
<Compile Include="Implementation\Library\FindResults\LibraryManager.cs" />
<Compile Include="Implementation\Library\FindResults\LibraryManager_FindReferences.cs" />
<Compile Include="Implementation\Library\FindResults\LibraryManager_GoToDefinition.cs" />
<Compile Include="Implementation\Library\FindResults\NavInfo.cs" />
<Compile Include="Implementation\Library\FindResults\ObjectList.cs" />
<Compile Include="Implementation\Library\FindResults\SourceListItem.cs" />
<Compile Include="Implementation\Library\FindResults\TreeItems\SourceReferenceTreeItem.cs" />
<Compile Include="Implementation\Library\ObjectBrowser\AbstractDescriptionBuilder.cs" />
<Compile Include="Implementation\Library\ObjectBrowser\AbstractDescriptionBuilder.LinkFlags.cs" />
<Compile Include="Implementation\Library\ObjectBrowser\AbstractObjectBrowserLibraryManager.cs" />
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册