Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,13 @@ public TextDocumentIdentifier GetTextDocumentIdentifier(LSP.CallHierarchyPrepare
=> request.TextDocument;

public async Task<LSP.CallHierarchyItem[]?> HandleRequestAsync(LSP.CallHierarchyPrepareParams request, RequestContext context, CancellationToken cancellationToken)
=> await PrepareCallHierarchyAsync(context.GetRequiredDocument(), ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(false);
{
var document = context.GetRequiredDocument();
return await PrepareCallHierarchyAsync(document, ProtocolConversions.PositionToLinePosition(request.Position), document.Id, cancellationToken)
.ConfigureAwait(false);
}

internal static async Task<LSP.CallHierarchyItem[]?> PrepareCallHierarchyAsync(Document document, LinePosition linePosition, CancellationToken cancellationToken)
internal static async Task<LSP.CallHierarchyItem[]?> PrepareCallHierarchyAsync(Document document, LinePosition linePosition, DocumentId preferredDocumentId, CancellationToken cancellationToken)
{
var solution = document.Project.Solution;
var position = await document.GetPositionFromLinePositionAsync(linePosition, cancellationToken).ConfigureAwait(false);
Expand All @@ -47,7 +51,7 @@ public TextDocumentIdentifier GetTextDocumentIdentifier(LSP.CallHierarchyPrepare
if (itemDescriptor == null)
return null;

var item = await CallHierarchyHelpers.CreateItemAsync(itemDescriptor, solution, preferredDocumentId: document.Id, cancellationToken).ConfigureAwait(false);
var item = await CallHierarchyHelpers.CreateItemAsync(itemDescriptor, solution, preferredDocumentId, cancellationToken).ConfigureAwait(false);
return item == null ? null : [item];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,27 @@ protected override IRemoteCallHierarchyService CreateService(in ServiceArgs args
}

var generatedDocument = await context.Snapshot
.GetGeneratedDocumentAsync(cancellationToken)
.GetGeneratedDocumentAsync(positionInfo.InDeclDocument, cancellationToken)
.ConfigureAwait(false);

var items = await PrepareCallHierarchyHandler.PrepareCallHierarchyAsync(generatedDocument, positionInfo.Position.ToLinePosition(), cancellationToken)
var linePosition = positionInfo.Position.ToLinePosition();
var items = await PrepareCallHierarchyHandler.PrepareCallHierarchyAsync(generatedDocument, linePosition, generatedDocument.Id, cancellationToken)
.ConfigureAwait(false);

if (items is null && !positionInfo.InDeclDocument)
{
// Razor implementation generated documents can contain call sites for members whose declarations live in the
// paired declaration generated document. In that case Roslyn's prepare path can't create an item for the
// implementation document, so retry while explicitly preferring the declaration document.
var declarationGeneratedDocument = await context.Snapshot.TryGetGeneratedDocumentAsync(declarationDocument: true, cancellationToken).ConfigureAwait(false);
if (declarationGeneratedDocument is null)
{
return RemoteResponse<CallHierarchyItem[]?>.NoFurtherHandling;
}

items = await PrepareCallHierarchyHandler.PrepareCallHierarchyAsync(generatedDocument, linePosition, declarationGeneratedDocument.Id, cancellationToken).ConfigureAwait(false);
}

if (items is null)
{
return RemoteResponse<CallHierarchyItem[]?>.NoFurtherHandling;
Expand All @@ -92,9 +107,11 @@ protected override IRemoteCallHierarchyService CreateService(in ServiceArgs args
CallHierarchyItem item,
CancellationToken cancellationToken)
{
var generatedDocument = await context.Snapshot
.GetGeneratedDocumentAsync(cancellationToken)
.ConfigureAwait(false);
var generatedDocument = await TryGetGeneratedDocumentForItemAsync(context, item, cancellationToken).ConfigureAwait(false);
if (generatedDocument is null)
{
return RemoteResponse<CallHierarchyIncomingCall[]?>.NoFurtherHandling;
}

var incomingCalls = await CallHierarchyIncomingCallsHandler.GetIncomingCallsAsync(generatedDocument, item, allowRazorSourceGeneratedDocuments: true, cancellationToken)
.ConfigureAwait(false);
Expand Down Expand Up @@ -141,9 +158,11 @@ protected override IRemoteCallHierarchyService CreateService(in ServiceArgs args
CallHierarchyItem item,
CancellationToken cancellationToken)
{
var generatedDocument = await context.Snapshot
.GetGeneratedDocumentAsync(cancellationToken)
.ConfigureAwait(false);
var generatedDocument = await TryGetGeneratedDocumentForItemAsync(context, item, cancellationToken).ConfigureAwait(false);
if (generatedDocument is null)
{
return RemoteResponse<CallHierarchyOutgoingCall[]?>.NoFurtherHandling;
}

var outgoingCalls = await CallHierarchyOutgoingCallsHandler.GetOutgoingCallsAsync(generatedDocument, item, cancellationToken)
.ConfigureAwait(false);
Expand Down Expand Up @@ -174,6 +193,16 @@ protected override IRemoteCallHierarchyService CreateService(in ServiceArgs args
return RemoteResponse<CallHierarchyOutgoingCall[]?>.Results(builder.ToArray());
}

private static async ValueTask<SourceGeneratedDocument?> TryGetGeneratedDocumentForItemAsync(
RemoteDocumentContext context,
CallHierarchyItem item,
CancellationToken cancellationToken)
{
var resolveData = CallHierarchyHelpers.GetResolveData(item);
var generatedDocumentUri = resolveData.TextDocument.DocumentUri.GetRequiredSystemUri();
return await context.Snapshot.TextDocument.Project.Solution.TryGetSourceGeneratedDocumentAsync(generatedDocumentUri, cancellationToken).ConfigureAwait(false);
}

private async Task<CallHierarchyItem[]?> MapItemsAsync(RemoteDocumentContext context, CallHierarchyItem[] items, CancellationToken cancellationToken)
{
using var builder = new PooledArrayBuilder<CallHierarchyItem>(items.Length);
Expand Down
Loading