Exemplo n.º 1
0
        protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
        {
            var @namespace = documentNode.FindPrimaryNamespace();
            var @class     = documentNode.FindPrimaryClass();

            if (@namespace == null || @class == null)
            {
                // Nothing to do, bail. We can't function without the standard structure.
                return;
            }

            // For each event handler *usage* we need to rewrite the tag helper node to map to basic constructs.
            // Each usage will be represented by a tag helper property that is a descendant of either
            // a component or element.
            var references = documentNode.FindDescendantReferences <TagHelperPropertyIntermediateNode>();

            var parents = new HashSet <IntermediateNode>();

            for (var i = 0; i < references.Count; i++)
            {
                parents.Add(references[i].Parent);
            }

            foreach (var parent in parents)
            {
                ProcessDuplicates(parent);
            }

            for (var i = 0; i < references.Count; i++)
            {
                var reference = references[i];
                var node      = (TagHelperPropertyIntermediateNode)reference.Node;

                if (!reference.Parent.Children.Contains(node))
                {
                    // This node was removed as a duplicate, skip it.
                    continue;
                }

                if (node.TagHelper.IsEventHandlerTagHelper())
                {
                    reference.Replace(RewriteUsage(reference.Parent, node));
                }
            }
        }
        protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
        {
            var @namespace = documentNode.FindPrimaryNamespace();

            if (@namespace == null || string.IsNullOrEmpty(@namespace.Content))
            {
                // No namespace node or it's incomplete. Skip.
                return;
            }

            var @class = documentNode.FindPrimaryClass();

            if (@class == null || string.IsNullOrEmpty(@class.ClassName))
            {
                // No class node or it's incomplete. Skip.
                return;
            }

            string generatedTypeName  = $"{@namespace.Content}.{@class.ClassName}";
            string templateKey        = codeDocument.Source.FilePath;
            string escapedTemplateKey = EscapeAsVerbatimLiteral(templateKey);

            string attribute;

            if (documentNode.DocumentKind == MvcViewDocumentClassifierPass2.MvcViewDocumentKind)
            {
                attribute = $"[assembly:{assemblyTemplateAttribute}({escapedTemplateKey}, typeof({generatedTypeName}))]";
            }
            else
            {
                return;
            }

            int index = documentNode.Children.IndexOf(@namespace);

            var pageAttribute = new CSharpCodeIntermediateNode();

            pageAttribute.Children.Add(new IntermediateToken()
            {
                Kind    = TokenKind.CSharp,
                Content = attribute,
            });

            documentNode.Children.Insert(index, pageAttribute);
        }
