public void Execute_ErrorsForRazorBlockFileScopedSinglyOccurringDirectives() { // Arrange var directive = DirectiveDescriptor.CreateRazorBlockDirective("custom", b => b.Usage = DirectiveUsage.FileScopedSinglyOccurring); var phase = new DefaultRazorIntermediateNodeLoweringPhase(); var engine = RazorProjectEngine.CreateEmpty(b => { b.Phases.Add(phase); b.Features.Add(new DefaultRazorCodeGenerationOptionsFeature(designTime: false)); b.AddDirective(directive); }); var options = RazorParserOptions.Create(builder => builder.Directives.Add(directive)); var importSource = TestRazorSourceDocument.Create("@custom { }", filePath: "import.cshtml"); var codeDocument = TestRazorCodeDocument.Create("<p>NonDirective</p>"); codeDocument.SetSyntaxTree(RazorSyntaxTree.Parse(codeDocument.Source, options)); codeDocument.SetImportSyntaxTrees(new[] { RazorSyntaxTree.Parse(importSource, options) }); var expectedDiagnostic = RazorDiagnosticFactory.CreateDirective_BlockDirectiveCannotBeImported("custom"); // Act phase.Execute(codeDocument); // Assert var documentNode = codeDocument.GetDocumentIntermediateNode(); var directives = documentNode.Children.OfType <DirectiveIntermediateNode>(); Assert.Empty(directives); var diagnostic = Assert.Single(documentNode.GetAllDiagnostics()); Assert.Equal(expectedDiagnostic, diagnostic); }
private void ImportDirectives(DocumentIntermediateNode document) { var visitor = new DirectiveVisitor(); visitor.VisitDocument(document); var seenDirectives = new HashSet <DirectiveDescriptor>(); for (var i = visitor.Directives.Count - 1; i >= 0; i--) { var reference = visitor.Directives[i]; var directive = (DirectiveIntermediateNode)reference.Node; var descriptor = directive.Directive; var seenDirective = !seenDirectives.Add(descriptor); if (!directive.IsImported()) { continue; } switch (descriptor.Kind) { case DirectiveKind.SingleLine: if (seenDirective && descriptor.Usage == DirectiveUsage.FileScopedSinglyOccurring) { // This directive has been overridden, it should be removed from the document. break; } continue; case DirectiveKind.RazorBlock: case DirectiveKind.CodeBlock: if (descriptor.Usage == DirectiveUsage.FileScopedSinglyOccurring) { // A block directive cannot be imported. document.Diagnostics.Add( RazorDiagnosticFactory.CreateDirective_BlockDirectiveCannotBeImported(descriptor.Directive)); } break; default: throw new InvalidOperationException(Resources.FormatUnexpectedDirectiveKind(typeof(DirectiveKind).FullName)); } // Overridden and invalid imported directives make it to here. They should be removed from the document. reference.Remove(); } }