public void DecorateCodeBuilder_DesignTimeRazorPathNormalizer_NormalizesChunkInheritanceUtilityPaths(
            string rootPrefix)
        {
            // Arrange
            var rootedAppPath  = $"{rootPrefix}SomeComputer/Location/Project/";
            var rootedFilePath = $"{rootPrefix}SomeComputer/Location/Project/src/file.cshtml";
            var host           = new MvcRazorHost(
                codeTreeCache: null,
                pathNormalizer: new DesignTimeRazorPathNormalizer(rootedAppPath));
            var chunkInheritanceUtility = new PathValidatingChunkInheritanceUtility(host);
            var codeBuilderContext      = new CodeBuilderContext(
                new CodeGeneratorContext(
                    host,
                    host.DefaultClassName,
                    host.DefaultNamespace,
                    rootedFilePath,
                    shouldGenerateLinePragmas: true),
                new ParserErrorSink());
            var codeBuilder = new CSharpCodeBuilder(codeBuilderContext);

            host.ChunkInheritanceUtility = chunkInheritanceUtility;

            // Act
            host.DecorateCodeBuilder(codeBuilder, codeBuilderContext);

            // Assert
            Assert.Equal("src/file.cshtml", chunkInheritanceUtility.InheritedCodeTreePagePath, StringComparer.Ordinal);
        }
        public virtual ProxyGeneratorBuildResult Build(
            Type proxyInterfaceType,
            IEnumerable <InterfaceDescription> interfaceDescriptions)
        {
            // create the context to build the proxy
            var context = new CodeBuilderContext(
                assemblyName: this.CodeBuilder.Names.GetProxyAssemblyName(proxyInterfaceType),
                assemblyNamespace: this.CodeBuilder.Names.GetProxyAssemblyNamespace(proxyInterfaceType),
                enableDebugging: CodeBuilderAttribute.IsDebuggingEnabled(proxyInterfaceType));
            var result = new ProxyGeneratorBuildResult(context);


            // build the proxy class that implements all of the interfaces explicitly
            result.ProxyType = this.BuildProxyType(context, proxyInterfaceType, interfaceDescriptions);

            // build the activator type to create instances of the proxy
            result.ProxyActivatorType = this.BuildProxyActivatorType(context, proxyInterfaceType, result.ProxyType);

            // build the proxy generator
            result.ProxyGenerator = this.CreateProxyGenerator(proxyInterfaceType,
                                                              result.ProxyActivatorType);

            context.Complete();
            return(result);
        }
Beispiel #3
0
        protected internal virtual GeneratorResults GenerateCodeCore(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 generator = CreateCodeGenerator(className, rootNamespace, sourceFileName);

            generator.DesignTimeMode = Host.DesignTimeMode;
            generator.Visit(results);

            var codeBuilderContext = new CodeBuilderContext(generator.Context);

            codeBuilderContext.Checksum = checksum;
            var builder       = CreateCodeBuilder(codeBuilderContext);
            var builderResult = builder.Build();

            // Collect results and return
            return(new GeneratorResults(results, builderResult, codeBuilderContext.CodeTreeBuilder.CodeTree));
        }
Beispiel #4
0
        public void CreateCodeBuilder_PassesCodeGeneratorThroughDecorateMethodOnHost()
        {
            // Arrange
            var mockHost = new Mock <RazorEngineHost>(new CSharpRazorCodeLanguage())
            {
                CallBase = true
            };
            var codeBuilderContext = new CodeBuilderContext(
                mockHost.Object,
                "different-class",
                "different-ns",
                string.Empty,
                shouldGenerateLinePragmas: true);

            var expected = new CSharpCodeBuilder(codeBuilderContext);

            mockHost.Setup(h => h.DecorateCodeBuilder(It.IsAny <CSharpCodeBuilder>(), codeBuilderContext))
            .Returns(expected);
            var engine = new RazorTemplateEngine(mockHost.Object);

            // Act
            var actual = engine.CreateCodeBuilder(codeBuilderContext);

            // Assert
            Assert.Equal(expected, actual);
        }
