Skip to content

Commit

Permalink
Support Go To Definition on properties/items
Browse files Browse the repository at this point in the history
For properties/items, there isn't a definition per se, but searching
for places where they are written/assigned seems like a reasonable
interpretation that makes F12 more useful.

Partial fix for #163
  • Loading branch information
mhutch committed Apr 17, 2024
1 parent 834ae72 commit 136a024
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#nullable enable annotations

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
Expand Down Expand Up @@ -109,6 +111,16 @@ public bool Navigate (MSBuildNavigationResult result, ITextBuffer buffer)
return true;
}

if (result.Kind == MSBuildReferenceKind.Item) {
FindItemWrites (result.Name, buffer).LogTaskExceptionsAndForget (logger);
return true;
}

if (result.Kind == MSBuildReferenceKind.Property) {
FindPropertyWrites (result.Name, buffer).LogTaskExceptionsAndForget (logger);
return true;
}

if (result.Paths != null) {
if (result.Paths.Length == 1) {
EditorHost.OpenFile (result.Paths[0], 0);
Expand Down Expand Up @@ -263,6 +275,46 @@ async Task FindTargetDefinitions (string targetName, ITextBuffer buffer)
await searchCtx.OnCompletedAsync ();
}

async Task FindPropertyWrites (string propertyName, ITextBuffer buffer)
{
var searchCtx = Presenter.StartSearch ($"Property '{propertyName}' writes", propertyName, true);

try {
await FindReferences (
searchCtx,
(doc, text, logger, reporter) => new MSBuildPropertyReferenceCollector (doc, text, logger, propertyName, reporter),
buffer,
result => result.Usage switch {
ReferenceUsage.Declaration or ReferenceUsage.Write => true,
_ => false
});
} catch (Exception ex) when (!(ex is OperationCanceledException && searchCtx.CancellationToken.IsCancellationRequested)) {
var logger = LoggerService.GetLogger<MSBuildReferenceCollector> (buffer);
LogErrorFindReferences (logger, ex);
}
await searchCtx.OnCompletedAsync ();
}

async Task FindItemWrites (string itemName, ITextBuffer buffer)
{
var searchCtx = Presenter.StartSearch ($"Item '{itemName}' item", itemName, true);

try {
await FindReferences (
searchCtx,
(doc, text, logger, reporter) => new MSBuildItemReferenceCollector (doc, text, logger, itemName, reporter),
buffer,
result => result.Usage switch {
ReferenceUsage.Declaration or ReferenceUsage.Write => true,
_ => false
});
} catch (Exception ex) when (!(ex is OperationCanceledException && searchCtx.CancellationToken.IsCancellationRequested)) {
var logger = LoggerService.GetLogger<MSBuildReferenceCollector> (buffer);
LogErrorFindReferences (logger, ex);
}
await searchCtx.OnCompletedAsync ();
}

delegate MSBuildReferenceCollector ReferenceCollectorFactory (MSBuildDocument doc, ITextSource textSource, ILogger logger, FindReferencesReporter reportResult);

/// <remarks>
Expand All @@ -271,7 +323,8 @@ async Task FindTargetDefinitions (string targetName, ITextBuffer buffer)
async Task FindReferences (
FindReferencesContext searchCtx,
ReferenceCollectorFactory collectorFactory,
ITextBuffer buffer)
ITextBuffer buffer,
Func<FindReferencesResult, bool>? resultFilter = null)
{
var openDocuments = EditorHost.GetOpenDocuments ();

Expand Down Expand Up @@ -314,6 +367,10 @@ await ParallelAsync.ForEach (jobs, Environment.ProcessorCount, async (job, token
void ReportResult (FindReferencesResult result)
{
if (resultFilter is not null && resultFilter (result) == false) {
return;
}
var line = job.TextSource.Snapshot.GetLineFromPosition (result.Offset);
var col = result.Offset - line.Start.Position;
var lineText = line.GetText ();
Expand Down
8 changes: 8 additions & 0 deletions MonoDevelop.MSBuild/Language/MSBuildNavigation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,14 @@ IEnumerable<string> GetAnnotatedPaths ()
}
}

if (rr.ReferenceKind == MSBuildReferenceKind.Item) {
return new MSBuildNavigationResult (MSBuildReferenceKind.Item, rr.GetItemReference (), rr.ReferenceOffset, rr.ReferenceLength);
}

if (rr.ReferenceKind == MSBuildReferenceKind.Property) {
return new MSBuildNavigationResult (MSBuildReferenceKind.Property, rr.GetPropertyReference (), rr.ReferenceOffset, rr.ReferenceLength);
}

if (rr.ReferenceKind == MSBuildReferenceKind.Target) {
return new MSBuildNavigationResult (MSBuildReferenceKind.Target, rr.GetTargetReference (), rr.ReferenceOffset, rr.ReferenceLength);
}
Expand Down

0 comments on commit 136a024

Please sign in to comment.