зеркало из https://github.com/dotnet/razor.git
This commit is contained in:
Родитель
9d7ab3dfc1
Коммит
c9404f4394
|
@ -26,8 +26,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
|
|||
{
|
||||
"Generate Equals and GetHashCode",
|
||||
"Add null check",
|
||||
"Add null checks for all parameters",
|
||||
"Add 'DebuggerDisplay' attribute"
|
||||
"Add null checks for all parameters"
|
||||
};
|
||||
|
||||
public override Task<IReadOnlyList<CodeAction>> ProvideAsync(
|
||||
|
|
|
@ -2,14 +2,17 @@
|
|||
// 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 System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.AspNetCore.Razor.LanguageServer.CodeActions.Models;
|
||||
using Microsoft.AspNetCore.Razor.LanguageServer.Common;
|
||||
using Microsoft.AspNetCore.Razor.LanguageServer.Formatting;
|
||||
using Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem;
|
||||
using Microsoft.CodeAnalysis.Razor;
|
||||
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
|
||||
|
||||
|
@ -33,13 +36,15 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
|
|||
private readonly DocumentResolver _documentResolver;
|
||||
private readonly RazorFormattingService _razorFormattingService;
|
||||
private readonly DocumentVersionCache _documentVersionCache;
|
||||
private readonly RazorDocumentMappingService _documentMappingService;
|
||||
|
||||
public DefaultCSharpCodeActionResolver(
|
||||
ForegroundDispatcher foregroundDispatcher,
|
||||
DocumentResolver documentResolver,
|
||||
ClientNotifierServiceBase languageServer,
|
||||
RazorFormattingService razorFormattingService,
|
||||
DocumentVersionCache documentVersionCache)
|
||||
DocumentVersionCache documentVersionCache,
|
||||
RazorDocumentMappingService documentMappingService)
|
||||
: base(languageServer)
|
||||
{
|
||||
if (foregroundDispatcher is null)
|
||||
|
@ -62,10 +67,16 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
|
|||
throw new ArgumentNullException(nameof(documentVersionCache));
|
||||
}
|
||||
|
||||
if (documentMappingService is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(documentMappingService));
|
||||
}
|
||||
|
||||
_foregroundDispatcher = foregroundDispatcher;
|
||||
_documentResolver = documentResolver;
|
||||
_razorFormattingService = razorFormattingService;
|
||||
_documentVersionCache = documentVersionCache;
|
||||
_documentMappingService = documentMappingService;
|
||||
}
|
||||
|
||||
public override string Action => LanguageServerConstants.CodeActions.Default;
|
||||
|
@ -122,7 +133,6 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
|
|||
|
||||
var csharpTextEdits = documentChanged.TextDocumentEdit.Edits.ToArray();
|
||||
|
||||
|
||||
// Remaps the text edits from the generated C# to the razor file,
|
||||
// as well as applying appropriate formatting.
|
||||
var formattedEdits = await _razorFormattingService.ApplyFormattedEditsAsync(
|
||||
|
@ -136,7 +146,8 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
|
|||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
if (await DoesFormattingChangeNonWhitespaceContentAsync(documentSnapshot, csharpTextEdits, formattedEdits))
|
||||
if (formattedEdits?.Length == 0 ||
|
||||
await DoesFormattingChangeNonWhitespaceContentAsync(documentSnapshot, csharpTextEdits, formattedEdits))
|
||||
{
|
||||
return codeAction;
|
||||
}
|
||||
|
@ -169,14 +180,74 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
|
|||
return resolvedCodeAction;
|
||||
}
|
||||
|
||||
private static async Task<bool> DoesFormattingChangeNonWhitespaceContentAsync(CodeAnalysis.Razor.ProjectSystem.DocumentSnapshot documentSnapshot, TextEdit[] csharpTextEdits, TextEdit[] formattedEdits)
|
||||
private async Task<bool> DoesFormattingChangeNonWhitespaceContentAsync(DocumentSnapshot documentSnapshot, TextEdit[] csharpTextEdits, TextEdit[] formattedEdits)
|
||||
{
|
||||
var expectedUnformattedSourceText = SourceText.From(csharpTextEdits.FirstOrDefault()?.NewText);
|
||||
var codeDocument = await documentSnapshot.GetGeneratedOutputAsync();
|
||||
|
||||
var originalSourceText = await documentSnapshot.GetTextAsync();
|
||||
|
||||
var remappedCSharpTextEdits = RemapTextEdits(codeDocument, csharpTextEdits);
|
||||
var unformattedChanges = remappedCSharpTextEdits.Select(e => e.AsTextChange(originalSourceText));
|
||||
var expectedUnformattedSourceText = originalSourceText.WithChanges(unformattedChanges);
|
||||
|
||||
var formattedChanges = formattedEdits.Select(e => e.AsTextChange(originalSourceText));
|
||||
var actualFormattedSourceText = originalSourceText.WithChanges(formattedChanges);
|
||||
|
||||
return !expectedUnformattedSourceText.NonWhitespaceContentEquals(actualFormattedSourceText);
|
||||
|
||||
//var originalEditLength = GetNonWhitespaceLengthOfEdits(csharpTextEdits);
|
||||
//var formattedEditLength = GetNonWhitespaceLengthOfEdits(formattedEdits);
|
||||
|
||||
//return originalEditLength != formattedEditLength;
|
||||
}
|
||||
|
||||
//private static int GetNonWhitespaceLengthOfEdits(TextEdit[] edits)
|
||||
//{
|
||||
// var length = 0;
|
||||
|
||||
// foreach (var edit in edits)
|
||||
// {
|
||||
// foreach (var c in edit.NewText)
|
||||
// {
|
||||
// if (!char.IsWhiteSpace(c))
|
||||
// {
|
||||
// length++;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// return length;
|
||||
//}
|
||||
|
||||
|
||||
protected TextEdit[] RemapTextEdits(RazorCodeDocument codeDocument, TextEdit[] projectedTextEdits)
|
||||
{
|
||||
if (projectedTextEdits is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(projectedTextEdits));
|
||||
}
|
||||
|
||||
var edits = new List<TextEdit>();
|
||||
for (var i = 0; i < projectedTextEdits.Length; i++)
|
||||
{
|
||||
var projectedRange = projectedTextEdits[i].Range;
|
||||
if (codeDocument.IsUnsupported() ||
|
||||
!_documentMappingService.TryMapFromProjectedDocumentRange(codeDocument, projectedRange, out var originalRange))
|
||||
{
|
||||
// Can't map range. Discard this edit.
|
||||
continue;
|
||||
}
|
||||
|
||||
var edit = new TextEdit()
|
||||
{
|
||||
Range = originalRange,
|
||||
NewText = projectedTextEdits[i].NewText
|
||||
};
|
||||
|
||||
edits.Add(edit);
|
||||
}
|
||||
|
||||
return edits.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,27 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
|
|||
Edits = new TextEditContainer(
|
||||
new TextEdit()
|
||||
{
|
||||
NewText = "Generated C# Based Edit"
|
||||
NewText = "Some CodeAction Edit"
|
||||
}
|
||||
)
|
||||
}
|
||||
))
|
||||
}
|
||||
};
|
||||
private static readonly CodeAction ImproperlyResolvedCodeAction = new CodeAction()
|
||||
{
|
||||
Title = "ResolvedCodeAction",
|
||||
Data = JToken.FromObject(new object()),
|
||||
Edit = new WorkspaceEdit()
|
||||
{
|
||||
DocumentChanges = new Container<WorkspaceEditDocumentChange>(
|
||||
new WorkspaceEditDocumentChange(
|
||||
new TextDocumentEdit()
|
||||
{
|
||||
Edits = new TextEditContainer(
|
||||
new TextEdit()
|
||||
{
|
||||
NewText = "me CodeAction Edit"
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -50,7 +70,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
|
|||
{
|
||||
new TextEdit()
|
||||
{
|
||||
NewText = "Remapped & Formatted Edit"
|
||||
NewText = $"\t Some CodeAction Edit {Environment.NewLine}"
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -63,7 +83,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
|
|||
public async Task ResolveAsync_ReturnsResolvedCodeAction()
|
||||
{
|
||||
// Arrange
|
||||
CreateCodeActionResolver(out var codeActionParams, out var csharpCodeActionResolver);
|
||||
CreateCodeActionResolver(out var codeActionParams, out var csharpCodeActionResolver, resolvedCodeAction: DefaultResolvedCodeAction);
|
||||
|
||||
// Act
|
||||
var returnedCodeAction = await csharpCodeActionResolver.ResolveAsync(codeActionParams, DefaultUnresolvedCodeAction, default);
|
||||
|
@ -77,6 +97,20 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
|
|||
Assert.Equal(DefaultFormattedEdits.First(), returnedTextDocumentEdit);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ResolveAsync_NonWhitespaceContentChangedByFormatting_ReturnsOriginalCodeAction()
|
||||
{
|
||||
// Arrange
|
||||
CreateCodeActionResolver(out var codeActionParams, out var csharpCodeActionResolver, resolvedCodeAction: ImproperlyResolvedCodeAction);
|
||||
|
||||
// Act
|
||||
var returnedCodeAction = await csharpCodeActionResolver.ResolveAsync(codeActionParams, DefaultUnresolvedCodeAction, default);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(DefaultUnresolvedCodeAction.Title, returnedCodeAction.Title);
|
||||
Assert.Null(returnedCodeAction.Edit);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ResolveAsync_NoDocumentChanges_ReturnsOriginalCodeAction()
|
||||
{
|
||||
|
@ -100,6 +134,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
|
|||
|
||||
// Assert
|
||||
Assert.Equal(DefaultUnresolvedCodeAction.Title, returnedCodeAction.Title);
|
||||
Assert.Null(returnedCodeAction.Edit);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -147,6 +182,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
|
|||
|
||||
// Assert
|
||||
Assert.Equal(DefaultUnresolvedCodeAction.Title, returnedCodeAction.Title);
|
||||
Assert.Null(returnedCodeAction.Edit);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -178,6 +214,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
|
|||
|
||||
// Assert
|
||||
Assert.Equal(DefaultUnresolvedCodeAction.Title, returnedCodeAction.Title);
|
||||
Assert.Null(returnedCodeAction.Edit);
|
||||
}
|
||||
|
||||
private void CreateCodeActionResolver(
|
||||
|
@ -185,7 +222,8 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
|
|||
out DefaultCSharpCodeActionResolver csharpCodeActionResolver,
|
||||
ClientNotifierServiceBase languageServer = null,
|
||||
DocumentVersionCache documentVersionCache = null,
|
||||
RazorFormattingService razorFormattingService = null)
|
||||
RazorFormattingService razorFormattingService = null,
|
||||
CodeAction resolvedCodeAction = null)
|
||||
{
|
||||
var documentPath = "c:/Test.razor";
|
||||
var documentUri = new Uri(documentPath);
|
||||
|
@ -198,7 +236,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
|
|||
RazorFileUri = documentUri
|
||||
};
|
||||
|
||||
languageServer ??= CreateLanguageServer();
|
||||
languageServer ??= CreateLanguageServer(resolvedCodeAction);
|
||||
documentVersionCache ??= CreateDocumentVersionCache();
|
||||
razorFormattingService ??= CreateRazorFormattingService(documentUri);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче