This commit is contained in:
David Wengier 2024-08-23 16:24:43 +10:00
Родитель 3b7942872b
Коммит 2157169d4d
5 изменённых файлов: 55 добавлений и 11 удалений

Просмотреть файл

@ -4,6 +4,7 @@
using System;
using System.Collections.Frozen;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Threading;
@ -35,9 +36,11 @@ internal class DocumentOnTypeFormattingEndpoint(
private readonly IHtmlFormatter _htmlFormatter = htmlFormatter;
private readonly ILogger _logger = loggerFactory.GetOrCreateLogger<DocumentOnTypeFormattingEndpoint>();
private static readonly FrozenSet<string> s_csharpTriggerCharacters = FrozenSet.ToFrozenSet(["}", ";"]);
private static readonly FrozenSet<string> s_htmlTriggerCharacters = FrozenSet.ToFrozenSet(["\n", "{", "}", ";"]);
private static readonly FrozenSet<string> s_allTriggerCharacters = FrozenSet.ToFrozenSet(s_csharpTriggerCharacters.Concat(s_htmlTriggerCharacters));
private static readonly ImmutableArray<string> s_allTriggerCharacters = ["}", ";", "\n", "{"];
private static readonly FrozenSet<string> s_csharpTriggerCharacterSet = FrozenSet.ToFrozenSet(["}", ";"], StringComparer.Ordinal);
private static readonly FrozenSet<string> s_htmlTriggerCharacterSet = FrozenSet.ToFrozenSet(["\n", "{", "}", ";"], StringComparer.Ordinal);
private static readonly FrozenSet<string> s_allTriggerCharacterSet = s_allTriggerCharacters.ToFrozenSet(StringComparer.Ordinal);
public bool MutatesSolutionState => false;
@ -45,8 +48,8 @@ internal class DocumentOnTypeFormattingEndpoint(
{
serverCapabilities.DocumentOnTypeFormattingProvider = new DocumentOnTypeFormattingOptions
{
FirstTriggerCharacter = s_allTriggerCharacters.First(),
MoreTriggerCharacter = s_allTriggerCharacters.Skip(1).ToArray(),
FirstTriggerCharacter = s_allTriggerCharacters[0],
MoreTriggerCharacter = s_allTriggerCharacters.AsSpan()[1..].ToArray(),
};
}
@ -71,7 +74,7 @@ internal class DocumentOnTypeFormattingEndpoint(
return null;
}
if (!s_allTriggerCharacters.Contains(request.Character, StringComparer.Ordinal))
if (!s_allTriggerCharacterSet.Contains(request.Character))
{
_logger.LogWarning($"Unexpected trigger character '{request.Character}'.");
return null;
@ -149,14 +152,21 @@ internal class DocumentOnTypeFormattingEndpoint(
{
if (languageKind == RazorLanguageKind.CSharp)
{
return s_csharpTriggerCharacters.Contains(triggerCharacter);
return s_csharpTriggerCharacterSet.Contains(triggerCharacter);
}
else if (languageKind == RazorLanguageKind.Html)
{
return s_htmlTriggerCharacters.Contains(triggerCharacter);
return s_htmlTriggerCharacterSet.Contains(triggerCharacter);
}
// Unknown trigger character.
return false;
}
internal static class TestAccessor
{
public static ImmutableArray<string> GetAllTriggerCharacters() => s_allTriggerCharacters;
public static FrozenSet<string> GetCSharpTriggerCharacterSet() => s_csharpTriggerCharacterSet;
public static FrozenSet<string> GetHtmlTriggerCharacterSet() => s_htmlTriggerCharacterSet;
}
}

Просмотреть файл

@ -13,6 +13,7 @@ using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.LanguageServer.EndpointContracts;
using Microsoft.AspNetCore.Razor.LanguageServer.Formatting;
using Microsoft.AspNetCore.Razor.LanguageServer.Hosting;
using Microsoft.AspNetCore.Razor.PooledObjects;
using Microsoft.CodeAnalysis.Razor.DocumentMapping;
using Microsoft.CodeAnalysis.Razor.Formatting;
using Microsoft.CodeAnalysis.Razor.Logging;
@ -113,7 +114,7 @@ internal sealed class InlineCompletionEndpoint(
return null;
}
var items = new List<VSInternalInlineCompletionItem>();
using var items = new PooledArrayBuilder<VSInternalInlineCompletionItem>(list.Items.Length);
foreach (var item in list.Items)
{
var containsSnippet = item.TextFormat == InsertTextFormat.Snippet;
@ -152,7 +153,7 @@ internal sealed class InlineCompletionEndpoint(
_logger.LogInformation($"Returning {items.Count} items.");
return new VSInternalInlineCompletionList
{
Items = [.. items]
Items = items.ToArray()
};
}

Просмотреть файл

@ -221,7 +221,7 @@ internal sealed class FormattingContext : IDisposable
{
result = null;
var formattingSpans = GetFormattingSpans();
foreach (var formattingSpan in formattingSpans)
foreach (var formattingSpan in formattingSpans.AsEnumerable())
{
var span = formattingSpan.Span;

Просмотреть файл

@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Test.Common.LanguageServer;
@ -18,6 +19,37 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Formatting;
public class DocumentOnTypeFormattingEndpointTest(ITestOutputHelper testOutput) : FormattingLanguageServerTestBase(testOutput)
{
[Fact]
public void AllTriggerCharacters_IncludesCSharpTriggerCharacters()
{
var allChars = DocumentOnTypeFormattingEndpoint.TestAccessor.GetAllTriggerCharacters();
foreach (var character in DocumentOnTypeFormattingEndpoint.TestAccessor.GetCSharpTriggerCharacterSet())
{
Assert.Contains(character, allChars);
}
}
[Fact]
public void AllTriggerCharacters_IncludesHtmlTriggerCharacters()
{
var allChars = DocumentOnTypeFormattingEndpoint.TestAccessor.GetAllTriggerCharacters();
foreach (var character in DocumentOnTypeFormattingEndpoint.TestAccessor.GetHtmlTriggerCharacterSet())
{
Assert.Contains(character, allChars);
}
}
[Fact]
public void AllTriggerCharacters_ContainsUniqueCharacters()
{
var allChars = DocumentOnTypeFormattingEndpoint.TestAccessor.GetAllTriggerCharacters();
var distinctChars = allChars.Distinct().ToArray();
Assert.Equal(distinctChars, allChars);
}
[Fact]
public async Task Handle_OnTypeFormatting_FormattingDisabled_ReturnsNull()
{

Просмотреть файл

@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT license. See License.txt in the project root for license information.
using System;
using System.Collections.Immutable;
using System.Threading;
using System.Threading.Tasks;