/// <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(); }
public void DecorateCodeGenerator_DesignTimeRazorPathNormalizer_NormalizesChunkInheritanceUtilityPaths( string rootPrefix) { // Arrange var rootedAppPath = $"{rootPrefix}SomeComputer/Location/Project/"; var rootedFilePath = $"{rootPrefix}SomeComputer/Location/Project/src/file.cshtml"; var host = new MvcRazorHost( chunkTreeCache: null, pathNormalizer: new DesignTimeRazorPathNormalizer(rootedAppPath)); var chunkInheritanceUtility = new PathValidatingChunkInheritanceUtility(host); var codeGeneratorContext = new CodeGeneratorContext( new ChunkGeneratorContext( host, host.DefaultClassName, host.DefaultNamespace, rootedFilePath, shouldGenerateLinePragmas: true), new ErrorSink()); var codeGenerator = new CSharpCodeGenerator(codeGeneratorContext); host.ChunkInheritanceUtility = chunkInheritanceUtility; // Act host.DecorateCodeGenerator(codeGenerator, codeGeneratorContext); // Assert Assert.Equal("src/file.cshtml", chunkInheritanceUtility.InheritedChunkTreePagePath, StringComparer.Ordinal); }
public MvcCSharpCodeGenerator( CodeGeneratorContext context, string defaultModel, string injectAttribute, GeneratedTagHelperAttributeContext tagHelperAttributeContext) : base(context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (defaultModel == null) { throw new ArgumentNullException(nameof(defaultModel)); } if (injectAttribute == null) { throw new ArgumentNullException(nameof(injectAttribute)); } if (tagHelperAttributeContext == null) { throw new ArgumentNullException(nameof(tagHelperAttributeContext)); } _tagHelperAttributeContext = tagHelperAttributeContext; _defaultModel = defaultModel; _injectAttribute = injectAttribute; }
public MvcCSharpDesignTimeCodeVisitor( CSharpCodeVisitor csharpCodeVisitor, CSharpCodeWriter writer, CodeGeneratorContext context) : base(csharpCodeVisitor, writer, context) { }
/// <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); }
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); } }
public override CodeGenerator DecorateCodeGenerator(CodeGenerator incomingBuilder, CodeGeneratorContext context) { if (incomingBuilder is CodeGenTestCodeGenerator) { return incomingBuilder; } else { return new CodeGenTestCodeGenerator(context); } }
private static Mock<ChunkVisitor<CodeWriter>> CreateVisitor() { var codeGeneratorContext = new CodeGeneratorContext( new RazorEngineHost(new CSharpRazorCodeLanguage()), "myclass", "myns", string.Empty, shouldGenerateLinePragmas: false, errorSink: new ErrorSink()); var writer = Mock.Of<CodeWriter>(); return new Mock<ChunkVisitor<CodeWriter>>(writer, codeGeneratorContext); }
/// <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(); }
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)); } }
public void ChunkTreeWithUsings() { var syntaxTreeNode = new Mock<Span>(new SpanBuilder()); var language = new CSharpRazorCodeLanguage(); var host = new CodeGenTestHost(language); var codeGeneratorContext = new CodeGeneratorContext( host, "TestClass", "TestNamespace", "Foo.cs", shouldGenerateLinePragmas: false, errorSink: new ErrorSink()); codeGeneratorContext.ChunkTreeBuilder.AddUsingChunk("FakeNamespace1", syntaxTreeNode.Object); codeGeneratorContext.ChunkTreeBuilder.AddUsingChunk("FakeNamespace2.SubNamespace", syntaxTreeNode.Object); var codeGenerator = new CodeGenTestCodeGenerator(codeGeneratorContext); var testFile = TestFile.Create("TestFiles/CodeGenerator/Output/CSharpCodeGenerator.cs"); string expectedOutput; #if GENERATE_BASELINES if (testFile.Exists()) { expectedOutput = testFile.ReadAllText(); } else { expectedOutput = null; } #else expectedOutput = testFile.ReadAllText(); #endif // Act var result = codeGenerator.Generate(); // Assert #if GENERATE_BASELINES // Update baseline files if files do not already match. if (!string.Equals(expectedOutput, result.Code, StringComparison.Ordinal)) { BaselineWriter.WriteBaseline( @"test\Microsoft.AspNet.Razor.Test\TestFiles\CodeGenerator\Output\CSharpCodeGenerator.cs", result.Code); } #else Assert.Equal(expectedOutput, result.Code); #endif }
public CodeGenerator DecorateCodeGenerator(CodeGenerator incomingGenerator, CodeGeneratorContext context) { var inheritedChunkTrees = GetInheritedChunkTrees(context.SourceFile); ChunkInheritanceUtility.MergeInheritedChunkTrees( context.ChunkTreeBuilder.ChunkTree, inheritedChunkTrees, _host.DefaultModel); return new MyCSharpCodeGenerator( context, _host.DefaultModel, _host.InjectAttribute, new GeneratedTagHelperAttributeContext { ModelExpressionTypeName = _host.ModelExpressionType, CreateModelExpressionMethodName = _host.CreateModelExpressionMethod }); }
public void CreateCodeGenerator_ReturnsNewCSharpCodeGenerator() { // Arrange var language = new CSharpRazorCodeLanguage(); var host = new RazorEngineHost(language); var codeGeneratorContext = new CodeGeneratorContext( host, "myclass", "myns", string.Empty, shouldGenerateLinePragmas: false, errorSink: new ErrorSink()); // Act var generator = language.CreateCodeGenerator(codeGeneratorContext); // Assert Assert.IsType<CSharpCodeGenerator>(generator); }
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; }
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()); }
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 + "]"; }
/// <inheritdoc /> public override CodeGenerator DecorateCodeGenerator( CodeGenerator incomingGenerator, CodeGeneratorContext context) { if (incomingGenerator == null) { throw new ArgumentNullException(nameof(incomingGenerator)); } if (context == null) { throw new ArgumentNullException(nameof(context)); } var inheritedChunkTrees = GetInheritedChunkTrees(context.SourceFile); ChunkInheritanceUtility.MergeInheritedChunkTrees( context.ChunkTreeBuilder.ChunkTree, inheritedChunkTrees, DefaultModel); return new MvcCSharpCodeGenerator( context, DefaultModel, InjectAttribute, new GeneratedTagHelperAttributeContext { ModelExpressionTypeName = ModelExpressionType, CreateModelExpressionMethodName = CreateModelExpressionMethod }); }
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); }
/// <summary> /// Gets an instance of the code generator and is provided an opportunity to decorate or replace it /// </summary> /// <param name="incomingBuilder">The code generator</param> /// <returns>Either the same code generator, after modifications, or a different code generator.</returns> public virtual CodeGenerator DecorateCodeGenerator( CodeGenerator incomingBuilder, CodeGeneratorContext context) { if (incomingBuilder == null) { throw new ArgumentNullException(nameof(incomingBuilder)); } return incomingBuilder; }
protected internal virtual GeneratorResults GenerateCodeCore( [NotNull] ITextDocument input, string className, string rootNamespace, string sourceFileName, string checksum, CancellationToken? cancelToken) { className = (className ?? Host.DefaultClassName) ?? DefaultClassName; rootNamespace = (rootNamespace ?? Host.DefaultNamespace) ?? DefaultNamespace; // Run the parser var parser = CreateParser(sourceFileName); Debug.Assert(parser != null); var results = parser.Parse(input); // Generate code var chunkGenerator = CreateChunkGenerator(className, rootNamespace, sourceFileName); chunkGenerator.DesignTimeMode = Host.DesignTimeMode; chunkGenerator.Visit(results); var codeGeneratorContext = new CodeGeneratorContext(chunkGenerator.Context, results.ErrorSink); codeGeneratorContext.Checksum = checksum; var codeGenerator = CreateCodeGenerator(codeGeneratorContext); var codeGeneratorResult = codeGenerator.Generate(); // Collect results and return return new GeneratorResults(results, codeGeneratorResult, codeGeneratorContext.ChunkTreeBuilder.ChunkTree); }
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; }
public TestCSharpCodeGenerator( CodeGeneratorContext context, string defaultModel, string activateAttribute, GeneratedTagHelperAttributeContext tagHelperAttributeContext) : base(context, defaultModel, activateAttribute, tagHelperAttributeContext) { _tagHelperAttributeContext = tagHelperAttributeContext; }
public override CodeGenerator DecorateCodeGenerator( CodeGenerator incomingBuilder, CodeGeneratorContext context) { base.DecorateCodeGenerator(incomingBuilder, context); return new TestCSharpCodeGenerator( context, DefaultModel, "Microsoft.AspNet.Mvc.Razor.Internal.RazorInjectAttribute", new GeneratedTagHelperAttributeContext { ModelExpressionTypeName = ModelExpressionType, CreateModelExpressionMethodName = CreateModelExpressionMethod }); }
/// <summary> /// Gets an instance of the code generator and is provided an opportunity to decorate or replace it /// </summary> /// <param name="incomingBuilder">The code generator</param> /// <returns>Either the same code generator, after modifications, or a different code generator.</returns> public virtual CodeGenerator DecorateCodeGenerator( [NotNull] CodeGenerator incomingBuilder, CodeGeneratorContext context) { return incomingBuilder; }
protected internal virtual CodeGenerator CreateCodeGenerator(CodeGeneratorContext context) { return Host.DecorateCodeGenerator(Host.CodeLanguage.CreateCodeGenerator(context), context); }
public CodeGenTestCodeGenerator(CodeGeneratorContext context) : base(context) { }
public TrackingUniqueIdsTagHelperCodeRenderer( IChunkVisitor bodyVisitor, CSharpCodeWriter writer, CodeGeneratorContext context) : base(bodyVisitor, writer, context) { }
public MyCSharpCodeVisitor(CSharpCodeWriter writer, CodeGeneratorContext context) : base(writer, context) { Writer = writer; Context = context; }