public void WriteTagHelperBody_DesignTime_WritesChildren()
        {
            // Arrange
            var extension = new DefaultTagHelperTargetExtension();
            var context   = TestCodeRenderingContext.CreateDesignTime();

            var tagHelperNode = new TagHelperIntermediateNode();
            var node          = new DefaultTagHelperBodyIntermediateNode()
            {
                Children =
                {
                    new CSharpExpressionIntermediateNode(),
                }
            };

            tagHelperNode.Children.Add(node);
            Push(context, tagHelperNode);

            // Act
            extension.WriteTagHelperBody(context, node);

            // Assert
            var csharp = context.CodeWriter.GenerateCode();

            Assert.Equal(
                @"Render Children
",
                csharp,
                ignoreLineEndingDifferences: true);
        }
Ejemplo n.º 2
0
 private void ProcessAttributes(TagHelperIntermediateNode node)
 {
     for (var i = node.Children.Count - 1; i >= 0; i--)
     {
         if (node.Children[i] is TagHelperPropertyIntermediateNode propertyNode)
         {
             if (TrySimplifyContent(propertyNode) && node.TagHelpers.Any(t => t.IsComponentTagHelper()))
             {
                 node.Diagnostics.Add(ComponentDiagnosticFactory.Create_UnsupportedComplexContent(
                                          propertyNode,
                                          propertyNode.AttributeName));
                 node.Children.RemoveAt(i);
                 continue;
             }
         }
         else if (node.Children[i] is TagHelperHtmlAttributeIntermediateNode htmlNode)
         {
             if (TrySimplifyContent(htmlNode) && node.TagHelpers.Any(t => t.IsComponentTagHelper()))
             {
                 node.Diagnostics.Add(ComponentDiagnosticFactory.Create_UnsupportedComplexContent(
                                          htmlNode,
                                          htmlNode.AttributeName));
                 node.Children.RemoveAt(i);
                 continue;
             }
         }
     }
 }
Ejemplo n.º 3
0
        public void WriteTagHelperExecute_DesignTime_WritesNothing()
        {
            // Arrange
            var extension = new DefaultTagHelperTargetExtension()
            {
                DesignTime = true
            };
            var context = TestCodeRenderingContext.CreateDesignTime();

            var tagHelperNode = new TagHelperIntermediateNode();
            var node          = new DefaultTagHelperExecuteIntermediateNode();

            tagHelperNode.Children.Add(node);
            Push(context, tagHelperNode);

            // Act
            extension.WriteTagHelperExecute(context, node);

            // Assert
            var csharp = context.CodeWriter.GenerateCode();

            Assert.Equal(
                @"",
                csharp,
                ignoreLineEndingDifferences: true);
        }
        public void WriteTagHelperCreate_Runtime_RendersCorrectly_UsesSpecifiedTagHelperType()
        {
            // Arrange
            var extension = new DefaultTagHelperTargetExtension();
            var context   = TestCodeRenderingContext.CreateRuntime();

            var tagHelperNode = new TagHelperIntermediateNode();
            var node          = new DefaultTagHelperCreateIntermediateNode()
            {
                FieldName = "__TestNamespace_MyTagHelper",
                TypeName  = "TestNamespace.MyTagHelper",
            };

            tagHelperNode.Children.Add(node);
            Push(context, tagHelperNode);

            // Act
            extension.WriteTagHelperCreate(context, node);

            // Assert
            var csharp = context.CodeWriter.GenerateCode();

            Assert.Equal(
                @"__TestNamespace_MyTagHelper = CreateTagHelper<global::TestNamespace.MyTagHelper>();
__tagHelperExecutionContext.Add(__TestNamespace_MyTagHelper);
",
                csharp,
                ignoreLineEndingDifferences: true);
        }
Ejemplo n.º 5
0
        private ComponentIntermediateNode RewriteAsComponent(TagHelperIntermediateNode node, TagHelperDescriptor tagHelper)
        {
            var component = new ComponentIntermediateNode()
            {
                Component = tagHelper,
                Source    = node.Source,
                TagName   = node.TagName,
                TypeName  = tagHelper.GetTypeName(),
            };

            for (var i = 0; i < node.Diagnostics.Count; i++)
            {
                component.Diagnostics.Add(node.Diagnostics[i]);
            }

            var visitor = new ComponentRewriteVisitor(component);

            visitor.Visit(node);

            // Fixup the parameter names of child content elements. We can't do this during the rewrite
            // because we see the nodes in the wrong order.
            foreach (var childContent in component.ChildContents)
            {
                childContent.ParameterName = childContent.ParameterName ?? component.ChildContentParameterName ?? ComponentMetadata.ChildContent.DefaultParameterName;
            }

            return(component);
        }
