/// <summary>
        /// Instantiates a new <see cref="CSharpTagHelperCodeRenderer"/>.
        /// </summary>
        /// <param name="bodyVisitor">The <see cref="IChunkVisitor"/> used to render chunks found in the body.</param>
        /// <param name="writer">The <see cref="CSharpCodeWriter"/> used to write code.</param>
        /// <param name="context">A <see cref="CodeGeneratorContext"/> instance that contains information about
        /// the current code generation process.</param>
        public CSharpTagHelperCodeRenderer(
            IChunkVisitor bodyVisitor,
            CSharpCodeWriter writer,
            CodeGeneratorContext context)
        {
            if (bodyVisitor == null)
            {
                throw new ArgumentNullException(nameof(bodyVisitor));
            }

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

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

            _bodyVisitor = bodyVisitor;
            _writer = writer;
            _context = context;
            _tagHelperContext = context.Host.GeneratedClassContext.GeneratedTagHelperContext;
            _designTimeMode = context.Host.DesignTimeMode;

            _literalBodyVisitor = new CSharpLiteralCodeVisitor(this, writer, context);
            AttributeValueCodeRenderer = new TagHelperAttributeValueCodeRenderer();
        }
示例#2
0
 private CSharpLineMappingWriter([NotNull] CSharpCodeWriter writer, bool addLineMappings)
 {
     _writer = writer;
     _addLineMapping = addLineMappings;
     _startIndent = _writer.CurrentIndent;
     _writer.ResetIndent();
 }
        public CSharpDisableWarningScope(CSharpCodeWriter writer, int warningNumber)
        {
            _writer = writer;
            _warningNumber = warningNumber;

            _writer.WritePragma("warning disable " + _warningNumber);
        }
        public void WriterConstructedWithoutContentLengthAndSourceFile_AddsLinePragmas_OnDispose()
        {
            // Arrange
            var location = new SourceLocation(10, 1, 20);
            var expected = string.Join(Environment.NewLine,
                                       @"#line 2 ""myfile""",
                                       "Hello world",
                                       "",
                                       "#line default",
                                       "#line hidden",
                                       "");
            var expectedMappings = new LineMapping(
                                new MappingLocation(location, 30),
                                new MappingLocation(new SourceLocation(18, 1, 0), 11));
            var writer = new CSharpCodeWriter();

            // Act
            using (var mappingWriter = new CSharpLineMappingWriter(writer, location, "myfile"))
            {
                writer.Write("Hello world");
            }

            // Assert
            Assert.Equal(expected, writer.GenerateCode());
            Assert.Empty(writer.LineMappingManager.Mappings);
        }
        protected override CSharpCodeWritingScope BuildClassDeclaration(CSharpCodeWriter writer)
        {
            // Grab the last model chunk so it gets intellisense.
            var modelChunk = ChunkHelper.GetModelChunk(Context.ChunkTreeBuilder.ChunkTree);

            Model = modelChunk != null ? modelChunk.ModelType : _defaultModel;

            // If there were any model chunks then we need to modify the class declaration signature.
            if (modelChunk != null)
            {
                writer.Write(string.Format(CultureInfo.InvariantCulture, "public class {0} : ", Context.ClassName));

                var modelVisitor = new ModelChunkVisitor(writer, Context);
                // This generates the base class signature
                modelVisitor.Accept(modelChunk);

                writer.WriteLine();

                return new CSharpCodeWritingScope(writer);
            }
            else
            {
                return base.BuildClassDeclaration(writer);
            }
        }
        /// <summary>
        /// Called during Razor's code generation process to generate code that instantiates the value of the tag
        /// helper's property. Last value written should not be or end with a semicolon.
        /// </summary>
        /// <param name="attributeDescriptor">
        /// The <see cref="TagHelperAttributeDescriptor"/> to generate code for.
        /// </param>
        /// <param name="writer">The <see cref="CSharpCodeWriter"/> that's used to write code.</param>
        /// <param name="context">A <see cref="Chunks.Generators.ChunkGeneratorContext"/> instance that contains
        /// information about the current code generation process.</param>
        /// <param name="renderAttributeValue">
        /// <see cref="Action"/> that renders the raw value of the HTML attribute.
        /// </param>
        /// <param name="complexValue">
        /// Indicates whether or not the source attribute value contains more than simple text. <c>false</c> for plain
        /// C# expressions e.g. <c>"PropertyName"</c>. <c>true</c> if the attribute value contain at least one in-line
        /// Razor construct e.g. <c>"@(@readonly)"</c>.
        /// </param>
        public virtual void RenderAttributeValue(
            TagHelperAttributeDescriptor attributeDescriptor,
            CSharpCodeWriter writer,
            CodeGeneratorContext context,
            Action<CSharpCodeWriter> renderAttributeValue,
            bool complexValue)
        {
            if (attributeDescriptor == null)
            {
                throw new ArgumentNullException(nameof(attributeDescriptor));
            }

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

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

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

            renderAttributeValue(writer);
        }
 public MvcCSharpDesignTimeCodeVisitor(
     CSharpCodeVisitor csharpCodeVisitor,
     CSharpCodeWriter writer,
     CodeGeneratorContext context)
     : base(csharpCodeVisitor, writer, context)
 {
 }
        public void Visit_GeneratesProperties_ForInjectChunks()
        {
            // Arrange
            var expected =
@"[ActivateAttribute]
public MyType1 MyPropertyName1 { get; private set; }
[ActivateAttribute]
public MyType2 @MyPropertyName2 { get; private set; }
";
            var writer = new CSharpCodeWriter();
            var context = CreateContext();

            var visitor = new InjectChunkVisitor(writer, context, "ActivateAttribute");
            var factory = SpanFactory.CreateCsHtml();
            var node = (Span)factory.Code("Some code")
                                    .As(new InjectParameterGenerator("MyType", "MyPropertyName"));

            // Act
            visitor.Accept(new Chunk[]
            {
                new LiteralChunk(),
                new InjectChunk("MyType1", "MyPropertyName1") { Association = node },
                new InjectChunk("MyType2", "@MyPropertyName2") { Association = node }
            });
            var code = writer.GenerateCode();

            // Assert
            Assert.Equal(expected, code);
        }
        protected override CSharpCodeVisitor CreateCSharpCodeVisitor(CSharpCodeWriter writer, CodeGeneratorContext context)
        {
            var csharpCodeVisitor = new MyCSharpCodeVisitor(writer, context);

            csharpCodeVisitor.TagHelperRenderer.AttributeValueCodeRenderer =
                new MvcTagHelperAttributeValueCodeRenderer(_tagHelperAttributeContext);

            return csharpCodeVisitor;
        }
            protected override CSharpCodeVisitor CreateCSharpCodeVisitor(
                CSharpCodeWriter writer,
                CodeGeneratorContext context)
            {
                var bodyVisitor = base.CreateCSharpCodeVisitor(writer, context);

                bodyVisitor.TagHelperRenderer.AttributeValueCodeRenderer = new CustomTagHelperAttributeCodeRenderer();

                return bodyVisitor;
            }
        /// <inheritdoc />
        /// <remarks>If the attribute being rendered is of the type
        /// <see cref="GeneratedTagHelperAttributeContext.ModelExpressionTypeName"/>, then a model expression will be
        /// created by calling into <see cref="GeneratedTagHelperAttributeContext.CreateModelExpressionMethodName"/>.
        /// </remarks>
        public override void RenderAttributeValue(
            TagHelperAttributeDescriptor attributeDescriptor,
            CSharpCodeWriter writer,
            CodeGeneratorContext codeGeneratorContext,
            Action<CSharpCodeWriter> renderAttributeValue,
            bool complexValue)
        {
            if (attributeDescriptor == null)
            {
                throw new ArgumentNullException(nameof(attributeDescriptor));
            }

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

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

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

            if (attributeDescriptor.TypeName.Equals(_context.ModelExpressionTypeName, StringComparison.Ordinal))
            {
                writer
                    .WriteStartMethodInvocation(_context.CreateModelExpressionMethodName)
                    .Write(ModelLambdaVariableName)
                    .Write(" => ");
                if (!complexValue)
                {
                    writer
                        .Write(ModelLambdaVariableName)
                        .Write(".");

                }

                renderAttributeValue(writer);

                writer.WriteEndMethodInvocation(endLine: false);
            }
            else
            {
                base.RenderAttributeValue(
                    attributeDescriptor,
                    writer,
                    codeGeneratorContext,
                    renderAttributeValue,
                    complexValue);
            }
        }
        private CSharpLineMappingWriter(CSharpCodeWriter writer, bool addLineMappings)
        {
            if (writer == null)
            {
                throw new ArgumentNullException(nameof(writer));
            }

            _writer = writer;
            _addLineMapping = addLineMappings;
            _startIndent = _writer.CurrentIndent;
            _writer.ResetIndent();
        }
        public CSharpLineMappingWriter(
            CSharpCodeWriter writer,
            SourceLocation documentLocation,
            int contentLength,
            string sourceFilename)
            : this(writer, documentLocation, contentLength)
        {
            _writePragmas = true;

            _writer.WriteLineNumberDirective(documentLocation, sourceFilename);
            _generatedLocation = _writer.GetCurrentSourceLocation();
        }
        /// <summary>
        /// Instantiates a new <see cref="CSharpTagHelperCodeRenderer"/>.
        /// </summary>
        /// <param name="bodyVisitor">The <see cref="IChunkVisitor"/> used to render chunks found in the body.</param>
        /// <param name="writer">The <see cref="CSharpCodeWriter"/> used to write code.</param>
        /// <param name="context">A <see cref="CodeGeneratorContext"/> instance that contains information about
        /// the current code generation process.</param>
        public CSharpTagHelperCodeRenderer(
            [NotNull] IChunkVisitor bodyVisitor,
            [NotNull] CSharpCodeWriter writer,
            [NotNull] CodeGeneratorContext context)
        {
            _bodyVisitor = bodyVisitor;
            _writer = writer;
            _context = context;
            _tagHelperContext = context.Host.GeneratedClassContext.GeneratedTagHelperContext;
            _designTimeMode = context.Host.DesignTimeMode;

            _literalBodyVisitor = new CSharpLiteralCodeVisitor(this, writer, context);
            AttributeValueCodeRenderer = new TagHelperAttributeValueCodeRenderer();
        }
        /// <summary>
        /// Initializes a new instance of <see cref="CSharpLineMappingWriter"/> used for generation of runtime
        /// line mappings. The constructed instance of <see cref="CSharpLineMappingWriter"/> does not track
        /// mappings between the Razor content and the generated content.
        /// </summary>
        /// <param name="writer">The <see cref="CSharpCodeWriter"/> to write output to.</param>
        /// <param name="documentLocation">The <see cref="SourceLocation"/> of the Razor content being mapping.</param>
        /// <param name="sourceFileName">The input file path.</param>
        public CSharpLineMappingWriter(
            CSharpCodeWriter writer,
            SourceLocation documentLocation,
            string sourceFileName)
            : this(writer, addLineMappings: false)
        {
            if (writer == null)
            {
                throw new ArgumentNullException(nameof(writer));
            }

            _writePragmas = true;
            _writer.WriteLineNumberDirective(documentLocation, sourceFileName);
        }
