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 @@ -41,7 +41,7 @@ internal static partial class ProtocolConversions

private static readonly char[] s_dirSeparators = [PathUtilities.DirectorySeparatorChar, PathUtilities.AltDirectorySeparatorChar];

private static readonly Regex s_markdownEscapeRegex = new(@"([\\`\*_\{\}\[\]\(\)#+\-\.!])", RegexOptions.Compiled);
private static readonly Regex s_markdownEscapeRegex = new(@"([\\`\*_\{\}\[\]\(\)#+\-\.!<>])", RegexOptions.Compiled);

// NOTE: While the spec allows it, don't use Function and Method, as both VS and VS Code display them the same
// way which can confuse users
Expand Down
42 changes: 42 additions & 0 deletions src/LanguageServer/ProtocolUnitTests/Hover/HoverTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,7 @@ public async Task<string> DoAsync()
expectedLocation).ConfigureAwait(false);
Assert.Equal(expectedMarkdown, results.Contents.Fourth.Value);
}

[Theory, CombinatorialData]
public async Task TestGetHoverAsync_UsesNonBreakingSpaceForSupportedPlatforms(bool mutatingLspWorkspace)
{
Expand Down Expand Up @@ -586,6 +587,47 @@ static void Main(string[] args)
Assert.Equal(expectedMarkdown, result.Contents.Fourth.Value);
}

[Theory, CombinatorialData, WorkItem("https://github.com/dotnet/vscode-csharp/issues/6577")]
public async Task TestGetHoverAsync_EscapesAngleBracketsInGenerics(bool mutatingLspWorkspace)
{
var markup =
"""
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Threading.Tasks;
class C
{
private async Task<IDictionary<string, ImmutableArray<int>>> GetData()
{
{|caret:var|} d = await GetData();
return null;
}
}
""";
var clientCapabilities = new LSP.ClientCapabilities
{
TextDocument = new LSP.TextDocumentClientCapabilities { Hover = new LSP.HoverSetting { ContentFormat = [LSP.MarkupKind.Markdown] } }
};
await using var testLspServer = await CreateTestLspServerAsync(markup, mutatingLspWorkspace, clientCapabilities);
var expectedLocation = testLspServer.GetLocations("caret").Single();

var expectedMarkdown = """
```csharp
interface System.Collections.Generic.IDictionary<TKey, TValue>
```


TKey&nbsp;is&nbsp;string
TValue&nbsp;is&nbsp;ImmutableArray\<int\>

""";

var results = await RunGetHoverAsync(
testLspServer,
expectedLocation).ConfigureAwait(false);
Assert.Equal(expectedMarkdown, results.Contents.Fourth.Value);
}

private static async Task<LSP.Hover> RunGetHoverAsync(
TestLspServer testLspServer,
LSP.Location caret,
Expand Down