From 85fa3bbc8a601310243340439bd5aa9cb3b5ffae Mon Sep 17 00:00:00 2001 From: David Wengier Date: Fri, 3 Mar 2023 14:21:30 +1100 Subject: [PATCH 1/3] Null annotate FirstAncestorOrSelf --- .../src/Syntax/SyntaxNode.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxNode.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxNode.cs index 9d4e97df4c8..e4eaeb5fecc 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxNode.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxNode.cs @@ -340,10 +340,11 @@ public IEnumerable AncestorsAndSelf() } } +#nullable enable /// /// Gets the first node of type TNode that matches the predicate. /// - public TNode FirstAncestorOrSelf(Func predicate = null) + public TNode? FirstAncestorOrSelf(Func? predicate = null) where TNode : SyntaxNode { for (var node = this; node != null; node = node.Parent) @@ -356,6 +357,7 @@ public TNode FirstAncestorOrSelf(Func predicate = null) return default; } +#nullable disable /// /// Gets a list of descendant nodes in prefix document order. From 9d26f265d7ad12ff26d083ad40a78882ac05c1ed Mon Sep 17 00:00:00 2001 From: David Wengier Date: Fri, 3 Mar 2023 14:21:37 +1100 Subject: [PATCH 2/3] Fix null warnings --- .../RazorTranslateDiagnosticsService.cs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Diagnostics/RazorTranslateDiagnosticsService.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Diagnostics/RazorTranslateDiagnosticsService.cs index 80cfc179680..7850846cf63 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Diagnostics/RazorTranslateDiagnosticsService.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Diagnostics/RazorTranslateDiagnosticsService.cs @@ -241,7 +241,7 @@ static bool IsCSharpInStyleBlock(Diagnostic diagnostic, SourceText sourceText, R var element = owner.FirstAncestorOrSelf(n => n.StartTag?.Name.Content == "style"); var csharp = owner.FirstAncestorOrSelf(); - return element.Body.Any(c => c is CSharpCodeBlockSyntax) || csharp is not null; + return element?.Body.Any(c => c is CSharpCodeBlockSyntax) ?? false || csharp is not null; } // Ideally this would be solved instead by not emitting the "!" at the HTML backing file, @@ -255,6 +255,10 @@ static bool IsAnyFilteredTooFewElementsError(Diagnostic diagnostic, SourceText s } var element = owner.FirstAncestorOrSelf(); + if (element is null) + { + return false; + } if (element.StartTag?.Name.Content != "html") { @@ -280,8 +284,8 @@ static bool IsHtmlWithBangAndMatchingTags(Diagnostic diagnostic, SourceText sour } var element = owner.FirstAncestorOrSelf(); - var startNode = element.StartTag; - var endNode = element.EndTag; + var startNode = element?.StartTag; + var endNode = element?.EndTag; if (startNode is null || endNode is null) { @@ -290,9 +294,9 @@ static bool IsHtmlWithBangAndMatchingTags(Diagnostic diagnostic, SourceText sour } var haveBang = startNode.Bang is not null && endNode.Bang is not null; - var namesEquivilant = startNode.Name.Content == endNode.Name.Content; + var namesEquivalent = startNode.Name.Content == endNode.Name.Content; - return haveBang && namesEquivilant; + return haveBang && namesEquivalent; } static bool IsAnyFilteredInvalidNestingError(Diagnostic diagnostic, SourceText sourceText, RazorSyntaxTree syntaxTree, ILogger logger) @@ -334,7 +338,7 @@ static bool IsInvalidNestingFromBody(Diagnostic diagnostic, SourceText sourceTex return false; } - return diagnostic.Message.EndsWith("cannot be nested inside element 'html'.") && body.StartTag?.Bang is not null; + return diagnostic.Message.EndsWith("cannot be nested inside element 'html'.") && body?.StartTag?.Bang is not null; } } From cb516fd217c508e015857d71a4541e5277f2d259 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Fri, 3 Mar 2023 14:21:50 +1100 Subject: [PATCH 3/3] Test! --- .../RazorTranslateDiagnosticsEndpointTest.cs | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Diagnostics/RazorTranslateDiagnosticsEndpointTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Diagnostics/RazorTranslateDiagnosticsEndpointTest.cs index ac40daf9441..8d5e373f374 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Diagnostics/RazorTranslateDiagnosticsEndpointTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Diagnostics/RazorTranslateDiagnosticsEndpointTest.cs @@ -347,6 +347,45 @@ public async Task Handle_FilterDiagnostics_CSharpInsideStyleBlock() Assert.Empty(response.Diagnostics); } + [Fact] + public async Task Handle_FilterDiagnostics_CSharpInsideStyleBlockSpace_NotStyleTag() + { + // Arrange + var documentPath = new Uri("C:/path/to/document.cshtml"); + var codeDocument = CreateCodeDocumentWithCSharpProjection( + " @DateTime.Now ", + "var __o = DateTime.Now", + new[] { + new SourceMapping( + new SourceSpan(4, 12), + new SourceSpan(10, 12)) + }); + var documentContext = CreateDocumentContext(documentPath, codeDocument); + var diagnosticsService = new RazorTranslateDiagnosticsService(_mappingService, LoggerFactory); + var diagnosticsEndpoint = new RazorTranslateDiagnosticsEndpoint(diagnosticsService, LoggerFactory); + var request = new RazorDiagnosticsParams() + { + Kind = RazorLanguageKind.Html, + Diagnostics = new[] { + new VSDiagnostic() { + Range = new Range { Start = new Position(0, 7),End = new Position(0, 7) }, + Code = CSSErrorCodes.MissingSelectorBeforeCombinatorCode, + Severity = DiagnosticSeverity.Warning + } + }, + RazorDocumentUri = documentPath, + }; + var expectedRange = new Range { Start = new Position(0, 8), End = new Position(0, 15) }; + var requestContext = CreateRazorRequestContext(documentContext); + + // Act + var response = await Task.Run(() => diagnosticsEndpoint.HandleRequestAsync(request, requestContext, default)); + + // Assert + Assert.NotNull(response.Diagnostics); + Assert.Equal(CSSErrorCodes.MissingSelectorBeforeCombinatorCode, response.Diagnostics![0].Code); + } + [Fact] public async Task Handle_FilterDiagnostics_CSharpWarning() {