Ejemplo n.º 6
0
        private void ProcessAttributes(TagHelperIntermediateNode node)
        {
            for (var i = node.Children.Count - 1; i >= 0; i--)
            {
                if (node.Children[i] is TagHelperPropertyIntermediateNode propertyNode)
                {
                    if (HasComplexChildContent(propertyNode))
                    {
                        node.Diagnostics.Add(BlazorDiagnosticFactory.Create_UnsupportedComplexContent(
                                                 propertyNode,
                                                 propertyNode.AttributeName));
                        node.Children.RemoveAt(i);
                        continue;
                    }

                    node.Children[i] = new ComponentAttributeExtensionNode(propertyNode);
                }
                else if (node.Children[i] is TagHelperHtmlAttributeIntermediateNode htmlNode)
                {
                    if (HasComplexChildContent(htmlNode))
                    {
                        node.Diagnostics.Add(BlazorDiagnosticFactory.Create_UnsupportedComplexContent(
                                                 htmlNode,
                                                 htmlNode.AttributeName));
                        node.Children.RemoveAt(i);
                        continue;
                    }
                }
            }
        }
Ejemplo n.º 7
0
        public void WriteTagHelperHtmlAttribute_RendersCorrectly()
        {
            // Arrange
            var extension = new PreallocatedAttributeTargetExtension();
            var context   = TestCodeRenderingContext.CreateRuntime();

            var tagHelperNode = new TagHelperIntermediateNode();
            var node          = new PreallocatedTagHelperHtmlAttributeIntermediateNode()
            {
                VariableName = "_tagHelper1"
            };

            tagHelperNode.Children.Add(node);
            Push(context, tagHelperNode);

            // Act
            extension.WriteTagHelperHtmlAttribute(context, node);

            // Assert
            var csharp = context.CodeWriter.GenerateCode();

            Assert.Equal(
                @"__tagHelperExecutionContext.AddHtmlAttribute(_tagHelper1);
",
                csharp,
                ignoreLineEndingDifferences: true);
        }
Ejemplo n.º 8
0
        public void WriteSetPreallocatedTagHelperProperty_IndexerAttribute_MultipleValues()
        {
            // Arrange
            var extension = new PreallocatedAttributeTargetExtension();
            var context   = TestCodeRenderingContext.CreateRuntime();

            var tagHelperBuilder = new DefaultTagHelperDescriptorBuilder(TagHelperConventions.DefaultKind, "FooTagHelper", "Test");

            tagHelperBuilder.TypeName("FooTagHelper");

            var builder = new DefaultBoundAttributeDescriptorBuilder(tagHelperBuilder, TagHelperConventions.DefaultKind);

            builder
            .Name("Foo")
            .TypeName("System.Collections.Generic.Dictionary<System.String, System.String>")
            .AsDictionaryAttribute("pre-", "System.String")
            .PropertyName("FooProp");

            var boundAttribute = builder.Build();
            var tagHelper      = tagHelperBuilder.Build();

            var tagHelperNode = new TagHelperIntermediateNode();
            var node1         = new PreallocatedTagHelperPropertyIntermediateNode()
            {
                AttributeName      = "pre-Bar",
                FieldName          = "__FooTagHelper",
                VariableName       = "_tagHelper0s",
                BoundAttribute     = boundAttribute,
                IsIndexerNameMatch = true,
                PropertyName       = "FooProp",
                TagHelper          = tagHelper,
            };
            var node2 = new PreallocatedTagHelperPropertyIntermediateNode()
            {
                AttributeName      = "pre-Foo",
                FieldName          = "__FooTagHelper",
                VariableName       = "_tagHelper1",
                BoundAttribute     = boundAttribute,
                IsIndexerNameMatch = true,
                PropertyName       = "FooProp",
                TagHelper          = tagHelper,
            };

            tagHelperNode.Children.Add(node1);
            tagHelperNode.Children.Add(node2);
            Push(context, tagHelperNode);

            // Act
            extension.WriteTagHelperProperty(context, node2);

            // Assert
            var csharp = context.CodeWriter.GenerateCode();

            Assert.Equal(
                @"__FooTagHelper.FooProp[""Foo""] = (string)_tagHelper1.Value;
__tagHelperExecutionContext.AddTagHelperAttribute(_tagHelper1);
",
                csharp,
                ignoreLineEndingDifferences: true);
        }
        public void WriteTagHelperExecute_Runtime_RendersCorrectly()
        {
            // Arrange
            var extension = new DefaultTagHelperTargetExtension();
            var context   = TestCodeRenderingContext.CreateRuntime();

            var tagHelperNode = new TagHelperIntermediateNode();
            var node          = new DefaultTagHelperExecuteIntermediateNode();

            tagHelperNode.Children.Add(node);
            Push(context, tagHelperNode);

            // Act
            extension.WriteTagHelperExecute(context, node);

            // Assert
            var csharp = context.CodeWriter.GenerateCode();

            Assert.Equal(
                @"await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
if (!__tagHelperExecutionContext.Output.IsContentModified)
{
    await __tagHelperExecutionContext.SetOutputContentAsync();
}
Write(__tagHelperExecutionContext.Output);
__tagHelperExecutionContext = __tagHelperScopeManager.End();
",
                csharp,
                ignoreLineEndingDifferences: true);
        }
        public void WriteTagHelperBody_Runtime_RendersCorrectly_UsesTagNameAndModeFromContext()
        {
            // Arrange
            var extension = new DefaultTagHelperTargetExtension();
            var context   = TestCodeRenderingContext.CreateRuntime();

            var tagHelperNode = new TagHelperIntermediateNode();
            var node          = new DefaultTagHelperBodyIntermediateNode()
            {
                Children =
                {
                    new CSharpExpressionIntermediateNode(),
                },
                TagMode = TagMode.SelfClosing,
                TagName = "p",
            };

            tagHelperNode.Children.Add(node);
            Push(context, tagHelperNode);

            // Act
            extension.WriteTagHelperBody(context, node);

            // Assert
            var csharp = context.CodeWriter.GenerateCode();

            Assert.Equal(
                @"__tagHelperExecutionContext = __tagHelperScopeManager.Begin(""p"", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, ""test"", async() => {
    Render Children
}
);
",
                csharp,
                ignoreLineEndingDifferences: true);
        }