示例#16
0
        /// <summary>
        /// Instantiates a new <see cref="CSharpTagHelperCodeRenderer"/>.
        /// </summary>
        /// <param name="bodyVisitor">The <see cref="IChunkVisitor"/> used to render chunks found in the body.</param>
        /// <param name="writer">The <see cref="CSharpCodeWriter"/> used to write code.</param>
        /// <param name="context">A <see cref="CodeGeneratorContext"/> instance that contains information about
        /// the current code generation process.</param>
        public CSharpTagHelperCodeRenderer(
            [NotNull] IChunkVisitor bodyVisitor,
            [NotNull] CSharpCodeWriter writer,
            [NotNull] CodeGeneratorContext context)
        {
            _bodyVisitor      = bodyVisitor;
            _writer           = writer;
            _context          = context;
            _tagHelperContext = context.Host.GeneratedClassContext.GeneratedTagHelperContext;
            _designTimeMode   = context.Host.DesignTimeMode;

            _literalBodyVisitor        = new CSharpLiteralCodeVisitor(this, writer, context);
            AttributeValueCodeRenderer = new TagHelperAttributeValueCodeRenderer();
        }
        protected override CSharpCodeWritingScope BuildClassDeclaration(CSharpCodeWriter writer)
        {
            if (Context.Host.DesignTimeMode &&
                string.Equals(
                    Path.GetFileName(Context.SourceFile),
                    ViewHierarchyUtility.ViewImportsFileName,
                    StringComparison.OrdinalIgnoreCase))
            {
                // Write a using TModel = System.Object; token during design time to make intellisense work
                writer.WriteLine($"using {ChunkHelper.TModelToken} = {typeof(object).FullName};");
            }

            return base.BuildClassDeclaration(writer);
        }
        /// <summary>
        /// Initializes a new instance of <see cref="CSharpLineMappingWriter"/> used for generation of runtime
        /// line mappings. The constructed instance of <see cref="CSharpLineMappingWriter"/> does not track
        /// mappings between the Razor content and the generated content.
        /// </summary>
        /// <param name="writer">The <see cref="CSharpCodeWriter"/> to write output to.</param>
        /// <param name="documentLocation">The <see cref="SourceLocation"/> of the Razor content being mapping.</param>
        /// <param name="sourceFileName">The input file path.</param>
        public CSharpLineMappingWriter(
            CSharpCodeWriter writer,
            SourceLocation documentLocation,
            string sourceFileName)
            : this(writer, addLineMappings : false)
        {
            if (writer == null)
            {
                throw new ArgumentNullException(nameof(writer));
            }

            _writePragmas = true;
            _writer.WriteLineNumberDirective(documentLocation, sourceFileName);
        }