Beispiel #5
0
        public void CodeTreeWithUsings()
        {
            var syntaxTreeNode     = new Mock <Span>(new SpanBuilder());
            var language           = new CSharpRazorCodeLanguage();
            var host               = new RazorEngineHost(language);
            var codeBuilderContext = new CodeBuilderContext(
                host,
                "TestClass",
                "TestNamespace",
                "Foo.cs",
                shouldGenerateLinePragmas: false);

            codeBuilderContext.CodeTreeBuilder.AddUsingChunk("FakeNamespace1", syntaxTreeNode.Object);
            codeBuilderContext.CodeTreeBuilder.AddUsingChunk("FakeNamespace2.SubNamespace", syntaxTreeNode.Object);
            var codeBuilder = language.CreateCodeBuilder(codeBuilderContext);

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

            BaselineWriter.WriteBaseline(
                @"test\Microsoft.AspNet.Razor.Test\TestFiles\CodeGenerator\CS\Output\CSharpCodeBuilder.cs",
                result.Code);

            var expectedOutput = TestFile.Create("TestFiles/CodeGenerator/CS/Output/CSharpCodeBuilder.cs").ReadAllText();

            // Assert
            Assert.Equal(expectedOutput, result.Code);
        }
Beispiel #6
0
 public CSharpHelperVisitor([NotNull] CSharpCodeVisitor csharpCodeVisitor,
                            [NotNull] CSharpCodeWriter writer,
                            [NotNull] CodeBuilderContext context)
     : base(writer, context)
 {
     _csharpCodeVisitor = csharpCodeVisitor;
 }
 /// <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="CodeGeneratorContext"/> 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>
 public virtual void RenderAttributeValue([NotNull] TagHelperAttributeDescriptor attributeDescriptor,
                                          [NotNull] CSharpCodeWriter writer,
                                          [NotNull] CodeBuilderContext context,
                                          [NotNull] Action <CSharpCodeWriter> renderAttributeValue)
 {
     renderAttributeValue(writer);
 }
Beispiel #8
0
        public ProxyGeneratorBuildResult Build(
            Type proxyInterfaceType,
            IEnumerable <InterfaceDescription> interfaceDescriptions)
        {
            // create the context to build the proxy
            var context = new CodeBuilderContext(
                assemblyName: this.CodeBuilder.Names.GetProxyAssemblyName(proxyInterfaceType),
                assemblyNamespace: this.CodeBuilder.Names.GetProxyAssemblyNamespace(proxyInterfaceType),
                enableDebugging: CodeBuilderAttribute.IsDebuggingEnabled(proxyInterfaceType));
            var result = new ProxyGeneratorBuildResult(context);

            // ensure that method data types are built for each of the remote interfaces
            var methodBodyTypesResultsMap = interfaceDescriptions.ToDictionary(
                d => d,
                d => this.CodeBuilder.GetOrBuildMethodBodyTypes(d.InterfaceType));

            // build the proxy class that implements all of the interfaces explicitly
            result.ProxyType = this.BuildProxyType(context, proxyInterfaceType, methodBodyTypesResultsMap);

            // build the activator type to create instances of the proxy
            result.ProxyActivatorType = this.BuildProxyActivatorType(context, proxyInterfaceType, result.ProxyType);

            // build the proxy generator
            result.ProxyGenerator = this.CreateProxyGenerator(proxyInterfaceType, methodBodyTypesResultsMap,
                                                              result.ProxyActivatorType);

            context.Complete();
            return(result);
        }
Beispiel #9
0
 public TrackingUniqueIdsTagHelperCodeRenderer(
     IChunkVisitor bodyVisitor,
     CSharpCodeWriter writer,
     CodeBuilderContext context)
     : base(bodyVisitor, writer, context)
 {
 }
Beispiel #10
0
 public InjectChunkVisitor([NotNull] CSharpCodeWriter writer,
                           [NotNull] CodeBuilderContext context,
                           [NotNull] string injectAttributeName)
     : base(writer, context)
 {
     _injectAttribute = "[" + injectAttributeName + "]";
 }