Ejemplo n.º 11
0
 public override void VisitTagHelper(TagHelperIntermediateNode node)
 {
     // Visit children, we're replacing this node.
     for (var i = 0; i < node.Children.Count; i++)
     {
         Visit(node.Children[i]);
     }
 }
        private void RewriteUsage(Context context, TagHelperIntermediateNode node, TagHelperDescriptor tagHelper)
        {
            if (!tagHelper.IsDefaultKind())
            {
                return;
            }

            context.Add(tagHelper);

            // First we need to insert a node for the creation of the tag helper, and the hook up to the execution
            // context. This should come after the body node and any existing create nodes.
            //
            // If we're dealing with something totally malformed, then we'll end up just inserting at the end, and that's not
            // so bad.
            var i = 0;

            // Find the body node.
            while (i < node.Children.Count && node.Children[i] is TagHelperBodyIntermediateNode)
            {
                i++;
            }
            while (i < node.Children.Count && node.Children[i] is DefaultTagHelperBodyIntermediateNode)
            {
                i++;
            }

            // Now find the last create node.
            while (i < node.Children.Count && node.Children[i] is DefaultTagHelperCreateIntermediateNode)
            {
                i++;
            }

            // Now i has the right insertion point.
            node.Children.Insert(i, new DefaultTagHelperCreateIntermediateNode()
            {
                FieldName = context.GetFieldName(tagHelper),
                TagHelper = tagHelper,
                TypeName  = tagHelper.GetTypeName(),
            });

            // Next we need to rewrite any property nodes to use the field and property name for this
            // tag helper.
            for (i = 0; i < node.Children.Count; i++)
            {
                if (node.Children[i] is TagHelperPropertyIntermediateNode propertyNode &&
                    propertyNode.TagHelper == tagHelper)
                {
                    // This belongs to the current tag helper, replace it.
                    node.Children[i] = new DefaultTagHelperPropertyIntermediateNode(propertyNode)
                    {
                        FieldName    = context.GetFieldName(tagHelper),
                        PropertyName = propertyNode.BoundAttribute.GetPropertyName(),
                    };
                }
            }
        }
 private void RewriteHtmlAttributes(TagHelperIntermediateNode node)
 {
     // We need to rewrite each html attribute, so that it will get added to the execution context.
     for (var i = 0; i < node.Children.Count; i++)
     {
         if (node.Children[i] is TagHelperHtmlAttributeIntermediateNode htmlAttributeNode)
         {
             node.Children[i] = new DefaultTagHelperHtmlAttributeIntermediateNode(htmlAttributeNode);
         }
     }
 }
        public void WriteTagHelperProperty_Runtime_NonStringIndexer_RendersCorrectly()
        {
            // Arrange
            var extension = new DefaultTagHelperTargetExtension();
            var context   = TestCodeRenderingContext.CreateRuntime();

            var tagHelperNode = new TagHelperIntermediateNode();
            var node          = new DefaultTagHelperPropertyIntermediateNode()
            {
                AttributeName      = "foo-bound",
                AttributeStructure = AttributeStructure.DoubleQuotes,
                BoundAttribute     = IntIndexerTagHelper.BoundAttributes.Single(),
                FieldName          = "__InputTagHelper",
                IsIndexerNameMatch = true,
                PropertyName       = "IntIndexer",
                TagHelper          = IntIndexerTagHelper,
                Source             = Span,
                Children           =
                {
                    new CSharpExpressionIntermediateNode()
                    {
                        Children ={ new IntermediateToken                {
                          Kind = TokenKind.CSharp, Content = "32",
                      } },
                    }
                }
            };

            tagHelperNode.Children.Add(node);
            Push(context, tagHelperNode);

            // Act
            extension.WriteTagHelperProperty(context, node);

            // Assert
            var csharp = context.CodeWriter.GenerateCode();

            Assert.Equal(
                @"if (__InputTagHelper.IntIndexer == null)
{
    throw new InvalidOperationException(InvalidTagHelperIndexerAssignment(""foo-bound"", ""InputTagHelper"", ""IntIndexer""));
}
#nullable restore
#line 3 ""test.cshtml""
__InputTagHelper.IntIndexer[""bound""] = 32;

#line default
#line hidden
#nullable disable
__tagHelperExecutionContext.AddTagHelperAttribute(""foo-bound"", __InputTagHelper.IntIndexer[""bound""], global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
",
                csharp,
                ignoreLineEndingDifferences: true);
        }
Ejemplo n.º 15
0
        private void RewriteUsage(Context context, TagHelperIntermediateNode node, TagHelperDescriptor tagHelper)
        {
            if (!tagHelper.IsViewComponentKind())
            {
                return;
            }

            context.Add(tagHelper);

            // Now we need to insert a create node using the default tag helper runtime. This is similar to
            // code in DefaultTagHelperOptimizationPass.
            //
            // Find the body node.
            var i = 0;

            while (i < node.Children.Count && node.Children[i] is TagHelperBodyIntermediateNode)
            {
                i++;
            }
            while (i < node.Children.Count && node.Children[i] is DefaultTagHelperBodyIntermediateNode)
            {
                i++;
            }

            // Now find the last create node.
            while (i < node.Children.Count && node.Children[i] is DefaultTagHelperCreateIntermediateNode)
            {
                i++;
            }

            // Now i has the right insertion point.
            node.Children.Insert(i, new DefaultTagHelperCreateIntermediateNode()
            {
                FieldName = context.GetFieldName(tagHelper),
                TagHelper = tagHelper,
                TypeName  = context.GetFullyQualifiedName(tagHelper),
            });

            // Now we need to rewrite any set property nodes to use the default runtime.
            for (i = 0; i < node.Children.Count; i++)
            {
                if (node.Children[i] is TagHelperPropertyIntermediateNode propertyNode &&
                    propertyNode.TagHelper == tagHelper)
                {
                    // This is a set property for this VCTH - we need to replace it with a node
                    // that will use our field and property name.
                    node.Children[i] = new DefaultTagHelperPropertyIntermediateNode(propertyNode)
                    {
                        FieldName    = context.GetFieldName(tagHelper),
                        PropertyName = propertyNode.BoundAttribute.GetPropertyName(),
                    };
                }
            }
        }
        private bool IsTagHelperRuntimeNode(TagHelperIntermediateNode node)
        {
            foreach (var tagHelper in node.TagHelpers)
            {
                if (tagHelper.KindUsesDefaultTagHelperRuntime())
                {
                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 17
0
        private void RewriteUsage(TagHelperIntermediateNode node, TagHelperDescriptor tagHelper)
        {
            // Ignore Kind here. Some versions of Razor have a bug in the serializer that ignores it.

            // We need to surround the contents of the node with open and close nodes to ensure the component
            // is scoped correctly.
            node.Children.Insert(0, new ComponentOpenExtensionNode()
            {
                TypeName = tagHelper.GetTypeName(),
            });

            for (var i = node.Children.Count - 1; i >= 0; i--)
            {
                if (node.Children[i] is TagHelperBodyIntermediateNode bodyNode)
                {
                    // Replace with a node that we recognize so that it we can do proper scope tracking.
                    //
                    // Note that we force the body node to be last, this is done to push it after the
                    // attribute nodes. This gives us the ordering we want for the render tree.
                    node.Children.RemoveAt(i);
                    node.Children.Add(new ComponentBodyExtensionNode(bodyNode)
                    {
                        TagMode = node.TagMode,
                        TagName = node.TagName,
                    });
                }
            }

            node.Children.Add(new ComponentCloseExtensionNode());

            // Now we need to rewrite any set property or HTML nodes to call the appropriate AddAttribute api.
            for (var i = node.Children.Count - 1; i >= 0; i--)
            {
                if (node.Children[i] is TagHelperPropertyIntermediateNode propertyNode &&
                    propertyNode.TagHelper == tagHelper)
                {
                    // We don't support 'complex' content for components (mixed C# and markup) right now.
                    // It's not clear yet if Blazor will have a good scenario to use these constructs.
                    //
                    // This is where a lot of the complexity in the Razor/TagHelpers model creeps in and we
                    // might be able to avoid it if these features aren't needed.
                    if (HasComplexChildContent(propertyNode))
                    {
                        node.Diagnostics.Add(BlazorDiagnosticFactory.Create_UnsupportedComplexContent(
                                                 propertyNode,
                                                 propertyNode.AttributeName));
                        node.Children.RemoveAt(i);
                        continue;
                    }

                    node.Children[i] = new ComponentAttributeExtensionNode(propertyNode);
                }
Ejemplo n.º 18
0
            public override void VisitTagHelper(TagHelperIntermediateNode node)
            {
                base.VisitTagHelper(node);

                // Use a post-order traversal because we're going to rewite tag helper nodes, and thus
                // change the parent nodes.
                //
                // This ensures that we operate the leaf nodes first.
                if (!node.TagHelpers.Any(t => t.IsComponentTagHelper()))
                {
                    References.Add(new IntermediateNodeReference(Parent, node));
                }
            }
Ejemplo n.º 19
0
        private void ProcessDuplicates(TagHelperIntermediateNode node)
        {
            // Reverse order because we will remove nodes.
            //
            // Each 'property' node could be duplicated if there are multiple tag helpers that match that
            // particular attribute. This is likely to happen when a component also defines something like
            // OnClick. We want to remove the 'onclick' and let it fall back to be handled by the component.
            for (var i = node.Children.Count - 1; i >= 0; i--)
            {
                var attributeNode = node.Children[i] as ComponentAttributeExtensionNode;
                if (attributeNode != null &&
                    attributeNode.TagHelper != null &&
                    attributeNode.TagHelper.IsEventHandlerTagHelper())
                {
                    for (var j = 0; j < node.Children.Count; j++)
                    {
                        var duplicate = node.Children[j] as ComponentAttributeExtensionNode;
                        if (duplicate != null &&
                            duplicate.TagHelper != null &&
                            duplicate.TagHelper.IsComponentTagHelper() &&
                            duplicate.AttributeName == attributeNode.AttributeName)
                        {
                            // Found a duplicate - remove the 'fallback' in favor of the
                            // more specific tag helper.
                            node.Children.RemoveAt(i);
                            node.TagHelpers.Remove(attributeNode.TagHelper);
                            break;
                        }
                    }
                }
            }

            // If we still have duplicates at this point then they are genuine conflicts.
            var duplicates = node.Children
                             .OfType <ComponentAttributeExtensionNode>()
                             .Where(p => p.TagHelper?.IsEventHandlerTagHelper() ?? false)
                             .GroupBy(p => p.AttributeName)
                             .Where(g => g.Count() > 1);

            foreach (var duplicate in duplicates)
            {
                node.Diagnostics.Add(BlazorDiagnosticFactory.CreateEventHandler_Duplicates(
                                         node.Source,
                                         duplicate.Key,
                                         duplicate.ToArray()));
                foreach (var property in duplicate)
                {
                    node.Children.Remove(property);
                }
            }
        }
        public void WriteTagHelperProperty_DesignTime_NonStringIndexer_RendersCorrectly()
        {
            // Arrange
            var extension = new DefaultTagHelperTargetExtension();
            var context   = TestCodeRenderingContext.CreateDesignTime();

            var tagHelperNode = new TagHelperIntermediateNode();
            var node          = new DefaultTagHelperPropertyIntermediateNode()
            {
                AttributeName      = "foo-bound",
                AttributeStructure = AttributeStructure.DoubleQuotes,
                BoundAttribute     = IntIndexerTagHelper.BoundAttributes.Single(),
                FieldName          = "__InputTagHelper",
                IsIndexerNameMatch = true,
                PropertyName       = "IntIndexer",
                TagHelper          = IntIndexerTagHelper,
                Source             = Span,
                Children           =
                {
                    new CSharpExpressionIntermediateNode()
                    {
                        Children ={ new IntermediateToken                {
                          Kind = TokenKind.CSharp, Content = "32",
                      } },
                    }
                }
            };

            tagHelperNode.Children.Add(node);
            Push(context, tagHelperNode);

            // Act
            extension.WriteTagHelperProperty(context, node);

            // Assert
            var csharp = context.CodeWriter.GenerateCode();

            Assert.Equal(
                @"
#nullable restore
#line 3 ""test.cshtml""
__InputTagHelper.IntIndexer[""bound""] = 32;

#line default
#line hidden
#nullable disable
",
                csharp,
                ignoreLineEndingDifferences: true);
        }
 private void RewriteBody(TagHelperIntermediateNode node)
 {
     for (var i = 0; i < node.Children.Count; i++)
     {
         if (node.Children[i] is TagHelperBodyIntermediateNode bodyNode)
         {
             // We only expect one body node.
             node.Children[i] = new DefaultTagHelperBodyIntermediateNode(bodyNode)
             {
                 TagMode = node.TagMode,
                 TagName = node.TagName,
             };
             break;
         }
     }
 }
Ejemplo n.º 22
0
        public void WriteTagHelperHtmlAttribute_DesignTime_WritesNothing()
        {
            // Arrange
            var extension = new DefaultTagHelperTargetExtension()
            {
                DesignTime = true
            };
            var context = TestCodeRenderingContext.CreateDesignTime();

            var tagHelperNode = new TagHelperIntermediateNode();
            var node          = new DefaultTagHelperHtmlAttributeIntermediateNode()
            {
                AttributeName      = "name",
                AttributeStructure = AttributeStructure.DoubleQuotes,
                Children           =
                {
                    new HtmlAttributeValueIntermediateNode()
                    {
                        Children ={ new IntermediateToken                {
                          Kind = TokenKind.Html, Content = "Blah-"
                      } }
                    },
                    new CSharpCodeAttributeValueIntermediateNode()
                    {
                        Children ={ new IntermediateToken                {
                          Kind = TokenKind.CSharp, Content = "\"Foo\"",
                      } },
                    }
                }
            };

            tagHelperNode.Children.Add(node);
            Push(context, tagHelperNode);

            // Act
            extension.WriteTagHelperHtmlAttribute(context, node);

            // Assert
            var csharp = context.CodeWriter.GenerateCode();

            Assert.Equal(
                @"Render Children
Render Children
",
                csharp,
                ignoreLineEndingDifferences: true);
        }
        public void WriteTagHelperProperty_Runtime_StringProperty_HtmlContent_RendersCorrectly()
        {
            // Arrange
            var extension = new DefaultTagHelperTargetExtension();
            var context   = TestCodeRenderingContext.CreateRuntime();

            var tagHelperNode = new TagHelperIntermediateNode();
            var node          = new DefaultTagHelperPropertyIntermediateNode()
            {
                AttributeName      = "bound",
                AttributeStructure = AttributeStructure.DoubleQuotes,
                BoundAttribute     = StringPropertyTagHelper.BoundAttributes.Single(),
                FieldName          = "__InputTagHelper",
                IsIndexerNameMatch = false,
                PropertyName       = "StringProp",
                TagHelper          = StringPropertyTagHelper,
                Children           =
                {
                    new HtmlContentIntermediateNode()
                    {
                        Children ={ new IntermediateToken                {
                          Kind = TokenKind.Html, Content = "\"value\"",
                      } },
                    }
                }
            };

            tagHelperNode.Children.Add(node);
            Push(context, tagHelperNode);

            // Act
            extension.WriteTagHelperProperty(context, node);

            // Assert
            var csharp = context.CodeWriter.GenerateCode();

            // The attribute value is not rendered inline because we are not using the preallocated writer.
            Assert.Equal(
                @"BeginWriteTagHelperAttribute();
Render Children
__tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
__InputTagHelper.StringProp = __tagHelperStringValueBuffer;
__tagHelperExecutionContext.AddTagHelperAttribute(""bound"", __InputTagHelper.StringProp, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
",
                csharp,
                ignoreLineEndingDifferences: true);
        }
Ejemplo n.º 24
0
        [Fact] // We don't actually assign the expression result at design time, we just use string.Empty as a placeholder.
        public void WriteTagHelperProperty_DesignTime_StringProperty_NonHtmlContent_RendersCorrectly()
        {
            // Arrange
            var extension = new DefaultTagHelperTargetExtension()
            {
                DesignTime = true
            };
            var context = TestCodeRenderingContext.CreateDesignTime();

            var tagHelperNode = new TagHelperIntermediateNode();
            var node          = new DefaultTagHelperPropertyIntermediateNode()
            {
                AttributeName      = "bound",
                AttributeStructure = AttributeStructure.DoubleQuotes,
                BoundAttribute     = StringPropertyTagHelper.BoundAttributes.Single(),
                FieldName          = "__InputTagHelper",
                IsIndexerNameMatch = false,
                PropertyName       = "StringProp",
                TagHelper          = StringPropertyTagHelper,
                Children           =
                {
                    new CSharpExpressionIntermediateNode()
                    {
                        Children ={ new IntermediateToken                {
                          Kind = TokenKind.CSharp, Content = "\"3+5\"",
                      } },
                    }
                }
            };

            tagHelperNode.Children.Add(node);
            Push(context, tagHelperNode);

            // Act
            extension.WriteTagHelperProperty(context, node);

            // Assert
            var csharp = context.CodeWriter.GenerateCode();

            Assert.Equal(
                @"Render Children
__InputTagHelper.StringProp = string.Empty;
",
                csharp,
                ignoreLineEndingDifferences: true);
        }
        public void WriteTagHelperHtmlAttribute_Runtime_DynamicAttribute_RendersCorrectly()
        {
            // Arrange
            var extension = new DefaultTagHelperTargetExtension();
            var context   = TestCodeRenderingContext.CreateRuntime();

            var tagHelperNode = new TagHelperIntermediateNode();
            var node          = new DefaultTagHelperHtmlAttributeIntermediateNode()
            {
                AttributeName      = "name",
                AttributeStructure = AttributeStructure.DoubleQuotes,
                Children           =
                {
                    new HtmlAttributeValueIntermediateNode()
                    {
                        Children ={ new IntermediateToken                {
                          Kind = TokenKind.Html, Content = "Blah-"
                      } }
                    },
                    new CSharpCodeAttributeValueIntermediateNode()
                    {
                        Children ={ new IntermediateToken                {
                          Kind = TokenKind.CSharp, Content = "\"Foo\"",
                      } },
                    }
                }
            };

            tagHelperNode.Children.Add(node);
            Push(context, tagHelperNode);

            // Act
            extension.WriteTagHelperHtmlAttribute(context, node);

            // Assert
            var csharp = context.CodeWriter.GenerateCode();

            Assert.Equal(
                @"BeginAddHtmlAttributeValues(__tagHelperExecutionContext, ""name"", 2, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
Render Children
Render Children
EndAddHtmlAttributeValues(__tagHelperExecutionContext);
",
                csharp,
                ignoreLineEndingDifferences: true);
        }
Ejemplo n.º 26
0
        public void WriteTagHelperProperty_DesignTime_NonStringProperty_SecondUseOfAttribute()
        {
            // Arrange
            var extension = new DefaultTagHelperTargetExtension()
            {
                DesignTime = true
            };
            var context = TestCodeRenderingContext.CreateDesignTime();

            var tagHelperNode = new TagHelperIntermediateNode();
            var node1         = new DefaultTagHelperPropertyIntermediateNode()
            {
                // We only look at the attribute name here.
                AttributeName = "bound",
                FieldName     = "__OtherTagHelper",
                PropertyName  = "IntProp",
            };
            var node2 = new DefaultTagHelperPropertyIntermediateNode()
            {
                AttributeName      = "bound",
                AttributeStructure = AttributeStructure.DoubleQuotes,
                BoundAttribute     = IntPropertyTagHelper.BoundAttributes.Single(),
                FieldName          = "__InputTagHelper",
                IsIndexerNameMatch = false,
                PropertyName       = "IntProp",
                TagHelper          = IntPropertyTagHelper,
                Source             = Span,
            };

            tagHelperNode.Children.Add(node1);
            tagHelperNode.Children.Add(node2);
            Push(context, tagHelperNode);

            // Act
            extension.WriteTagHelperProperty(context, node2);

            // Assert
            var csharp = context.CodeWriter.GenerateCode();

            Assert.Equal(
                @"__InputTagHelper.IntProp = __OtherTagHelper.IntProp;
",
                csharp,
                ignoreLineEndingDifferences: true);
        }
Ejemplo n.º 27
0
        public void WriteTagHelperProperty_RendersCorrectly()
        {
            // Arrange
            var extension = new PreallocatedAttributeTargetExtension();
            var context   = TestCodeRenderingContext.CreateRuntime();

            var tagHelperBuilder = new DefaultTagHelperDescriptorBuilder(TagHelperConventions.DefaultKind, "FooTagHelper", "Test");

            tagHelperBuilder.TypeName("FooTagHelper");

            var builder = new DefaultBoundAttributeDescriptorBuilder(tagHelperBuilder, TagHelperConventions.DefaultKind);

            builder
            .Name("Foo")
            .TypeName("System.String")
            .PropertyName("FooProp");

            var descriptor = builder.Build();

            var tagHelperNode = new TagHelperIntermediateNode();
            var node          = new PreallocatedTagHelperPropertyIntermediateNode()
            {
                AttributeName  = descriptor.Name,
                BoundAttribute = descriptor,
                FieldName      = "__FooTagHelper",
                PropertyName   = "FooProp",
                VariableName   = "_tagHelper1",
            };

            tagHelperNode.Children.Add(node);
            Push(context, tagHelperNode);

            // Act
            extension.WriteTagHelperProperty(context, node);

            // Assert
            var csharp = context.CodeWriter.GenerateCode();

            Assert.Equal(
                @"__FooTagHelper.FooProp = (string)_tagHelper1.Value;
__tagHelperExecutionContext.AddTagHelperAttribute(_tagHelper1);
",
                csharp,
                ignoreLineEndingDifferences: true);
        }
Ejemplo n.º 28
0
            public override void VisitTagHelper(TagHelperIntermediateNode node)
            {
                if (node.Source != null)
                {
                    Items.Add(new InstrumentationItem(node, Parent, isLiteral: false, source: node.Source.Value));
                }

                // Inside a tag helper we only want to visit inside of the body (skip all of the attributes and properties).
                for (var i = 0; i < node.Children.Count; i++)
                {
                    var child = node.Children[i];
                    if (child is TagHelperBodyIntermediateNode ||
                        child is DefaultTagHelperBodyIntermediateNode)
                    {
                        VisitDefault(child);
                    }
                }
            }
        public void WriteTagHelperProperty_Runtime_NonStringProperty_RendersCorrectly_WithoutLocation()
        {
            // Arrange
            var extension = new DefaultTagHelperTargetExtension();
            var context   = TestCodeRenderingContext.CreateRuntime();

            var tagHelperNode = new TagHelperIntermediateNode();
            var node          = new DefaultTagHelperPropertyIntermediateNode()
            {
                AttributeName      = "bound",
                AttributeStructure = AttributeStructure.DoubleQuotes,
                BoundAttribute     = IntPropertyTagHelper.BoundAttributes.Single(),
                FieldName          = "__InputTagHelper",
                IsIndexerNameMatch = false,
                PropertyName       = "IntProp",
                TagHelper          = IntPropertyTagHelper,
                Children           =
                {
                    new CSharpExpressionIntermediateNode()
                    {
                        Children ={ new IntermediateToken                {
                          Kind = TokenKind.CSharp, Content = "32",
                      } },
                    }
                }
            };

            tagHelperNode.Children.Add(node);
            Push(context, tagHelperNode);

            // Act
            extension.WriteTagHelperProperty(context, node);

            // Assert
            var csharp = context.CodeWriter.GenerateCode();

            Assert.Equal(
                @"__InputTagHelper.IntProp = 32;
__tagHelperExecutionContext.AddTagHelperAttribute(""bound"", __InputTagHelper.IntProp, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
",
                csharp,
                ignoreLineEndingDifferences: true);
        }
Ejemplo n.º 30
0
        private MarkupElementIntermediateNode RewriteAsElement(TagHelperIntermediateNode node)
        {
            var result = new MarkupElementIntermediateNode()
            {
                Source  = node.Source,
                TagName = node.TagName,
            };

            for (var i = 0; i < node.Diagnostics.Count; i++)
            {
                result.Diagnostics.Add(node.Diagnostics[i]);
            }

            var visitor = new ElementRewriteVisitor(result.Children);

            visitor.Visit(node);

            return(result);
        }