Fix inaccurate HTML/CSS diagnostics on C#. (#4280)

* Fix inaccurate HTML/CSS diagnostics on C#.

- The CSS diagnostic system didn't recognize the C# portions of the document and was then warning about those portions of the document. It's expected that we'd get a diagnostic in this case; however, we should be filtering HTML diagnostics that map to C# literals because they can't see the C# literals properly.
- Added a test to capture this case.

### Before
![image](https://user-images.githubusercontent.com/2008729/135360938-4f7af400-5675-4c5f-93bc-e37aebd0dad7.png)

### After
![image](https://user-images.githubusercontent.com/2008729/135360655-79d2fb12-3c38-4d25-97c7-fc8a71f57394.png)

Fixes dotnet/aspnetcore#36321

* Update src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Diagnostics/RazorDiagnosticsEndpoint.cs

Co-authored-by: David Wengier <david.wengier@microsoft.com>

* Fix tests

Co-authored-by: David Wengier <david.wengier@microsoft.com>
This commit is contained in:
N. Taylor Mullen 2021-09-29 20:19:04 -07:00 коммит произвёл GitHub
Родитель 18acff7a73
Коммит 4fa0705308
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 55 добавлений и 1 удалений

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

@ -171,6 +171,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Diagnostics
var filteredDiagnostics = unmappedDiagnostics
.Where(d =>
!InCSharpLiteral(d, sourceText, syntaxTree) &&
!InAttributeContainingCSharp(d, sourceText, syntaxTree, processedAttributes) &&
!AppliesToTagHelperTagName(d, sourceText, syntaxTree) &&
!ShouldFilterHtmlDiagnosticBasedOnErrorCode(d, sourceText, syntaxTree))
@ -179,6 +180,24 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Diagnostics
return filteredDiagnostics;
}
private static bool InCSharpLiteral(OmniSharpVSDiagnostic d, SourceText sourceText, RazorSyntaxTree syntaxTree)
{
if (d.Range is null)
{
return false;
}
var owner = syntaxTree.GetOwner(sourceText, d.Range.End);
if (owner is null)
{
return false;
}
var isCSharp = owner.Kind is SyntaxKind.CSharpExpressionLiteral or SyntaxKind.CSharpStatementLiteral or SyntaxKind.CSharpEphemeralTextLiteral;
return isCSharp;
}
private static bool AppliesToTagHelperTagName(OmniSharpVSDiagnostic diagnostic, SourceText sourceText, RazorSyntaxTree syntaxTree)
{
// Goal of this method is to filter diagnostics that touch TagHelper tag names. Reason being is TagHelpers can output anything. Meaning

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

@ -270,6 +270,41 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Diagnostics
Assert.Empty(response.Diagnostics);
}
[Fact]
public async Task Handle_FilterDiagnostics_CSharpInsideStylePropertySpace()
{
// Arrange
var documentPath = "C:/path/to/document.cshtml";
var codeDocument = CreateCodeDocumentWithCSharpProjection(
"<style> body { overflow: @DateTime.Now; } </style>",
"var __o = DateTime.Now",
new[] {
new SourceMapping(
new SourceSpan(26, 12),
new SourceSpan(10, 12))
});
var documentResolver = CreateDocumentResolver(documentPath, codeDocument);
var diagnosticsEndpoint = new RazorDiagnosticsEndpoint(Dispatcher, documentResolver, DocumentVersionCache, MappingService, LoggerFactory);
var request = new RazorDiagnosticsParams()
{
Kind = RazorLanguageKind.Html,
Diagnostics = new[] {
new OmniSharpVSDiagnostic() {
Range = new Range(new Position(0, 25), new Position(0, 38)),
Code = "CSS123456",
Severity = DiagnosticSeverity.Warning
}
},
RazorDocumentUri = new Uri(documentPath),
};
// Act
var response = await Task.Run(() => diagnosticsEndpoint.Handle(request, default));
// Assert
Assert.Empty(response.Diagnostics);
}
[Fact]
public async Task Handle_FilterDiagnostics_CSharpInsideStyleBlock()
{
@ -620,7 +655,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Diagnostics
var request = new RazorDiagnosticsParams()
{
Kind = RazorLanguageKind.Razor,
Diagnostics = new[] { new OmniSharpVSDiagnostic() { Range = new Range(new Position(0, 3), new Position(0, 4)) } },
Diagnostics = new[] { new OmniSharpVSDiagnostic() { Range = new Range(new Position(0, 1), new Position(0, 3)) } },
RazorDocumentUri = new Uri(documentPath),
};