Beispiel #11
0
 public InjectChunkVisitor([NotNull] CSharpCodeWriter writer,
                           [NotNull] CodeBuilderContext context,
                           [NotNull] string activateAttributeName)
     : base(writer, context)
 {
     _activateAttribute = '[' + activateAttributeName + ']';
 }
        /// <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([NotNull] TagHelperAttributeDescriptor attributeDescriptor,
                                                  [NotNull] CSharpCodeWriter writer,
                                                  [NotNull] CodeBuilderContext codeBuilderContext,
                                                  [NotNull] Action<CSharpCodeWriter> renderAttributeValue,
                                                  bool complexValue)
        {
            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,
                    codeBuilderContext,
                    renderAttributeValue,
                    complexValue);
            }
        }
Beispiel #13
0
        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("MyAttribute", "SomeProperty", propertyType);
            var writer           = new CSharpCodeWriter();
            var generatorContext = new CodeGeneratorContext(host: null,
                                                            className: string.Empty,
                                                            rootNamespace: string.Empty,
                                                            sourceFile: string.Empty,
                                                            shouldGenerateLinePragmas: true);
            var context = new CodeBuilderContext(generatorContext);

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

            // Assert
            Assert.Equal(expectedValue, writer.GenerateCode());
        }
 public CSharpTagHelperFieldDeclarationVisitor([NotNull] CSharpCodeWriter writer,
                                               [NotNull] CodeBuilderContext context)
     : base(writer, context)
 {
     _declaredTagHelpers = new HashSet <string>(StringComparer.Ordinal);
     _tagHelperContext   = Context.Host.GeneratedClassContext.GeneratedTagHelperContext;
 }
        public MethodDispatcherBuildResult Build(InterfaceDescription interfaceDescription)
        {
            var context = new CodeBuilderContext(
                assemblyName: this.CodeBuilder.Names.GetMethodDispatcherAssemblyName(interfaceDescription
                                                                                     .InterfaceType),
                assemblyNamespace: this.CodeBuilder.Names.GetMethodDispatcherAssemblyNamespace(interfaceDescription
                                                                                               .InterfaceType),
                enableDebugging: CodeBuilderAttribute.IsDebuggingEnabled(interfaceDescription.InterfaceType));

            var result = new MethodDispatcherBuildResult(context);

            // build dispatcher class
            var classBuilder = CodeBuilderUtils.CreateClassBuilder(
                context.ModuleBuilder,
                ns: context.AssemblyNamespace,
                className: this.CodeBuilder.Names.GetMethodDispatcherClassName(interfaceDescription.InterfaceType),
                baseType: this.MethodDispatcherBaseType);

            this.AddOnDispatchAsyncMethod(classBuilder, interfaceDescription);
            this.AddOnDispatchMethod(classBuilder, interfaceDescription);

            var methodNameMap = GetMethodNameMap(interfaceDescription);

            // create the dispatcher type, instantiate and initialize it
            result.MethodDispatcherType = classBuilder.CreateTypeInfo().AsType();
            result.MethodDispatcher     = (TMethodDispatcher)Activator.CreateInstance(result.MethodDispatcherType);
            var v2MethodDispatcherBase = (MethodDispatcherBase)result.MethodDispatcher;

            v2MethodDispatcherBase.Initialize(
                interfaceDescription,
                methodNameMap);

            context.Complete();
            return(result);
        }
