Preserve directive node diagnostics in document node

This commit is contained in:
Ajay Bhargav Baaskaran 2018-04-09 13:21:43 -07:00
parent 6270c1f47e
commit 5504374125
4 changed files with 54 additions and 7 deletions

View File

@ -116,9 +116,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
if (!PageDirective.TryGetPageDirective(leadingDirectiveDocumentNode, out var _))
{
// The page directive is not the leading directive. Add an error.
// Note: Adding the error to the top-level document node because the directive node will be removed by a later optimization pass.
var originalDocumentNode = codeDocument.GetDocumentIntermediateNode();
originalDocumentNode.Diagnostics.Add(
pageDirective.DirectiveNode.Diagnostics.Add(
RazorExtensionsDiagnosticFactory.CreatePageDirective_MustExistAtTheTopOfFile(pageDirective.DirectiveNode.Source.Value));
}
}

View File

@ -17,6 +17,12 @@ namespace Microsoft.AspNetCore.Razor.Language
foreach (var nodeReference in visitor.DirectiveNodes)
{
// Lift the diagnostics in the directive node up to the document node.
for (var i = 0; i < nodeReference.Node.Diagnostics.Count; i++)
{
documentNode.Diagnostics.Add(nodeReference.Node.Diagnostics[i]);
}
nodeReference.Remove();
}
}

View File

@ -68,8 +68,9 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
visitor.Visit(irDocument);
// Assert
var documentNode = codeDocument.GetDocumentIntermediateNode();
var diagnostic = Assert.Single(documentNode.Diagnostics);
var pageDirectives = irDocument.FindDirectiveReferences(PageDirective.Directive);
var directive = Assert.Single(pageDirectives);
var diagnostic = Assert.Single(directive.Node.Diagnostics);
Assert.Equal(expectedDiagnostic, diagnostic);
}
@ -97,8 +98,9 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
visitor.Visit(irDocument);
// Assert
var documentNode = codeDocument.GetDocumentIntermediateNode();
Assert.Empty(documentNode.Diagnostics);
var pageDirectives = irDocument.FindDirectiveReferences(PageDirective.Directive);
var directive = Assert.Single(pageDirectives);
Assert.Empty(directive.Node.Diagnostics);
}
[Fact]

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Linq;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
using Xunit;
using static Microsoft.AspNetCore.Razor.Language.Intermediate.IntermediateNodeAssert;
@ -72,6 +73,46 @@ namespace Microsoft.AspNetCore.Razor.Language
Assert.Empty(method.Children);
}
[Fact]
public void Execute_DirectiveWithError_PreservesDiagnosticsAndRemovesDirectiveNodeFromDocument()
{
// Arrange
var content = "@custom \"Hello\"";
var expectedDiagnostic = RazorDiagnostic.Create(new RazorDiagnosticDescriptor("RZ9999", () => "Some diagnostic message.", RazorDiagnosticSeverity.Error), SourceSpan.Undefined);
var sourceDocument = TestRazorSourceDocument.Create(content);
var codeDocument = RazorCodeDocument.Create(sourceDocument);
var defaultEngine = RazorEngine.Create(b =>
{
b.AddDirective(DirectiveDescriptor.CreateDirective("custom", DirectiveKind.SingleLine, d => d.AddStringToken()));
});
var documentNode = Lower(codeDocument, defaultEngine);
// Add the diagnostic to the directive node.
var directiveNode = documentNode.FindDescendantNodes<DirectiveIntermediateNode>().Single();
directiveNode.Diagnostics.Add(expectedDiagnostic);
var pass = new DirectiveRemovalOptimizationPass()
{
Engine = defaultEngine,
};
// Act
pass.Execute(codeDocument, documentNode);
// Assert
var diagnostic = Assert.Single(documentNode.Diagnostics);
Assert.Equal(expectedDiagnostic, diagnostic);
Children(documentNode,
node => Assert.IsType<NamespaceDeclarationIntermediateNode>(node));
var @namespace = documentNode.Children[0];
Children(@namespace,
node => Assert.IsType<ClassDeclarationIntermediateNode>(node));
var @class = @namespace.Children[0];
var method = SingleChild<MethodDeclarationIntermediateNode>(@class);
Assert.Empty(method.Children);
}
private static DocumentIntermediateNode Lower(RazorCodeDocument codeDocument, RazorEngine engine)
{
for (var i = 0; i < engine.Phases.Count; i++)