提交 351c2546 编写于 作者: C CyrusNajmabadi

Put partial references underneath definitions.

上级 9a7a5387
...@@ -65,11 +65,11 @@ public void ExecuteCommand(FindReferencesCommandArgs args, Action nextHandler) ...@@ -65,11 +65,11 @@ public void ExecuteCommand(FindReferencesCommandArgs args, Action nextHandler)
// See if we're running on a host that can provide streaming results. // See if we're running on a host that can provide streaming results.
// We'll both need a FAR service that can stream results to us, and // We'll both need a FAR service that can stream results to us, and
// a presenter that can accept streamed results. // a presenter that can accept streamed results.
if (streamingService != null && streamingPresenter != null) //if (streamingService != null && streamingPresenter != null)
{ //{
StreamingFindReferences(document, streamingService, streamingPresenter, caretPosition); // StreamingFindReferences(document, streamingService, streamingPresenter, caretPosition);
return; // return;
} //}
// Otherwise, either the language doesn't support streaming results, // Otherwise, either the language doesn't support streaming results,
// or the host has no way to present results in a sreaming manner. // or the host has no way to present results in a sreaming manner.
......
...@@ -23,10 +23,15 @@ internal sealed class DefinitionItem ...@@ -23,10 +23,15 @@ internal sealed class DefinitionItem
public ImmutableArray<TaggedText> DisplayParts { get; } public ImmutableArray<TaggedText> DisplayParts { get; }
/// <summary> /// <summary>
/// The locations to present in the UI. A definition may have multiple locations for cases /// The main locations to present in the UI.
/// like partial types/members.
/// </summary> /// </summary>
public ImmutableArray<DefinitionLocation> Locations { get; } public DefinitionLocation MainLocation { get; }
/// <summary>
/// Additional locations to present in the UI. A definition may have multiple locations
/// for cases like partial types/members.
/// </summary>
public ImmutableArray<DocumentLocation> AdditionalLocations { get; }
/// <summary> /// <summary>
/// Whether or not this definition should be presented if we never found any references to /// Whether or not this definition should be presented if we never found any references to
...@@ -43,12 +48,14 @@ internal sealed class DefinitionItem ...@@ -43,12 +48,14 @@ internal sealed class DefinitionItem
public DefinitionItem( public DefinitionItem(
ImmutableArray<string> tags, ImmutableArray<string> tags,
ImmutableArray<TaggedText> displayParts, ImmutableArray<TaggedText> displayParts,
ImmutableArray<DefinitionLocation> locations, DefinitionLocation mainLocation,
ImmutableArray<DocumentLocation> additionalLocations,
bool displayIfNoReferences) bool displayIfNoReferences)
{ {
Tags = tags; Tags = tags;
DisplayParts = displayParts; DisplayParts = displayParts;
Locations = locations; MainLocation = mainLocation;
AdditionalLocations = additionalLocations;
DisplayIfNoReferences = displayIfNoReferences; DisplayIfNoReferences = displayIfNoReferences;
} }
} }
......
...@@ -146,20 +146,22 @@ internal static class DefinitionItemExtensions ...@@ -146,20 +146,22 @@ internal static class DefinitionItemExtensions
this ISymbol definition, this ISymbol definition,
Solution solution) Solution solution)
{ {
var definitionLocations = ConvertDefinitionLocations(solution, definition); var locations = ConvertDefinitionLocations(solution, definition);
var displayParts = definition.ToDisplayParts(s_definitionDisplayFormat).ToTaggedText(); var displayParts = definition.ToDisplayParts(s_definitionDisplayFormat).ToTaggedText();
return new DefinitionItem( return new DefinitionItem(
GlyphTags.GetTags(definition.GetGlyph()), GlyphTags.GetTags(definition.GetGlyph()),
displayParts, displayParts,
definitionLocations, locations.Item1,
locations.Item2,
definition.ShouldShowWithNoReferenceLocations()); definition.ShouldShowWithNoReferenceLocations());
} }
private static ImmutableArray<DefinitionLocation> ConvertDefinitionLocations( private static ValueTuple<DefinitionLocation, ImmutableArray<DocumentLocation>> ConvertDefinitionLocations(
Solution solution, ISymbol definition) Solution solution, ISymbol definition)
{ {
var result = ImmutableArray.CreateBuilder<DefinitionLocation>(); var additionalLocations = ImmutableArray.CreateBuilder<DocumentLocation>();
DefinitionLocation mainLocation = null;
// If it's a namespace, don't create any normal lcoation. Namespaces // If it's a namespace, don't create any normal lcoation. Namespaces
// come from many different sources, but we'll only show a single // come from many different sources, but we'll only show a single
...@@ -170,29 +172,36 @@ internal static class DefinitionItemExtensions ...@@ -170,29 +172,36 @@ internal static class DefinitionItemExtensions
{ {
if (location.IsInMetadata) if (location.IsInMetadata)
{ {
result.Add(DefinitionLocation.CreateSymbolLocation(solution, definition)); mainLocation = DefinitionLocation.CreateSymbolLocation(solution, definition);
} }
else if (location.IsVisibleSourceLocation()) else if (location.IsVisibleSourceLocation())
{ {
var document = solution.GetDocument(location.SourceTree); var document = solution.GetDocument(location.SourceTree);
if (document != null) if (document != null)
{ {
result.Add(DefinitionLocation.CreateDocumentLocation( var documentLocation = new DocumentLocation(document, location.SourceSpan);
new DocumentLocation(document, location.SourceSpan))); if (mainLocation == null)
{
mainLocation = DefinitionLocation.CreateDocumentLocation(documentLocation);
}
else
{
additionalLocations.Add(documentLocation);
}
} }
} }
} }
} }
if (result.Count == 0) if (mainLocation == null)
{ {
// If we got no definition locations, then create a sentinel one // If we got no definition locations, then create a sentinel one
// that we can display but which will not allow navigation. // that we can display but which will not allow navigation.
result.Add(DefinitionLocation.CreateNonNavigatingLocation( mainLocation = DefinitionLocation.CreateNonNavigatingLocation(
DefinitionLocation.GetOriginationParts(definition))); DefinitionLocation.GetOriginationParts(definition));
} }
return result.ToImmutable(); return ValueTuple.Create(mainLocation, additionalLocations.ToImmutable());
} }
public static SourceReferenceItem TryCreateSourceReferenceItem( public static SourceReferenceItem TryCreateSourceReferenceItem(
......
...@@ -32,7 +32,7 @@ private class ReferenceEntry ...@@ -32,7 +32,7 @@ private class ReferenceEntry
private readonly VisualStudioWorkspaceImpl _workspace; private readonly VisualStudioWorkspaceImpl _workspace;
private readonly RoslynDefinitionBucket _definitionBucket; private readonly RoslynDefinitionBucket _definitionBucket;
private readonly SourceReferenceItem _sourceReferenceItem; private readonly DocumentLocation _documentLocation;
private readonly object _boxedProjectGuid; private readonly object _boxedProjectGuid;
private readonly SourceText _sourceText; private readonly SourceText _sourceText;
...@@ -42,7 +42,7 @@ private class ReferenceEntry ...@@ -42,7 +42,7 @@ private class ReferenceEntry
TableDataSourceFindReferencesContext context, TableDataSourceFindReferencesContext context,
VisualStudioWorkspaceImpl workspace, VisualStudioWorkspaceImpl workspace,
RoslynDefinitionBucket definitionBucket, RoslynDefinitionBucket definitionBucket,
SourceReferenceItem sourceReferenceItem, DocumentLocation documentLocation,
Guid projectGuid, Guid projectGuid,
SourceText sourceText, SourceText sourceText,
TaggedTextAndHighlightSpan taggedLineParts) TaggedTextAndHighlightSpan taggedLineParts)
...@@ -51,7 +51,7 @@ private class ReferenceEntry ...@@ -51,7 +51,7 @@ private class ReferenceEntry
_workspace = workspace; _workspace = workspace;
_definitionBucket = definitionBucket; _definitionBucket = definitionBucket;
_sourceReferenceItem = sourceReferenceItem; _documentLocation = documentLocation;
_boxedProjectGuid = projectGuid; _boxedProjectGuid = projectGuid;
_sourceText = sourceText; _sourceText = sourceText;
...@@ -66,9 +66,8 @@ public bool TryGetValue(string keyName, out object content) ...@@ -66,9 +66,8 @@ public bool TryGetValue(string keyName, out object content)
return content != null; return content != null;
} }
private DocumentLocation Location => _sourceReferenceItem.Location; private Document Document => _documentLocation.Document;
private Document Document => Location.Document; private TextSpan SourceSpan => _documentLocation.SourceSpan;
private TextSpan SourceSpan => Location.SourceSpan;
private object GetValue(string keyName) private object GetValue(string keyName)
{ {
...@@ -93,7 +92,7 @@ private object GetValue(string keyName) ...@@ -93,7 +92,7 @@ private object GetValue(string keyName)
case StandardTableKeyNames.Column: case StandardTableKeyNames.Column:
return _sourceText.Lines.GetLinePosition(SourceSpan.Start).Character; return _sourceText.Lines.GetLinePosition(SourceSpan.Start).Character;
case StandardTableKeyNames.ProjectName: case StandardTableKeyNames.ProjectName:
return Location.Document.Project.Name; return Document.Project.Name;
case StandardTableKeyNames.ProjectGuid: case StandardTableKeyNames.ProjectGuid:
return _boxedProjectGuid; return _boxedProjectGuid;
...@@ -217,14 +216,14 @@ private void SetHighlightSpansOnBuffer() ...@@ -217,14 +216,14 @@ private void SetHighlightSpansOnBuffer()
var key = PredefinedPreviewTaggerKeys.ReferenceHighlightingSpansKey; var key = PredefinedPreviewTaggerKeys.ReferenceHighlightingSpansKey;
textBuffer.Properties.RemoveProperty(key); textBuffer.Properties.RemoveProperty(key);
textBuffer.Properties.AddProperty(key, new NormalizedSnapshotSpanCollection( textBuffer.Properties.AddProperty(key, new NormalizedSnapshotSpanCollection(
_sourceReferenceItem.Location.SourceSpan.ToSnapshotSpan(textBuffer.CurrentSnapshot))); SourceSpan.ToSnapshotSpan(textBuffer.CurrentSnapshot)));
} }
private Span GetRegionSpanForReference() private Span GetRegionSpanForReference()
{ {
const int AdditionalLineCountPerSide = 3; const int AdditionalLineCountPerSide = 3;
var referenceSpan = this._sourceReferenceItem.Location.SourceSpan; var referenceSpan = this.SourceSpan;
var lineNumber = _sourceText.Lines.GetLineFromPosition(referenceSpan.Start).LineNumber; var lineNumber = _sourceText.Lines.GetLineFromPosition(referenceSpan.Start).LineNumber;
var firstLineNumber = Math.Max(0, lineNumber - AdditionalLineCountPerSide); var firstLineNumber = Math.Max(0, lineNumber - AdditionalLineCountPerSide);
var lastLineNumber = Math.Min(_sourceText.Lines.Count - 1, lineNumber + AdditionalLineCountPerSide); var lastLineNumber = Math.Min(_sourceText.Lines.Count - 1, lineNumber + AdditionalLineCountPerSide);
......
...@@ -37,15 +37,7 @@ private class RoslynDefinitionBucket : DefinitionBucket, ISupportsNavigation ...@@ -37,15 +37,7 @@ private class RoslynDefinitionBucket : DefinitionBucket, ISupportsNavigation
public bool TryNavigateTo() public bool TryNavigateTo()
{ {
foreach (var location in DefinitionItem.Locations) return DefinitionItem.MainLocation.TryNavigateTo();
{
if (location.TryNavigateTo())
{
return true;
}
}
return false;
} }
public override bool TryGetValue(string key, out object content) public override bool TryGetValue(string key, out object content)
......
...@@ -149,7 +149,7 @@ public async override void OnReferenceFound(SourceReferenceItem reference) ...@@ -149,7 +149,7 @@ public async override void OnReferenceFound(SourceReferenceItem reference)
// know so that it doesn't verify results until this completes. // know so that it doesn't verify results until this completes.
using (var token = Presenter._asyncListener.BeginAsyncOperation(nameof(OnReferenceFound))) using (var token = Presenter._asyncListener.BeginAsyncOperation(nameof(OnReferenceFound)))
{ {
await OnReferenceFoundAsync(reference).ConfigureAwait(false); await OnReferenceFoundAsync(reference.Definition, reference.Location).ConfigureAwait(false);
} }
} }
catch (Exception e) when (FatalError.ReportWithoutCrashUnlessCanceled(e)) catch (Exception e) when (FatalError.ReportWithoutCrashUnlessCanceled(e))
...@@ -157,14 +157,15 @@ public async override void OnReferenceFound(SourceReferenceItem reference) ...@@ -157,14 +157,15 @@ public async override void OnReferenceFound(SourceReferenceItem reference)
} }
} }
private async Task OnReferenceFoundAsync(SourceReferenceItem referenceItem) private async Task OnReferenceFoundAsync(
DefinitionItem definition, DocumentLocation referenceLocation)
{ {
var cancellationToken = _cancellationTokenSource.Token; var cancellationToken = _cancellationTokenSource.Token;
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
// First find the bucket corresponding to our definition. If we can't find/create // First find the bucket corresponding to our definition. If we can't find/create
// one, then don't do anything for this reference. // one, then don't do anything for this reference.
var definitionBucket = GetOrCreateDefinitionBucket(referenceItem.Definition); var definitionBucket = GetOrCreateDefinitionBucket(definition);
if (definitionBucket == null) if (definitionBucket == null)
{ {
return; return;
...@@ -174,7 +175,7 @@ private async Task OnReferenceFoundAsync(SourceReferenceItem referenceItem) ...@@ -174,7 +175,7 @@ private async Task OnReferenceFoundAsync(SourceReferenceItem referenceItem)
//var entryData = await this.TryCreateNavigableItemEntryData( //var entryData = await this.TryCreateNavigableItemEntryData(
// referenceItem, isDefinition: false, cancellationToken: cancellationToken).ConfigureAwait(false); // referenceItem, isDefinition: false, cancellationToken: cancellationToken).ConfigureAwait(false);
var referenceEntry = await this.CreateReferenceEntryAsync( var referenceEntry = await this.CreateReferenceEntryAsync(
definitionBucket, referenceItem, cancellationToken).ConfigureAwait(false); definitionBucket, referenceLocation, cancellationToken).ConfigureAwait(false);
if (referenceEntry == null) if (referenceEntry == null)
{ {
return; return;
...@@ -227,10 +228,9 @@ private ITextBuffer CreateNewBuffer(Document document, SourceText sourceText) ...@@ -227,10 +228,9 @@ private ITextBuffer CreateNewBuffer(Document document, SourceText sourceText)
private async Task<ReferenceEntry> CreateReferenceEntryAsync( private async Task<ReferenceEntry> CreateReferenceEntryAsync(
RoslynDefinitionBucket definitionBucket, SourceReferenceItem referenceItem, CancellationToken cancellationToken) RoslynDefinitionBucket definitionBucket, DocumentLocation documentLocation, CancellationToken cancellationToken)
{ {
var location = referenceItem.Location; var document = documentLocation.Document;
var document = location.Document;
// The FAR system needs to know the guid for the project that a def/reference is // The FAR system needs to know the guid for the project that a def/reference is
// from. So we only support this for documents from a VSWorkspace. // from. So we only support this for documents from a VSWorkspace.
...@@ -248,13 +248,13 @@ private ITextBuffer CreateNewBuffer(Document document, SourceText sourceText) ...@@ -248,13 +248,13 @@ private ITextBuffer CreateNewBuffer(Document document, SourceText sourceText)
var sourceText = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); var sourceText = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
var referenceSpan = referenceItem.Location.SourceSpan; var referenceSpan = documentLocation.SourceSpan;
var lineSpan = GetLineSpanForReference(sourceText, referenceSpan); var lineSpan = GetLineSpanForReference(sourceText, referenceSpan);
var taggedLineParts = await GetTaggedTextForReferenceAsync(document, referenceSpan, lineSpan, cancellationToken).ConfigureAwait(false); var taggedLineParts = await GetTaggedTextForReferenceAsync(document, referenceSpan, lineSpan, cancellationToken).ConfigureAwait(false);
return new ReferenceEntry( return new ReferenceEntry(
this, workspace, definitionBucket, referenceItem, this, workspace, definitionBucket, documentLocation,
projectGuid.Value, sourceText, taggedLineParts); projectGuid.Value, sourceText, taggedLineParts);
} }
......
...@@ -40,13 +40,14 @@ public VisualStudioDefinitionsAndReferencesFactory(SVsServiceProvider servicePro ...@@ -40,13 +40,14 @@ public VisualStudioDefinitionsAndReferencesFactory(SVsServiceProvider servicePro
} }
var displayParts = GetDisplayParts(filePath, lineNumber, charOffset); var displayParts = GetDisplayParts(filePath, lineNumber, charOffset);
var definitionLocation = new ExternalDefinitionLocation( var mainLocation = new ExternalDefinitionLocation(
_serviceProvider, filePath, lineNumber, charOffset); _serviceProvider, filePath, lineNumber, charOffset);
return new DefinitionItem( return new DefinitionItem(
GlyphTags.GetTags(definition.GetGlyph()), GlyphTags.GetTags(definition.GetGlyph()),
displayParts, displayParts,
ImmutableArray.Create<DefinitionLocation>(definitionLocation), mainLocation,
additionalLocations: ImmutableArray<DocumentLocation>.Empty,
displayIfNoReferences: true); displayIfNoReferences: true);
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
using Microsoft.CodeAnalysis.FindReferences; using Microsoft.CodeAnalysis.FindReferences;
using Microsoft.VisualStudio.LanguageServices.Implementation.Utilities; using Microsoft.VisualStudio.LanguageServices.Implementation.Utilities;
using Roslyn.Utilities; using Roslyn.Utilities;
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.Library.FindResults namespace Microsoft.VisualStudio.LanguageServices.Implementation.Library.FindResults
{ {
...@@ -24,19 +25,21 @@ public void PresentDefinitionsAndReferences(DefinitionsAndReferences definitions ...@@ -24,19 +25,21 @@ public void PresentDefinitionsAndReferences(DefinitionsAndReferences definitions
internal IList<AbstractTreeItem> CreateFindReferencesItems( internal IList<AbstractTreeItem> CreateFindReferencesItems(
DefinitionsAndReferences definitionsAndReferences) DefinitionsAndReferences definitionsAndReferences)
{ {
var documents = definitionsAndReferences.References.Select(r => r.Location.Document) var definitionDocuments =
.WhereNotNull() definitionsAndReferences.Definitions.SelectMany(d => d.AdditionalLocations)
.ToSet(); .Select(loc => loc.Document);
var commonPathElements = CountCommonPathElements(documents); var referenceDocuments =
definitionsAndReferences.References.Select(r => r.Location.Document);
var query = from d in definitionsAndReferences.Definitions var documents = definitionDocuments.Concat(referenceDocuments).WhereNotNull().ToSet();
from i in CreateDefinitionItems(d, definitionsAndReferences, commonPathElements) var commonPathElements = CountCommonPathElements(documents);
select (AbstractTreeItem)i;
return query.ToList(); return definitionsAndReferences.Definitions
.Select(d => CreateDefinitionItem(d, definitionsAndReferences, commonPathElements))
.ToList<AbstractTreeItem>();
} }
private ImmutableArray<DefinitionTreeItem> CreateDefinitionItems( private DefinitionTreeItem CreateDefinitionItem(
DefinitionItem definitionItem, DefinitionItem definitionItem,
DefinitionsAndReferences definitionsAndReferences, DefinitionsAndReferences definitionsAndReferences,
int commonPathElements) int commonPathElements)
...@@ -44,29 +47,28 @@ public void PresentDefinitionsAndReferences(DefinitionsAndReferences definitions ...@@ -44,29 +47,28 @@ public void PresentDefinitionsAndReferences(DefinitionsAndReferences definitions
var referenceItems = CreateReferenceItems( var referenceItems = CreateReferenceItems(
definitionItem, definitionsAndReferences, commonPathElements); definitionItem, definitionsAndReferences, commonPathElements);
return ConvertToDefinitionTreeItems(definitionItem, referenceItems); return ConvertToDefinitionTreeItem(definitionItem, referenceItems, commonPathElements);
} }
private ImmutableArray<DefinitionTreeItem> ConvertToDefinitionTreeItems( private DefinitionTreeItem ConvertToDefinitionTreeItem(
DefinitionItem definitionItem, DefinitionItem definitionItem,
ImmutableArray<SourceReferenceTreeItem> referenceItems) ImmutableArray<SourceReferenceTreeItem> referenceItems,
int commonPathElements)
{ {
var result = ImmutableArray.CreateBuilder<DefinitionTreeItem>(); var finalReferenceItems = ImmutableArray.CreateBuilder<SourceReferenceTreeItem>();
for (int i = 0, n = definitionItem.Locations.Length; i < n; i++) foreach (var additionalLocation in definitionItem.AdditionalLocations)
{ {
var location = definitionItem.Locations[i]; finalReferenceItems.Add(new SourceReferenceTreeItem(
additionalLocation.Document,
// Each definition item may end up as several top nodes (because of partials). additionalLocation.SourceSpan,
// Add the references to the last item actually in the list. definitionItem.Tags.GetGlyph().GetGlyphIndex(),
var childItems = i == n - 1 commonPathElements));
? referenceItems
: ImmutableArray<SourceReferenceTreeItem>.Empty;
result.Add(new DefinitionTreeItem(definitionItem, location, childItems));
} }
return result.ToImmutable(); finalReferenceItems.AddRange(referenceItems);
return new DefinitionTreeItem(definitionItem, finalReferenceItems.ToImmutable());
} }
private ImmutableArray<SourceReferenceTreeItem> CreateReferenceItems( private ImmutableArray<SourceReferenceTreeItem> CreateReferenceItems(
......
...@@ -12,16 +12,13 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.Library.FindRes ...@@ -12,16 +12,13 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.Library.FindRes
internal class DefinitionTreeItem : AbstractTreeItem internal class DefinitionTreeItem : AbstractTreeItem
{ {
private readonly DefinitionItem _definitionItem; private readonly DefinitionItem _definitionItem;
private readonly DefinitionLocation _definitionLocation;
public DefinitionTreeItem( public DefinitionTreeItem(
DefinitionItem definitionItem, DefinitionItem definitionItem,
DefinitionLocation definitionLocation,
ImmutableArray<SourceReferenceTreeItem> referenceItems) ImmutableArray<SourceReferenceTreeItem> referenceItems)
: base(definitionItem.Tags.GetGlyph().GetGlyphIndex()) : base(definitionItem.Tags.GetGlyph().GetGlyphIndex())
{ {
_definitionItem = definitionItem; _definitionItem = definitionItem;
_definitionLocation = definitionLocation;
this.Children.AddRange(referenceItems); this.Children.AddRange(referenceItems);
this.DisplayText = CreateDisplayText(); this.DisplayText = CreateDisplayText();
...@@ -41,9 +38,9 @@ private string CreateDisplayText() ...@@ -41,9 +38,9 @@ private string CreateDisplayText()
// results that tell us about their definition location, but not any additional // results that tell us about their definition location, but not any additional
// reference. We don't want to say '0' references in that case as that can // reference. We don't want to say '0' references in that case as that can
// be misleading. // be misleading.
var hasOrigination = _definitionLocation.OriginationParts.Length > 0; var hasOrigination = _definitionItem.MainLocation.OriginationParts.Length > 0;
return hasOrigination return hasOrigination
? $"[{_definitionLocation.OriginationParts.JoinText()}] {displayString} ({referenceCountDisplay})" ? $"[{_definitionItem.MainLocation.OriginationParts.JoinText()}] {displayString} ({referenceCountDisplay})"
: referenceCount > 0 : referenceCount > 0
? $"{displayString} ({referenceCountDisplay})" ? $"{displayString} ({referenceCountDisplay})"
: displayString; : displayString;
...@@ -51,14 +48,14 @@ private string CreateDisplayText() ...@@ -51,14 +48,14 @@ private string CreateDisplayText()
public override int GoToSource() public override int GoToSource()
{ {
return _definitionLocation.TryNavigateTo() return _definitionItem.MainLocation.TryNavigateTo()
? VSConstants.S_OK ? VSConstants.S_OK
: VSConstants.E_FAIL; : VSConstants.E_FAIL;
} }
public override bool CanGoToDefinition() public override bool CanGoToDefinition()
{ {
return _definitionLocation.CanNavigateTo(); return _definitionItem.MainLocation.CanNavigateTo();
} }
} }
} }
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册