Beispiel #16
0
 /// <summary>
 /// Gets an instance of the code builder and is provided an opportunity to decorate or replace it
 /// </summary>
 /// <param name="incomingBuilder">The code builder</param>
 /// <returns>Either the same code builder, after modifications, or a different code builder.</returns>
 public virtual CodeBuilder DecorateCodeBuilder(CodeBuilder incomingBuilder, CodeBuilderContext context)
 {
     if (incomingBuilder == null)
     {
         throw new ArgumentNullException("incomingBuilder");
     }
     return(incomingBuilder);
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="CSharpTagHelperAttributeValueVisitor"/> class.
 /// </summary>
 /// <param name="writer">The <see cref="CSharpCodeWriter"/> used to write code.</param>
 /// <param name="context">
 /// A <see cref="CodeBuilderContext"/> instance that contains information about the current code generation
 /// process.
 /// </param>
 /// <param name="attributeTypeName">
 /// Full name of the property <see cref="System.Type"/> for which this
 /// <see cref="CSharpTagHelperAttributeValueVisitor"/> is writing the value.
 /// </param>
 public CSharpTagHelperAttributeValueVisitor(
     CSharpCodeWriter writer,
     CodeBuilderContext context,
     string attributeTypeName)
     : base(writer, context)
 {
     _attributeTypeName = attributeTypeName;
 }
Beispiel #18
0
 public TestCSharpCodeBuilder(CodeBuilderContext context,
                              string defaultModel,
                              string activateAttribute,
                              GeneratedTagHelperAttributeContext tagHelperAttributeContext)
     : base(context, defaultModel, activateAttribute, tagHelperAttributeContext)
 {
     _tagHelperAttributeContext = tagHelperAttributeContext;
 }
            public override void RenderAttributeValue([NotNull] TagHelperAttributeDescriptor attributeInfo,
                                                      [NotNull] CSharpCodeWriter writer,
                                                      [NotNull] CodeBuilderContext context,
                                                      [NotNull] Action <CSharpCodeWriter> renderAttributeValue)
            {
                writer.Write("**From custom attribute code renderer**: ");

                base.RenderAttributeValue(attributeInfo, writer, context, renderAttributeValue);
            }
            protected override CSharpCodeVisitor CreateCSharpCodeVisitor([NotNull] CSharpCodeWriter writer,
                                                                         [NotNull] CodeBuilderContext context)
            {
                var bodyVisitor = base.CreateCSharpCodeVisitor(writer, context);

                bodyVisitor.TagHelperRenderer.AttributeValueCodeRenderer = new CustomTagHelperAttributeCodeRenderer();

                return(bodyVisitor);
            }
Beispiel #21
0
 public MvcCSharpCodeBuilder([NotNull] CodeBuilderContext context,
                             [NotNull] string defaultModel,
                             [NotNull] string activateAttribute,
                             [NotNull] GeneratedTagHelperAttributeContext tagHelperAttributeContext)
     : base(context)
 {
     _tagHelperAttributeContext = tagHelperAttributeContext;
     _defaultModel      = defaultModel;
     _activateAttribute = activateAttribute;
 }
 public CSharpLiteralCodeVisitor(
     CSharpTagHelperCodeRenderer tagHelperRenderer,
     CSharpCodeWriter writer,
     CodeBuilderContext context)
     : base(writer, context)
 {
     // Ensure that no matter how this class is used, we don't create numerous CSharpTagHelperCodeRenderer
     // instances.
     TagHelperRenderer = tagHelperRenderer;
 }
 /// <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="CodeBuilderContext"/> instance that contains information about
 /// the current code generation process.</param>
 public CSharpTagHelperCodeRenderer([NotNull] IChunkVisitor bodyVisitor,
                                    [NotNull] CSharpCodeWriter writer,
                                    [NotNull] CodeBuilderContext context)
 {
     _bodyVisitor               = bodyVisitor;
     _writer                    = writer;
     _context                   = context;
     _tagHelperContext          = context.Host.GeneratedClassContext.GeneratedTagHelperContext;
     AttributeValueCodeRenderer = new TagHelperAttributeValueCodeRenderer();
 }
Beispiel #24
0
        private static Mock <ChunkVisitor <CodeWriter> > CreateVisitor()
        {
            var codeBuilderContext = new CodeBuilderContext(
                new RazorEngineHost(new CSharpRazorCodeLanguage()),
                "myclass",
                "myns",
                string.Empty,
                shouldGenerateLinePragmas: false);
            var writer = Mock.Of <CodeWriter>();

            return(new Mock <ChunkVisitor <CodeWriter> >(writer, codeBuilderContext));
        }
Beispiel #25
0
        private Type BuildProxyActivatorType(
            CodeBuilderContext context,
            Type proxyInterfaceType,
            Type proxyType)
        {
            var classBuilder = CodeBuilderUtils.CreateClassBuilder(
                context.ModuleBuilder,
                ns: context.AssemblyNamespace,
                className: this.CodeBuilder.Names.GetProxyActivatorClassName(proxyInterfaceType),
                interfaces: new[] { typeof(IProxyActivator) });

            AddCreateInstanceMethod(classBuilder, proxyType);
            return(classBuilder.CreateTypeInfo().AsType());
        }
        /// <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="CodeBuilderContext"/> instance that contains information about
        /// the current code generation process.</param>
        public CSharpTagHelperCodeRenderer(
            [NotNull] IChunkVisitor bodyVisitor,
            [NotNull] CSharpCodeWriter writer,
            [NotNull] CodeBuilderContext 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();
        }
Beispiel #27
0
        public static CSharpCodeWriter RenderPreWriteStart(CSharpCodeWriter writer, CodeBuilderContext context)
        {
            if (!string.IsNullOrEmpty(context.TargetWriterName))
            {
                writer.WriteStartMethodInvocation(context.Host.GeneratedClassContext.WriteLiteralToMethodName)
                .Write(context.TargetWriterName)
                .WriteParameterSeparator();
            }
            else
            {
                writer.WriteStartMethodInvocation(context.Host.GeneratedClassContext.WriteLiteralMethodName);
            }

            return(writer);
        }
        private Type BuildProxyType(CodeBuilderContext context, Type proxyInterfaceType,
                                    IEnumerable <InterfaceDescription> interfaceDescriptions)
        {
            var classBuilder = CodeBuilderUtils.CreateClassBuilder(
                context.ModuleBuilder,
                ns: context.AssemblyNamespace,
                className: this.CodeBuilder.Names.GetProxyClassName(proxyInterfaceType),
                baseType: this.proxyBaseType,
                interfaces: interfaceDescriptions.Select(p => p.InterfaceType).ToArray());

            this.AddGetReturnValueMethod(classBuilder, interfaceDescriptions);
            this.AddInterfaceImplementations(classBuilder, interfaceDescriptions);

            return(classBuilder.CreateTypeInfo().AsType());
        }
Beispiel #29
0
        private Type BuildProxyType(
            CodeBuilderContext context,
            Type proxyInterfaceType,
            IDictionary <InterfaceDescription, MethodBodyTypesBuildResult> methodBodyTypesResultsMap)
        {
            var classBuilder = CodeBuilderUtils.CreateClassBuilder(
                context.ModuleBuilder,
                ns: context.AssemblyNamespace,
                className: this.CodeBuilder.Names.GetProxyClassName(proxyInterfaceType),
                baseType: this.proxyBaseType,
                interfaces: methodBodyTypesResultsMap.Select(item => item.Key.InterfaceType).ToArray());

            this.AddGetReturnValueMethod(classBuilder, methodBodyTypesResultsMap);
            this.AddInterfaceImplementations(classBuilder, methodBodyTypesResultsMap);

            return(classBuilder.CreateTypeInfo().AsType());
        }
Beispiel #30
0
        /// <inheritdoc />
        public override CodeBuilder DecorateCodeBuilder([NotNull] CodeBuilder incomingBuilder,
                                                        [NotNull] CodeBuilderContext context)
        {
            var inheritedChunks = ChunkInheritanceUtility.GetInheritedChunks(context.SourceFile);

            ChunkInheritanceUtility.MergeInheritedChunks(context.CodeTreeBuilder.CodeTree,
                                                         inheritedChunks,
                                                         DefaultModel);

            return(new MvcCSharpCodeBuilder(context,
                                            DefaultModel,
                                            ActivateAttribute,
                                            new GeneratedTagHelperAttributeContext
            {
                ModelExpressionTypeName = ModelExpressionType,
                CreateModelExpressionMethodName = CreateModelExpressionMethod
            }));
        }
Beispiel #31
0
 public CSharpCodeBuilder(CodeBuilderContext context)
     : base(context)
 {
 }
Beispiel #32
0
 public CodeBuilder(CodeBuilderContext context)
 {
     _context = context;
 }