示例#19
0
 private void RenderBufferedAttributeValueAccessor(CSharpCodeWriter writer)
 {
     if (_designTimeMode)
     {
         // There is no value buffer in design time mode but we still want to write out a value. We write a
         // value to ensure the tag helper's property type is string.
         writer.Write("string.Empty");
     }
     else
     {
         writer.WriteInstanceMethodInvocation(StringValueBufferVariableName,
                                              "ToString",
                                              endLine: false);
     }
 }
示例#20
0
        public void WriteLineNumberDirective_UsesFilePath_WhenFileInSourceLocationIsNull()
        {
            // Arrange
            var filePath = "some-path";
            var writer = new CSharpCodeWriter();
            var expected = $"#line 5 \"{filePath}\"" + writer.NewLine;
            var sourceLocation = new SourceLocation(10, 4, 3);

            // Act
            writer.WriteLineNumberDirective(sourceLocation, filePath);
            var code = writer.GenerateCode();

            // Assert
            Assert.Equal(expected, code);
        }
示例#21
0
        public MvcCSharpCodeVisitor(
            CSharpCodeWriter writer,
            CodeGeneratorContext context)
            : base(writer, context)
        {
            if (writer == null)
            {
                throw new ArgumentNullException(nameof(writer));
            }

            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
        }
