Skip to content

Commit

Permalink
Expose breakable range handler to Razor (#76629)
Browse files Browse the repository at this point in the history
Roslyn side of dotnet/razor#11337
  • Loading branch information
davidwengier authored Jan 6, 2025
2 parents e4242b9 + 04063fb commit 83debc8
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,13 @@ internal sealed class ValidateBreakableRangeHandler() : ILspServiceDocumentReque
public TextDocumentIdentifier GetTextDocumentIdentifier(LSP.VSInternalValidateBreakableRangeParams request)
=> request.TextDocument;

public async Task<LSP.Range?> HandleRequestAsync(LSP.VSInternalValidateBreakableRangeParams request, RequestContext context, CancellationToken cancellationToken)
{
var document = context.GetRequiredDocument();
public Task<LSP.Range?> HandleRequestAsync(LSP.VSInternalValidateBreakableRangeParams request, RequestContext context, CancellationToken cancellationToken)
=> GetBreakableRangeAsync(context.GetRequiredDocument(), request.Range, cancellationToken);

public static async Task<LSP.Range?> GetBreakableRangeAsync(Document document, LSP.Range range, CancellationToken cancellationToken)
{
var text = await document.GetValueTextAsync(cancellationToken).ConfigureAwait(false);
var span = ProtocolConversions.RangeToTextSpan(request.Range, text);
var span = ProtocolConversions.RangeToTextSpan(range, text);
var breakpointService = document.Project.Services.GetRequiredService<IBreakpointResolutionService>();

if (span.Length > 0)
Expand Down Expand Up @@ -62,7 +63,7 @@ public TextDocumentIdentifier GetTextDocumentIdentifier(LSP.VSInternalValidateBr
if (tree.GetDiagnostics(cancellationToken).Any(d => d.Severity == DiagnosticSeverity.Error))
{
// Keep the span as is.
return request.Range;
return range;
}
}
}
Expand Down Expand Up @@ -93,7 +94,7 @@ public TextDocumentIdentifier GetTextDocumentIdentifier(LSP.VSInternalValidateBr
// BP: int a = $$ GetData();
//
// If the user types "1;" we'd shrink the breakpoint, so stick to the end of the range.
if (!result.IsLineBreakpoint && BreakpointRangeIsSmaller(breakpointRange, request.Range))
if (!result.IsLineBreakpoint && BreakpointRangeIsSmaller(breakpointRange, range))
{
var secondResult = await breakpointService.ResolveBreakpointAsync(document, new TextSpan(span.End, length: 0), cancellationToken).ConfigureAwait(false);
if (secondResult is not null)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.LanguageServer;
using Microsoft.CodeAnalysis.LanguageServer.Handler;
using Microsoft.CodeAnalysis.Text;

namespace Microsoft.CodeAnalysis.ExternalAccess.Razor.Cohost.Handlers;

internal static class ValidateBreakableRange
{
public static async Task<LinePositionSpan?> GetBreakableRangeAsync(Document document, LinePositionSpan span, CancellationToken cancellationToken)
{
var range = ProtocolConversions.LinePositionToRange(span);
var result = await ValidateBreakableRangeHandler.GetBreakableRangeAsync(document, range, cancellationToken).ConfigureAwait(false);

if (result is null)
{
return null;
}

return ProtocolConversions.RangeToLinePositionSpan(result);
}
}
18 changes: 18 additions & 0 deletions src/Tools/ExternalAccess/Razor/ITextBufferExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Diagnostics.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;
using Microsoft.VisualStudio.Text;

namespace Microsoft.CodeAnalysis.ExternalAccess.Razor;

internal static class ITextBufferExtensions
{
public static bool TryGetTextDocument(this ITextBuffer textBuffer, [NotNullWhen(true)] out TextDocument? textDocument)
{
textDocument = textBuffer.CurrentSnapshot.AsText().GetOpenTextDocumentInCurrentContextWithChanges();
return textDocument is not null;
}
}

0 comments on commit 83debc8

Please # to comment.