Exemplo n.º 3
0
        public void Execute_NoIdentifier_Noops()
        {
            // Arrange
            var engine = CreateEngine();
            var pass   = new MetadataAttributePass()
            {
                Engine = engine,
            };

            var sourceDocument = TestRazorSourceDocument.Create();
            var codeDocument   = RazorCodeDocument.Create(sourceDocument);

            var irDocument = new DocumentIntermediateNode()
            {
                DocumentKind = "test",
                Options      = RazorCodeGenerationOptions.Create((o) => { }),
            };
            var builder    = IntermediateNodeBuilder.Create(irDocument);
            var @namespace = new NamespaceDeclarationIntermediateNode
            {
                Annotations =
                {
                    [CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace,
                },
                Content = "Some.Namespace"
            };

            builder.Push(@namespace);
            var @class = new ClassDeclarationIntermediateNode
            {
                Annotations =
                {
                    [CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass,
                },
                ClassName = "Test",
            };

            builder.Add(@class);

            // Act
            pass.Execute(codeDocument, irDocument);

            // Assert
            SingleChild <NamespaceDeclarationIntermediateNode>(irDocument);
        }
Exemplo n.º 4
0
        private void Rewrite(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
        {
            // Rewrite the document from a flat structure to use a sensible default structure,
            // a namespace and class declaration with a single 'razor' method.
            var children = new List <IntermediateNode>(documentNode.Children);

            documentNode.Children.Clear();

            var @namespace = new NamespaceDeclarationIntermediateNode();

            @namespace.Annotations[CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace;

            var @class = new ClassDeclarationIntermediateNode();

            @class.Annotations[CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass;

            var method = new MethodDeclarationIntermediateNode();

            method.Annotations[CommonAnnotations.PrimaryMethod] = CommonAnnotations.PrimaryMethod;

            var documentBuilder = IntermediateNodeBuilder.Create(documentNode);

            var namespaceBuilder = IntermediateNodeBuilder.Create(documentBuilder.Current);

            namespaceBuilder.Push(@namespace);

            var classBuilder = IntermediateNodeBuilder.Create(namespaceBuilder.Current);

            classBuilder.Push(@class);

            var methodBuilder = IntermediateNodeBuilder.Create(classBuilder.Current);

            methodBuilder.Push(method);

            var visitor = new Visitor(documentBuilder, namespaceBuilder, classBuilder, methodBuilder);

            for (var i = 0; i < children.Count; i++)
            {
                visitor.Visit(children[i]);
            }

            // Note that this is called at the *end* of rewriting so that user code can see the tree
            // and look at its content to make a decision.
            OnDocumentStructureCreated(codeDocument, @namespace, @class, method);
        }
Exemplo n.º 5
0
        protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
        {
            var @namespace = documentNode.FindPrimaryNamespace();
            var @class     = documentNode.FindPrimaryClass();

            if (@namespace == null || @class == null)
            {
                // Nothing to do, bail. We can't function without the standard structure.
                return;
            }

            // For each component *usage* we need to rewrite the tag helper node to map to the relevant component
            // APIs.
            var references = documentNode.FindDescendantReferences <TagHelperIntermediateNode>();

            for (var i = 0; i < references.Count; i++)
            {
                var reference = references[i];
                var node      = (TagHelperIntermediateNode)reference.Node;

                var count = 0;
                for (var j = 0; j < node.TagHelpers.Count; j++)
                {
                    if (node.TagHelpers[j].IsComponentTagHelper())
                    {
                        // Only allow a single component tag helper per element. If there are multiple, we'll just consider
                        // the first one and ignore the others.
                        if (count++ > 1)
                        {
                            node.Diagnostics.Add(BlazorDiagnosticFactory.Create_MultipleComponents(node.Source, node.TagName, node.TagHelpers));
                            break;
                        }
                    }
                }

                if (count >= 1)
                {
                    reference.Replace(RewriteAsComponent(node, node.TagHelpers.First(t => t.IsComponentTagHelper())));
                }
                else
                {
                    reference.Replace(RewriteAsElement(node));
                }
            }
        }
Exemplo n.º 6
0
        protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
        {
            if (documentNode.Options.DesignTime)
            {
                return;
            }

            var walker = new Visitor();

            walker.VisitDocument(documentNode);

            for (var i = 0; i < walker.Items.Count; i++)
            {
                var node = walker.Items[i];

                AddInstrumentation(node);
            }
        }
    public void FindPrimaryNamespace_FindsNamespaceWithAnnotation()
    {
        // Arrange
        var document   = new DocumentIntermediateNode();
        var @namespace = new NamespaceDeclarationIntermediateNode();

        @namespace.Annotations[CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace;

        var builder = IntermediateNodeBuilder.Create(document);

        builder.Add(@namespace);

        // Act
        var result = document.FindPrimaryNamespace();

        // Assert
        Assert.Same(@namespace, result);
    }
    public void FindPrimaryMethod_FindsMethodWithAnnotation()
    {
        // Arrange
        var document = new DocumentIntermediateNode();
        var method   = new MethodDeclarationIntermediateNode();

        method.Annotations[CommonAnnotations.PrimaryMethod] = CommonAnnotations.PrimaryMethod;

        var builder = IntermediateNodeBuilder.Create(document);

        builder.Add(method);

        // Act
        var result = document.FindPrimaryMethod();

        // Assert
        Assert.Same(method, result);
    }
    public void FindPrimaryClass_FindsClassWithAnnotation()
    {
        // Arrange
        var document = new DocumentIntermediateNode();
        var @class   = new ClassDeclarationIntermediateNode();

        @class.Annotations[CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass;

        var builder = IntermediateNodeBuilder.Create(document);

        builder.Add(@class);

        // Act
        var result = document.FindPrimaryClass();

        // Assert
        Assert.Same(@class, result);
    }
    public void TryComputeNamespace_OverrideImportsNamespaceDirective()
    {
        // Arrange
        var sourceDocument = TestRazorSourceDocument.Create(
            content: "@namespace My.Custom.OverrideNS",
            filePath: "C:\\Hello\\Components\\Test.cshtml",
            relativePath: "\\Components\\Test.cshtml");
        var codeDocument = TestRazorCodeDocument.Create(sourceDocument, Array.Empty <RazorSourceDocument>());

        codeDocument.SetFileKind(FileKinds.Component);
        codeDocument.SetSyntaxTree(RazorSyntaxTree.Parse(sourceDocument, RazorParserOptions.Create(options =>
        {
            options.Directives.Add(NamespaceDirective.Directive);
        })));

        var importSourceDocument = TestRazorSourceDocument.Create(
            content: "@namespace My.Custom.NS",
            filePath: "C:\\Hello\\_Imports.razor",
            relativePath: "\\_Imports.razor");

        codeDocument.SetImportSyntaxTrees(new[]
        {
            RazorSyntaxTree.Parse(importSourceDocument, RazorParserOptions.Create(options =>
            {
                options.Directives.Add(NamespaceDirective.Directive);
            }))
        });

        var documentNode = new DocumentIntermediateNode()
        {
            Options = RazorCodeGenerationOptions.Create(c =>
            {
                c.RootNamespace = "Hello.World";
            })
        };

        codeDocument.SetDocumentIntermediateNode(documentNode);

        // Act
        codeDocument.TryComputeNamespace(fallbackToRootNamespace: true, out var @namespace);

        // Assert
        Assert.Equal("My.Custom.OverrideNS", @namespace);
    }
Exemplo n.º 11
0
            protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
            {
                if (documentNode.DocumentKind != RazorPageDocumentClassifierPass.RazorPageDocumentKind &&
                    documentNode.DocumentKind != MvcViewDocumentClassifierPass.MvcViewDocumentKind)
                {
                    // Not a MVC file. Skip.
                    return;
                }

                var visitor = new Visitor();

                visitor.Visit(documentNode);
                var modelType = ModelDirective.GetModelType(documentNode);

                var properties = new HashSet <string>(StringComparer.Ordinal);

                for (var i = visitor.Directives.Count - 1; i >= 0; i--)
                {
                    var directive = visitor.Directives[i];
                    var tokens    = directive.Tokens.ToArray();
                    if (tokens.Length < 2)
                    {
                        continue;
                    }

                    var typeName   = tokens[0].Content;
                    var memberName = tokens[1].Content;

                    if (!properties.Add(memberName))
                    {
                        continue;
                    }

                    typeName = typeName.Replace("<TModel>", "<" + modelType + ">");

                    var injectNode = new InjectIntermediateNode()
                    {
                        TypeName   = typeName,
                        MemberName = memberName,
                    };

                    visitor.Class.Children.Add(injectNode);
                }
            }
Exemplo n.º 12
0
        protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
        {
            if (codeDocument == null)
            {
                throw new ArgumentNullException(nameof(codeDocument));
            }

            if (documentNode == null)
            {
                throw new ArgumentNullException(nameof(documentNode));
            }

            if (!IsComponentDocument(documentNode))
            {
                return;
            }

            if (documentNode.Options.SuppressPrimaryMethodBody)
            {
                // There's no benefit running the whitespace trimmer if we're not emitting
                // the method bodies.
                return;
            }

            // There's no benefit running the whitespace trimmer during design-time builds
            if (documentNode.Options.DesignTime)
            {
                return;
            }

            // Respect @preservewhitespace directives
            if (PreserveWhitespaceIsEnabled(documentNode))
            {
                return;
            }

            var @class = documentNode.FindPrimaryClass();

            if (@class != null)
            {
                var visitor = new Visitor();
                visitor.Visit(@class);
            }
        }
Exemplo n.º 13
0
        public void WriteDocument_WritesMethod()
        {
            // Arrange
            var document = new DocumentIntermediateNode();
            var builder  = IntermediateNodeBuilder.Create(document);

            builder.Add(new MethodDeclarationIntermediateNode()
            {
                Modifiers =
                {
                    "internal",
                    "virtual",
                    "async",
                },
                MethodName = "TestMethod",
                ReturnType = "string",
            });

            var codeDocument = TestRazorCodeDocument.CreateEmpty();
            var options      = RazorCodeGenerationOptions.CreateDefault();

            var target = CodeTarget.CreateDefault(codeDocument, options);
            var writer = new DefaultDocumentWriter(target, options);

            // Act
            var result = writer.WriteDocument(codeDocument, document);

            // Assert
            var csharp = result.GeneratedCode;

            Assert.Equal(
                @"#pragma checksum ""test.cshtml"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""da39a3ee5e6b4b0d3255bfef95601890afd80709""
// <auto-generated/>
#pragma warning disable 1591
#pragma warning disable 1998
internal virtual async string TestMethod()
{
}
#pragma warning restore 1998
#pragma warning restore 1591
",
                csharp,
                ignoreLineEndingDifferences: true);
        }
        public void Execute_NoOps_IfNamespaceNodeIsMissing()
        {
            // Arrange
            var irDocument = new DocumentIntermediateNode()
            {
                Options = RazorCodeGenerationOptions.CreateDefault(),
            };

            var pass = new AssemblyAttributeInjectionPass
            {
                Engine = RazorProjectEngine.Create().Engine,
            };

            // Act
            pass.Execute(TestRazorCodeDocument.CreateEmpty(), irDocument);

            // Assert
            Assert.Empty(irDocument.Children);
        }
Exemplo n.º 15
0
        protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
        {
            var @class = documentNode.FindPrimaryClass();

            if (@class == null)
            {
                return;
            }

            foreach (var inherits in documentNode.FindDirectiveReferences(InheritsDirective.Directive))
            {
                var token = ((DirectiveIntermediateNode)inherits.Node).Tokens.FirstOrDefault();
                if (token != null)
                {
                    @class.BaseType = token.Content;
                    break;
                }
            }
        }
Exemplo n.º 16
0
        public void Execute(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
        {
            if (codeDocument == null)
            {
                throw new ArgumentNullException(nameof(codeDocument));
            }

            if (documentNode == null)
            {
                throw new ArgumentNullException(nameof(documentNode));
            }

            if (Engine == null)
            {
                throw new InvalidOperationException(Resources.FormatPhaseMustBeInitialized(nameof(Engine)));
            }

            ExecuteCore(codeDocument, documentNode);
        }
Exemplo n.º 17
0
        public void WriteDocument_WritesClass()
        {
            // Arrange
            var document = new DocumentIntermediateNode();
            var builder  = IntermediateNodeBuilder.Create(document);

            builder.Add(new ClassDeclarationIntermediateNode()
            {
                Modifiers =
                {
                    "internal"
                },
                BaseType   = "TestBase",
                Interfaces = new List <string> {
                    "IFoo", "IBar",
                },
                ClassName = "TestClass",
            });

            var codeDocument = TestRazorCodeDocument.CreateEmpty();
            var options      = RazorCodeGenerationOptions.CreateDefault();

            var target = CodeTarget.CreateDefault(codeDocument, options);
            var writer = new DefaultDocumentWriter(target, options);

            // Act
            var result = writer.WriteDocument(codeDocument, document);

            // Assert
            var csharp = result.GeneratedCode;

            Assert.Equal(
                @"#pragma checksum ""test.cshtml"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""da39a3ee5e6b4b0d3255bfef95601890afd80709""
// <auto-generated/>
#pragma warning disable 1591
internal class TestClass : TestBase, IFoo, IBar
{
}
#pragma warning restore 1591
",
                csharp,
                ignoreLineEndingDifferences: true);
        }
Exemplo n.º 18
0
        protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
        {
            ClassDeclarationIntermediateNode primaryClass = documentNode.FindPrimaryClass();

            if (primaryClass == null)
            {
                return;
            }

            string fullClassName = null;

            foreach (IntermediateNodeReference directiveReference in documentNode.FindDirectiveReferences(InheritsDirective.Directive))
            {
                DirectiveTokenIntermediateNode intermediateNode =
                    ((DirectiveIntermediateNode)directiveReference.Node).Tokens
                    .FirstOrDefault <DirectiveTokenIntermediateNode>();
                if (intermediateNode != null)
                {
                    fullClassName = intermediateNode.Content;
                    break;
                }
            }
            if (fullClassName == null)
            {
                return;
            }


            if (PartialClassMode)
            {
                var info = new TypeReferenceInfo(fullClassName);

                var pns = documentNode.FindPrimaryNamespace().Content = info.Namespace;
                primaryClass.BaseType = null;
                primaryClass.Modifiers.Add("partial");
                primaryClass.ClassName = info.Name;
            }
            else
            {
                primaryClass.BaseType = fullClassName;
            }
        }
Exemplo n.º 19
0
        protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
        {
            var @namespace = documentNode.FindPrimaryNamespace();
            var @class     = documentNode.FindPrimaryClass();

            if (@namespace == null || @class == null)
            {
                return;
            }

            var directives = documentNode.FindDirectiveReferences(ComponentLayoutDirective.Directive);

            if (directives.Count == 0)
            {
                return;
            }

            var token = ((DirectiveIntermediateNode)directives[0].Node).Tokens.FirstOrDefault();

            if (token == null)
            {
                return;
            }

            var attributeNode = new CSharpCodeIntermediateNode();

            attributeNode.Children.Add(new IntermediateToken()
            {
                Kind    = TokenKind.CSharp,
                Content = $"[{ComponentsApi.LayoutAttribute.FullTypeName}(typeof({token.Content}))]",
            });

            // Insert the new attribute on top of the class
            for (var i = 0; i < @namespace.Children.Count; i++)
            {
                if (object.ReferenceEquals(@namespace.Children[i], @class))
                {
                    @namespace.Children.Insert(i, attributeNode);
                    break;
                }
            }
        }
        public void Execute_IgnoresDocumentsWithDocumentKind()
        {
            // Arrange
            var documentNode = new DocumentIntermediateNode()
            {
                DocumentKind = "ignore",
                Options      = RazorCodeGenerationOptions.CreateDefault(),
            };

            var pass = new DefaultDocumentClassifierPass();

            pass.Engine = RazorProjectEngine.Create().Engine;

            // Act
            pass.Execute(TestRazorCodeDocument.CreateEmpty(), documentNode);

            // Assert
            Assert.Equal("ignore", documentNode.DocumentKind);
            NoChildren(documentNode);
        }
Exemplo n.º 21
0
        public void Execute_NullCodeGenerationOptions_Noops()
        {
            // Arrange
            var engine = CreateEngine();
            var pass   = new MetadataAttributePass()
            {
                Engine = engine,
            };

            var sourceDocument = TestRazorSourceDocument.Create();
            var codeDocument   = RazorCodeDocument.Create(sourceDocument);

            var irDocument = new DocumentIntermediateNode();

            // Act
            pass.Execute(codeDocument, irDocument);

            // Assert
            NoChildren(irDocument);
        }
    public void Build_PopsMultipleLevels()
    {
        // Arrange
        var builder = new DefaultRazorIntermediateNodeBuilder();

        var document = new DocumentIntermediateNode();

        builder.Push(document);

        var node = new BasicIntermediateNode();

        builder.Push(node);

        // Act
        var result = builder.Build();

        // Assert
        Assert.Same(document, result);
        Assert.Null(builder.Current);
    }
Exemplo n.º 23
0
    protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
    {
        if (documentNode.DocumentKind != RazorPageDocumentClassifierPass.RazorPageDocumentKind &&
            documentNode.DocumentKind != MvcViewDocumentClassifierPass.MvcViewDocumentKind)
        {
            // Not a MVC file. Skip.
            return;
        }

        var @namespace = documentNode.FindPrimaryNamespace();
        var @class     = documentNode.FindPrimaryClass();

        if (@namespace == null || @class == null)
        {
            // Nothing to do, bail. We can't function without the standard structure.
            return;
        }

        var context = new Context(@namespace, @class);

        // For each VCTH *usage* we need to rewrite the tag helper node to use the tag helper runtime to construct
        // and set properties on the the correct field, and using the name of the type we will generate.
        var nodes = documentNode.FindDescendantNodes <TagHelperIntermediateNode>();

        for (var i = 0; i < nodes.Count; i++)
        {
            var node = nodes[i];
            foreach (var tagHelper in node.TagHelpers)
            {
                RewriteUsage(context, node, tagHelper);
            }
        }

        // Then for each VCTH *definition* that we've seen we need to generate the class that implements
        // ITagHelper and the field that will hold it.
        foreach (var tagHelper in context.TagHelpers)
        {
            AddField(context, tagHelper);
            AddTagHelperClass(context, tagHelper);
        }
    }
        protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
        {
            var visitor = new Visitor();

            visitor.Visit(documentNode);

            foreach (var implementsNode in visitor.ImplementsNodes)
            {
                visitor.MethodNode.Children.Remove(implementsNode);
            }

            if (visitor.ClassNode.Interfaces == null)
            {
                visitor.ClassNode.Interfaces = new List <string>();
            }

            foreach (var implementsType in visitor.ImplementsTypes)
            {
                visitor.ClassNode.Interfaces.Add(implementsType);
            }
        }
Exemplo n.º 25
0
    protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
    {
        if (!IsComponentDocument(documentNode))
        {
            return;
        }

        var cssScope = codeDocument.GetCssScope();

        if (string.IsNullOrEmpty(cssScope))
        {
            return;
        }

        var nodes = documentNode.FindDescendantNodes <MarkupElementIntermediateNode>();

        for (var i = 0; i < nodes.Count; i++)
        {
            ProcessElement(nodes[i], cssScope);
        }
    }
Exemplo n.º 26
0
    protected sealed override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
    {
        if (documentNode.DocumentKind != null)
        {
            return;
        }

        if (!IsMatch(codeDocument, documentNode))
        {
            return;
        }

        documentNode.DocumentKind = DocumentKind;
        documentNode.Target       = CreateTarget(codeDocument, documentNode.Options);
        if (documentNode.Target == null)
        {
            throw new InvalidOperationException($"{nameof(CreateTarget)} must return a non-null {nameof(CodeTarget)}.");
        }

        Rewrite(codeDocument, documentNode);
    }
    public void TryComputeNamespace_SanitizesNamespaceName()
    {
        // Arrange
        var sourceDocument = TestRazorSourceDocument.Create(filePath: "C:\\Hello\\Components with space\\Test$name.cshtml", relativePath: "\\Components with space\\Test$name.cshtml");
        var codeDocument   = TestRazorCodeDocument.Create(sourceDocument, Array.Empty <RazorSourceDocument>());
        var documentNode   = new DocumentIntermediateNode()
        {
            Options = RazorCodeGenerationOptions.Create(c =>
            {
                c.RootNamespace = "Hel?o.World";
            })
        };

        codeDocument.SetDocumentIntermediateNode(documentNode);

        // Act
        codeDocument.TryComputeNamespace(fallbackToRootNamespace: true, out var @namespace);

        // Assert
        Assert.Equal("Hel_o.World.Components_with_space", @namespace);
    }
    protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
    {
        if (!IsComponentDocument(documentNode))
        {
            return;
        }

        var visitor = new Visitor();

        visitor.Visit(documentNode);

        for (var i = 0; i < visitor.Candidates.Count; i++)
        {
            var candidate = visitor.Candidates[i];
            candidate.Parent.Diagnostics.Add(ComponentDiagnosticFactory.Create_TemplateInvalidLocation(candidate.Node.Source));

            // Remove the offending node since we don't know how to render it. This means that the user won't get C#
            // completion at this location, which is fine because it's inside an HTML attribute.
            candidate.Remove();
        }
    }
        public void InstrumentationPass_SkipsTagHelper_WithoutLocation()
        {
            // Arrange
            var document = new DocumentIntermediateNode();
            var builder  = IntermediateNodeBuilder.Create(document);

            builder.Push(new TagHelperIntermediateNode());

            var pass = new InstrumentationPass()
            {
                Engine = RazorEngine.CreateEmpty(b => { }),
            };

            // Act
            pass.Execute(TestRazorCodeDocument.CreateEmpty(), document);

            // Assert
            Children(
                document,
                n => Assert.IsType <TagHelperIntermediateNode>(n));
        }
        public void Execute_NoMatch_IgnoresDocument()
        {
            // Arrange
            var documentNode = new DocumentIntermediateNode()
            {
                Options = RazorCodeGenerationOptions.CreateDefault(),
            };

            var pass = new TestDocumentClassifierPass()
            {
                Engine      = Engine,
                ShouldMatch = false,
            };

            // Act
            pass.Execute(TestRazorCodeDocument.CreateEmpty(), documentNode);

            // Assert
            Assert.Null(documentNode.DocumentKind);
            NoChildren(documentNode);
        }