示例#22
0
        public void WriteLineNumberDirective_UsesFilePath_WhenFileInSourceLocationIsNull()
        {
            // Arrange
            var filePath       = "some-path";
            var writer         = new CSharpCodeWriter();
            var expected       = $"#line 5 \"{filePath}\"" + writer.NewLine;
            var sourceLocation = new SourceLocation(10, 4, 3);

            // Act
            writer.WriteLineNumberDirective(sourceLocation, filePath);
            var code = writer.GenerateCode();

            // Assert
            Assert.Equal(expected, code);
        }
示例#23
0
        protected virtual CSharpCodeVisitor CreateCSharpCodeVisitor(
            CSharpCodeWriter writer,
            CodeGeneratorContext context)
        {
            if (writer == null)
            {
                throw new ArgumentNullException(nameof(writer));
            }

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

            return(new CSharpCodeVisitor(writer, context));
        }
 private void RenderBufferedAttributeValueAccessor(CSharpCodeWriter writer)
 {
     if (_designTimeMode)
     {
         // There is no value buffer in design time mode but we still want to write out a value. We write a
         // value to ensure the tag helper's property type is string.
         writer.Write("string.Empty");
     }
     else
     {
         writer.WriteInstanceMethodInvocation(
             StringValueBufferVariableName,
             _tagHelperContext.TagHelperContentGetContentMethodName,
             endLine: false,
             parameters: new string[] { _tagHelperContext.HtmlEncoderPropertyName });
     }
 }
示例#25
0
        public void Visit_IgnoresNonInjectChunks()
        {
            // Arrange
            var writer = new CSharpCodeWriter();
            var context = CreateContext();

            var visitor = new InjectChunkVisitor(writer, context, "ActivateAttribute");

            // Act
            visitor.Accept(new Chunk[]
            {
                new LiteralChunk(),
                new CodeAttributeChunk()
            });
            var code = writer.GenerateCode();

            // Assert
            Assert.Empty(code);
        }
        public void WriterConstructedWithContentLength_AddsLineMappings_OnDispose()
        {
            // Arrange
            var location = new SourceLocation(10, 15, 20);
            var expected = new LineMapping(
                                new MappingLocation(location, 30),
                                new MappingLocation(new SourceLocation(0, 0, 0), 11));
            var writer = new CSharpCodeWriter();

            // Act
            using (var mappingWriter = new CSharpLineMappingWriter(writer, location, 30))
            {
                writer.Write("Hello world");
            }

            // Assert
            Assert.Equal("Hello world", writer.GenerateCode());
            var mapping = Assert.Single(writer.LineMappingManager.Mappings);
            Assert.Equal(expected, mapping);
        }
        protected override CSharpCodeVisitor CreateCSharpCodeVisitor(
            CSharpCodeWriter writer,
            CodeGeneratorContext context)
        {
            if (writer == null)
            {
                throw new ArgumentNullException(nameof(writer));
            }

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

            var csharpCodeVisitor = base.CreateCSharpCodeVisitor(writer, context);

            csharpCodeVisitor.TagHelperRenderer.AttributeValueCodeRenderer =
                new MvcTagHelperAttributeValueCodeRenderer(_tagHelperAttributeContext);

            return csharpCodeVisitor;
        }
示例#28
0
        public void WriterConstructedWithContentLength_AddsLineMappings_OnDispose()
        {
            // Arrange
            var location = new SourceLocation(10, 15, 20);
            var expected = new LineMapping(
                new MappingLocation(location, 30),
                new MappingLocation(new SourceLocation(0, 0, 0), 11));
            var writer = new CSharpCodeWriter();

            // Act
            using (var mappingWriter = new CSharpLineMappingWriter(writer, location, 30))
            {
                writer.Write("Hello world");
            }

            // Assert
            Assert.Equal("Hello world", writer.GenerateCode());
            var mapping = Assert.Single(writer.LineMappingManager.Mappings);

            Assert.Equal(expected, mapping);
        }
        public void RenderAttributeValue_RendersModelExpressionsCorrectly(
            string modelExpressionType,
            string propertyType,
            string expectedValue)
        {
            // Arrange
            var renderer = new MvcTagHelperAttributeValueCodeRenderer(
                new GeneratedTagHelperAttributeContext
                {
                    ModelExpressionTypeName = modelExpressionType,
                    CreateModelExpressionMethodName = "SomeMethod"
                });
            var attributeDescriptor = new TagHelperAttributeDescriptor
            {
                Name = "MyAttribute",
                PropertyName = "SomeProperty",
                TypeName = propertyType,
            };
            var writer = new CSharpCodeWriter();
            var generatorContext = new ChunkGeneratorContext(
                host: null,
                className: string.Empty,
                rootNamespace: string.Empty,
                sourceFile: string.Empty,
                shouldGenerateLinePragmas: true);
            var errorSink = new ErrorSink();
            var context = new CodeGeneratorContext(generatorContext, errorSink);

            // Act
            renderer.RenderAttributeValue(attributeDescriptor, writer, context,
            (codeWriter) =>
            {
                codeWriter.Write("MyValue");
            },
            complexValue: false);

            // Assert
            Assert.Equal(expectedValue, writer.GenerateCode());
        }
示例#30
0
        public InjectChunkVisitor(
            CSharpCodeWriter writer,
            CodeGeneratorContext context,
            string injectAttributeName)
            : base(writer, context)
        {
            if (writer == null)
            {
                throw new ArgumentNullException(nameof(writer));
            }

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

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

            _injectAttribute = "[" + injectAttributeName + "]";
        }
 public TagHelperAttributeCodeVisitor(
     CSharpCodeWriter writer,
     CodeGeneratorContext context)
     : base(writer, context)
 {
 }
 public CSharpLineMappingWriter(CSharpCodeWriter writer, SourceLocation documentLocation, int contentLength)
     : this(writer, addLineMappings: true)
 {
     _documentMapping = new MappingLocation(documentLocation, contentLength);
     _generatedLocation = _writer.GetCurrentSourceLocation();
 }
示例#33
0
 protected virtual CSharpCodeVisitor CreateCSharpCodeVisitor([NotNull] CSharpCodeWriter writer,
                                                             [NotNull] CodeGeneratorContext context)
 {
     return(new CSharpCodeVisitor(writer, context));
 }
            public TrackingUniqueIdsTagHelperCodeRenderer(
                IChunkVisitor bodyVisitor,
                CSharpCodeWriter writer,
                CodeGeneratorContext context)
                : base(bodyVisitor, writer, context)
            {

            }
 private static TrackingUniqueIdsTagHelperCodeRenderer CreateCodeRenderer()
 {
     var writer = new CSharpCodeWriter();
     var codeGeneratorContext = CreateContext();
     var visitor = new CSharpCodeVisitor(writer, codeGeneratorContext);
     var codeRenderer = new TrackingUniqueIdsTagHelperCodeRenderer(
         visitor,
         writer,
         codeGeneratorContext);
     visitor.TagHelperRenderer = codeRenderer;
     return codeRenderer;
 }
示例#36
0
 public CSharpLineMappingWriter(CSharpCodeWriter writer, SourceLocation documentLocation, int contentLength)
     : this(writer, addLineMappings : true)
 {
     _documentMapping   = new MappingLocation(documentLocation, contentLength);
     _generatedLocation = _writer.GetCurrentSourceLocation();
 }
 public CSharpDisableWarningScope(CSharpCodeWriter writer) : this(writer, 219)
 { }
 public CSharpDisableWarningScope(CSharpCodeWriter writer) : this(writer, 219)
 {
 }
示例#39
0
 protected override CSharpCodeVisitor CreateCSharpCodeVisitor(
     CSharpCodeWriter writer,
     CodeGeneratorContext context)
 {
     var visitor = base.CreateCSharpCodeVisitor(writer, context);
     visitor.TagHelperRenderer = new NoUniqueIdsTagHelperCodeRenderer(visitor, writer, context)
     {
         AttributeValueCodeRenderer =
             new MvcTagHelperAttributeValueCodeRenderer(_tagHelperAttributeContext)
     };
     return visitor;
 }
        protected override CSharpDesignTimeCodeVisitor CreateCSharpDesignTimeCodeVisitor(
            CSharpCodeVisitor csharpCodeVisitor,
            CSharpCodeWriter writer,
            CodeGeneratorContext context)
        {
            if (csharpCodeVisitor == null)
            {
                throw new ArgumentNullException(nameof(csharpCodeVisitor));
            }

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

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

            return new MvcCSharpDesignTimeCodeVisitor(csharpCodeVisitor, writer, context);
        }
        protected override void BuildConstructor(CSharpCodeWriter writer)
        {
            if (writer == null)
            {
                throw new ArgumentNullException(nameof(writer));
            }

            base.BuildConstructor(writer);

            writer.WriteLineHiddenDirective();

            var injectVisitor = new InjectChunkVisitor(writer, Context, _injectAttribute);
            injectVisitor.Accept(Context.ChunkTreeBuilder.Root.Children);

            writer.WriteLine();
            writer.WriteLineHiddenDirective();
        }